2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2020 Nordix Foundation
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * SPDX-License-Identifier: Apache-2.0
21 * ============LICENSE_END=========================================================
24 package org.onap.policy.pdp.xacml.application.common.matchable;
26 import static org.assertj.core.api.Assertions.assertThat;
27 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertNotNull;
31 import com.att.research.xacml.api.Identifier;
32 import com.att.research.xacml.api.XACML3;
33 import com.att.research.xacml.std.IdentifierImpl;
34 import com.att.research.xacml.util.XACMLPolicyWriter;
35 import java.io.ByteArrayOutputStream;
36 import java.util.HashMap;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
45 import org.junit.BeforeClass;
46 import org.junit.Test;
47 import org.onap.policy.common.utils.coder.CoderException;
48 import org.onap.policy.common.utils.coder.StandardYamlCoder;
49 import org.onap.policy.common.utils.resources.ResourceUtils;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntrySchema;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
56 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
57 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
58 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 public class MatchablePolicyTypeTest implements MatchableCallback {
63 private static final Logger LOGGER = LoggerFactory.getLogger(MatchablePolicyTypeTest.class);
64 private static final StandardYamlCoder yamlCoder = new StandardYamlCoder();
65 private static final String TEST_POLICYTYPE_FILE = "src/test/resources/matchable/onap.policies.Test-1.0.0.yaml";
66 private static final String TEST_POLICY_FILE = "src/test/resources/matchable/test.policies.input.tosca.yaml";
67 private static final String TEST_POLICYTYPE = "onap.policies.base.middle.Test";
68 private static ToscaServiceTemplate testTemplate;
69 private static ToscaPolicy testPolicy;
72 * Loads our resources.
74 * @throws CoderException object
77 public static void setupLoadPolicy() throws CoderException {
79 // Load our test policy type
81 String policyType = ResourceUtils.getResourceAsString(TEST_POLICYTYPE_FILE);
83 // Serialize it into a class
85 ToscaServiceTemplate serviceTemplate = yamlCoder.decode(policyType, ToscaServiceTemplate.class);
87 // Make sure all the fields are setup properly
89 JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
90 jtst.fromAuthorative(serviceTemplate);
91 testTemplate = jtst.toAuthorative();
93 // Make sure the Policy Types are there
95 assertEquals(3, testTemplate.getPolicyTypes().size());
96 assertNotNull(testTemplate.getPolicyTypes().get("onap.policies.Base"));
97 assertNotNull(testTemplate.getPolicyTypes().get("onap.policies.base.Middle"));
98 assertNotNull(testTemplate.getPolicyTypes().get(TEST_POLICYTYPE));
100 // Load our test policy
102 String policy = ResourceUtils.getResourceAsString(TEST_POLICY_FILE);
104 // Serialize it into a class
106 serviceTemplate = yamlCoder.decode(policy, ToscaServiceTemplate.class);
108 // Make sure all the fields are setup properly
110 jtst = new JpaToscaServiceTemplate();
111 jtst.fromAuthorative(serviceTemplate);
112 ToscaServiceTemplate policyTemplate = jtst.toAuthorative();
113 assertEquals(1, policyTemplate.getToscaTopologyTemplate().getPolicies().size());
114 testPolicy = policyTemplate.getToscaTopologyTemplate().getPolicies().get(0).get("Test.policy");
115 assertNotNull(testPolicy);
119 public void testAllCodeCoverage() {
120 assertThatExceptionOfType(NullPointerException.class).isThrownBy(() ->
121 new MatchablePolicyType(null, null));
123 assertThatExceptionOfType(NullPointerException.class).isThrownBy(() ->
124 new MatchablePropertyTypeMap(null));
125 assertThatExceptionOfType(NullPointerException.class).isThrownBy(() ->
126 MatchablePolicyType.isMatchable(null));
127 assertThat(MatchablePolicyType.isMatchable(new ToscaProperty())).isFalse();
129 // Unlikely these would be called - just get code coverage on them
131 ToscaEntrySchema schema = new ToscaEntrySchema();
132 schema.setType("integer");
133 assertThat(MatchablePolicyType.handlePrimitive("foo", schema)).isNotNull();
134 schema.setType("float");
135 assertThat(MatchablePolicyType.handlePrimitive("foo", schema)).isNotNull();
136 schema.setType("boolean");
137 assertThat(MatchablePolicyType.handlePrimitive("foo", schema)).isNotNull();
138 schema.setType("timestamp");
139 assertThat(MatchablePolicyType.handlePrimitive("foo", schema)).isNotNull();
140 schema.setType("footype");
141 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
142 MatchablePolicyType.handlePrimitive("foo", schema)
144 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
145 MatchablePolicyType.handlePrimitive("foo", schema)
147 ToscaProperty toscaProperty = new ToscaProperty();
148 Map<String, String> metadata = new HashMap<>();
149 metadata.put("matchable", "true");
150 toscaProperty.setMetadata(metadata);
151 toscaProperty.setType("garbage");
152 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
153 MatchablePolicyType.handlePrimitive("foo", toscaProperty)
155 Map<String, MatchableProperty> matchables = null;
156 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
157 MatchablePolicyType.handleList("foo", toscaProperty, matchables, this)
159 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
160 MatchablePolicyType.handleMap("foo", toscaProperty, matchables, this)
165 public void testPrimitiveValidation() throws Exception {
166 ToscaProperty property = new ToscaProperty();
167 MatchablePropertyTypeBoolean booleanValue = new MatchablePropertyTypeBoolean(property);
168 assertThat(booleanValue.validate(Boolean.TRUE)).isEqualTo(Boolean.TRUE);
169 assertThat(booleanValue.validate("no")).isEqualTo(Boolean.FALSE);
170 assertThat(booleanValue.validate("foo")).isEqualTo(Boolean.FALSE);
172 MatchablePropertyTypeInteger integerValue = new MatchablePropertyTypeInteger(property);
173 assertThat(integerValue.validate("5")).isEqualTo(5);
174 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> integerValue.validate("foo"));
176 MatchablePropertyTypeFloat floatValue = new MatchablePropertyTypeFloat(property);
177 assertThat(floatValue.validate("5")).isEqualTo(5);
178 assertThat(floatValue.validate(Float.MIN_NORMAL)).isEqualTo(Float.MIN_NORMAL);
179 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() -> floatValue.validate("foo"));
181 MatchablePropertyTypeTimestamp timestampValue = new MatchablePropertyTypeTimestamp(property);
182 assertThat(timestampValue.validate("2018-10-11T22:12:44").getHour()).isEqualTo(22);
183 assertThatExceptionOfType(ToscaPolicyConversionException.class).isThrownBy(() ->
184 timestampValue.validate("foo"));
186 ToscaEntrySchema schema = new ToscaEntrySchema();
187 schema.setType("string");
188 property.setEntrySchema(schema);
189 MatchablePropertyTypeMap mapValue = new MatchablePropertyTypeMap(property);
190 assertThat(mapValue.validate("foo")).isEmpty();
192 MatchablePropertyTypeList listValue = new MatchablePropertyTypeList(property);
193 assertThat(listValue.validate("foo")).isEmpty();
197 public void testMatchables() throws ToscaPolicyConversionException {
199 // Step 1: Create matchables from the PolicyType
201 MatchablePolicyType matchablePolicyType = new MatchablePolicyType(testTemplate.getPolicyTypes()
202 .get(TEST_POLICYTYPE), this);
203 assertThat(matchablePolicyType).isNotNull();
204 assertThat(matchablePolicyType.getPolicyId()).isNotNull();
205 assertThat(matchablePolicyType.getPolicyId().getName()).isEqualTo(TEST_POLICYTYPE);
207 // Dump them out to see what we have
209 matchablePolicyType.getMatchables().forEach((matchable, property) -> {
210 LOGGER.info("matchable: {}: {}", matchable, property);
213 // Sanity check - these are the total possible match types available
215 assertThat(matchablePolicyType.getMatchables()).hasSize(19);
217 // Step 2) Go through example policy and generate data for our Target
219 final TargetType target = new TargetType();
220 target.getAnyOf().add(new AnyOfType());
221 generateTargetType(target, matchablePolicyType, testPolicy.getProperties());
223 // Stuff results in a simple Policy
225 final PolicyType policy = new PolicyType();
226 policy.setTarget(target);
227 policy.setPolicyId("foo");
228 policy.setVersion("1");
229 policy.setRuleCombiningAlgId(XACML3.DENY_UNLESS_PERMIT);
231 // Dump it out so we can see what was created
233 ByteArrayOutputStream os = new ByteArrayOutputStream();
234 XACMLPolicyWriter.writePolicyFile(os, policy);
235 LOGGER.info("{}", os);
237 // Sanity check - the example policy should have each possible match type plus
238 // an extra one for the list and an extra one for the map.
240 assertThat(policy.getTarget().getAnyOf()).hasSize(20);
244 public ToscaPolicyType retrievePolicyType(String derivedFrom) {
245 for (Entry<String, ToscaPolicyType> entrySet : testTemplate.getPolicyTypes().entrySet()) {
246 if (entrySet.getValue().getName().equals(derivedFrom)) {
247 return entrySet.getValue();
254 public ToscaDataType retrieveDataType(String datatype) {
255 return testTemplate.getDataTypes().get(datatype);
258 @SuppressWarnings("unchecked")
259 private void generateTargetType(TargetType target, MatchablePolicyType matchablePolicyType,
260 Map<String, Object> properties) throws ToscaPolicyConversionException {
261 for (Entry<String, Object> entrySet : properties.entrySet()) {
262 String propertyName = entrySet.getKey();
263 Object propertyValue = entrySet.getValue();
264 MatchableProperty matchable = matchablePolicyType.get(propertyName);
265 if (matchable != null) {
266 Identifier id = new IdentifierImpl(ToscaDictionary.ID_RESOURCE_MATCHABLE + propertyName);
267 Object object = matchable.getType().generate(propertyValue, id);
269 // Depending on what type it is, add it into the target
271 if (object instanceof AnyOfType) {
272 target.getAnyOf().add((AnyOfType) object);
273 } else if (object instanceof MatchType) {
274 AllOfType allOf = new AllOfType();
275 allOf.getMatch().add((MatchType) object);
276 AnyOfType anyOf = new AnyOfType();
277 anyOf.getAllOf().add(allOf);
278 target.getAnyOf().add(anyOf);
282 // Here is the special case where we look for a Collection of values that may
283 // contain potential matchables
285 if (propertyValue instanceof List) {
286 for (Object listValue : ((List<?>) propertyValue)) {
287 if (listValue instanceof Map) {
288 generateTargetType(target, matchablePolicyType, (Map<String, Object>) listValue);
291 } else if (propertyValue instanceof Map) {
292 generateTargetType(target, matchablePolicyType, (Map<String, Object>) propertyValue);