2  * ============LICENSE_START==========================================
 
   4  * ===================================================================
 
   5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
 
   6  * ===================================================================
 
   8  * Unless otherwise specified, all software contained herein is licensed
 
   9  * under the Apache License, Version 2.0 (the “License”);
 
  10  * you may not use this software except in compliance with the License.
 
  11  * You may obtain a copy of the License at
 
  13  *             http://www.apache.org/licenses/LICENSE-2.0
 
  15  * Unless required by applicable law or agreed to in writing, software
 
  16  * distributed under the License is distributed on an "AS IS" BASIS,
 
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  18  * See the License for the specific language governing permissions and
 
  19  * limitations under the License.
 
  21  * Unless otherwise specified, all documentation contained herein is licensed
 
  22  * under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
 
  23  * you may not use this documentation except in compliance with the License.
 
  24  * You may obtain a copy of the License at
 
  26  *             https://creativecommons.org/licenses/by/4.0/
 
  28  * Unless required by applicable law or agreed to in writing, documentation
 
  29  * distributed under the License is distributed on an "AS IS" BASIS,
 
  30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  31  * See the License for the specific language governing permissions and
 
  32  * limitations under the License.
 
  34  * ============LICENSE_END============================================
 
  36  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
 
  38 package org.openecomp.portalapp.widget.service.impl;
 
  41 import java.io.FileOutputStream;
 
  42 import java.io.IOException;
 
  43 import java.io.InputStream;
 
  44 import java.io.UnsupportedEncodingException;
 
  45 import java.nio.file.Files;
 
  46 import java.nio.file.Paths;
 
  47 import java.util.Arrays;
 
  48 import java.util.List;
 
  50 import java.util.regex.Matcher;
 
  51 import java.util.regex.Pattern;
 
  52 import java.util.zip.ZipEntry;
 
  53 import java.util.zip.ZipOutputStream;
 
  55 import org.hibernate.Criteria;
 
  56 import org.hibernate.Session;
 
  57 import org.hibernate.SessionFactory;
 
  58 import org.hibernate.Transaction;
 
  59 import org.hibernate.criterion.Restrictions;
 
  60 import org.openecomp.portalapp.widget.constant.WidgetConstant;
 
  61 import org.openecomp.portalapp.widget.domain.ValidationRespond;
 
  62 import org.openecomp.portalapp.widget.domain.WidgetCatalog;
 
  63 import org.openecomp.portalapp.widget.domain.WidgetFile;
 
  64 import org.openecomp.portalapp.widget.excetpion.StorageException;
 
  65 import org.openecomp.portalapp.widget.service.StorageService;
 
  66 import org.openecomp.portalapp.widget.service.WidgetCatalogService;
 
  67 import org.openecomp.portalapp.widget.utils.UnzipUtil;
 
  68 import org.slf4j.Logger;
 
  69 import org.slf4j.LoggerFactory;
 
  70 import org.springframework.beans.factory.annotation.Autowired;
 
  71 import org.springframework.stereotype.Service;
 
  72 import org.springframework.transaction.annotation.Transactional;
 
  73 import org.springframework.web.multipart.MultipartFile;
 
  76 public class StorageServiceImpl implements StorageService {
 
  78         private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class);
 
  81         private SessionFactory sessionFactory;
 
  84         WidgetCatalogService widgetCatalogService;
 
  88         public void deleteWidgetFile(long widgetId) {
 
  89                 WidgetFile widgetFile = getWidgetFile(widgetId);
 
  90                 logger.debug("StorageServiceImpl.deleteWidgetFile: deleting widget file {}", widgetId);
 
  91                 if (widgetFile == null) {
 
  93                                         "StorageServiceImpl.deleteWidgetFile: No widget file found in database while performing StorageServiceImpl.deleteWidgetFile.");
 
  96                 Session session = sessionFactory.getCurrentSession();
 
  97                 Transaction tx = session.beginTransaction();
 
  98                 session.delete(widgetFile);
 
 103         @SuppressWarnings("unchecked")
 
 105         public WidgetFile getWidgetFile(long widgetId) {
 
 106                 logger.debug("StorageServiceImpl.getWidgetFile: getting widget file {}", widgetId);
 
 107                 WidgetFile widgetFile = null;
 
 108                 Session session = sessionFactory.openSession();
 
 109                 Criteria criteria = session.createCriteria(WidgetFile.class);
 
 110                 criteria.add(Restrictions.eq("widgetId", widgetId));
 
 111                 List<WidgetFile> widgetFiles = criteria.list();
 
 114                 if (widgetFiles.size() > 0)
 
 115                         widgetFile = widgetFiles.get(0);
 
 120         public ValidationRespond checkZipFile(MultipartFile file) {
 
 121                 StringBuilder error_msg = new StringBuilder();
 
 122                 UnzipUtil unzipper = new UnzipUtil();
 
 123                 Map<String, byte[]> map;
 
 125                 boolean isValid = true;
 
 126                 if (!file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')).equals(".zip")) {
 
 128                         error_msg.append(WidgetConstant.VALIDATION_MESSAGE_ZIP);
 
 129                         logger.error("StorageServiceImpl.checkZipFile: invalid file format");
 
 132                         if (file.isEmpty()) {
 
 134                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
 
 135                                 throw new StorageException(
 
 136                                                 "StorageServiceImpl.checkZipFile: Failed to store empty file " + file.getOriginalFilename());
 
 138                         String fileLocation = file.getOriginalFilename();
 
 139                         logger.debug("StorageServiceImpl.checkZipFile: store the widget to:" + fileLocation);
 
 140                         convFile = new File(fileLocation);
 
 141                         FileOutputStream fos = new FileOutputStream(convFile);
 
 142                         fos.write(file.getBytes());
 
 144                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
 
 146                 } catch (IOException e) {
 
 147                         logger.error("StorageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
 
 148                         throw new StorageException(
 
 149                                         "torageServiceImpl.checkZipFile: Failed to store file " + file.getOriginalFilename(), e);
 
 152                 for (byte[] b : map.values()) {
 
 153                         if (isValid && b == null) {
 
 155                                 error_msg.append(WidgetConstant.VALIDATION_MESSAGE_FILES);
 
 159                 return new ValidationRespond(isValid, error_msg.toString());
 
 164         public void save(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
 
 166                 UnzipUtil unzipper = new UnzipUtil();
 
 167                 Map<String, byte[]> map;
 
 170                         if (file.isEmpty()) {
 
 171                                 logger.error("Failed to store empty file " + file.getOriginalFilename());
 
 172                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
 
 174                         String fileLocation = file.getOriginalFilename();
 
 175                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
 
 176                         convFile = new File(fileLocation);
 
 177                         FileOutputStream fos = new FileOutputStream(convFile);
 
 178                         fos.write(file.getBytes());
 
 180                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
 
 182                 } catch (IOException e) {
 
 183                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getOriginalFilename(), e);
 
 184                         throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
 
 186                 saveHelper(newWidget, widgetId, map);
 
 191         public void initSave(File file, WidgetCatalog newWidget, long widgetId) {
 
 193                 UnzipUtil unzipper = new UnzipUtil();
 
 194                 Map<String, byte[]> map;
 
 197                         String fileLocation = file.getPath();
 
 198                         logger.debug("StorageServiceImpl.save: store the widget to:" + fileLocation);
 
 199                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
 
 200                 } catch (IOException e) {
 
 201                         logger.error("StorageServiceImpl.save: Failed to store file " + file.getName(), e);
 
 202                         throw new StorageException("Failed to store file " + file.getName(), e);
 
 205                 saveHelper(newWidget, widgetId, map);
 
 209          * Helper method for saving widget files (controller.js, framework.js,
 
 210          * markup.html and style.css) to ep_widget_catalog_files table in database
 
 216         private void saveHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) {
 
 218                 logger.debug("Going to save widget " + newWidget);
 
 219                 WidgetFile widgetFile = new WidgetFile();
 
 220                 widgetFile.setName(newWidget.getName());
 
 221                 widgetFile.setWidgetId(widgetId);
 
 223                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
 
 227                         byte[] bytes = new byte[fileInputStream.available()];
 
 228                         fileInputStream.read(bytes);
 
 229                         sb = new String(bytes, "UTF-8");
 
 230                 } catch (IOException e) {
 
 231                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
 
 234                         if (fileInputStream != null) {
 
 236                                         fileInputStream.close();
 
 237                                 } catch (IOException e) {
 
 238                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
 
 243                 String namespace = "Portal" + widgetId + "Widget";
 
 244                 String controllerName = "Portal" + widgetId + "Ctrl";
 
 245                 String cssName = "portal" + widgetId + "-css-ready";
 
 246                 String colorArg1 = "color: #fff";
 
 247                 String framework = sb.replaceAll("ARUGMENT1", namespace).replaceAll("ARUGMENT2", controllerName)
 
 248                                 .replaceAll("ARUGMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
 
 249                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
 
 250                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
 
 252                 widgetFile.setFramework(framework.getBytes());
 
 254                 final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION);
 
 255                 if (controllerLoc == null || controllerLoc.length == 0)
 
 256                         throw new IllegalArgumentException(
 
 257                                         "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION);
 
 258                 String javascript = new String(controllerLoc);
 
 259                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
 
 260                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
 
 261                 javascript = javascript.replaceFirst(functionName, controllerName);
 
 262                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
 
 263                 List<String> paramList = Arrays.asList(functionParam.split(","));
 
 265                 int left_bracket_index = javascript.indexOf("{") + 1;
 
 266                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
 
 267                 javascript = javascript.substring(0, left_bracket_index) + widgetData
 
 268                                 + javascript.substring(left_bracket_index);
 
 270                 StringBuilder injectStr = new StringBuilder().append("[");
 
 271                 for (int i = 0; i < paramList.size(); i++) {
 
 272                         if (i == paramList.size() - 1)
 
 273                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
 
 275                                 injectStr.append("'" + paramList.get(i).trim() + "',");
 
 277                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
 
 278                                 + injectStr.toString();
 
 280                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
 
 284                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
 
 285                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
 
 286                 if (cssMatcher.find()) {
 
 287                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
 
 288                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
 
 291                 widgetFile.setMarkup(html.getBytes());
 
 292                 widgetFile.setController(javascript.getBytes());
 
 293                 Session session = sessionFactory.openSession();
 
 294                 session.save(widgetFile);
 
 297                 // sessionFactory.getCurrentSession().save(widgetFile);
 
 299                                 "StorageServiceImpl.save: saved fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
 
 305         public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) {
 
 306                 UnzipUtil unzipper = new UnzipUtil();
 
 307                 Map<String, byte[]> map;
 
 310                         if (file.isEmpty()) {
 
 311                                 logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename());
 
 312                                 throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
 
 314                         String fileLocation = file.getOriginalFilename();
 
 315                         logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation);
 
 316                         convFile = new File(fileLocation);
 
 317                         FileOutputStream fos = new FileOutputStream(convFile);
 
 318                         fos.write(file.getBytes());
 
 320                         map = unzipper.unzip_db(fileLocation, ".", "tempWidgets");
 
 322                 } catch (IOException e) {
 
 323                         logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e);
 
 324                         throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(),
 
 327                 WidgetFile widgetFile = getWidgetFile(widgetId);
 
 329                 InputStream fileInputStream = this.getClass().getClassLoader().getResourceAsStream("framework-template.js");
 
 332                         byte[] bytes = new byte[fileInputStream.available()];
 
 333                         fileInputStream.read(bytes);
 
 334                         sb = new String(bytes, "UTF-8");
 
 335                 } catch (IOException e) {
 
 336                         logger.error("StorageServiceImpl.save: Failed to load framework-template.js file ", e);
 
 339                         if (fileInputStream != null) {
 
 341                                         fileInputStream.close();
 
 342                                 } catch (IOException e) {
 
 343                                         logger.error("StorageServiceImpl.update: Failed to close the fileInputStream ", e);
 
 349                 String namespace = "Portal" + widgetId + "Widget";
 
 350                 String controllerName = "Portal" + widgetId + "Ctrl";
 
 351                 String cssName = "portal" + widgetId + "-css-ready";
 
 352                 String colorArg1 = "color: #fff";
 
 353                 String framework = sb.replaceAll("ARUGMENT1", namespace).replaceAll("ARUGMENT2", controllerName)
 
 354                                 .replaceAll("ARUGMENT3", cssName).replaceAll("CSS_ARG1", colorArg1)
 
 355                                 .replaceAll("MICROSERVICE_ID", newWidget.getServiceId().toString())
 
 356                                 .replaceAll("WIDGET_ID", Long.toString(widgetId));
 
 357                 widgetFile.setFramework(framework.getBytes());
 
 359                 String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION));
 
 360                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
 
 361                 String functionName = functionHeader.substring(functionHeader.indexOf(" "), functionHeader.indexOf("(")).trim();
 
 362                 javascript = javascript.replaceFirst(functionName, controllerName);
 
 363                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
 
 364                 List<String> paramList = Arrays.asList(functionParam.split(","));
 
 366                 int left_bracket_index = javascript.indexOf("{") + 1;
 
 367                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
 
 368                 javascript = javascript.substring(0, left_bracket_index) + widgetData
 
 369                                 + javascript.substring(left_bracket_index);
 
 371                 StringBuilder injectStr = new StringBuilder().append("[");
 
 372                 for (int i = 0; i < paramList.size(); i++) {
 
 373                         if (i == paramList.size() - 1)
 
 374                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
 
 376                                 injectStr.append("'" + paramList.get(i).trim() + "',");
 
 378                 javascript = namespace + ".controller = " + javascript + ";" + namespace + ".controller.$inject = "
 
 379                                 + injectStr.toString();
 
 381                 String html = new String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
 
 385                 Pattern cssPattern = Pattern.compile("#.*-css-ready");
 
 386                 Matcher cssMatcher = cssPattern.matcher(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION)));
 
 387                 if (cssMatcher.find()) {
 
 388                         widgetFile.setCss(new String(map.get(WidgetConstant.WIDGET_STYLE_LOCATION))
 
 389                                         .replace(cssMatcher.group(0), "#" + cssName).getBytes());
 
 392                 widgetFile.setMarkup(html.getBytes());
 
 393                 widgetFile.setController(javascript.getBytes());
 
 394                 // widgetFile.setCss(map.get(WidgetConstant.WIDGET_STYLE_LOCATION));
 
 395                 Session session = sessionFactory.openSession();
 
 396                 Transaction tx = session.beginTransaction();
 
 397                 session.update(widgetFile);
 
 402                                 "StorageServiceImpl.save: updated fraemwork.js controller.js, markup.html and style.css files to the database for widget {}",
 
 407         @SuppressWarnings("unchecked")
 
 409         public String getWidgetMarkup(long widgetId) throws UnsupportedEncodingException {
 
 410                 String markup = 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.getWidgetMarkup: getting widget markup result={}", widgetFile);
 
 417                 if (widgetFile.size() > 0)
 
 418                         markup = new String(widgetFile.get(0).getMarkup(), "UTF-8");
 
 423         @SuppressWarnings("unchecked")
 
 425         public String getWidgetController(long widgetId) throws UnsupportedEncodingException {
 
 426                 String controller = null;
 
 427                 Session session = sessionFactory.getCurrentSession();
 
 428                 Criteria criteria = session.createCriteria(WidgetFile.class);
 
 429                 criteria.add(Restrictions.eq("widgetId", widgetId));
 
 430                 List<WidgetFile> widgetFile = criteria.list();
 
 431                 logger.debug("StorageServiceImpl.getWidgetController: getting widget controller result={}", widgetFile);
 
 433                 if (widgetFile.size() > 0)
 
 434                         controller = new String(widgetFile.get(0).getController(), "UTF-8");
 
 439         @SuppressWarnings("unchecked")
 
 441         public String getWidgetFramework(long widgetId) throws UnsupportedEncodingException {
 
 442                 String framework = null;
 
 443                 Session session = sessionFactory.getCurrentSession();
 
 444                 Criteria criteria = session.createCriteria(WidgetFile.class);
 
 445                 criteria.add(Restrictions.eq("widgetId", widgetId));
 
 446                 List<WidgetFile> widgetFile = criteria.list();
 
 447                 logger.debug("StorageServiceImpl.getWidgetFramework: getting widget framework result={}", widgetFile);
 
 449                 if (widgetFile.size() > 0)
 
 450                         framework = new String(widgetFile.get(0).getFramework(), "UTF-8");
 
 455         @SuppressWarnings("unchecked")
 
 457         public String getWidgetCSS(long widgetId) throws UnsupportedEncodingException {
 
 459                 Session session = sessionFactory.getCurrentSession();
 
 460                 Criteria criteria = session.createCriteria(WidgetFile.class);
 
 461                 criteria.add(Restrictions.eq("widgetId", widgetId));
 
 462                 List<WidgetFile> widgetFile = criteria.list();
 
 463                 logger.debug("StorageServiceImpl.getWidgetCSS: getting widget css result={}", widgetFile);
 
 465                 if (widgetFile.size() > 0)
 
 466                         css = new String(widgetFile.get(0).getCss(), "UTF-8");
 
 472         public byte[] getWidgetCatalogContent(long widgetId) throws Exception {
 
 474                 WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId);
 
 475                 String namespace = "Portal" + widgetId + "Widget";
 
 476                 String controllerName = "Portal" + widgetId + "Ctrl";
 
 477                 String cssName = "portal" + widgetId + "-css-ready";
 
 479                 String styles = getWidgetCSS(widgetId).replaceAll(cssName, widget.getName() + "-css-ready");
 
 480                 File f = File.createTempFile("temp", ".zip");
 
 481                 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
 
 482                 ZipEntry e = new ZipEntry(widget.getName() + "/styles/styles.css");
 
 483                 out.putNextEntry(new ZipEntry(widget.getName() + "/"));
 
 484                 out.putNextEntry(new ZipEntry(widget.getName() + "/styles/"));
 
 486                 byte[] data = styles.getBytes();
 
 487                 out.write(data, 0, data.length);
 
 489                 String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;";
 
 490                 String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =",
 
 493                 String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1);
 
 494                 javascript = javascript.replaceFirst(controllerName, widget.getName() + "Ctrl");
 
 495                 String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")"));
 
 496                 StringBuilder injectStr = new StringBuilder().append("[");
 
 497                 List<String> paramList = Arrays.asList(functionParam.split(","));
 
 498                 for (int i = 0; i < paramList.size(); i++) {
 
 499                         if (i == paramList.size() - 1)
 
 500                                 injectStr.append("'" + paramList.get(i).trim() + "'];");
 
 502                                 injectStr.append("'" + paramList.get(i).trim() + "',");
 
 504                 javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), "");
 
 506                 e = new ZipEntry(widget.getName() + "/js/controller.js");
 
 507                 out.putNextEntry(new ZipEntry(widget.getName() + "/js/"));
 
 509                 data = javascript.getBytes();
 
 510                 out.write(data, 0, data.length);
 
 512                 String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl");
 
 515                 // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName,
 
 518                 e = new ZipEntry(widget.getName() + "/markup/markup.html");
 
 519                 out.putNextEntry(new ZipEntry(widget.getName() + "/markup/"));
 
 521                 data = html.getBytes();
 
 522                 out.write(data, 0, data.length);
 
 525                 byte[] result = Files.readAllBytes(Paths.get(f.getPath()));