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 LOGGER.warn("left model is invalid: " + leftValidationResult.toString());
84 throw new ApexModelException("left model is invalid: " + leftValidationResult.toString());
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());
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));
102 // The Compared to policy model is the unfavoured side
103 final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel);
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());
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());
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));
131 for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) {
132 mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
133 copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
135 for (final AxArtifactKey eventKey : copyOverEventKeys) {
136 mergedPolicyModel.getEvents().getEventMap().put(eventKey,
137 copyFromPolicyModel.getEvents().getEventMap().get(eventKey));
139 for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) {
140 mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
141 copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
143 for (final AxArtifactKey taskKey : copyOverTaskKeys) {
144 mergedPolicyModel.getTasks().getTaskMap().put(taskKey,
145 copyFromPolicyModel.getTasks().getTaskMap().get(taskKey));
147 for (final AxArtifactKey policyKey : copyOverPolicyKeys) {
148 mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey,
149 copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey));
152 // That's it, return the model
153 return mergedPolicyModel;