Portal Spring Boot Development
[portal.git] / ecomp-portal-widget-ms / widget-ms / src / main / java / org / onap / portalapp / widget / service / impl / StorageServiceImpl.java
1 package org.onap.portalapp.widget.service.impl;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.UnsupportedEncodingException;
8 import java.nio.file.Files;
9 import java.nio.file.Paths;
10 import java.util.Arrays;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15 import java.util.zip.ZipEntry;
16 import java.util.zip.ZipOutputStream;
17
18 import org.hibernate.Criteria;
19 import org.hibernate.Session;
20 import org.hibernate.SessionFactory;
21 import org.hibernate.Transaction;
22 import org.hibernate.criterion.Restrictions;
23 import org.onap.portalapp.widget.constant.WidgetConstant;
24 import org.onap.portalapp.widget.domain.ValidationRespond;
25 import org.onap.portalapp.widget.domain.WidgetCatalog;
26 import org.onap.portalapp.widget.domain.WidgetFile;
27 import org.onap.portalapp.widget.excetpion.StorageException;
28 import org.onap.portalapp.widget.service.StorageService;
29 import org.onap.portalapp.widget.service.WidgetCatalogService;
30 import org.onap.portalapp.widget.utils.UnzipUtil;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.stereotype.Service;
35 import org.springframework.transaction.annotation.Transactional;
36 import org.springframework.web.multipart.MultipartFile;
37
38 @Service
39 public class StorageServiceImpl implements StorageService {
40
41         private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class);
42
43         @Autowired
44         private SessionFactory sessionFactory;
45
46         @Autowired
47         WidgetCatalogService widgetCatalogService;
48
49         @Override
50         @Transactional
51         public void deleteWidgetFile(long widgetId) {
52                 WidgetFile widgetFile = getWidgetFile(widgetId);
53                 logger.debug("StorageServiceImpl.deleteWidgetFile: deleting widget file {}", widgetId);
54                 if (widgetFile == null) {
55                         logger.debug(
56                                         "StorageServiceImpl.deleteWidgetFile: No widget file found in database while performing StorageServiceImpl.deleteWidgetFile.");
57                         return;
58                 }
59                 Session session = sessionFactory.getCurrentSession();
60                 Transaction tx = session.beginTransaction();
61                 session.delete(widgetFile);
62                 tx.commit();
63         }
64
65         @Override
66         @SuppressWarnings("unchecked")
67         @Transactional
68         public WidgetFile getWidgetFile(long widgetId) {
69                 logger.debug("StorageServiceImpl.getWidgetFile: getting widget file {}", widgetId);
70                 WidgetFile widgetFile = null;
71                 Session session = sessionFactory.openSession();
72                 Criteria criteria = session.createCriteria(WidgetFile.class);
73                 criteria.add(Restrictions.eq("widgetId", widgetId));
74                 List<WidgetFile> widgetFiles = criteria.list();
75                 session.flush();
76                 session.close();
77                 if (widgetFiles.size() > 0)
78                         widgetFile = widgetFiles.get(0);
79                 return widgetFile;
80         }
81
82         @Override
83         public ValidationRespond checkZipFile(MultipartFile file) {
84                 StringBuilder error_msg = new StringBuilder();
85                 UnzipUtil unzipper = new UnzipUtil();
86                 Map<String, byte[]> map;
87                 File convFile;
88                 boolean isValid = true;
89                 if (!file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).equals(".zip")) {
90                         isValid = false;
91                         error_msg.append(WidgetConstant.VALIDATION_MESSAGE_ZIP);
92                         logger.error("StorageServiceImpl.checkZipFile: invalid file format");
93                 }
94                 try {
95                         if (file.isEmpty()) {
96                                 logger.error(
97                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
98                                 throw new StorageException(
99                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
100                         }
101                         String fileLocation = file.getOriginalFilename();
102                         logger.debug("StorageServiceImpl.checkZipFile: store the widget to:" + fileLocation);
103                         convFile = new File(fileLocation);
104                         try(FileOutputStream fos = new FileOutputStream(convFile)){
105                                 fos.write(file.getBytes());
106                         }
107                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
108                         convFile.delete();
109                 } catch (IOException e) {
110                         logger.error("StorageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
111                         throw new StorageException(
112                                         "torageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
113                 }
114
115                 for (byte[] b : map.values()) {
116                         if (isValid && b == null) {
117                                 isValid = false;
118                                 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_FILES);
119                                 break;
120                         }
121                 }
122                 return new ValidationRespond(isValid, error_msg.toString());
123         }
124
125         @Override
126         @Transactional
127         public void save(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
128
129                 UnzipUtil unzipper = new UnzipUtil();
130                 Map<String, byte[]> map;
131                 File convFile;
132                 try {
133                         if (file.isEmpty()) {
134                                 logger.error("Failed to store empty file " + file.getOriginalFilename());
135                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
136                         }
137                         String fileLocation = file.getOriginalFilename();
138                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
139                         convFile = new File(fileLocation);
140                         try(FileOutputStream fos = new FileOutputStream(convFile)){
141                                 fos.write(file.getBytes());
142                         }
143                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
144                         convFile.delete();
145                 } catch (IOException e) {
146                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getOriginalFilename(), e);
147                         throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
148                 }
149                 saveHelper(newWidget, widgetId, map);
150         }
151
152         @Override
153         @Transactional
154         public void initSave(File file, WidgetCatalog newWidget, long widgetId) {
155
156                 UnzipUtil unzipper = new UnzipUtil();
157                 Map<String, byte[]> map;
158
159                 try {
160                         String fileLocation = file.getPath();
161                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
162                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
163                 } catch (IOException e) {
164                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getName(), e);
165                         throw new StorageException("Failed to store file " + file.getName(), e);
166                 }
167                 
168                 saveHelper(newWidget, widgetId, map);
169         }
170
171         /**
172          * Helper method for saving widget files (controller.js, framework.js,
173          * markup.html and style.css) to ep_widget_catalog_files table in database
174          * 
175          * @param newWidget
176          * @param widgetId
177          * @param map
178          */
179         private void saveHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
180
181                 logger.debug("Going to save widget " + newWidget);
182                 WidgetFile widgetFile = new WidgetFile();
183                 widgetFile.setName(newWidget.getName());
184                 widgetFile.setWidgetId(widgetId);
185
186                 
187
188                 String sb = null;
189                 try(InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js")) {
190                         byte[] bytes = new byte[fileInputStream.available()];
191                         if(fileInputStream.read(bytes) > 0) {
192                                 sb = new String(bytes, "UTF-8");
193                         }
194                 } catch (IOException e) {
195                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
196                 }
197
198                 String namespace = "Portal" + widgetId + "Widget";
199                 String controllerName = "Portal" + widgetId + "Ctrl";
200                 String cssName = "portal" + widgetId + "-css-ready";
201                 String colorArg1 = "color: #fff";
202                 String framework="";
203                 if(sb!=null) {
204                         framework = sb.replaceAll("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
205                                         .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
206                                         .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
207                                         .replaceAll("WIDGET_ID", Long.toString(widgetId));
208                 }
209                 widgetFile.setFramework(framework.getBytes());
210
211                 final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION);
212                 if (controllerLoc == null || controllerLoc.length == 0)
213                         throw new IllegalArgumentException(
214                                         "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION);
215                 String javascript = new String(controllerLoc);
216                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
217                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
218                 javascript = javascript.replaceFirst(functionName, controllerName);
219                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
220                 List<String> paramList = Arrays.asList(functionParam.split(","));
221
222                 int left_bracket_index = javascript.indexOf("{") + 1;
223                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
224                 javascript = javascript.substring(0, left_bracket_index) + widgetData
225                                 + javascript.substring(left_bracket_index);
226
227                 StringBuilder injectStr = new StringBuilder().append("[");
228                 for (int i = 0; i < paramList.size(); i++) {
229                         if (i == paramList.size() - 1)
230                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
231                         else
232                                 injectStr.append("'" + paramList.get(i).trim() + "',");
233                 }
234                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
235                                 + injectStr.toString();
236
237                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
238                                 controllerName);
239                 ;
240
241                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
242                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
243                 if (cssMatcher.find()) {
244                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
245                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
246                 }
247
248                 widgetFile.setMarkup(html.getBytes());
249                 widgetFile.setController(javascript.getBytes());
250                 Session session = sessionFactory.openSession();
251                 session.save(widgetFile);
252                 session.flush();
253                 session.close();
254                 // sessionFactory.getCurrentSession().save(widgetFile);
255                 logger.debug(
256                                 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
257                                 widgetId);
258
259         }
260
261         @Override
262         public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
263                 UnzipUtil unzipper = new UnzipUtil();
264                 Map<String, byte[]> map;
265                 File convFile;
266                 try {
267                         if (file.isEmpty()) {
268                                 logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename());
269                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
270                         }
271                         String fileLocation = file.getOriginalFilename();
272                         logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
273                         convFile = new File(fileLocation);
274                         try(FileOutputStream fos = new FileOutputStream(convFile)){
275                                 fos.write(file.getBytes());
276                         }
277                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
278                         convFile.delete();
279                 } catch (IOException e) {
280                         logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
281                         throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
282                                         e);
283                 }
284                 WidgetFile widgetFile = getWidgetFile(widgetId);
285
286                 String sb = null;
287                 try(InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js")){
288                         byte[] bytes = new byte[fileInputStream.available()];
289                         if(fileInputStream.read(bytes) > 0) {
290                                 sb = new String(bytes, "UTF-8");
291                         }
292                 } catch (IOException e) {
293                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
294                 }
295
296                 String namespace = "Portal" + widgetId + "Widget";
297                 String controllerName = "Portal" + widgetId + "Ctrl";
298                 String cssName = "portal" + widgetId + "-css-ready";
299                 String colorArg1 = "color: #fff";
300                 String framework="";
301                 if(sb!=null) {
302                         framework = sb.replaceAll("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
303                                         .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
304                                         .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
305                                         .replaceAll("WIDGET_ID", Long.toString(widgetId));
306                 }
307                 widgetFile.setFramework(framework.getBytes());
308
309                 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
310                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
311                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
312                 javascript = javascript.replaceFirst(functionName, controllerName);
313                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
314                 List<String> paramList = Arrays.asList(functionParam.split(","));
315
316                 int left_bracket_index = javascript.indexOf("{") + 1;
317                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
318                 javascript = javascript.substring(0, left_bracket_index) + widgetData
319                                 + javascript.substring(left_bracket_index);
320
321                 StringBuilder injectStr = new StringBuilder().append("[");
322                 for (int i = 0; i < paramList.size(); i++) {
323                         if (i == paramList.size() - 1)
324                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
325                         else
326                                 injectStr.append("'" + paramList.get(i).trim() + "',");
327                 }
328                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
329                                 + injectStr.toString();
330
331                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
332                                 controllerName);
333                 ;
334
335                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
336                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
337                 if (cssMatcher.find()) {
338                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
339                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
340                 }
341
342                 widgetFile.setMarkup(html.getBytes());
343                 widgetFile.setController(javascript.getBytes());
344                 // widgetFile.setCss(map.get(WidgetConstant.WIDGET_STYLE_LOCATION));
345                 Session session = sessionFactory.openSession();
346                 Transaction tx = session.beginTransaction();
347                 session.update(widgetFile);
348                 tx.commit();
349                 session.flush();
350                 session.close();
351                 logger.debug(
352                                 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
353                                 widgetId);
354         }
355
356         @Override
357         @SuppressWarnings("unchecked")
358         @Transactional
359         public String getWidgetMarkup(long widgetId) throws UnsupportedEncodingException {
360                 String markup = null;
361                 Session session = sessionFactory.getCurrentSession();
362                 Criteria criteria = session.createCriteria(WidgetFile.class);
363                 criteria.add(Restrictions.eq("widgetId", widgetId));
364                 List<WidgetFile> widgetFile = criteria.list();
365                 logger.debug("StorageServiceImpl.getWidgetMarkup: getting widget markup result={}", widgetFile);
366
367                 if (widgetFile.size() > 0)
368                         markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
369                 return markup;
370         }
371
372         @Override
373         @SuppressWarnings("unchecked")
374         @Transactional
375         public String getWidgetController(long widgetId) throws UnsupportedEncodingException {
376                 String controller = null;
377                 Session session = sessionFactory.getCurrentSession();
378                 Criteria criteria = session.createCriteria(WidgetFile.class);
379                 criteria.add(Restrictions.eq("widgetId", widgetId));
380                 List<WidgetFile> widgetFile = criteria.list();
381                 logger.debug("StorageServiceImpl.getWidgetController: getting widget controller result={}", widgetFile);
382
383                 if (widgetFile.size() > 0)
384                         controller = new String(widgetFile.get(0).getController(), "UTF-8");
385                 return controller;
386         }
387
388         @Override
389         @SuppressWarnings("unchecked")
390         @Transactional
391         public String getWidgetFramework(long widgetId) throws UnsupportedEncodingException {
392                 String framework = null;
393                 Session session = sessionFactory.getCurrentSession();
394                 Criteria criteria = session.createCriteria(WidgetFile.class);
395                 criteria.add(Restrictions.eq("widgetId", widgetId));
396                 List<WidgetFile> widgetFile = criteria.list();
397                 logger.debug("StorageServiceImpl.getWidgetFramework: getting widget framework result={}", widgetFile);
398
399                 if (widgetFile.size() > 0)
400                         framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
401                 return framework;
402         }
403
404         @Override
405         @SuppressWarnings("unchecked")
406         @Transactional
407         public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
408                 String css = null;
409                 Session session = sessionFactory.getCurrentSession();
410                 Criteria criteria = session.createCriteria(WidgetFile.class);
411                 criteria.add(Restrictions.eq("widgetId", widgetId));
412                 List<WidgetFile> widgetFile = criteria.list();
413                 logger.debug("StorageServiceImpl.getWidgetCSS: getting widget css result={}", widgetFile);
414
415                 if (widgetFile.size() > 0)
416                         css = new String(widgetFile.get(0).getCss(), "UTF-8");
417                 return css;
418         }
419
420         @Override
421         @Transactional
422         public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
423
424                 WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId);
425                 String namespace = "Portal" + widgetId + "Widget";
426                 String controllerName = "Portal" + widgetId + "Ctrl";
427                 String cssName = "portal" + widgetId + "-css-ready";
428
429                 String styles = getWidgetCSS(widgetId).replaceAll(cssName, widget.getName() + "-css-ready");
430                 File f = File.createTempFile("temp", ".zip");
431                 try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f))){
432                         ZipEntry e = new ZipEntry(widget.getName() + "/styles/styles.css");
433                         out.putNextEntry(new ZipEntry(widget.getName() + "/"));
434                         out.putNextEntry(new ZipEntry(widget.getName() + "/styles/"));
435                         out.putNextEntry(e);
436                         byte[] data = styles.getBytes();
437                         out.write(data, 0, data.length);
438         
439                         String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
440                         String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =",
441                                         "");
442         
443                         String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
444                         javascript = javascript.replaceFirst(controllerName, widget.getName() + "Ctrl");
445                         String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
446                         StringBuilder injectStr = new StringBuilder().append("[");
447                         List<String> paramList = Arrays.asList(functionParam.split(","));
448                         for (int i = 0; i < paramList.size(); i++) {
449                                 if (i == paramList.size() - 1)
450                                         injectStr.append("'" + paramList.get(i).trim() + "'];");
451                                 else
452                                         injectStr.append("'" + paramList.get(i).trim() + "',");
453                         }
454                         javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), "");
455         
456                         e = new ZipEntry(widget.getName() + "/js/controller.js");
457                         out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
458                         out.putNextEntry(e);
459                         data = javascript.getBytes();
460                         out.write(data, 0, data.length);
461         
462                         String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl");
463         
464                         // new
465                         // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
466                         // controllerName);;
467         
468                         e = new ZipEntry(widget.getName() + "/markup/markup.html");
469                         out.putNextEntry(new ZipEntry(widget.getName() + "/markup/"));
470                         out.putNextEntry(e);
471                         data = html.getBytes();
472                         out.write(data, 0, data.length);
473                         out.closeEntry();
474                         byte[] result = Files.readAllBytes(Paths.get(f.getPath()));
475                         f.delete();
476                         return result;
477                 }
478         }
479
480 }