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