ee94c6f96f3c546fdb225a47f02af3c9947f3dce
[policy/engine.git] / BRMSGateway / src / main / java / org / onap / policy / brms / api / BrmsPush.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * Modifications Copyright (C) 2019 Nordix Foundation.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.brms.api;
24
25 import com.att.nsa.cambria.client.CambriaBatchingPublisher;
26 import com.att.nsa.cambria.client.CambriaClientBuilders;
27 import com.att.nsa.cambria.client.CambriaClientBuilders.PublisherBuilder;
28 import com.fasterxml.jackson.core.JsonProcessingException;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.Writer;
35 import java.net.URL;
36 import java.nio.channels.Channels;
37 import java.nio.channels.ReadableByteChannel;
38 import java.nio.charset.StandardCharsets;
39 import java.nio.file.Files;
40 import java.nio.file.Path;
41 import java.nio.file.Paths;
42 import java.security.GeneralSecurityException;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collections;
46 import java.util.Enumeration;
47 import java.util.HashMap;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Properties;
51 import java.util.UUID;
52 import java.util.concurrent.TimeUnit;
53 import java.util.jar.JarEntry;
54 import java.util.jar.JarFile;
55 import java.util.regex.Pattern;
56 import javax.persistence.EntityManager;
57 import javax.persistence.EntityManagerFactory;
58 import javax.persistence.EntityTransaction;
59 import javax.persistence.Persistence;
60 import javax.persistence.TypedQuery;
61 import javax.ws.rs.ProcessingException;
62 import org.apache.commons.io.FileUtils;
63 import org.apache.commons.lang3.StringEscapeUtils;
64 import org.apache.maven.model.Dependency;
65 import org.apache.maven.model.DeploymentRepository;
66 import org.apache.maven.model.DistributionManagement;
67 import org.apache.maven.model.Model;
68 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
69 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
70 import org.apache.maven.shared.invoker.DefaultInvoker;
71 import org.apache.maven.shared.invoker.InvocationRequest;
72 import org.apache.maven.shared.invoker.InvocationResult;
73 import org.apache.maven.shared.invoker.Invoker;
74 import org.codehaus.plexus.util.IOUtil;
75 import org.codehaus.plexus.util.WriterFactory;
76 import org.eclipse.persistence.config.PersistenceUnitProperties;
77 import org.onap.policy.api.PEDependency;
78 import org.onap.policy.api.PolicyException;
79 import org.onap.policy.brms.api.nexus.NexusRestSearchParameters;
80 import org.onap.policy.brms.api.nexus.NexusRestWrapper;
81 import org.onap.policy.brms.api.nexus.NexusRestWrapperException;
82 import org.onap.policy.brms.api.nexus.pojo.NexusArtifact;
83 import org.onap.policy.brms.entity.BrmsGroupInfo;
84 import org.onap.policy.brms.entity.BrmsPolicyInfo;
85 import org.onap.policy.brms.entity.DependencyInfo;
86 import org.onap.policy.common.im.IntegrityMonitor;
87 import org.onap.policy.common.logging.eelf.MessageCodes;
88 import org.onap.policy.common.logging.eelf.PolicyLogger;
89 import org.onap.policy.common.logging.flexlogger.FlexLogger;
90 import org.onap.policy.common.logging.flexlogger.Logger;
91 import org.onap.policy.utils.BackUpHandler;
92 import org.onap.policy.utils.BackUpMonitor;
93 import org.onap.policy.utils.BusPublisher;
94 import org.onap.policy.utils.PeCryptoUtils;
95 import org.onap.policy.utils.PolicyUtils;
96 import org.onap.policy.xacml.api.XACMLErrorConstants;
97
98 /**
99  * BRMSPush: Application responsible to push policies to the BRMS PDP Policy Repository (PR).
100  * Mavenize and push policy to PR
101  *
102  * @version 1.0
103  */
104
105 public class BrmsPush {
106     private static final String GROUP_NAMES = "groupNames";
107     private static final String DROOLS_APPS_TEMPLATE_GROUP =
108             "org.onap.policy.drools-applications.controlloop.templates";
109     private static final String DROOLS_APPS_MODEL_GROUP =
110             "org.onap.policy.models.policy-models-interactions.model-impl";
111     private static final String META_INF = "META-INF";
112     private static final String KMODULE_XML_FILE = "kmodule.xml";
113     private static final String POM_XML_FILE = "pom.xml";
114     private static final String VERSION_0_1_0 = "0.1.0";
115     private static final String RULES = "rules";
116     private static final String RESOURCES = "resources";
117     private static final Logger LOGGER = FlexLogger.getLogger(BrmsPush.class.getName());
118     private static final String PROJECTSLOCATION = "RuleProjects";
119     private static final String[] GOALS = {"clean", "deploy"};
120     private static final String DEFAULT_VERSION = "1.6.1-SNAPSHOT";
121     private static final String DEPENDENCY_FILE = "dependency.json";
122     private static final String PROP_AES_KEY = "org.onap.policy.encryption.aes.key";
123     public static final String BRMSPERSISTENCE = "brmsEclipselink.persistencexml";
124
125     private static Map<String, String> modifiedGroups = new HashMap<>();
126     private static IntegrityMonitor im;
127     private static BackUpMonitor bm;
128     private String defaultName = null;
129     private String repId = null;
130     private String repName = null;
131     private List<String> repUrlList = null;
132     private String repUserName = null;
133     private String repPassword = null;
134     private String policyKeyId = null;
135     private boolean createFlag = false;
136     private String uebList = null;
137     private List<String> dmaapList = null;
138     private String pubTopic = null;
139     private PublisherBuilder pubBuilder = null;
140     protected BusPublisher publisher = null;
141     private Long uebDelay = Long.parseLong("20");
142     private Long dmaapDelay = Long.parseLong("5000");
143     private String notificationType = null;
144     private List<ControllerPojo> controllers;
145     private Map<String, ArrayList<Object>> groupMap = new HashMap<>();
146     private final Map<String, String> policyMap = new HashMap<>();
147     private String brmsdependencyversion;
148     private EntityManager em;
149     private boolean syncFlag = false;
150
151     /**
152      * Responsible to push policies to the BRMS PDP Policy Repository (PR).
153      *
154      * @param propertiesFile the properties file
155      * @param handler the {@link BackUpHandler}
156      * @throws PolicyException PolicyException related to the operation
157      */
158     public BrmsPush(final String propertiesFile, final BackUpHandler handler) throws PolicyException {
159         if (propertiesFile == null || handler == null) {
160             throw new PolicyException("Error no propertiesFile or handler");
161         }
162         final Properties config = new Properties();
163         final Path file = Paths.get(propertiesFile);
164         if (Files.notExists(file)) {
165             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Config File doesn't Exist in the specified Path "
166                     + file.toString());
167             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE
168                     + "Config File doesn't Exist in the specified Path " + file.toString());
169         } else {
170             if (file.toString().endsWith(".properties")) {
171                 // Grab the Properties.
172                 setProperty(file, config, handler);
173             }
174         }
175     }
176
177     private void setProperty(final Path file, final Properties config, final BackUpHandler handler)
178             throws PolicyException {
179         InputStream in;
180         try {
181             in = new FileInputStream(file.toFile());
182             config.load(in);
183         } catch (final IOException e) {
184             LOGGER.error(
185                     XACMLErrorConstants.ERROR_DATA_ISSUE + "Data/File Read Error while reading from the property file.",
186                     e);
187             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE
188                     + "Data/File Read Error while reading from the property file.");
189         }
190         // init the aes key from prop or env
191         PeCryptoUtils.initAesKey(config.getProperty(PROP_AES_KEY));
192
193         LOGGER.info("Trying to set up IntegrityMonitor");
194         String resourceName = null;
195         try {
196             LOGGER.info("Trying to set up IntegrityMonitor");
197             resourceName = config.getProperty("RESOURCE_NAME");
198             if (resourceName == null) {
199                 LOGGER.warn("RESOURCE_NAME is missing setting default value. ");
200                 resourceName = "brmsgw_pdp01";
201             }
202             resourceName = resourceName.trim();
203             setIntegrityMonitor(IntegrityMonitor.getInstance(resourceName, config));
204         } catch (final Exception e) {
205             LOGGER.error("Error starting Integerity Monitor: " + e);
206         }
207         LOGGER.info("Trying to set up BackUpMonitor");
208         try {
209             setBackupMonitor(BackUpMonitor.getInstance(BackUpMonitor.ResourceNode.BRMS.toString(), resourceName, config,
210                     handler));
211         } catch (final Exception e) {
212             LOGGER.error("Error starting BackUpMonitor: " + e);
213         }
214         if (!config.containsKey(BRMSPERSISTENCE)) {
215             config.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistenceBRMS.xml");
216         } else {
217             config.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML,
218                     config.getProperty(BRMSPERSISTENCE, "META-INF/persistenceBRMS.xml"));
219         }
220         final EntityManagerFactory emf = Persistence.createEntityManagerFactory("BRMSGW", config);
221         em = emf.createEntityManager();
222         defaultName = config.getProperty("defaultName");
223         if (defaultName == null) {
224             LOGGER.error(
225                     XACMLErrorConstants.ERROR_DATA_ISSUE + "defaultName property is missing from the property file ");
226             throw new PolicyException(
227                     XACMLErrorConstants.ERROR_DATA_ISSUE + "defaultName property is missing from the property file");
228         }
229         defaultName = defaultName.trim();
230         repId = config.getProperty("repositoryID");
231         if (repId == null) {
232             LOGGER.error(
233                     XACMLErrorConstants.ERROR_DATA_ISSUE + "repositoryID property is missing from the property file ");
234             throw new PolicyException(
235                     XACMLErrorConstants.ERROR_DATA_ISSUE + "repositoryID property is missing from the property file ");
236         }
237         repId = repId.trim();
238         repName = config.getProperty("repositoryName");
239         if (repName == null) {
240             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE
241                     + "repositoryName property is missing from the property file ");
242             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE
243                     + "repositoryName property is missing from the property file ");
244         }
245         repName = repName.trim();
246         final String repUrl = config.getProperty("repositoryURL");
247         if (repUrl == null) {
248             LOGGER.error(
249                     XACMLErrorConstants.ERROR_DATA_ISSUE + "repositoryURL property is missing from the property file ");
250             throw new PolicyException(
251                     XACMLErrorConstants.ERROR_DATA_ISSUE + "repositoryURL property is missing from the property file ");
252         }
253         if (repUrl.contains(",")) {
254             repUrlList = new ArrayList<>(Arrays.asList(repUrl.trim().split(",")));
255         } else {
256             repUrlList = new ArrayList<>();
257             repUrlList.add(repUrl);
258         }
259         repUserName = getValue(config.getProperty("repositoryUsername"));
260         repPassword = PeCryptoUtils.decrypt(getValue(config.getProperty("repositoryPassword")));
261         if (repUserName == null || repPassword == null) {
262             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE
263                     + "repostoryUserName and respositoryPassword properties are required.");
264             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE
265                     + "repostoryUserName and respositoryPassword properties are required.");
266         }
267         repUserName = repUserName.trim();
268         repPassword = repPassword.trim();
269         policyKeyId = config.getProperty("policyKeyID");
270         if (policyKeyId == null) {
271             LOGGER.error(
272                     XACMLErrorConstants.ERROR_DATA_ISSUE + "policyKeyID property is missing from the property file ");
273             throw new PolicyException(
274                     XACMLErrorConstants.ERROR_DATA_ISSUE + "policyKeyID property is missing from the property file ");
275         }
276         policyKeyId = policyKeyId.trim();
277         final String syncF = config.getProperty("sync", "false").trim();
278         syncFlag = Boolean.parseBoolean(syncF);
279         if (syncFlag) {
280             PolicyLogger.info("SYNC Flag is turned ON. DB will be given Priority.");
281         }
282         brmsdependencyversion = config.getProperty("brms.dependency.version");
283         if (brmsdependencyversion == null) {
284             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE
285                     + "brmsdependencyversion property is missing from the property file, Using default Version.");
286             brmsdependencyversion = DEFAULT_VERSION;
287         }
288         brmsdependencyversion = brmsdependencyversion.trim();
289         readGroups(config);
290
291         // Setup Publisher
292         notificationType = config.getProperty("NOTIFICATION_TYPE");
293         if ("dmaap".equalsIgnoreCase(notificationType)) {
294
295             LOGGER.info("Notification Type being used is DMaaP... creating instance of BusPublisher.");
296             // Setting up the Publisher for DMaaP MR
297             String dmaapServers = config.getProperty("NOTIFICATION_SERVERS");
298             pubTopic = config.getProperty("NOTIFICATION_TOPIC");
299             final String aafLogin = config.getProperty("CLIENT_ID").trim();
300             final String aafPassword = config.getProperty("CLIENT_KEY").trim();
301
302             if (dmaapServers == null || pubTopic == null) {
303                 LOGGER.error(
304                         XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
305                 throw new PolicyException(
306                         XACMLErrorConstants.ERROR_DATA_ISSUE + "DMaaP properties are missing from the property file ");
307             }
308
309             dmaapServers = dmaapServers.trim();
310             pubTopic = pubTopic.trim();
311
312             if (dmaapServers.contains(",")) {
313                 dmaapList = new ArrayList<>(Arrays.asList(dmaapServers.split("\\s*,\\s*")));
314             } else {
315                 dmaapList = new ArrayList<>();
316                 dmaapList.add(dmaapServers);
317             }
318
319             this.publisher =
320                     new BusPublisher.DmaapPublisherWrapper(this.dmaapList, this.pubTopic, aafLogin, aafPassword);
321
322             String notificationDelay = config.getProperty("NOTIFICATION_DELAY");
323             if (notificationDelay != null && !notificationDelay.isEmpty()) {
324                 notificationDelay = notificationDelay.trim();
325                 try {
326                     dmaapDelay = Long.parseLong(notificationDelay);
327                 } catch (final NumberFormatException e) {
328                     LOGGER.error("DMAAP_DELAY not a long format number" + e);
329                 }
330             }
331             LOGGER.info("DMAAP BusPublisher is created.");
332
333         } else {
334             LOGGER.info("Notification Type being used is UEB... creating instance of PublisherBuilder.");
335             // Setting up the Publisher for UEB
336             uebList = config.getProperty("NOTIFICATION_SERVERS");
337             pubTopic = config.getProperty("NOTIFICATION_TOPIC");
338             if (uebList == null || pubTopic == null) {
339                 LOGGER.error(
340                         XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file ");
341                 throw new PolicyException(
342                         XACMLErrorConstants.ERROR_DATA_ISSUE + "UEB properties are missing from the property file ");
343             }
344             uebList = uebList.trim();
345             pubTopic = pubTopic.trim();
346             pubBuilder = new CambriaClientBuilders.PublisherBuilder();
347             pubBuilder.usingHosts(uebList).onTopic(pubTopic).usingHttps(true);
348             String apiKey = config.getProperty("UEB_API_KEY");
349             String apiSecret = config.getProperty("UEB_API_SECRET");
350             if (apiKey != null && !apiKey.isEmpty() && apiSecret != null && !apiSecret.isEmpty()) {
351                 apiKey = apiKey.trim();
352                 apiSecret = apiSecret.trim();
353                 pubBuilder.authenticatedBy(apiKey, apiSecret);
354             }
355             String notificationDelay = config.getProperty("NOTIFICATION_DELAY");
356             if (notificationDelay != null && !notificationDelay.isEmpty()) {
357                 notificationDelay = notificationDelay.trim();
358                 try {
359                     uebDelay = Long.parseLong(notificationDelay);
360                 } catch (final NumberFormatException e) {
361                     LOGGER.error("UEB_DELAY not a long format number" + e);
362                 }
363             }
364             LOGGER.info("UEB PublisherBuilder is created.");
365
366         }
367
368     }
369
370     private String getValue(final String value) {
371         if (value != null && value.matches("[$][{].*[}]$")) {
372             return System.getenv(value.substring(2, value.length() - 1));
373         }
374         return value;
375     }
376
377     private static void setBackupMonitor(final BackUpMonitor instance) {
378         bm = instance;
379     }
380
381     private static void setIntegrityMonitor(final IntegrityMonitor instance) {
382         im = instance;
383     }
384
385     /**
386      * Will Initialize the variables required for BRMSPush.
387      */
388     public void initiate(final boolean flag) {
389         resetModifiedGroups();
390         controllers = new ArrayList<>();
391         try {
392             bm.updateNotification();
393         } catch (final Exception e) {
394             LOGGER.error("Error while updating Notification: " + e.getMessage(), e);
395         }
396         if (flag) {
397             syncGroupInfo();
398         }
399     }
400
401     public void resetDs() {
402         resetModifiedGroups();
403         controllers = new ArrayList<>();
404     }
405
406     private static void resetModifiedGroups() {
407         modifiedGroups = new HashMap<>();
408     }
409
410     /**
411      * Will Add rules to projects. Creates necessary folders if required.
412      */
413     public void addRule(final String name, final String rule, final Map<String, String> responseAttributes) {
414         // 1 check the response Attributes and determine if this belongs to any projects.
415         // 2 if not create folder
416         // 3 create pom.
417         // 4 copy the rule.
418         // 5 store the groups that have been updated.
419         String ksessionName = null;
420         String selectedName = null;
421         if (!responseAttributes.isEmpty()) {
422             // Pick selected Value
423             String userControllerName = null;
424             final ArrayList<PEDependency> userDependencies = new ArrayList<>();
425             for (final Map.Entry<String, String> entry : responseAttributes.entrySet()) {
426                 final String key = entry.getKey();
427                 final String value = entry.getValue();
428                 if (key.equals(policyKeyId)) {
429                     selectedName = value;
430                 }
431                 // kmodule configurations
432                 else if ("kSessionName".equals(key)) {
433                     ksessionName = value;
434                 }
435                 // Check User Specific values.
436                 if ("$controller:".equals(key)) {
437                     userControllerName = getUserControllerName(key, value);
438                 } else if ("$dependency$".equals(key) && value.startsWith("[") && value.endsWith("]")) {
439                     updateUserDependencies(userDependencies, value);
440                 }
441             }
442             if (userControllerName != null) {
443                 // Adding custom dependencies here.
444                 final ArrayList<Object> values = groupMap.get(userControllerName);
445                 values.add(userDependencies);
446                 groupMap.put(userControllerName, values);
447                 selectedName = userControllerName;
448             }
449         }
450         // If no Match then pick Default.
451         if (selectedName == null) {
452             selectedName = defaultName;
453         }
454         if (groupMap.containsKey(selectedName)) {
455             // If the key is not got as parameters set by the user, setting the default value for
456             // kSessionName as
457             // closedLoop
458             if (ksessionName == null) {
459                 LOGGER.info("kSessionName is null, selectedName is  : " + selectedName);
460                 if (selectedName.equalsIgnoreCase(defaultName)) {
461                     ksessionName = "closedloop";
462                 } else {
463                     ksessionName = "closedloop-" + selectedName;
464                 }
465             }
466             // create directories if missing.
467             manageProject(selectedName, ksessionName, name, rule);
468
469             // Will check for Create Later after generating the Pom.
470             addModifiedGroup(selectedName, "update");
471         }
472     }
473
474     private String getUserControllerName(final String key, final String value) {
475         String userControllerName = null;
476         // Check User Specific values.
477         try {
478             final PEDependency dependency = PolicyUtils.jsonStringToObject(value, PEDependency.class);
479             userControllerName = key.replaceFirst("$controller:", "");
480             LOGGER.info("addRule: userControllerName - " + userControllerName + ", dependency: - " + dependency);
481             addToGroup(userControllerName, dependency);
482         } catch (final Exception e) {
483             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while resolving Controller: " + e);
484         }
485         return userControllerName;
486     }
487
488     private void updateUserDependencies(final ArrayList<PEDependency> userDependencies, String value) {
489         // update the user dependencies supplied as parameter to this method
490         value = value.substring(1, value.length() - 1).trim();
491         final List<String> dependencyStrings = Arrays.asList(value.split(Pattern.quote("},{")));
492         for (final String dependencyString : dependencyStrings) {
493             try {
494                 userDependencies.add(PolicyUtils.jsonStringToObject(dependencyString, PEDependency.class));
495             } catch (final Exception e) {
496                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while resolving Dependencies: " + e);
497             }
498         }
499     }
500
501     private void syncGroupInfo() {
502         // Sync DB to JMemory.
503         final EntityTransaction et = em.getTransaction();
504         try {
505             et.begin();
506             final TypedQuery<BrmsGroupInfo> groupInfoQuery =
507                     em.createQuery("select b from BrmsGroupInfo AS b", BrmsGroupInfo.class);
508             final List<BrmsGroupInfo> groupInfoResult = groupInfoQuery.getResultList();
509             if (groupInfoResult.size() != groupMap.size()) {
510                 for (final BrmsGroupInfo brmsGroupInfo : groupInfoResult) {
511                     final PEDependency dependency = new PEDependency();
512                     dependency.setArtifactId(brmsGroupInfo.getArtifactId());
513                     dependency.setGroupId(brmsGroupInfo.getGroupId());
514                     dependency.setVersion(brmsGroupInfo.getVersion());
515                     final ArrayList<Object> values = new ArrayList<>();
516                     values.add(dependency);
517                     groupMap.put(brmsGroupInfo.getControllerName(), values);
518                 }
519             }
520
521             final TypedQuery<BrmsPolicyInfo> policyInfoQuery =
522                     em.createQuery("select g from BrmsPolicyInfo AS g", BrmsPolicyInfo.class);
523             final List<BrmsPolicyInfo> policyInfoResult = policyInfoQuery.getResultList();
524             if (policyInfoResult.size() != policyMap.size()) {
525                 for (final BrmsPolicyInfo brmsPolicyInfo : policyInfoResult) {
526                     policyMap.put(brmsPolicyInfo.getPolicyName(),
527                             brmsPolicyInfo.getControllerName().getControllerName());
528                 }
529             }
530             et.commit();
531             LOGGER.info("Updated Local Memory values with values from database.");
532         } catch (final Exception exception) {
533             LOGGER.error("Unable to sync group info", exception);
534             if (et.isActive()) {
535                 et.rollback();
536             }
537
538         }
539     }
540
541     private void manageProject(final String selectedName, final String ksessionName, final String name,
542             final String rule) {
543         // Check if the Project is in Sync. If not get the latest Version.
544         syncProject(selectedName);
545         createProject(PROJECTSLOCATION + File.separator + getArtifactId(selectedName) + File.separator + "src"
546                 + File.separator + "main" + File.separator + RESOURCES, ksessionName);
547         copyDataToFile(PROJECTSLOCATION + File.separator + getArtifactId(selectedName) + File.separator + "src"
548                 + File.separator + "main" + File.separator + RESOURCES + File.separator + RULES + File.separator + name
549                 + ".drl", rule);
550         addToPolicy(name, selectedName);
551     }
552
553     /*
554      * Add Policy to JMemory and DataBase.
555      */
556     private void addToPolicy(final String policyName, final String controllerName) {
557
558         final EntityTransaction et = em.getTransaction();
559         try {
560             et.begin();
561             boolean create = false;
562             final TypedQuery<BrmsPolicyInfo> policyInfoQuery =
563                     em.createQuery("select b from BrmsPolicyInfo as b where b.policyName = :pn", BrmsPolicyInfo.class);
564             policyInfoQuery.setParameter("pn", policyName);
565             final List<BrmsPolicyInfo> policyInfoResultList = policyInfoQuery.getResultList();
566             BrmsPolicyInfo brmsPolicyInfo = new BrmsPolicyInfo();
567             if (!policyInfoResultList.isEmpty()) {
568                 // Already exists.
569                 brmsPolicyInfo = policyInfoResultList.get(0);
570                 if (!brmsPolicyInfo.getControllerName().getControllerName().equals(controllerName)) {
571                     create = true;
572                 }
573             } else {
574                 create = true;
575             }
576             if (create) {
577                 final TypedQuery<BrmsGroupInfo> groupInfoQuery = em.createQuery(
578                         "select b from BrmsGroupInfo as b where b.controllerName = :cn", BrmsGroupInfo.class);
579                 groupInfoQuery.setParameter("cn", controllerName);
580                 final List<BrmsGroupInfo> groupInfoResultList = groupInfoQuery.getResultList();
581                 BrmsGroupInfo brmsGroupInfo = new BrmsGroupInfo();
582                 if (!groupInfoResultList.isEmpty()) {
583                     brmsGroupInfo = groupInfoResultList.get(0);
584                 }
585                 brmsPolicyInfo.setPolicyName(policyName);
586                 brmsPolicyInfo.setControllerName(brmsGroupInfo);
587                 em.persist(brmsPolicyInfo);
588                 em.flush();
589             }
590             et.commit();
591
592             policyMap.put(policyName, controllerName);
593         } catch (final Exception exception) {
594             LOGGER.error("Unable add policy to database", exception);
595             et.rollback();
596         }
597     }
598
599     private void syncProject(final String selectedName) {
600         final boolean projectExists = checkProject(selectedName);
601         if (projectExists) {
602             String version;
603             version = getVersion(selectedName);
604             if (version == null) {
605                 LOGGER.error("Error getting local version for the given Controller Name:" + selectedName
606                         + " going with Default value");
607                 version = VERSION_0_1_0;
608             }
609             final String nextVersion = incrementVersion(version);
610             final boolean outOfSync = checkRemoteSync(selectedName, nextVersion);
611             if (!outOfSync) {
612                 return;
613             }
614         }
615         // We are out of Sync or Project is not Present.
616         downloadProject(selectedName);
617     }
618
619     private void downloadProject(final String selectedName) {
620         final NexusArtifact artifact = getLatestArtifactFromNexus(selectedName);
621         if (artifact == null) {
622             return;
623         }
624         final String dirName = getDirectoryName(selectedName);
625         URL website;
626         final String fileName = "rule.jar";
627         try {
628             website = new URL(artifact.getUrlPath() + ".jar");
629             try (ReadableByteChannel rbc = Channels.newChannel(website.openStream());
630                     FileOutputStream fos = new FileOutputStream(fileName)) {
631                 fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
632                 extractJar(fileName, dirName);
633                 new File(fileName).delete();
634             } catch (final IOException e) {
635                 LOGGER.error("Error while downloading the project to File System. " + e.getMessage(), e);
636             }
637
638         } catch (final IOException e1) {
639             LOGGER.error("Error while retrieve the artifact. " + e1.getMessage(), e1);
640         }
641     }
642
643     private void extractJar(final String jarFileName, final String artifactId) {
644         try (JarFile jar = new JarFile(jarFileName)) {
645             final Enumeration<?> enumEntries = jar.entries();
646             while (enumEntries.hasMoreElements()) {
647                 parseJarContents(artifactId, jar, enumEntries);
648             }
649         } catch (final IOException e) {
650             LOGGER.info("exception Occured" + e);
651         }
652     }
653
654     private void parseJarContents(final String artifactId, final JarFile jar, final Enumeration<?> enumEntries) {
655         final JarEntry jarEntry = (JarEntry) enumEntries.nextElement();
656         File file = null;
657         final String fileName = jarEntry.getName().substring(jarEntry.getName().lastIndexOf("/") + 1);
658         if (jarEntry.getName().endsWith(".drl")) {
659             final String path = PROJECTSLOCATION + File.separator + artifactId + File.separator + "src" + File.separator
660                     + "main" + File.separator + RESOURCES + File.separator + RULES;
661             new File(path).mkdirs();
662             if (syncFlag && policyMap.containsKey(fileName.replace(".drl", ""))) {
663                 file = new File(path + File.separator + fileName);
664             } else {
665                 file = new File(path + File.separator + fileName);
666             }
667         } else if (jarEntry.getName().endsWith(POM_XML_FILE)) {
668             final String path = PROJECTSLOCATION + File.separator + artifactId;
669             new File(path).mkdirs();
670             file = new File(path + File.separator + fileName);
671         } else if (jarEntry.getName().endsWith(KMODULE_XML_FILE)) {
672             final String path = PROJECTSLOCATION + File.separator + artifactId + File.separator + "src" + File.separator
673                     + "main" + File.separator + RESOURCES + File.separator + META_INF;
674             new File(path).mkdirs();
675             file = new File(path + File.separator + fileName);
676         }
677         if (file != null) {
678             try (InputStream is = jar.getInputStream(jarEntry); FileOutputStream fos = new FileOutputStream(file)) {
679                 while (is.available() > 0) {
680                     fos.write(is.read());
681                 }
682                 LOGGER.info(fileName + " Created..");
683             } catch (final IOException e) {
684                 LOGGER.info("exception Occured" + e);
685             }
686         }
687     }
688
689     private NexusArtifact getLatestArtifactFromNexus(final String selectedName) {
690         final List<NexusArtifact> artifacts = getArtifactFromNexus(selectedName, null);
691         int bigNum = 0;
692         int smallNum = 0;
693         NexusArtifact result = null;
694         for (final NexusArtifact artifact : artifacts) {
695             final int majorVal =
696                     Integer.parseInt(artifact.getVersion().substring(0, artifact.getVersion().indexOf(".")));
697             final int minorVal = Integer.parseInt(artifact.getVersion()
698                     .substring(artifact.getVersion().indexOf(".") + 1, artifact.getVersion().lastIndexOf(".")));
699             if (majorVal > bigNum) {
700                 bigNum = majorVal;
701                 smallNum = minorVal;
702             }
703             if ((bigNum == majorVal) && (minorVal > smallNum)) {
704                 smallNum = minorVal;
705             }
706             if (bigNum == majorVal && minorVal == smallNum) {
707                 result = artifact;
708             }
709         }
710         return additionalNexusLatestCheck(selectedName, result);
711     }
712
713     // Additional Check due to Limitations from Nexus API to check if the artifact is the latest.
714     private NexusArtifact additionalNexusLatestCheck(final String selectedName, final NexusArtifact result) {
715         if (result == null) {
716             return result;
717         }
718         final String nextVersion = incrementVersion(result.getVersion());
719         final List<NexusArtifact> artifact = getArtifactFromNexus(selectedName, nextVersion);
720         return artifact.isEmpty() ? result : additionalNexusLatestCheck(selectedName, artifact.get(0));
721     }
722
723     private boolean checkRemoteSync(final String selectedName, final String version) {
724         final List<NexusArtifact> artifacts = getArtifactFromNexus(selectedName, version);
725         return artifacts.isEmpty() ? false : true;
726     }
727
728     private List<NexusArtifact> getArtifactFromNexus(final String selectedName, final String version) {
729         NexusRestWrapper restWrapper = null;
730         int index = 0;
731         boolean flag = false;
732         while (index < repUrlList.size()) {
733             try {
734                 final String repUrl = repUrlList.get(0);
735                 restWrapper =
736                         new NexusRestWrapper(repUrl.substring(0, repUrl.indexOf(repUrl.split(":[0-9]+\\/nexus")[1])),
737                                 repUserName, repPassword);
738                 final NexusRestSearchParameters searchParameters = new NexusRestSearchParameters();
739                 searchParameters.useFilterSearch(getGroupId(selectedName), getArtifactId(selectedName), version, null,
740                         null);
741
742                 final List<NexusArtifact> resultList = restWrapper.findArtifact(searchParameters).getArtifactList();
743                 if (resultList != null) {
744                     flag = true;
745                     return resultList;
746                 }
747             } catch (NexusRestWrapperException | ProcessingException e) {
748                 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Connection to remote Nexus has failed. "
749                         + e.getMessage(), e);
750             } finally {
751                 if (null != restWrapper) {
752                     restWrapper.close();
753                 }
754                 if (!flag) {
755                     Collections.rotate(repUrlList, -1);
756                     index++;
757                 }
758             }
759         }
760         return new ArrayList<>();
761     }
762
763     private String incrementVersion(final String version) {
764         int majorVal = Integer.parseInt(version.substring(0, version.indexOf(".")));
765         int minorVal = Integer.parseInt(version.substring(version.indexOf(".") + 1, version.lastIndexOf(".")));
766         if (minorVal >= 9) {
767             majorVal += 1;
768             minorVal = 0;
769         } else {
770             minorVal += 1;
771         }
772         return majorVal + "." + minorVal + version.substring(version.lastIndexOf("."));
773     }
774
775     private boolean checkProject(final String selectedName) {
776         return new File(PROJECTSLOCATION + File.separator + getDirectoryName(selectedName)).exists();
777     }
778
779     private String getDirectoryName(final String selectedName) {
780         return getArtifactId(selectedName);
781     }
782
783     /**
784      * Will Push policies to the PolicyRepo.
785      *
786      * @throws PolicyException PolicyException related to the operation
787      */
788     public void pushRules() throws PolicyException {
789         // Check how many groups have been updated.
790         // Invoke their Maven process.
791         try {
792             im.startTransaction();
793         } catch (final Exception e) {
794             LOGGER.error("Error while starting Transaction " + e);
795         }
796         if (!modifiedGroups.isEmpty()) {
797             if (buildAndGenerateJarFile()) {
798                 sendNotification(controllers);
799             }
800         }
801         if (im != null) {
802             im.endTransaction();
803         }
804     }
805
806     /**
807      * Removes a Rule from Rule Projects.
808      */
809     public void removeRule(final String name) {
810         final String controllerName = getGroupName(name);
811         if (controllerName == null) {
812             LOGGER.info("Error finding the controllerName for the given Policy: " + name);
813             return;
814         }
815         syncProject(controllerName);
816         getNameAndSetRemove(controllerName, name);
817     }
818
819     private Boolean buildAndGenerateJarFile() throws PolicyException {
820         Boolean flag = false;
821         for (final Map.Entry<String, String> entry : modifiedGroups.entrySet()) {
822             InvocationResult result = null;
823             final String group = entry.getKey();
824             try {
825                 LOGGER.info("PushRules: ModifiedGroups, Key: " + group + ", Value: " + entry.getValue());
826                 final InvocationRequest request = new DefaultInvocationRequest();
827                 setVersion(group);
828                 createPom(group);
829                 request.setPomFile(new File(
830                         PROJECTSLOCATION + File.separator + getArtifactId(group) + File.separator + POM_XML_FILE));
831                 request.setGoals(Arrays.asList(GOALS));
832                 final Invoker invoker = new DefaultInvoker();
833                 result = invoker.execute(request);
834                 if (result.getExecutionException() != null) {
835                     LOGGER.error(result.getExecutionException());
836                 } else if (result.getExitCode() != 0) {
837                     LOGGER.error("Maven Invocation failure..!");
838                 }
839             } catch (final Exception e) {
840                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Maven Invocation issue for "
841                         + getArtifactId(group) + e.getMessage(), e);
842             }
843             if (result != null && result.getExitCode() == 0) {
844                 LOGGER.info("Build Completed..!");
845                 if (createFlag) {
846                     addNotification(group, "create");
847                 } else {
848                     addNotification(group, entry.getValue());
849                 }
850                 flag = true;
851             } else {
852                 throw new PolicyException(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Maven Invocation failure!");
853             }
854         }
855         return flag;
856     }
857
858     private String getGroupName(final String name) {
859         if (policyMap.containsKey(name)) {
860             return policyMap.get(name);
861         } else {
862             syncGroupInfo();
863             return policyMap.containsKey(name) ? policyMap.get(name) : null;
864         }
865     }
866
867     private void addModifiedGroup(final String controllerName, final String operation) {
868         if (controllerName != null) {
869             modifiedGroups.put(controllerName, operation);
870         }
871     }
872
873     private void addNotification(final String controllerName, final String operation) {
874         final ControllerPojo controllerPojo = new ControllerPojo();
875         controllerPojo.setName(controllerName);
876         controllerPojo.setOperation(operation);
877         final HashMap<String, String> drools = new HashMap<>();
878         drools.put("groupId", getGroupId(controllerName));
879         drools.put("artifactId", getArtifactId(controllerName));
880         drools.put("version", getVersion(controllerName));
881         controllerPojo.setDrools(drools);
882         controllers.add(controllerPojo);
883         try {
884             LOGGER.debug("Notification added: " + PolicyUtils.objectToJsonString(controllerPojo));
885         } catch (final JsonProcessingException e) {
886             LOGGER.error(MessageCodes.ERROR_SCHEMA_INVALID + "Json Processing Error " + e);
887         }
888     }
889
890     private void removedRuleModifiedGroup(final String controllerName) {
891         // This will be sending Notification to PDPD directly to Lock
892         final ControllerPojo controllerPojo = new ControllerPojo();
893         controllerPojo.setName(controllerName);
894         controllerPojo.setOperation("lock");
895         final List<ControllerPojo> controllerPojos = new ArrayList<>();
896         controllerPojos.add(controllerPojo);
897         sendNotification(controllerPojos);
898     }
899
900     private void sendNotification(final List<ControllerPojo> controllers) {
901         final NotificationPojo notification = new NotificationPojo();
902         final String requestId = UUID.randomUUID().toString();
903         LOGGER.info("Generating notification RequestID : " + requestId);
904         notification.setRequestId(requestId);
905         notification.setEntity("controller");
906         notification.setControllers(controllers);
907         try {
908             final String notificationJson = PolicyUtils.objectToJsonString(notification);
909             LOGGER.info("Sending Notification :\n" + notificationJson);
910             sendMessage(notificationJson);
911         } catch (final Exception e) {
912             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while sending notification to PDP-D "
913                     + e.getMessage(), e);
914         }
915     }
916
917     private void sendMessage(final String message) throws IOException, GeneralSecurityException, InterruptedException {
918
919         if ("dmaap".equalsIgnoreCase(notificationType)) {
920             // Sending Message through DMaaP Message Router
921             LOGGER.debug("DMAAP Publishing Message");
922
923             publisher.send("MyPartitionKey", message);
924
925             LOGGER.debug("Message Published on DMaaP :" + dmaapList.get(0) + "for Topic: " + pubTopic);
926
927             Thread.sleep(dmaapDelay);
928             publisher.close();
929         } else {
930             // Sending Message through UEB interface.
931             LOGGER.debug("UEB Publishing Message");
932
933             final CambriaBatchingPublisher pub = pubBuilder.build();
934             pub.send("MyPartitionKey", message);
935
936             final List<?> stuck = pub.close(uebDelay, TimeUnit.SECONDS);
937             if (!stuck.isEmpty()) {
938                 LOGGER.error(stuck.size() + " messages unsent");
939             } else {
940                 LOGGER.debug("Clean exit; Message Published on UEB : " + uebList + "for Topic: " + pubTopic);
941             }
942         }
943
944     }
945
946     private void createPom(final String name) {
947         final Model model = new Model();
948         model.setModelVersion("4.0.0");
949         model.setGroupId(getGroupId(name));
950         model.setArtifactId(getArtifactId(name));
951         model.setVersion(getVersion(name));
952         model.setName(name);
953         final DistributionManagement distributionManagement = new DistributionManagement();
954         final DeploymentRepository repository = new DeploymentRepository();
955         repository.setId(repId);
956         repository.setName(repName);
957         repository.setUrl(repUrlList.get(0));
958         distributionManagement.setRepository(repository);
959         model.setDistributionManagement(distributionManagement);
960         // Dependency Management goes here.
961         List<Dependency> dependencyList = new ArrayList<>();
962         if (groupMap.get(name).size() > 1) {
963             @SuppressWarnings("unchecked")
964             final ArrayList<PEDependency> dependencies = (ArrayList<PEDependency>) groupMap.get(name).get(1);
965             for (final PEDependency dependency : dependencies) {
966                 dependencyList.add(dependency.getDependency());
967             }
968         } else {
969             // Add Default dependencies.
970             dependencyList = getDependencies(name);
971         }
972         model.setDependencies(dependencyList);
973         Writer writer = null;
974         try {
975             writer = WriterFactory.newXmlWriter(
976                     new File(PROJECTSLOCATION + File.separator + getArtifactId(name) + File.separator + POM_XML_FILE));
977             final MavenXpp3Writer pomWriter = new MavenXpp3Writer();
978             pomWriter.write(writer, model);
979         } catch (final Exception e) {
980             LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while creating POM for " + getArtifactId(name)
981                     + e.getMessage(), e);
982         } finally {
983             IOUtil.close(writer);
984         }
985     }
986
987     private List<Dependency> getDependencies(final String controllerName) {
988         // Read the Dependency Information from property file.
989         final Path file = Paths.get(DEPENDENCY_FILE);
990         if (!Files.notExists(file)) {
991             try {
992                 final String dependencyJson = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
993                 final DependencyInfo dependencyInfo =
994                         PolicyUtils.jsonStringToObject(dependencyJson, DependencyInfo.class);
995                 String controller = "default";
996                 if (dependencyInfo.getDependencies().containsKey(controllerName)) {
997                     controller = controllerName;
998                 }
999                 final List<Dependency> dependencyList = new ArrayList<>();
1000                 for (final PEDependency dependency : dependencyInfo.getDependencies().get(controller)) {
1001                     dependencyList.add(dependency.getDependency());
1002                 }
1003                 return dependencyList;
1004             } catch (IOException | NullPointerException e) {
1005                 LOGGER.error(XACMLErrorConstants.ERROR_PROCESS_FLOW
1006                         + "Error while getting dependecy Information for controller: " + controllerName
1007                         + e.getMessage(), e);
1008             }
1009         }
1010         return defaultDependencies(controllerName);
1011     }
1012
1013     /**
1014      * Default Dependency Section. Can be changed as required.
1015      *
1016      * @param controllerName the controller name
1017      * @return changed dependency list
1018      */
1019     public List<Dependency> defaultDependencies(final String controllerName) {
1020
1021         final List<Dependency> dependencyList = new ArrayList<>();
1022         final String version = StringEscapeUtils.escapeJava(brmsdependencyversion);
1023
1024         final Dependency demoDependency = new Dependency();
1025         demoDependency.setGroupId(DROOLS_APPS_TEMPLATE_GROUP);
1026         demoDependency.setArtifactId("template.demo");
1027         demoDependency.setVersion(version);
1028         dependencyList.add(demoDependency);
1029
1030         final Dependency controlloopDependency = new Dependency();
1031         controlloopDependency.setGroupId(DROOLS_APPS_MODEL_GROUP);
1032         controlloopDependency.setArtifactId("events");
1033         controlloopDependency.setVersion(version);
1034         dependencyList.add(controlloopDependency);
1035
1036         final Dependency restDependency = new Dependency();
1037         restDependency.setGroupId(DROOLS_APPS_MODEL_GROUP);
1038         restDependency.setArtifactId("controlloop.common.model-impl.rest");
1039         restDependency.setVersion(version);
1040         dependencyList.add(restDependency);
1041
1042         final Dependency appcDependency = new Dependency();
1043         appcDependency.setGroupId(DROOLS_APPS_MODEL_GROUP);
1044         appcDependency.setArtifactId("controlloop.common.model-impl.appc");
1045         appcDependency.setVersion(version);
1046         dependencyList.add(appcDependency);
1047
1048         final Dependency aaiDependency = new Dependency();
1049         aaiDependency.setGroupId(DROOLS_APPS_MODEL_GROUP);
1050         aaiDependency.setArtifactId("controlloop.common.model-impl.aai");
1051         aaiDependency.setVersion(version);
1052         dependencyList.add(aaiDependency);
1053
1054         final Dependency msoDependency = new Dependency();
1055         msoDependency.setGroupId(DROOLS_APPS_MODEL_GROUP);
1056         msoDependency.setArtifactId("controlloop.common.model-impl.so");
1057         msoDependency.setVersion(version);
1058         dependencyList.add(msoDependency);
1059         return dependencyList;
1060     }
1061
1062     private void createProject(final String path, final String ksessionName) {
1063         new File(path + File.separator + RULES).mkdirs();
1064         new File(path + File.separator + META_INF).mkdirs();
1065         if (!Files.exists(Paths.get(path + File.separator + META_INF + File.separator + KMODULE_XML_FILE))) {
1066             // Hard coding XML for PDP Drools to accept our Rules.
1067             final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n"
1068                     + "<kmodule xmlns=\"http://jboss.org/kie/6.0.0/kmodule\">" + "\n"
1069                     + "<kbase name=\"rules\" packages=\"rules\">" + "\n" + "<ksession name=\"" + ksessionName + "\"/>"
1070                     + "\n" + "</kbase></kmodule>";
1071             copyDataToFile(path + File.separator + META_INF + File.separator + KMODULE_XML_FILE, xml);
1072         }
1073     }
1074
1075     private void copyDataToFile(final String file, final String rule) {
1076         try {
1077             FileUtils.writeStringToFile(new File(file), rule);
1078         } catch (final Exception e) {
1079             LOGGER.error(
1080                     XACMLErrorConstants.ERROR_PROCESS_FLOW + "Error while creating Rule for " + file + e.getMessage(),
1081                     e);
1082         }
1083     }
1084
1085     private void readGroups(final Properties config) throws PolicyException {
1086         String[] groupNames;
1087         final String groupNamesError = "groupNames property is missing or empty from the property file ";
1088         if (!config.containsKey(GROUP_NAMES) || config.getProperty(GROUP_NAMES) == null) {
1089             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE + groupNamesError);
1090         }
1091         if (config.getProperty(GROUP_NAMES).contains(",")) {
1092             groupNames = config.getProperty(GROUP_NAMES).replaceAll(" ", "").split(",");
1093         } else {
1094             groupNames = new String[] {config.getProperty(GROUP_NAMES).replaceAll(" ", "")};
1095         }
1096         if (groupNames == null || groupNames.length == 0) {
1097             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + groupNamesError);
1098             throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE + groupNamesError);
1099         }
1100         groupMap = new HashMap<>();
1101         for (int counter = 0; counter < groupNames.length; counter++) {
1102             final String name = groupNames[counter];
1103             final String groupId = config.getProperty(name + ".groupID");
1104             if (groupId == null) {
1105                 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + name
1106                         + ".groupID property is missing from the property file ");
1107                 throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE + name
1108                         + ".groupID property is missing from the property file ");
1109             }
1110             final String artifactId = config.getProperty(name + ".artifactID");
1111             if (artifactId == null) {
1112                 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + name
1113                         + ".artifactID property is missing from the property file ");
1114                 throw new PolicyException(XACMLErrorConstants.ERROR_DATA_ISSUE + name
1115                         + ".artifactID property is missing from the property file ");
1116             }
1117             final PEDependency dependency = new PEDependency();
1118             dependency.setArtifactId(artifactId);
1119             dependency.setGroupId(groupId);
1120             // Add to list if we got all
1121             addToGroup(name, dependency);
1122         }
1123     }
1124
1125     private void addToGroup(final String name, final PEDependency dependency) {
1126         final EntityTransaction et = em.getTransaction();
1127         try {
1128             et.begin();
1129             final TypedQuery<BrmsGroupInfo> query = em
1130                     .createQuery("select b from BrmsGroupInfo as b where b.controllerName = :cn", BrmsGroupInfo.class);
1131             query.setParameter("cn", name);
1132             final List<BrmsGroupInfo> groupList = query.getResultList();
1133             BrmsGroupInfo brmsGroupInfo = null;
1134             if (!groupList.isEmpty()) {
1135                 LOGGER.info("Controller name already Existing in DB. Will be updating the DB Values" + name);
1136                 brmsGroupInfo = groupList.get(0);
1137             }
1138             if (brmsGroupInfo == null) {
1139                 brmsGroupInfo = new BrmsGroupInfo();
1140             }
1141             brmsGroupInfo.setControllerName(name);
1142             brmsGroupInfo.setGroupId(dependency.getGroupId());
1143             brmsGroupInfo.setArtifactId(dependency.getArtifactId());
1144             brmsGroupInfo.setVersion(dependency.getVersion());
1145             em.persist(brmsGroupInfo);
1146             em.flush();
1147             et.commit();
1148
1149             final ArrayList<Object> values = new ArrayList<>();
1150             values.add(dependency);
1151             groupMap.put(name, values);
1152         } catch (final Exception exception) {
1153             LOGGER.error("Unable add/update policy group to database for controller name: " + name, exception);
1154             et.rollback();
1155         }
1156     }
1157
1158     private String getArtifactId(final String name) {
1159         return ((PEDependency) groupMap.get(name).get(0)).getArtifactId();
1160     }
1161
1162     private String getGroupId(final String name) {
1163         return ((PEDependency) groupMap.get(name).get(0)).getGroupId();
1164     }
1165
1166     private String getVersion(final String name) {
1167         return ((PEDependency) groupMap.get(name).get(0)).getVersion();
1168     }
1169
1170     private void getNameAndSetRemove(final String controllerName, final String policyName) {
1171         final String artifactName = getArtifactId(controllerName);
1172         final String ruleFolder = PROJECTSLOCATION + File.separator + artifactName + File.separator + "src"
1173                 + File.separator + "main" + File.separator + RESOURCES + File.separator + RULES;
1174         final File file = new File(ruleFolder + File.separator + policyName + ".drl");
1175         if (file.delete()) {
1176             LOGGER.info("Deleted File.. " + file.getAbsolutePath());
1177             removePolicyFromGroup(policyName, controllerName);
1178         }
1179         if (new File(ruleFolder).listFiles().length == 0) {
1180             removedRuleModifiedGroup(controllerName);
1181         } else {
1182             // This is an update in terms of PDPD.
1183             addModifiedGroup(controllerName, "update");
1184         }
1185     }
1186
1187     // Removes Policy from Memory and Database.
1188     private void removePolicyFromGroup(final String policyName, final String controllerName) {
1189         final EntityTransaction et = em.getTransaction();
1190         try {
1191             et.begin();
1192             final TypedQuery<BrmsPolicyInfo> query =
1193                     em.createQuery("select b from BrmsPolicyInfo as b where b.policyName = :pn", BrmsPolicyInfo.class);
1194             query.setParameter("pn", policyName);
1195             final List<BrmsPolicyInfo> pList = query.getResultList();
1196             BrmsPolicyInfo brmsPolicyInfo;
1197             if (!pList.isEmpty()) {
1198                 // Already exists.
1199                 brmsPolicyInfo = pList.get(0);
1200                 if (brmsPolicyInfo.getControllerName().getControllerName().equals(controllerName)) {
1201                     em.remove(brmsPolicyInfo);
1202                     em.flush();
1203                 }
1204             }
1205             et.commit();
1206             policyMap.remove(policyName);
1207         } catch (final Exception exception) {
1208             LOGGER.error("Unable remove policy from group to database for policy name: " + policyName, exception);
1209             et.rollback();
1210         }
1211     }
1212
1213     private void setVersion(final String selectedName) {
1214         String newVersion = VERSION_0_1_0;
1215         createFlag = false;
1216         final NexusArtifact artifact = getLatestArtifactFromNexus(selectedName);
1217         if (artifact != null) {
1218             newVersion = incrementVersion(artifact.getVersion());
1219         }
1220         if (VERSION_0_1_0.equals(newVersion)) {
1221             createFlag = true;
1222         }
1223         setVersion(newVersion, selectedName);
1224         LOGGER.info("Controller: " + selectedName + "is on version: " + newVersion);
1225     }
1226
1227     private void setVersion(final String newVersion, final String controllerName) {
1228         final PEDependency userController = (PEDependency) groupMap.get(controllerName).get(0);
1229         userController.setVersion(newVersion);
1230         groupMap.get(controllerName).set(0, userController);
1231     }
1232
1233     // Return BackUpMonitor
1234     public static BackUpMonitor getBackUpMonitor() {
1235         return bm;
1236     }
1237
1238     /**
1239      * Rotate URLs list.
1240      */
1241     public void rotateUrls() {
1242         if (repUrlList != null) {
1243             Collections.rotate(repUrlList, -1);
1244         }
1245     }
1246
1247     /**
1248      * Get URL List Size.
1249      *
1250      * @return URL list size
1251      */
1252     public int urlListSize() {
1253         return repUrlList != null ? repUrlList.size() : 0;
1254     }
1255 }