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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.model.policymodel.handling;
24 import java.util.TreeSet;
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;
34 * Helper class used to merge information from two policy models together into a single policy
37 * @author Liam Fallon (liam.fallon@ericsson.com)
39 public final class PolicyModelMerger {
40 private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelMerger.class);
43 * Private constructor used to prevent sub class instantiation.
45 private PolicyModelMerger() {}
48 * Get a merged policy model with information from two policy models merged into a larger policy
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
58 public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
59 final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches) throws ApexModelException {
60 return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false);
64 * Get a merged policy model with information from two policy models merged into a larger policy
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
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();
85 throw new ApexModelException(message);
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();
96 throw new ApexModelException(message);
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));
104 // The Compared to policy model is the unfavoured side
105 final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel);
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());
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());
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));
133 for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) {
134 mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
135 copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
137 for (final AxArtifactKey eventKey : copyOverEventKeys) {
138 mergedPolicyModel.getEvents().getEventMap().put(eventKey,
139 copyFromPolicyModel.getEvents().getEventMap().get(eventKey));
141 for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) {
142 mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
143 copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
145 for (final AxArtifactKey taskKey : copyOverTaskKeys) {
146 mergedPolicyModel.getTasks().getTaskMap().put(taskKey,
147 copyFromPolicyModel.getTasks().getTaskMap().get(taskKey));
149 for (final AxArtifactKey policyKey : copyOverPolicyKeys) {
150 mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey,
151 copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey));
154 // That's it, return the model
155 return mergedPolicyModel;