091f20462f369aeb0558ab98831efd3de40626a6
[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                 LOGGER.warn("left model is invalid: " + leftValidationResult.toString());
84                 throw new ApexModelException("left model is invalid: " + leftValidationResult.toString());
85             }
86         }
87
88         // Validate the right model
89         if (!ignoreInvalidSource) {
90             final AxValidationResult rightValidationResult = new AxValidationResult();
91             rightPolicyModel.validate(rightValidationResult);
92             if (!rightValidationResult.isValid()) {
93                 LOGGER.warn("right model is invalid: " + rightValidationResult.toString());
94                 throw new ApexModelException("right model is invalid: " + rightValidationResult.toString());
95             }
96         }
97
98         // The new policy model uses the favoured copy side as its base
99         final AxPolicyModel mergedPolicyModel = (AxPolicyModel) (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel)
100                 : new AxPolicyModel(rightPolicyModel));
101
102         // The Compared to policy model is the unfavoured side
103         final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel);
104
105         //  Get the keys to copy over
106         final Set<AxArtifactKey> copyOverKeyInfoKeys =
107                 new TreeSet<>(copyFromPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
108         final Set<AxArtifactKey> copyOverContextSchemaKeys =
109                 new TreeSet<>(copyFromPolicyModel.getSchemas().getSchemasMap().keySet());
110         final Set<AxArtifactKey> copyOverEventKeys =
111                 new TreeSet<>(copyFromPolicyModel.getEvents().getEventMap().keySet());
112         final Set<AxArtifactKey> copyOverContextAlbumKeys =
113                 new TreeSet<>(copyFromPolicyModel.getAlbums().getAlbumsMap().keySet());
114         final Set<AxArtifactKey> copyOverTaskKeys = new TreeSet<>(copyFromPolicyModel.getTasks().getTaskMap().keySet());
115         final Set<AxArtifactKey> copyOverPolicyKeys =
116                 new TreeSet<>(copyFromPolicyModel.getPolicies().getPolicyMap().keySet());
117
118         //  Remove keys that already exist
119         copyOverKeyInfoKeys.removeAll(mergedPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
120         copyOverContextSchemaKeys.removeAll(mergedPolicyModel.getSchemas().getSchemasMap().keySet());
121         copyOverEventKeys.removeAll(mergedPolicyModel.getEvents().getEventMap().keySet());
122         copyOverContextAlbumKeys.removeAll(mergedPolicyModel.getAlbums().getAlbumsMap().keySet());
123         copyOverTaskKeys.removeAll(mergedPolicyModel.getTasks().getTaskMap().keySet());
124         copyOverPolicyKeys.removeAll(mergedPolicyModel.getPolicies().getPolicyMap().keySet());
125
126         // Now add all the concepts that must be copied over
127         for (final AxArtifactKey keyInfoKey : copyOverKeyInfoKeys) {
128             mergedPolicyModel.getKeyInformation().getKeyInfoMap().put(keyInfoKey,
129                     copyFromPolicyModel.getKeyInformation().getKeyInfoMap().get(keyInfoKey));
130         }
131         for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) {
132             mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
133                     copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
134         }
135         for (final AxArtifactKey eventKey : copyOverEventKeys) {
136             mergedPolicyModel.getEvents().getEventMap().put(eventKey,
137                     copyFromPolicyModel.getEvents().getEventMap().get(eventKey));
138         }
139         for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) {
140             mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
141                     copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
142         }
143         for (final AxArtifactKey taskKey : copyOverTaskKeys) {
144             mergedPolicyModel.getTasks().getTaskMap().put(taskKey,
145                     copyFromPolicyModel.getTasks().getTaskMap().get(taskKey));
146         }
147         for (final AxArtifactKey policyKey : copyOverPolicyKeys) {
148             mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey,
149                     copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey));
150         }
151
152         // That's it, return the model
153         return mergedPolicyModel;
154     }
155 }