1 package org.onap.portalapp.widget.service.impl;
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;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15 import java.util.zip.ZipEntry;
16 import java.util.zip.ZipOutputStream;
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;
39 public class StorageServiceImpl implements StorageService {
41 private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class);
42 private final String TMP_PATH = "/tmp/";
45 private SessionFactory sessionFactory;
48 WidgetCatalogService widgetCatalogService;
52 public void deleteWidgetFile(long widgetId) {
53 WidgetFile widgetFile = getWidgetFile(widgetId);
54 logger.debug("StorageServiceImpl.deleteWidgetFile: deleting widget file {}", widgetId);
55 if (widgetFile == null) {
57 "StorageServiceImpl.deleteWidgetFile: No widget file found in database while performing StorageServiceImpl.deleteWidgetFile.");
60 Session session = sessionFactory.getCurrentSession();
61 Transaction tx = session.beginTransaction();
62 session.delete(widgetFile);
67 @SuppressWarnings("unchecked")
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();
78 if (widgetFiles.size() > 0)
79 widgetFile = widgetFiles.get(0);
84 public ValidationRespond checkZipFile(MultipartFile file) {
85 StringBuilder error_msg = new StringBuilder();
86 UnzipUtil unzipper = new UnzipUtil();
87 Map<String, byte[]> map;
89 boolean isValid = true;
90 if (!file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).equals(".zip")) {
92 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_ZIP);
93 logger.error("StorageServiceImpl.checkZipFile: invalid file format");
98 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
99 throw new StorageException(
100 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
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());
109 map = unzipper.unzip_db(fileLocation, TMP_PATH, "tempWidgets");
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);
117 for (byte[] b : map.values()) {
118 if (isValid && b == null) {
120 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_FILES);
124 return new ValidationRespond(isValid, error_msg.toString());
129 public void save(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
131 UnzipUtil unzipper = new UnzipUtil();
132 Map<String, byte[]> map;
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());
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());
145 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
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);
151 saveJsHelper(newWidget, widgetId, map);
156 public void initSave(File file, WidgetCatalog newWidget, long widgetId) {
158 UnzipUtil unzipper = new UnzipUtil();
159 Map<String, byte[]> map;
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);
170 saveJsHelper(newWidget, widgetId, map);
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
181 private void saveHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
183 logger.debug("Going to save widget " + newWidget);
184 WidgetFile widgetFile = new WidgetFile();
185 widgetFile.setName(newWidget.getName());
186 widgetFile.setWidgetId(widgetId);
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");
196 } catch (IOException e) {
197 logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
200 String namespace = "Portal" + widgetId + "Widget";
201 String controllerName = "Portal" + widgetId + "Ctrl";
202 String cssName = "portal" + widgetId + "-css-ready";
203 String colorArg1 = "color: #fff";
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));
211 widgetFile.setFramework(framework.getBytes());
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(","));
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);
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() + "'];");
234 injectStr.append("'" + paramList.get(i).trim() + "',");
236 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
237 + injectStr.toString();
239 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
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());
250 widgetFile.setMarkup(html.getBytes());
251 widgetFile.setController(javascript.getBytes());
252 Session session = sessionFactory.openSession();
253 session.save(widgetFile);
256 // sessionFactory.getCurrentSession().save(widgetFile);
258 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
264 * Helper method to UnZip File
268 private Map<String, byte[]> unZipFile(MultipartFile file) {
269 UnzipUtil unzipper = new UnzipUtil();
270 Map<String, byte[]> map;
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());
277 String fileLocation = file.getOriginalFilename();
278 logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
279 convFile = new File(fileLocation);
280 try(FileOutputStream fos = new FileOutputStream(convFile)){
281 fos.write(file.getBytes());
283 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
286 } catch (IOException e) {
287 logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
288 throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
294 * Helper method for saving widget file (controller.js) to ep_widget_catalog_files table in database
300 private void saveJsHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
302 logger.debug("Going to save controller.js " + newWidget);
303 WidgetFile widgetFile = new WidgetFile();
304 widgetFile.setName(newWidget.getName());
305 widgetFile.setWidgetId(widgetId);
306 final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION);
307 if (controllerLoc == null || controllerLoc.length == 0)
308 throw new IllegalArgumentException(
309 "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION);
310 String javascript = new String(controllerLoc);
312 widgetFile.setController(javascript.getBytes());
313 Session session = sessionFactory.openSession();
314 session.save(widgetFile);
318 "StorageServiceImpl.save: saved controller.js file to the database for widget {}",
324 public void updateJsFile(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
325 Map<String, byte[]> map;
326 map = unZipFile(file);
327 //Get existing widget file from DB
328 WidgetFile widgetFile = getWidgetFile(widgetId);
330 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
331 widgetFile.setController(javascript.getBytes());
332 Session session = sessionFactory.openSession();
333 Transaction tx = session.beginTransaction();
334 session.update(widgetFile);
339 "StorageServiceImpl.save: updated controller.js file to the database for widget {}",
348 public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
349 UnzipUtil unzipper = new UnzipUtil();
350 Map<String, byte[]> map;
353 if (file.isEmpty()) {
354 logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename());
355 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
357 String fileLocation = file.getOriginalFilename();
358 logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
359 convFile = new File(fileLocation);
360 try(FileOutputStream fos = new FileOutputStream(convFile)){
361 fos.write(file.getBytes());
363 map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
365 } catch (IOException e) {
366 logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
367 throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
370 WidgetFile widgetFile = getWidgetFile(widgetId);
373 try(InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js")){
374 byte[] bytes = new byte[fileInputStream.available()];
375 if(fileInputStream.read(bytes) > 0) {
376 sb = new String(bytes, "UTF-8");
378 } catch (IOException e) {
379 logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
382 String namespace = "Portal" + widgetId + "Widget";
383 String controllerName = "Portal" + widgetId + "Ctrl";
384 String cssName = "portal" + widgetId + "-css-ready";
385 String colorArg1 = "color: #fff";
388 framework = sb.replaceAll("ARGUMENT1", namespace).replaceAll("ARGUMENT2", controllerName)
389 .replaceAll("ARGUMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
390 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
391 .replaceAll("WIDGET_ID", Long.toString(widgetId));
393 widgetFile.setFramework(framework.getBytes());
395 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
396 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
397 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
398 javascript = javascript.replaceFirst(functionName, controllerName);
399 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
400 List<String> paramList = Arrays.asList(functionParam.split(","));
402 int left_bracket_index = javascript.indexOf("{") + 1;
403 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
404 javascript = javascript.substring(0, left_bracket_index) + widgetData
405 + javascript.substring(left_bracket_index);
407 StringBuilder injectStr = new StringBuilder().append("[");
408 for (int i = 0; i < paramList.size(); i++) {
409 if (i == paramList.size() - 1)
410 injectStr.append("'" + paramList.get(i).trim() + "'];");
412 injectStr.append("'" + paramList.get(i).trim() + "',");
414 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
415 + injectStr.toString();
417 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
421 Pattern cssPattern = Pattern.compile("#.*-css-ready");
422 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
423 if (cssMatcher.find()) {
424 widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
425 .replace(cssMatcher.group(0), "#" + cssName).getBytes());
428 widgetFile.setMarkup(html.getBytes());
429 widgetFile.setController(javascript.getBytes());
430 // widgetFile.setCss(map.get(WidgetConstant.WIDGET_STYLE_LOCATION));
431 Session session = sessionFactory.openSession();
432 Transaction tx = session.beginTransaction();
433 session.update(widgetFile);
438 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
443 @SuppressWarnings("unchecked")
445 public String getWidgetMarkup(long widgetId) throws UnsupportedEncodingException {
446 String markup = null;
447 Session session = sessionFactory.getCurrentSession();
448 Criteria criteria = session.createCriteria(WidgetFile.class);
449 criteria.add(Restrictions.eq("widgetId", widgetId));
450 List<WidgetFile> widgetFile = criteria.list();
451 logger.debug("StorageServiceImpl.getWidgetMarkup: getting widget markup result={}", widgetFile);
453 if (widgetFile.size() > 0)
454 markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
459 @SuppressWarnings("unchecked")
461 public String getWidgetController(long widgetId) throws UnsupportedEncodingException {
462 String controller = null;
463 Session session = sessionFactory.getCurrentSession();
464 Criteria criteria = session.createCriteria(WidgetFile.class);
465 criteria.add(Restrictions.eq("widgetId", widgetId));
466 List<WidgetFile> widgetFile = criteria.list();
467 logger.debug("StorageServiceImpl.getWidgetController: getting widget controller result={}", widgetFile);
469 if (widgetFile.size() > 0)
470 controller = new String(widgetFile.get(0).getController(), "UTF-8");
475 @SuppressWarnings("unchecked")
477 public String getWidgetFramework(long widgetId) throws UnsupportedEncodingException {
478 String framework = null;
479 Session session = sessionFactory.getCurrentSession();
480 Criteria criteria = session.createCriteria(WidgetFile.class);
481 criteria.add(Restrictions.eq("widgetId", widgetId));
482 List<WidgetFile> widgetFile = criteria.list();
483 logger.debug("StorageServiceImpl.getWidgetFramework: getting widget framework result={}", widgetFile);
485 if (widgetFile.size() > 0)
486 framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
491 @SuppressWarnings("unchecked")
493 public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
495 Session session = sessionFactory.getCurrentSession();
496 Criteria criteria = session.createCriteria(WidgetFile.class);
497 criteria.add(Restrictions.eq("widgetId", widgetId));
498 List<WidgetFile> widgetFile = criteria.list();
499 logger.debug("StorageServiceImpl.getWidgetCSS: getting widget css result={}", widgetFile);
501 if (widgetFile.size() > 0)
502 css = new String(widgetFile.get(0).getCss(), "UTF-8");
508 public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
510 WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId);
511 File f = File.createTempFile("temp", ".zip");
512 try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f))){
513 String javascript = getWidgetController(widgetId);
515 ZipEntry e = new ZipEntry(widget.getName() + "/js/controller.js");
516 out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
518 byte[] data = javascript.getBytes();
519 out.write(data, 0, data.length);
521 byte[] result = Files.readAllBytes(Paths.get(f.getPath()));