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