28133cefae11b1892c072faf981bdbc03a5d2f73
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * 
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * 
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.model.policymodel.handling;
22
23 import java.util.Set;
24 import java.util.TreeSet;
25
26 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
27 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
28 import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
29 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
30 import org.slf4j.ext.XLogger;
31 import org.slf4j.ext.XLoggerFactory;
32
33 /**
34  * Helper class used to merge information from two policy models together into a single policy
35  * model.
36  *
37  * @author Liam Fallon (liam.fallon@ericsson.com)
38  */
39 public final class PolicyModelMerger {
40     private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelMerger.class);
41
42     /**
43      * Private constructor used to prevent sub class instantiation.
44      */
45     private PolicyModelMerger() {}
46
47     /**
48      * Get a merged policy model with information from two policy models merged into a larger policy
49      * model.
50      *
51      * @param leftPolicyModel the source Apex Model
52      * @param rightPolicyModel the policies to include in sub policy model
53      * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
54      *        keys are found, if false it uses the concepts from the right model
55      * @return the new Destination Model
56      * @throws ApexModelException on model transfer errors
57      */
58     public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
59             final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches) throws ApexModelException {
60         return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false);
61     }
62
63     /**
64      * Get a merged policy model with information from two policy models merged into a larger policy
65      * model.
66      *
67      * @param leftPolicyModel the source Apex Model
68      * @param rightPolicyModel the policies to include in sub policy model
69      * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
70      *        keys are found, if false it uses the concepts from the right model
71      * @param ignoreInvalidSource Ignore errors on the source model, do the best you can
72      * @return the new Destination Model
73      * @throws ApexModelException on model transfer errors
74      */
75     public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
76             final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean ignoreInvalidSource)
77             throws ApexModelException {
78         // Validate the left model
79         if (!ignoreInvalidSource) {
80             final AxValidationResult leftValidationResult = new AxValidationResult();
81             leftPolicyModel.validate(leftValidationResult);
82             if (!leftValidationResult.isValid()) {
83                 String message = "left model is invalid: " + leftValidationResult.toString(); 
84                 LOGGER.warn(message);
85                 throw new ApexModelException(message);
86             }
87         }
88
89         // Validate the right model
90         if (!ignoreInvalidSource) {
91             final AxValidationResult rightValidationResult = new AxValidationResult();
92             rightPolicyModel.validate(rightValidationResult);
93             if (!rightValidationResult.isValid()) {
94                 String message = "right model is invalid: " + rightValidationResult.toString();
95                 LOGGER.warn(message);
96                 throw new ApexModelException(message);
97             }
98         }
99
100         // The new policy model uses the favoured copy side as its base
101         final AxPolicyModel mergedPolicyModel = (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel)
102                 : new AxPolicyModel(rightPolicyModel));
103
104         // The Compared to policy model is the unfavoured side
105         final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel);
106
107         //  Get the keys to copy over
108         final Set<AxArtifactKey> copyOverKeyInfoKeys =
109                 new TreeSet<>(copyFromPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
110         final Set<AxArtifactKey> copyOverContextSchemaKeys =
111                 new TreeSet<>(copyFromPolicyModel.getSchemas().getSchemasMap().keySet());
112         final Set<AxArtifactKey> copyOverEventKeys =
113                 new TreeSet<>(copyFromPolicyModel.getEvents().getEventMap().keySet());
114         final Set<AxArtifactKey> copyOverContextAlbumKeys =
115                 new TreeSet<>(copyFromPolicyModel.getAlbums().getAlbumsMap().keySet());
116         final Set<AxArtifactKey> copyOverTaskKeys = new TreeSet<>(copyFromPolicyModel.getTasks().getTaskMap().keySet());
117         final Set<AxArtifactKey> copyOverPolicyKeys =
118                 new TreeSet<>(copyFromPolicyModel.getPolicies().getPolicyMap().keySet());
119
120         //  Remove keys that already exist
121         copyOverKeyInfoKeys.removeAll(mergedPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
122         copyOverContextSchemaKeys.removeAll(mergedPolicyModel.getSchemas().getSchemasMap().keySet());
123         copyOverEventKeys.removeAll(mergedPolicyModel.getEvents().getEventMap().keySet());
124         copyOverContextAlbumKeys.removeAll(mergedPolicyModel.getAlbums().getAlbumsMap().keySet());
125         copyOverTaskKeys.removeAll(mergedPolicyModel.getTasks().getTaskMap().keySet());
126         copyOverPolicyKeys.removeAll(mergedPolicyModel.getPolicies().getPolicyMap().keySet());
127
128         // Now add all the concepts that must be copied over
129         for (final AxArtifactKey keyInfoKey : copyOverKeyInfoKeys) {
130             mergedPolicyModel.getKeyInformation().getKeyInfoMap().put(keyInfoKey,
131                     copyFromPolicyModel.getKeyInformation().getKeyInfoMap().get(keyInfoKey));
132         }
133         for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) {
134             mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
135                     copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
136         }
137         for (final AxArtifactKey eventKey : copyOverEventKeys) {
138             mergedPolicyModel.getEvents().getEventMap().put(eventKey,
139                     copyFromPolicyModel.getEvents().getEventMap().get(eventKey));
140         }
141         for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) {
142             mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
143                     copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
144         }
145         for (final AxArtifactKey taskKey : copyOverTaskKeys) {
146             mergedPolicyModel.getTasks().getTaskMap().put(taskKey,
147                     copyFromPolicyModel.getTasks().getTaskMap().get(taskKey));
148         }
149         for (final AxArtifactKey policyKey : copyOverPolicyKeys) {
150             mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey,
151                     copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey));
152         }
153
154         // That's it, return the model
155         return mergedPolicyModel;
156     }
157 }