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