c2633948cdc9fac5e37c00b2b95c9d34cc990017
[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                         FileOutputStream fos = new FileOutputStream(convFile);
105                         fos.write(file.getBytes());
106                         fos.close();
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                         FileOutputStream fos = new FileOutputStream(convFile);
141                         fos.write(file.getBytes());
142                         fos.close();
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                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
187
188                 String sb = null;
189                 try {
190                         byte[] bytes = new byte[fileInputStream.available()];
191                         fileInputStream.read(bytes);
192                         sb = new String(bytes, "UTF-8");
193                 } catch (IOException e) {
194                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
195                         e.printStackTrace();
196                 } finally {
197                         if (fileInputStream != null) {
198                                 try {
199                                         fileInputStream.close();
200                                 } catch (IOException e) {
201                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
202                                 }
203                         }
204                 }
205
206                 String namespace = "Portal" + widgetId + "Widget";
207                 String controllerName = "Portal" + widgetId + "Ctrl";
208                 String cssName = "portal" + widgetId + "-css-ready";
209                 String colorArg1 = "color: #fff";
210                 String framework = sb.replaceAll("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
211                                 .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
212                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
213                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
214
215                 widgetFile.setFramework(framework.getBytes());
216
217                 final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION);
218                 if (controllerLoc == null || controllerLoc.length == 0)
219                         throw new IllegalArgumentException(
220                                         "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION);
221                 String javascript = new String(controllerLoc);
222                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
223                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
224                 javascript = javascript.replaceFirst(functionName, controllerName);
225                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
226                 List<String> paramList = Arrays.asList(functionParam.split(","));
227
228                 int left_bracket_index = javascript.indexOf("{") + 1;
229                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
230                 javascript = javascript.substring(0, left_bracket_index) + widgetData
231                                 + javascript.substring(left_bracket_index);
232
233                 StringBuilder injectStr = new StringBuilder().append("[");
234                 for (int i = 0; i < paramList.size(); i++) {
235                         if (i == paramList.size() - 1)
236                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
237                         else
238                                 injectStr.append("'" + paramList.get(i).trim() + "',");
239                 }
240                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
241                                 + injectStr.toString();
242
243                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
244                                 controllerName);
245                 ;
246
247                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
248                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
249                 if (cssMatcher.find()) {
250                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
251                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
252                 }
253
254                 widgetFile.setMarkup(html.getBytes());
255                 widgetFile.setController(javascript.getBytes());
256                 Session session = sessionFactory.openSession();
257                 session.save(widgetFile);
258                 session.flush();
259                 session.close();
260                 // sessionFactory.getCurrentSession().save(widgetFile);
261                 logger.debug(
262                                 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
263                                 widgetId);
264
265         }
266
267         @Override
268         public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
269                 UnzipUtil unzipper = new UnzipUtil();
270                 Map<String, byte[]> map;
271                 File convFile;
272                 try {
273                         if (file.isEmpty()) {
274                                 logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename());
275                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
276                         }
277                         String fileLocation = file.getOriginalFilename();
278                         logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
279                         convFile = new File(fileLocation);
280                         FileOutputStream fos = new FileOutputStream(convFile);
281                         fos.write(file.getBytes());
282                         fos.close();
283                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
284                         convFile.delete();
285                 } catch (IOException e) {
286                         logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
287                         throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
288                                         e);
289                 }
290                 WidgetFile widgetFile = getWidgetFile(widgetId);
291
292                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
293                 String sb = null;
294                 try {
295                         byte[] bytes = new byte[fileInputStream.available()];
296                         fileInputStream.read(bytes);
297                         sb = new String(bytes, "UTF-8");
298                 } catch (IOException e) {
299                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
300                         e.printStackTrace();
301                 } finally {
302                         if (fileInputStream != null) {
303                                 try {
304                                         fileInputStream.close();
305                                 } catch (IOException e) {
306                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
307                                         e.printStackTrace();
308                                 }
309                         }
310                 }
311
312                 String namespace = "Portal" + widgetId + "Widget";
313                 String controllerName = "Portal" + widgetId + "Ctrl";
314                 String cssName = "portal" + widgetId + "-css-ready";
315                 String colorArg1 = "color: #fff";
316                 String framework = sb.replaceAll("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
317                                 .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
318                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
319                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
320                 widgetFile.setFramework(framework.getBytes());
321
322                 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
323                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
324                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
325                 javascript = javascript.replaceFirst(functionName, controllerName);
326                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
327                 List<String> paramList = Arrays.asList(functionParam.split(","));
328
329                 int left_bracket_index = javascript.indexOf("{") + 1;
330                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
331                 javascript = javascript.substring(0, left_bracket_index) + widgetData
332                                 + javascript.substring(left_bracket_index);
333
334                 StringBuilder injectStr = new StringBuilder().append("[");
335                 for (int i = 0; i < paramList.size(); i++) {
336                         if (i == paramList.size() - 1)
337                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
338                         else
339                                 injectStr.append("'" + paramList.get(i).trim() + "',");
340                 }
341                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
342                                 + injectStr.toString();
343
344                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
345                                 controllerName);
346                 ;
347
348                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
349                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
350                 if (cssMatcher.find()) {
351                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
352                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
353                 }
354
355                 widgetFile.setMarkup(html.getBytes());
356                 widgetFile.setController(javascript.getBytes());
357                 // widgetFile.setCss(map.get(WidgetConstant.WIDGET_STYLE_LOCATION));
358                 Session session = sessionFactory.openSession();
359                 Transaction tx = session.beginTransaction();
360                 session.update(widgetFile);
361                 tx.commit();
362                 session.flush();
363                 session.close();
364                 logger.debug(
365                                 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
366                                 widgetId);
367         }
368
369         @Override
370         @SuppressWarnings("unchecked")
371         @Transactional
372         public String getWidgetMarkup(long widgetId) throws UnsupportedEncodingException {
373                 String markup = null;
374                 Session session = sessionFactory.getCurrentSession();
375                 Criteria criteria = session.createCriteria(WidgetFile.class);
376                 criteria.add(Restrictions.eq("widgetId", widgetId));
377                 List<WidgetFile> widgetFile = criteria.list();
378                 logger.debug("StorageServiceImpl.getWidgetMarkup: getting widget markup result={}", widgetFile);
379
380                 if (widgetFile.size() > 0)
381                         markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
382                 return markup;
383         }
384
385         @Override
386         @SuppressWarnings("unchecked")
387         @Transactional
388         public String getWidgetController(long widgetId) throws UnsupportedEncodingException {
389                 String controller = null;
390                 Session session = sessionFactory.getCurrentSession();
391                 Criteria criteria = session.createCriteria(WidgetFile.class);
392                 criteria.add(Restrictions.eq("widgetId", widgetId));
393                 List<WidgetFile> widgetFile = criteria.list();
394                 logger.debug("StorageServiceImpl.getWidgetController: getting widget controller result={}", widgetFile);
395
396                 if (widgetFile.size() > 0)
397                         controller = new String(widgetFile.get(0).getController(), "UTF-8");
398                 return controller;
399         }
400
401         @Override
402         @SuppressWarnings("unchecked")
403         @Transactional
404         public String getWidgetFramework(long widgetId) throws UnsupportedEncodingException {
405                 String framework = null;
406                 Session session = sessionFactory.getCurrentSession();
407                 Criteria criteria = session.createCriteria(WidgetFile.class);
408                 criteria.add(Restrictions.eq("widgetId", widgetId));
409                 List<WidgetFile> widgetFile = criteria.list();
410                 logger.debug("StorageServiceImpl.getWidgetFramework: getting widget framework result={}", widgetFile);
411
412                 if (widgetFile.size() > 0)
413                         framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
414                 return framework;
415         }
416
417         @Override
418         @SuppressWarnings("unchecked")
419         @Transactional
420         public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
421                 String css = null;
422                 Session session = sessionFactory.getCurrentSession();
423                 Criteria criteria = session.createCriteria(WidgetFile.class);
424                 criteria.add(Restrictions.eq("widgetId", widgetId));
425                 List<WidgetFile> widgetFile = criteria.list();
426                 logger.debug("StorageServiceImpl.getWidgetCSS: getting widget css result={}", widgetFile);
427
428                 if (widgetFile.size() > 0)
429                         css = new String(widgetFile.get(0).getCss(), "UTF-8");
430                 return css;
431         }
432
433         @Override
434         @Transactional
435         public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
436
437                 WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId);
438                 String namespace = "Portal" + widgetId + "Widget";
439                 String controllerName = "Portal" + widgetId + "Ctrl";
440                 String cssName = "portal" + widgetId + "-css-ready";
441
442                 String styles = getWidgetCSS(widgetId).replaceAll(cssName, widget.getName() + "-css-ready");
443                 File f = File.createTempFile("temp", ".zip");
444                 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
445                 ZipEntry e = new ZipEntry(widget.getName() + "/styles/styles.css");
446                 out.putNextEntry(new ZipEntry(widget.getName() + "/"));
447                 out.putNextEntry(new ZipEntry(widget.getName() + "/styles/"));
448                 out.putNextEntry(e);
449                 byte[] data = styles.getBytes();
450                 out.write(data, 0, data.length);
451
452                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
453                 String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =",
454                                 "");
455
456                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
457                 javascript = javascript.replaceFirst(controllerName, widget.getName() + "Ctrl");
458                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
459                 StringBuilder injectStr = new StringBuilder().append("[");
460                 List<String> paramList = Arrays.asList(functionParam.split(","));
461                 for (int i = 0; i < paramList.size(); i++) {
462                         if (i == paramList.size() - 1)
463                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
464                         else
465                                 injectStr.append("'" + paramList.get(i).trim() + "',");
466                 }
467                 javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), "");
468
469                 e = new ZipEntry(widget.getName() + "/js/controller.js");
470                 out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
471                 out.putNextEntry(e);
472                 data = javascript.getBytes();
473                 out.write(data, 0, data.length);
474
475                 String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl");
476
477                 // new
478                 // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
479                 // controllerName);;
480
481                 e = new ZipEntry(widget.getName() + "/markup/markup.html");
482                 out.putNextEntry(new ZipEntry(widget.getName() + "/markup/"));
483                 out.putNextEntry(e);
484                 data = html.getBytes();
485                 out.write(data, 0, data.length);
486                 out.closeEntry();
487                 out.close();
488                 byte[] result = Files.readAllBytes(Paths.get(f.getPath()));
489                 f.delete();
490                 return result;
491         }
492
493 }