2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.policy.controller;
24 import java.io.BufferedOutputStream;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.io.PrintWriter;
32 import java.nio.file.FileVisitResult;
33 import java.nio.file.Files;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.nio.file.SimpleFileVisitor;
37 import java.nio.file.attribute.BasicFileAttributes;
38 import java.util.ArrayList;
39 import java.util.HashSet;
40 import java.util.LinkedHashMap;
41 import java.util.List;
45 import javax.servlet.ServletContext;
46 import javax.servlet.http.HttpServletRequest;
47 import javax.servlet.http.HttpServletResponse;
49 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
50 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
51 import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
52 import org.apache.commons.io.FilenameUtils;
53 import org.apache.commons.io.IOUtils;
54 import org.json.JSONObject;
55 import org.openecomp.policy.adapter.PolicyExportAdapter;
56 import org.openecomp.policy.dao.PolicyVersionDao;
57 import org.openecomp.policy.elk.client.ElkConnector;
58 import org.openecomp.policy.model.Roles;
59 import org.openecomp.policy.rest.jpa.PolicyVersion;
60 import org.openecomp.policy.utils.XACMLPolicyWriterWithPapNotify;
61 import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
62 import org.openecomp.portalsdk.core.web.support.UserUtils;
63 import org.springframework.beans.factory.annotation.Autowired;
64 import org.springframework.stereotype.Controller;
65 import org.springframework.web.bind.annotation.RequestMapping;
66 import org.springframework.web.servlet.ModelAndView;
68 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
69 import com.fasterxml.jackson.databind.DeserializationFeature;
70 import com.fasterxml.jackson.databind.JsonNode;
71 import com.fasterxml.jackson.databind.ObjectMapper;
72 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
73 import org.openecomp.policy.common.logging.flexlogger.Logger;
78 public class PolicyExportAndImportController extends RestrictedBaseController {
79 private static Logger logger = FlexLogger.getLogger(PolicyExportAndImportController.class);
80 private ArrayList<File> selectedPolicy;
81 public static String CONFIG_HOME = PolicyController.getConfigHome();
82 public static String ACTION_HOME = PolicyController.getActionHome();
84 private Set<String> scopes = null;
85 private List<String> roles = null;
86 private Boolean superadmin = false;
87 private Boolean showMessage = false;
88 private static final int BUFFER_SIZE = 4096;
89 private Path directory = PolicyController.getGitPath();
91 //Scopes Which Super Editor can't import
92 private Set<String> sEditorScopesCantCreate = new HashSet<String>();
93 //List of scopes in Tar file
94 private Set<String> listOfTarNewScopes = new HashSet<String>();
95 //List of xml policies
96 private ArrayList<String> xacmlFiles = new ArrayList<String>();
97 //Scopes of the User based on the Roles
98 private List<String> userScopes = null;
99 //Directory names from tar file
100 private Set<String> directoryNames = new HashSet<String>();
101 //compare the scopes of the user and tar file get unique
102 private Set<String> finalScopesToImport = new HashSet<String>();
103 //final scopes User can import
104 private Set<String> finalScopes = new HashSet<String>();
105 //User don't have permissions to import to scopes
106 private Set<String> roleIsNotSufficient = new HashSet<String>();
107 //User don't have access to import new scopes
108 private Set<String> userDontHavePermission = new HashSet<String>();
110 private Map<String, Roles> scopeAndRoles = null;
112 private static PolicyVersionDao policyVersionDao;
115 ServletContext servletContext;
118 private PolicyExportAndImportController(PolicyVersionDao policyVersionDao){
119 PolicyExportAndImportController.policyVersionDao = policyVersionDao;
122 public PolicyExportAndImportController(){}
124 @RequestMapping(value={"/policy_download/exportPolicy.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
125 public ModelAndView ExportPolicy(HttpServletRequest request, HttpServletResponse response) throws Exception{
127 selectedPolicy = new ArrayList<File>();
128 ObjectMapper mapper = new ObjectMapper();
129 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
130 JsonNode root = mapper.readTree(request.getReader());
131 PolicyExportAdapter adapter = mapper.readValue(root.get("exportData").toString(), PolicyExportAdapter.class);
132 for (Object policyId : adapter.getPolicyDatas()) {
133 LinkedHashMap<?, ?> selected = (LinkedHashMap<?, ?>)policyId;
134 Path file = Paths.get(selected.get("filePath").toString());
135 selectedPolicy.add(file.toFile());
137 // Grab our working repository
139 final Path repoPath = PolicyController.getGitPath().toAbsolutePath();
140 if(CONFIG_HOME == null || ACTION_HOME == null ){
141 CONFIG_HOME = PolicyController.getConfigHome();
142 ACTION_HOME = PolicyController.getActionHome();
144 Path configPath = Paths.get(CONFIG_HOME);
145 Path actionPath = Paths.get(ACTION_HOME);
146 String tempDir = System.getProperty("catalina.base") + File.separator + "webapps" + File.separator + "temp";
147 File temPath = new File(tempDir);
148 if(!temPath.exists()){
151 final Path tarFile = Paths.get(tempDir, "Repository.tar");
152 try (OutputStream os = Files.newOutputStream(tarFile)) {
153 try (TarArchiveOutputStream tarOut = new TarArchiveOutputStream(os)) {
154 tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
155 Files.walkFileTree(configPath, new SimpleFileVisitor<Path>() {
157 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
158 for (File policyId : selectedPolicy) {
159 // Get the current selection
160 String policyDir = policyId.toString();
161 policyDir = policyDir.substring(policyDir.indexOf("repository")+11);
162 String path = policyDir.replace('\\', '.');
163 if(path.contains("/")){
164 path = policyDir.replace('/', '.');
165 logger.info("print the path:" +path);
167 path = FilenameUtils.removeExtension(path);
168 if (path.endsWith(".xml")) {
169 path = path.substring(0, path.length() - 4);
171 File configFile = new File(path);
172 String fileName = FilenameUtils.removeExtension(file.getFileName().toString());
173 File configHome = new File(fileName);
174 if(configFile.equals(configHome)) {
175 Path relative = configPath.relativize(file);
176 TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
177 entry.setSize(Files.size(file));
178 tarOut.putArchiveEntry(entry);
180 IOUtils.copy(Files.newInputStream(file), tarOut);
181 } catch (IOException e) {
182 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
184 tarOut.closeArchiveEntry();
185 return super.visitFile(file, attrs);
188 return super.visitFile(file, attrs);
192 Files.walkFileTree(actionPath, new SimpleFileVisitor<Path>() {
194 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
195 for (File policyId : selectedPolicy) {
196 // Get the current selection
197 String policyDir = policyId.toString();
198 policyDir = policyDir.substring(policyDir.indexOf("repository")+11);
199 String path = policyDir.replace('\\', '.');
200 if(path.contains("/")){
201 path = policyDir.replace('/', '.');
202 logger.info("print the path:" +path);
204 path = FilenameUtils.removeExtension(path);
205 if (path.endsWith(".xml")) {
206 path = path.substring(0, path.length() - 4);
208 File actionFile = new File(path);
209 String fileName = FilenameUtils.removeExtension(file.getFileName().toString());
210 File actionHome = new File(fileName);
211 if(actionFile.equals(actionHome)) {
212 Path relative = actionPath.relativize(file);
213 TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
214 entry.setSize(Files.size(file));
215 tarOut.putArchiveEntry(entry);
217 IOUtils.copy(Files.newInputStream(file), tarOut);
218 } catch (IOException e) {
219 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
221 tarOut.closeArchiveEntry();
222 return super.visitFile(file, attrs);
225 return super.visitFile(file, attrs);
229 Files.walkFileTree(repoPath, new SimpleFileVisitor<Path>() {
231 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
232 if (file.getFileName().toString().endsWith(".xml") == false) {
233 return super.visitFile(file, attrs);
235 for (File policyId : selectedPolicy) {
236 // Get the current selection
237 if(policyId.getAbsoluteFile().getName().equals(file.getFileName().toString())) {
238 Path relative = repoPath.relativize(file);
239 TarArchiveEntry entry = new TarArchiveEntry(relative.toFile());
240 entry.setSize(Files.size(file));
241 tarOut.putArchiveEntry(entry);
243 IOUtils.copy(Files.newInputStream(file), tarOut);
244 } catch (IOException e) {
245 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
247 tarOut.closeArchiveEntry();
248 return super.visitFile(file, attrs);
251 return super.visitFile(file, attrs);
255 tarOut.closeArchiveEntry();
257 logger.debug("closing the tar file");
259 } catch (IOException e) {
260 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "getting IOexception");
261 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
263 logger.info("trying to send tar file "+tarFile.toAbsolutePath().toString());
265 response.setCharacterEncoding("UTF-8");
266 response.setContentType("application / json");
267 request.setCharacterEncoding("UTF-8");
268 String successMap = tarFile.toString().substring(tarFile.toString().lastIndexOf("webapps")+8);
269 PrintWriter out = response.getWriter();
270 String responseString = mapper.writeValueAsString(successMap);
271 JSONObject j = new JSONObject("{data: " + responseString + "}");
272 out.write(j.toString());
277 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR+"Exception Occured while Exporting Policies"+e);
283 public JSONObject ImportRepositoryFile(String file, HttpServletRequest request){
284 TarArchiveEntry entry = null;
285 TarArchiveInputStream extractFile = null;
287 extractFile = new TarArchiveInputStream (new FileInputStream(file));
288 } catch (FileNotFoundException e1) {
289 e1.printStackTrace();
291 String userId = null;
293 userId = UserUtils.getUserIdFromCookie(request);
294 } catch (Exception e) {
295 logger.error("Exception Occured while reading userid from cookie" +e);
297 scopeAndRoles = PolicyController.getUserRoles(userId);
298 //Check if the Role and Scope Size are Null get the values from db.
299 List<Roles> userRoles = PolicyController.getRoles(userId);
300 roles = new ArrayList<String>();
301 scopes = new HashSet<String>();
302 for(Roles userRole: userRoles){
303 roles.add(userRole.getRole());
304 scopes.add(userRole.getScope());
306 //Create a loop to read every single entry in TAR file
308 if (roles.contains("super-admin") || roles.contains("super-editor") || roles.contains("super-guest") ) {
309 while ((entry = extractFile.getNextTarEntry()) != null) {
310 this.superadmin = true;
312 copyFileToLocation(extractFile, entry, xacmlFiles, null, superadmin);
314 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR+"Exception while Importing Polcies"+e);
318 this.showMessage = true;
319 //get the directory names from tar file and add to the list
320 while ((entry = extractFile.getNextTarEntry()) != null) {
321 if(entry.getName().endsWith(".xls")) {
322 this.superadmin = true;
324 copyFileToLocation(extractFile, entry, xacmlFiles, finalScopes, superadmin);
326 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR+"Exception while Importing Polcies"+e);
329 if(entry.getName().endsWith(".xml")){
330 String filename = null;
331 if(entry.getName().contains("\\")){
332 filename = entry.getName().replace("\\", File.separator);
334 filename = entry.getName().replace("/", File.separator);
336 directoryNames.add(filename.substring(0, filename.lastIndexOf(File.separator)));
339 //get the matching scopes on comparing user scopes and tar file scopes
340 for(int i=0;i< userScopes.size(); i++){
341 for(int j=0; j<directoryNames.size(); j++){
342 if(userScopes.toArray()[i].equals(directoryNames.toArray()[j])){
343 finalScopesToImport.add(userScopes.toArray()[i].toString());
347 //get the scopes for which the user have permission to import
348 if(finalScopesToImport.size() != 0){
349 for(int i = 0; i < finalScopesToImport.size() ; i++){
350 String role = scopeAndRoles.get(finalScopesToImport.toArray()[i]).getRole();
351 if(role.equalsIgnoreCase("editor") || role.equalsIgnoreCase("admin")){
352 finalScopes.add(finalScopesToImport.toArray()[i].toString());
353 if(role.equalsIgnoreCase("super-guest") || role.equalsIgnoreCase("guest")){
354 roleIsNotSufficient.remove(finalScopesToImport.toArray()[i].toString());
357 roleIsNotSufficient.add(finalScopesToImport.toArray()[i].toString());
361 //if final Scopes to import set is not 0, then copy the files
362 if(finalScopes.size() != 0) {
363 this.superadmin = false;
365 copyFileToLocation(extractFile, entry, xacmlFiles, finalScopes, superadmin);
367 logger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR+"Exception while Importing Polcies"+e);
372 } catch (Exception e1) {
373 logger.info(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Exception:" +e1);
374 e1.printStackTrace();
376 // Close TarAchiveInputStream
379 } catch (IOException e) {
380 logger.info(XACMLErrorConstants.ERROR_PROCESS_FLOW+"IO Exception:"+e);
384 File tarFile1 = new File(file.toString());
387 for (String xacmlFile: xacmlFiles) {
388 String policyName = xacmlFile.substring(xacmlFile.indexOf("repository")+11);
389 if(policyName.endsWith(".xml")){
390 policyName = policyName.replace(".xml", "");
391 String version = policyName.substring(policyName.lastIndexOf(".")+1);
392 String finalPolicyName = policyName.substring(0, policyName.lastIndexOf("."));
393 PolicyVersion policyVersion = new PolicyVersion();
394 policyVersion.setPolicyName(finalPolicyName);
395 policyVersion.setActiveVersion(Integer.parseInt(version));
396 policyVersion.setHigherVersion(Integer.parseInt(version));
397 policyVersion.setCreatedBy(userId);
398 policyVersion.setModifiedBy(userId);
399 policyVersionDao.Save(policyVersion);
403 if(!XACMLPolicyWriterWithPapNotify.notifyPapOfCreateUpdate(xacmlFile)){
404 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW+"Failed adding imported policy to database: "+xacmlFile);
405 //throw new Exception("Failed adding imported policy to database: "+xacmlFile);
408 File f = new File(xacmlFile);
409 ElkConnector.singleton.update(f);
410 } catch (Exception e) {
411 logger.warn(XACMLErrorConstants.ERROR_DATA_ISSUE + ": Cannot ELK import: " + xacmlFile + " " +
416 //Filter the Set on Removing the Scopes which are imported
417 for(int j=0; j< finalScopesToImport.size(); j++){
418 for(int i = 0; i < directoryNames.size(); i++){
419 if(roles.contains("admin") || roles.contains("editor")){
420 if(!((directoryNames.toArray()[i]).toString()).startsWith(finalScopesToImport.toArray()[j].toString())){
421 userDontHavePermission.add(directoryNames.toArray()[i].toString());
427 //Show the Warn message to the User, if any of the policies are not Imported to teh Scopes
429 if(roleIsNotSufficient.size() == 0 && userDontHavePermission.size() != 0){
430 logger.warn(" User don't have Permissions to Import Policies to following Scopes:'"+userDontHavePermission+"'");
432 else if(roleIsNotSufficient.size() != 0 && userDontHavePermission.size() == 0){
433 logger.warn("Please Contact Super-Admin to Import the New Scopes:'"+roleIsNotSufficient+"'");
435 else if(roleIsNotSufficient.size() != 0 && userDontHavePermission.size() != 0){
436 logger.warn("Please Contact Super-Admin to Import the New Scopes:'"+roleIsNotSufficient+"' User don't have Permissions to Import Policies to following Scopes:'"+userDontHavePermission+"'");
437 }else if(sEditorScopesCantCreate.size() != 0){
438 logger.warn("Super-Editor can't create following new Scopes" +sEditorScopesCantCreate);
439 }else if(finalScopesToImport.size() == 0 && directoryNames.size() != 0){
440 logger.warn(" User don't have Permissions to Import Policies to following Scopes:'"+directoryNames+"'");
446 //Copy files to Directorys
447 private void copyFileToLocation(TarArchiveInputStream extractFile, TarArchiveEntry entry, ArrayList<String> xacmlFiles, Set<String> finalScopes, Boolean superadminValue ) throws IOException{
448 String individualFiles = "";
450 FileOutputStream outputFile=null;
451 // Get the name of the file
453 individualFiles = entry.getName();
454 //Add the list of scopes
455 if(entry.getName().endsWith(".xml")){
456 String filename = null;
457 if(entry.getName().contains("\\")){
458 filename = entry.getName().replace("\\", File.separator);
460 filename = entry.getName().replace("/", File.separator);
462 if(roles.contains("super-editor")){
463 listOfTarNewScopes.add(filename.substring(0, filename.lastIndexOf(File.separator)));
467 for(int i =0; i< finalScopes.size(); i++){
468 if(entry.getName().startsWith(finalScopes.toArray()[i].toString())){
469 individualFiles = entry.getName();
474 //Filter the new Scopes which Super-Editor can't create
475 if(roles.contains("super-editor")){
476 for(int j= 0; j< listOfTarNewScopes.size(); j++){
477 boolean scopeExistsFlag = false; // This Flag is used to know if the Scope Exists.
478 for(int i=0; i < scopes.size(); i++ ){
479 if(scopes.contains(listOfTarNewScopes.toArray()[j])){
480 scopeExistsFlag = true;
483 if(!scopeExistsFlag){
484 sEditorScopesCantCreate.add(listOfTarNewScopes.toArray()[j].toString());
490 individualFiles = individualFiles.replace("/", File.separator);
491 individualFiles = individualFiles.replace("\\", File.separator);
493 //Create the path with the entry name
494 String filePath = directory + File.separator + individualFiles;
495 String configPath = CONFIG_HOME + File.separator + individualFiles;
496 String actionPath = ACTION_HOME + File.separator + individualFiles;
497 logger.info("File Name in TAR File is: " + individualFiles);
498 logger.info("Xml directory file path: " + filePath);
499 logger.info("Config Home directory file path: " + configPath);
500 logger.info("Action Home directory file path: " + actionPath);
503 // Get Size of the file and create a byte array for the size
504 byte[] content = new byte[(int) entry.getSize()];
507 logger.info("File Name in TAR File is: " + individualFiles);
508 logger.info("Size of the File is: " + entry.getSize());
509 // Read file from the archive into byte array
510 extractFile.read(content, offset, content.length - offset);
511 if (!entry.isDirectory()) {
512 if(!individualFiles.contains(".Config_") || !individualFiles.contains(".Action_")){
513 // if the entry is a file, extracts it
514 String filePath1 = filePath.substring(0, filePath.lastIndexOf(File.separator));
515 File newFile = new File(filePath1);
516 if(!(newFile.exists()) && !(roles.contains("super-editor") || roles.contains("editor"))) {
517 File dir = new File(filePath1);
519 extractFile(extractFile, filePath);
523 // if the entry is a directory, make the directory
524 if(!(roles.contains("super-editor") || roles.contains("editor"))){
525 File dir = new File(filePath);
529 // Define OutputStream for writing the file
530 if(individualFiles.contains(".Config_")){
531 outputFile=new FileOutputStream(new File(configPath));
532 }else if(individualFiles.contains(".Action_")){
533 outputFile=new FileOutputStream(new File(actionPath));
535 if(filePath != null){
536 outputFile=new FileOutputStream(new File(filePath));
537 xacmlFiles.add(filePath);
541 // Use IOUtiles to write content of byte array to physical file
542 IOUtils.write(content,outputFile);
544 // Close Output Stream
547 } catch (IOException e) {
548 logger.info("IOException:" +e);
553 private void extractFile(TarArchiveInputStream extractFile, String filePath) throws IOException {
554 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
555 byte[] bytesIn = new byte[BUFFER_SIZE];
557 while ((read = extractFile.read(bytesIn)) != -1) {
558 bos.write(bytesIn, 0, read);