diff options
author | jhh <jorge.hernandez-herrero@att.com> | 2020-01-30 18:57:13 -0600 |
---|---|---|
committer | jhh <jorge.hernandez-herrero@att.com> | 2020-02-04 00:26:57 -0600 |
commit | baa4e928207f5930fcd620bddddcd493aa7a4122 (patch) | |
tree | b4832c661bc05bcb457e65a73c06f0a960ac7632 | |
parent | a54a2373f1b48cdb64d4920ec57ffeab4f228814 (diff) |
domain native and operational policies support
- moved DomainMaker to policy-utils/ project.
- support for native drools and controller drools policy types.
Issue-ID: POLICY-2345
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
Change-Id: I46b9816eadceb7ef280e0e6789f07b4d4ca51519
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
31 files changed, 2421 insertions, 0 deletions
diff --git a/feature-lifecycle/pom.xml b/feature-lifecycle/pom.xml index b57847a3..952cf983 100644 --- a/feature-lifecycle/pom.xml +++ b/feature-lifecycle/pom.xml @@ -129,6 +129,25 @@ <scope>test</scope> </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>gson</artifactId> + <version>${policy.common.version}</version> + </dependency> + + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-examples</artifactId> + <version>${policy.models.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.openpojo</groupId> + <artifactId>openpojo</artifactId> + <scope>test</scope> + </dependency> + </dependencies> </project> diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/DroolsPolicy.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/DroolsPolicy.java new file mode 100644 index 00000000..a0234661 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/DroolsPolicy.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.experimental.SuperBuilder; + +@Data +@SuperBuilder +public abstract class DroolsPolicy { + @SerializedName("type") + protected String type; + + @SerializedName("type_version") + protected String typeVersion; + + @SerializedName("version") + protected String version; + + @SerializedName("name") + protected String name; + + @SerializedName("metadata") + protected Metadata metadata; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/Metadata.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/Metadata.java new file mode 100644 index 00000000..fd68e5b5 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/Metadata.java @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * Metadata in Native Drools Policies. + */ + +@Data +@Builder +public class Metadata implements Serializable { + + private static final long serialVersionUID = -1027974819756498893L; + + @SerializedName("policy-id") + protected String policyId; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerCustomSerializer.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerCustomSerializer.java new file mode 100644 index 00000000..bda7748d --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerCustomSerializer.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; + + +@Data +@SuperBuilder +public class ControllerCustomSerializer implements Serializable { + private static final long serialVersionUID = 1505345574249332514L; + + @SerializedName("customSerializerClass") + protected String customSerializerClass; + + @SerializedName("jsonParser") + protected String jsonParser; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerPolicy.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerPolicy.java new file mode 100644 index 00000000..0d5a363e --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerPolicy.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; +import org.onap.policy.drools.domain.models.DroolsPolicy; + +/** + * Controller Policy model root object. + */ + +@Data +@SuperBuilder +public class ControllerPolicy extends DroolsPolicy implements Serializable { + + private static final long serialVersionUID = -8171337852833516581L; + + @SerializedName("properties") + protected ControllerProperties properties; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerProperties.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerProperties.java new file mode 100644 index 00000000..0ed6d33c --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerProperties.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import lombok.Data; +import lombok.experimental.SuperBuilder; + + +/** + * Controller Domain Policy. + */ + +@Data +@SuperBuilder +public class ControllerProperties implements Serializable { + private static final long serialVersionUID = 1259434187110418986L; + + @SerializedName("controllerName") + protected String controllerName; + + @SerializedName("sourceTopics") + protected List<ControllerSourceTopic> sourceTopics; + + @SerializedName("sinkTopics") + protected List<ControllerSinkTopic> sinkTopics; + + @SerializedName("customConfig") + protected Map<String, String> customConfig; + +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSerialization.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSerialization.java new file mode 100644 index 00000000..77a5e93d --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSerialization.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; + + +@Data +@SuperBuilder +public class ControllerSerialization implements Serializable { + + @SerializedName("eventClass") + public String eventClass; + + @SerializedName("eventFilter") + public String eventFilter; + + @SerializedName("customSerializer") + public ControllerCustomSerializer customSerializer; + +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSinkTopic.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSinkTopic.java new file mode 100644 index 00000000..acb4fb01 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSinkTopic.java @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.List; +import lombok.Data; +import lombok.experimental.SuperBuilder; + + +/** + * Sink Topic. + */ + +@Data +@SuperBuilder +public class ControllerSinkTopic implements Serializable { + private static final long serialVersionUID = 8770353732981476267L; + + @SerializedName("topicName") + protected String topicName; + + @SerializedName("serialization") + protected List<ControllerSerialization> serialization; + +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSourceTopic.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSourceTopic.java new file mode 100644 index 00000000..69d57bc6 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/controller/ControllerSourceTopic.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.controller; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import java.util.List; +import lombok.Data; +import lombok.experimental.SuperBuilder; + + +/** + * Source Topics. + */ + +@Data +@SuperBuilder +public class ControllerSourceTopic implements Serializable { + private static final long serialVersionUID = -1732598566914643612L; + + @SerializedName("topicName") + protected String topicName; + + @SerializedName("serialization") + protected List<ControllerSerialization> serialization; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsController.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsController.java new file mode 100644 index 00000000..0af96331 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsController.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.nativ.rules; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * Controller Model in Native Drools Policies. + */ + +@Data +@Builder +public class NativeDroolsController implements Serializable { + + private static final long serialVersionUID = -2070515139072136869L; + + @SerializedName("name") + protected String name; + + @SerializedName("version") + protected String version; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsPolicy.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsPolicy.java new file mode 100644 index 00000000..fce6ca1a --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsPolicy.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.nativ.rules; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; +import org.onap.policy.drools.domain.models.DroolsPolicy; + +/** + * Native Drools Policy model root object. + */ + +@Data +@SuperBuilder +public class NativeDroolsPolicy extends DroolsPolicy implements Serializable { + + private static final long serialVersionUID = -8171337852833516581L; + + @SerializedName("properties") + protected NativeDroolsProperties properties; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsProperties.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsProperties.java new file mode 100644 index 00000000..dfd25ca7 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsProperties.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.nativ.rules; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * Properties in Native Drools Policies. + */ + +@Data +@Builder +public class NativeDroolsProperties implements Serializable { + private static final long serialVersionUID = 2360030332628276427L; + + @SerializedName("rulesArtifact") + protected NativeDroolsRulesArtifact rulesArtifact; + + @SerializedName("controller") + protected NativeDroolsController controller; +} diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsRulesArtifact.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsRulesArtifact.java new file mode 100644 index 00000000..8ca33865 --- /dev/null +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/domain/models/nativ/rules/NativeDroolsRulesArtifact.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models.nativ.rules; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * Rules Artifact in Native Drools Policies. + */ + +@Data +@Builder +public class NativeDroolsRulesArtifact implements Serializable { + + private static final long serialVersionUID = -3519759514319217518L; + + @SerializedName("groupId") + protected String groupId; + + @SerializedName("artifactId") + protected String artifactId; + + @SerializedName("version") + protected String version; +} diff --git a/feature-lifecycle/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json b/feature-lifecycle/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json new file mode 100644 index 00000000..8548f7f7 --- /dev/null +++ b/feature-lifecycle/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json @@ -0,0 +1,315 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/onap.policies.controlloop.operational.common.Drools.schema.json", + "type": "object", + "title": "The Root Schema", + "required": [ + "type", + "type_version", + "version", + "metadata", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "title": "Policy Type", + "default": "onap.policies.controlloop.operational.common.Drools", + "examples": [ + "onap.policies.controlloop.operational.common.Drools" + ], + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "title": "Policy Type Version", + "default": "1.0.0", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "Policy Name", + "default": "", + "examples": [ + "example" + ], + "pattern": "^(.*)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Policy Version", + "default": "1.0.0", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "title": "Policy ID", + "examples": [ + "operational.restart" + ], + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "title": "Properties", + "required": [ + "id", + "timeout", + "abatement", + "trigger", + "operations", + "controllerName" + ], + "properties": { + "id": { + "$id": "#/properties/properties/properties/id", + "type": "string", + "title": "Control Loop Name", + "examples": [ + "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e" + ], + "pattern": "^(.+)$" + }, + "timeout": { + "$id": "#/properties/properties/properties/timeout", + "type": "integer", + "title": "Timeout in seconds", + "minimum": 1, + "default": 30, + "examples": [ + 3600 + ] + }, + "abatement": { + "$id": "#/properties/properties/properties/abatement", + "type": "boolean", + "title": "Abatement", + "default": false, + "examples": [ + true + ] + }, + "trigger": { + "$id": "#/properties/properties/properties/trigger", + "type": "string", + "title": "Trigger Operation", + "examples": [ + "unique-policy-id-1-restart" + ], + "pattern": "^(.+)$" + }, + "operations": { + "$id": "#/properties/properties/properties/operations", + "type": "array", + "title": "Operations", + "items": { + "$id": "#/properties/properties/properties/operations/items", + "type": "object", + "title": "Items", + "uniqueItems": true, + "required": [ + "id", + "description", + "operation", + "timeout", + "retries", + "success", + "failure", + "failure_timeout", + "failure_retries", + "failure_exception", + "failure_guard" + ], + "properties": { + "id": { + "$id": "#/properties/properties/properties/operations/items/properties/id", + "type": "string", + "title": "Operation Identifier", + "examples": [ + "unique-policy-id-1-restart" + ], + "pattern": "^(.+)$" + }, + "description": { + "$id": "#/properties/properties/properties/operations/items/properties/description", + "type": "string", + "title": "Description", + "examples": [ + "Restart the VM" + ], + "pattern": "^(.+)$" + }, + "operation": { + "$id": "#/properties/properties/properties/operations/items/properties/operation", + "type": "object", + "title": "Operation", + "required": [ + "actor", + "recipe", + "target" + ], + "properties": { + "actor": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/actor", + "type": "string", + "title": "Actor", + "examples": [ + "APPC" + ], + "pattern": "^(.+)$" + }, + "recipe": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/recipe", + "type": "string", + "title": "Recipe", + "examples": [ + "Restart" + ], + "pattern": "^(.+)$" + }, + "target": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/target", + "type": "object", + "title": "Target", + "required": [ + "type" + ], + "properties": { + "type": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/target/properties/type", + "type": "string", + "title": "Target Type", + "examples": [ + "VNF" + ], + "pattern": "^(.+)$" + } + } + } + } + }, + "timeout": { + "$id": "#/properties/properties/properties/operations/items/properties/timeout", + "type": "integer", + "title": "Operation Timeout in seconds", + "default": 10, + "minimum": 1, + "examples": [ + 1200 + ] + }, + "retries": { + "$id": "#/properties/properties/properties/operations/items/properties/retries", + "type": "integer", + "title": "Number of Retries", + "default": 0, + "examples": [ + 3 + ] + }, + "success": { + "$id": "#/properties/properties/properties/operations/items/properties/success", + "type": "string", + "title": "Success Treatment", + "default": "final_success", + "examples": [ + "final_success", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure": { + "$id": "#/properties/properties/properties/operations/items/properties/failure", + "type": "string", + "title": "Failure Treatment", + "default": "final_failure", + "examples": [ + "final_failure", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_timeout": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_timeout", + "type": "string", + "title": "Failure Timeout Treatment", + "default": "final_failure_timeout", + "examples": [ + "final_failure_timeout", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_retries": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_retries", + "type": "string", + "title": "Failure Retries Treatment", + "default": "final_failure_retries", + "examples": [ + "final_failure_retries", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_exception": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_exception", + "type": "string", + "title": "Failure Exception Treatment", + "default": "", + "examples": [ + "final_failure_exception", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_guard": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_guard", + "type": "string", + "title": "Failure Guard Treatment", + "default": "final_failure_guard", + "examples": [ + "final_failure_guard", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + } + } + } + }, + "controllerName": { + "$id": "#/properties/properties/properties/controllerName", + "type": "string", + "title": "Controller Name", + "default": "", + "examples": [ + "usecases" + ], + "pattern": "^(.+)$" + } + } + } + } +}
\ No newline at end of file diff --git a/feature-lifecycle/src/main/resources/schemas/onap.policies.drools.Controller-1.0.0.schema.json b/feature-lifecycle/src/main/resources/schemas/onap.policies.drools.Controller-1.0.0.schema.json new file mode 100644 index 00000000..e07a3e1e --- /dev/null +++ b/feature-lifecycle/src/main/resources/schemas/onap.policies.drools.Controller-1.0.0.schema.json @@ -0,0 +1,274 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/onap.policies.drools.Controller.schema.json", + "type": "object", + "title": "Domain onap.policies.drools.Controller Policy root schema", + "required": [ + "type", + "type_version", + "version", + "metadata", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "title": "Policy Type", + "default": "onap.policies.native.Drools", + "examples": [ + "onap.policies.native.Drools" + ], + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "title": "Policy Type Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "title": "The policy-id Schema", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "title": "Policy Domain Properties", + "required": [ + "controllerName" + ], + "properties": { + "controllerName": { + "$id": "#/properties/properties/properties/controllerName", + "type": "string", + "title": "Controller Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + }, + "sourceTopics": { + "$id": "#/properties/properties/properties/sourceTopics", + "type": "array", + "title": "Source Topics", + "items": { + "$id": "#/properties/properties/properties/sourceTopics/items", + "type": "object", + "title": "Topic Data", + "required": [ + "topicName", + "serialization" + ], + "properties": { + "topicName": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/topicName", + "type": "string", + "title": "Topic Name", + "examples": [ + "DCAE_TOPIC" + ], + "pattern": "^(.+)$" + }, + "serialization": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization", + "type": "array", + "title": "Serialization", + "items": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items", + "type": "object", + "title": "Serialization Data", + "required": [ + "eventClass", + "eventFilter", + "customSerializer" + ], + "properties": { + "eventClass": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items/properties/eventClass", + "type": "string", + "title": "Event Class", + "examples": [ + "org.onap.policy.controlloop.CanonicalOnset" + ], + "pattern": "^(.+)$" + }, + "eventFilter": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items/properties/eventFilter", + "type": "string", + "title": "Event Filter", + "examples": [ + "[?($.closedLoopEventStatus == 'ONSET')]" + ], + "pattern": "^(.+)$" + }, + "customSerializer": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items/properties/customSerializer", + "type": "object", + "title": "Custom Serializer", + "required": [ + "customSerializerClass", + "jsonParser" + ], + "properties": { + "customSerializerClass": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items/properties/customSerializer/properties/customSerializerClass", + "type": "string", + "title": "Custom Serializer Class", + "examples": [ + "org.onap.policy.controlloop.util.Serialization" + ], + "pattern": "^(.*)$" + }, + "jsonParser": { + "$id": "#/properties/properties/properties/sourceTopics/items/properties/serialization/items/properties/customSerializer/properties/jsonParser", + "type": "string", + "title": "JSON Parser reference", + "examples": [ + "gson" + ], + "pattern": "^(.+)$" + } + } + } + } + } + } + } + } + }, + "sinkTopics": { + "$id": "#/properties/properties/properties/sinkTopics", + "type": "array", + "title": "Sink Topics", + "items": { + "$id": "#/properties/properties/properties/sinkTopics/items", + "type": "object", + "title": "Sink Topic Data", + "required": [ + "topicName", + "serialization" + ], + "properties": { + "topicName": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/topicName", + "type": "string", + "title": "Topic Name", + "default": "", + "examples": [ + "APPC-CL" + ], + "pattern": "^(.+)$" + }, + "serialization": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization", + "type": "array", + "title": "The Serialization Schema", + "items": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items", + "type": "object", + "title": "Serialization Data", + "required": [ + "eventClass", + "eventFilter" + ], + "properties": { + "eventClass": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items/properties/eventClass", + "type": "string", + "title": "Event Class", + "examples": [ + "org.onap.policy.appc.Response" + ], + "pattern": "^(.+)$" + }, + "eventFilter": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items/properties/eventFilter", + "type": "string", + "title": "The Eventfilter Schema", + "examples": [ + "[?($.CommonHeader && $.Status)]" + ], + "pattern": "^(.+)$" + }, + "customSerializer": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items/properties/customSerializer", + "type": "object", + "title": "The Customserializer Schema", + "required": [ + "customSerializerClass", + "jsonParser" + ], + "properties": { + "customSerializerClass": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items/properties/customSerializer/properties/customSerializerClass", + "type": "string", + "title": "The Customserializerclass Schema", + "examples": [ + "org.onap.policy.appc.util.Serialization" + ], + "pattern": "^(.+)$" + }, + "jsonParser": { + "$id": "#/properties/properties/properties/sinkTopics/items/properties/serialization/items/properties/customSerializer/properties/jsonParser", + "type": "string", + "title": "The Jsonparser Schema", + "examples": [ + "gsonPretty" + ], + "pattern": "^(.+)$" + } + } + } + } + } + } + } + } + }, + "customConfig": { + "$id": "#/properties/properties/properties/customConfig", + "type": "object", + "title": "other Configuration" + } + } + } + } +} diff --git a/feature-lifecycle/src/main/resources/schemas/onap.policies.native.Drools-1.0.0.schema.json b/feature-lifecycle/src/main/resources/schemas/onap.policies.native.Drools-1.0.0.schema.json new file mode 100644 index 00000000..d1866c6b --- /dev/null +++ b/feature-lifecycle/src/main/resources/schemas/onap.policies.native.Drools-1.0.0.schema.json @@ -0,0 +1,150 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/onap.policies.controlloop.native.Drools.schema.json", + "type": "object", + "title": "Domain onap.policies.controlloop.native.Drools Policy root schema", + "required": [ + "type", + "type_version", + "version", + "metadata", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "title": "Policy Type", + "default": "onap.policies.native.Drools", + "examples": [ + "onap.policies.native.Drools" + ], + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "title": "Policy Type Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "title": "The Policy-id Schema", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "title": "Properties", + "required": [ + "rulesArtifact" + ], + "properties": { + "rulesArtifact": { + "$id": "#/properties/properties/properties/rulesArtifact", + "type": "object", + "title": "Rules Artifact", + "required": [ + "groupId", + "artifactId", + "version" + ], + "properties": { + "groupId": { + "$id": "#/properties/properties/properties/rulesArtifact/properties/groupId", + "type": "string", + "title": "Group Id", + "examples": [ + "org.onap.policy.controlloop" + ], + "pattern": "^(.*)$" + }, + "artifactId": { + "$id": "#/properties/properties/properties/rulesArtifact/properties/artifactId", + "type": "string", + "title": "Artifact ID", + "examples": [ + "example" + ], + "pattern": "^(.*)$" + }, + "version": { + "$id": "#/properties/properties/properties/rulesArtifact/properties/version", + "type": "string", + "title": "Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.*)$" + } + } + }, + "controller": { + "$id": "#/properties/properties/properties/controller", + "type": "object", + "title": "Controller", + "required": [ + "name", + "version" + ], + "properties": { + "name": { + "$id": "#/properties/properties/properties/controller/properties/name", + "type": "string", + "title": "Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + }, + "version": { + "$id": "#/properties/properties/properties/controller/properties/version", + "type": "string", + "title": "Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.*)$" + } + } + } + } + } + } +} diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DomainPolicyTypesTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DomainPolicyTypesTest.java new file mode 100644 index 00000000..945b00b1 --- /dev/null +++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DomainPolicyTypesTest.java @@ -0,0 +1,240 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.worldturner.medeia.api.ValidationFailedException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.drools.domain.models.controller.ControllerPolicy; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsController; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsPolicy; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsProperties; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsRulesArtifact; +import org.onap.policy.drools.policies.DomainMaker; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +public class DomainPolicyTypesTest { + + // Policy Types + private static final String OPERATIONAL_DROOLS_POLICY_TYPE = "onap.policies.controlloop.operational.common.Drools"; + private static final String NATIVE_DROOLS_POLICY_TYPE = "onap.policies.native.Drools"; + + // Operational vCPE Policy + private static final String OP_POLICY_NAME_VCPE = "operational.restart"; + private static final String VCPE_OPERATIONAL_DROOLS_POLICY_JSON = + "policies/vCPE.policy.operational.input.tosca.json"; + public static final String VCPE_OPERATIONAL_DROOLS_LEGACY_POLICY_JSON = + "src/test/resources/tosca-policy-operational-restart.json"; + + // Native Drools Policy + private static final String EXAMPLE_NATIVE_DROOLS_POLICY_NAME = "example"; + private static final String EXAMPLE_NATIVE_DROOLS_POLICY_JSON = + "src/test/resources/example.policy.native.drools.tosca.json"; + + // Controller Drools Policy + private static final String EXAMPLE_CONTROLLER_DROOLS_POLICY_NAME = "example"; + private static final String EXAMPLE_CONTROLLER_DROOLS_POLICY_JSON = + "src/test/resources/example.policy.drools.controller.tosca.json"; + + private DomainMaker domainMaker; + private StandardCoder nonValCoder; + + @Before + public void setUp() { + domainMaker = new DomainMaker(); + nonValCoder = new StandardCoder(); + } + + @Test + public void testToscaOperationalPolicyType() throws CoderException, IOException { + String rawVcpeToscaPolicy = getExamplesPolicyString(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, OP_POLICY_NAME_VCPE); + String rawVcpeLegacyToscaPolicy = getJsonFromFile(VCPE_OPERATIONAL_DROOLS_LEGACY_POLICY_JSON); + + // valid "known" policy type with implicit schema + assertTrue(domainMaker + .isConformant(new ToscaPolicyTypeIdentifier(OPERATIONAL_DROOLS_POLICY_TYPE, "1.0.0"), + rawVcpeToscaPolicy)); + + // policy type without schema + assertFalse(domainMaker + .isConformant(new ToscaPolicyTypeIdentifier("blah.blah", "1.0.0"), rawVcpeToscaPolicy)); + + // known policy type but invalid json (legacy). + assertFalse(domainMaker + .isConformant(new ToscaPolicyTypeIdentifier(OPERATIONAL_DROOLS_POLICY_TYPE, "1.0.0"), + rawVcpeLegacyToscaPolicy)); + + ToscaPolicy vcpeToscaPolicy = getExamplesPolicy(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, OP_POLICY_NAME_VCPE); + assertTrue(domainMaker.isConformant(vcpeToscaPolicy)); + assertTrue(domainMaker.conformance(vcpeToscaPolicy)); + + // set an invalid value in the Tosca Policy (timeout less than minimum value). + final int timeout = (int) vcpeToscaPolicy.getProperties().get("timeout"); + vcpeToscaPolicy.getProperties().put("timeout", 0); + assertFalse(domainMaker.isConformant(vcpeToscaPolicy)); + assertThatThrownBy(() -> + domainMaker.conformance(vcpeToscaPolicy)) + .isInstanceOf(ValidationFailedException.class) + .hasMessageContaining("Value 0 is smaller than minimum 1"); + + // put back the original timeout value in the Tosca Policy + vcpeToscaPolicy.getProperties().put("timeout", timeout); + assertTrue(domainMaker.isConformant(vcpeToscaPolicy)); + assertTrue(domainMaker.conformance(vcpeToscaPolicy)); + + // remove required element + final Object operations = vcpeToscaPolicy.getProperties().remove("operations"); + assertFalse(domainMaker.isConformant(vcpeToscaPolicy)); + assertThatThrownBy(() -> + domainMaker.conformance(vcpeToscaPolicy)) + .isInstanceOf(ValidationFailedException.class) + .hasMessageContaining("Required property operations is missing from object"); + + // put back the original operations value in the Tosca Policy + vcpeToscaPolicy.getProperties().put("operations", operations); + assertTrue(domainMaker.isConformant(vcpeToscaPolicy)); + assertTrue(domainMaker.conformance(vcpeToscaPolicy)); + } + + @Test + public void testToscaNativeDroolsPolicy() throws CoderException, IOException { + String rawNativeDroolsPolicy = + getPolicyFromFileString(EXAMPLE_NATIVE_DROOLS_POLICY_JSON, EXAMPLE_NATIVE_DROOLS_POLICY_NAME); + ToscaPolicy toscaPolicy = + getExamplesPolicy(EXAMPLE_NATIVE_DROOLS_POLICY_JSON, EXAMPLE_NATIVE_DROOLS_POLICY_NAME); + + ToscaPolicyTypeIdentifier policyTypeId = + new ToscaPolicyTypeIdentifier(NATIVE_DROOLS_POLICY_TYPE, "1.0.0"); + domainMaker.isConformant(policyTypeId, rawNativeDroolsPolicy); + + assertTrue(domainMaker.isConformant(toscaPolicy)); + NativeDroolsPolicy domainDroolsPolicy = domainMaker.convertTo(toscaPolicy, NativeDroolsPolicy.class); + assertEquals("org.onap.policy.controlloop", domainDroolsPolicy.getProperties().getRulesArtifact().getGroupId()); + assertEquals("example", domainDroolsPolicy.getProperties().getRulesArtifact().getArtifactId()); + assertEquals("1.0.0", domainDroolsPolicy.getProperties().getRulesArtifact().getVersion()); + + String policyId = toscaPolicy.getMetadata().remove("policy-id"); + assertThatThrownBy(() -> domainMaker.convertTo(toscaPolicy, NativeDroolsPolicy.class)) + .isInstanceOf(CoderException.class).hasCauseInstanceOf(ValidationFailedException.class); + + toscaPolicy.getMetadata().put("policy-id", policyId); + + assertTrue(domainMaker.isDomainConformant(policyTypeId, domainDroolsPolicy)); + assertTrue(domainMaker.conformance(policyTypeId, domainDroolsPolicy)); + + domainDroolsPolicy.setName(""); + assertFalse(domainMaker.isDomainConformant(policyTypeId, domainDroolsPolicy)); + assertThatThrownBy(() -> domainMaker.conformance(policyTypeId, domainDroolsPolicy)) + .isInstanceOf(ValidationFailedException.class) + .hasMessageContaining("Pattern ^(.+)$ is not contained in text"); + + NativeDroolsPolicy domainDroolsPolicy2 = + NativeDroolsPolicy.builder().metadata(Metadata.builder().policyId("policy-id").build()).name("example") + .version("1.0.0").properties( + NativeDroolsProperties.builder().controller( + NativeDroolsController.builder().name("example").version("1.0.0").build()) + .rulesArtifact( + NativeDroolsRulesArtifact.builder().groupId("org.onap.policy.controlloop") + .artifactId("example").version("example").build()).build()) + .type("onap.policies.native.Drools") + .typeVersion("1.0.0").build(); + assertTrue(domainMaker + .isDomainConformant( + new ToscaPolicyTypeIdentifier(domainDroolsPolicy2.getType(), domainDroolsPolicy2.getTypeVersion()), + domainDroolsPolicy2)); + } + + @Test + public void testToscaControllerPolicy() throws CoderException { + ToscaPolicy toscaPolicy = + getExamplesPolicy(EXAMPLE_CONTROLLER_DROOLS_POLICY_JSON, EXAMPLE_CONTROLLER_DROOLS_POLICY_NAME); + + assertTrue(domainMaker.isConformant(toscaPolicy)); + ControllerPolicy controllerPolicy = domainMaker.convertTo(toscaPolicy, ControllerPolicy.class); + + assertEquals("example", controllerPolicy.getName()); + assertEquals("1.0.0", controllerPolicy.getVersion()); + assertEquals("onap.policies.drools.Controller", controllerPolicy.getType()); + assertEquals("1.0.0", controllerPolicy.getTypeVersion()); + assertEquals("example", controllerPolicy.getMetadata().getPolicyId()); + assertEquals("example", controllerPolicy.getProperties().getControllerName()); + assertEquals("DCAE_TOPIC", controllerPolicy.getProperties().getSourceTopics().get(0).getTopicName()); + assertEquals("org.onap.policy.controlloop.CanonicalOnset", + controllerPolicy.getProperties().getSourceTopics().get(0).getSerialization().get(0).getEventClass()); + assertEquals("[?($.closedLoopEventStatus == 'ONSET')]", + controllerPolicy.getProperties().getSourceTopics().get(0).getSerialization().get(0).getEventFilter()); + assertEquals("org.onap.policy.controlloop.util.Serialization", + controllerPolicy.getProperties().getSourceTopics().get(0).getSerialization().get(0) + .getCustomSerializer().getCustomSerializerClass()); + assertEquals("gson", + controllerPolicy.getProperties().getSourceTopics().get(0).getSerialization().get(0) + .getCustomSerializer().getJsonParser()); + assertEquals("APPC-CL", controllerPolicy.getProperties().getSinkTopics().get(0).getTopicName()); + assertEquals("org.onap.policy.appc.Response", + controllerPolicy.getProperties().getSinkTopics().get(0).getSerialization().get(0).getEventClass()); + assertEquals("[?($.CommonHeader && $.Status)]", + controllerPolicy.getProperties().getSinkTopics().get(0).getSerialization().get(0).getEventFilter()); + assertEquals("org.onap.policy.appc.util.Serialization", + controllerPolicy.getProperties().getSinkTopics().get(0).getSerialization().get(0) + .getCustomSerializer().getCustomSerializerClass()); + assertEquals("gsonPretty", + controllerPolicy.getProperties().getSinkTopics().get(0).getSerialization().get(0) + .getCustomSerializer().getJsonParser()); + assertEquals("value1", controllerPolicy.getProperties().getCustomConfig().get("field1")); + } + + private String getJsonFromFile(String filePath) throws IOException { + return new String(Files.readAllBytes(Paths.get(filePath))); + } + + private String getJsonFromResource(String resourcePath) { + return ResourceUtils.getResourceAsString(resourcePath); + } + + private String getPolicyFromFileString(String filePath, String policyName) throws CoderException, IOException { + String policyJson = getJsonFromFile(filePath); + ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class); + return nonValCoder.encode(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName)); + } + + private ToscaPolicy getExamplesPolicy(String resourcePath, String policyName) throws CoderException { + String policyJson = getJsonFromResource(resourcePath); + ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class); + return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + } + + private String getExamplesPolicyString(String resourcePath, String policyName) throws CoderException { + return nonValCoder.encode(getExamplesPolicy(resourcePath, policyName)); + } +}
\ No newline at end of file diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DroolsPolicyModelsTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DroolsPolicyModelsTest.java new file mode 100644 index 00000000..813acdfa --- /dev/null +++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/domain/models/DroolsPolicyModelsTest.java @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.domain.models; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.filters.FilterChain; +import com.openpojo.reflection.filters.FilterClassName; +import com.openpojo.reflection.filters.FilterNonConcrete; +import com.openpojo.reflection.impl.PojoClassFactory; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import org.onap.policy.drools.domain.models.controller.ControllerPolicy; +import org.onap.policy.drools.domain.models.controller.ControllerProperties; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsController; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsPolicy; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsProperties; +import org.onap.policy.drools.domain.models.nativ.rules.NativeDroolsRulesArtifact; + +public class DroolsPolicyModelsTest { + + @Test + public void testPackage() { + /* validate model pojos */ + List<PojoClass> pojoClasses = + PojoClassFactory + .getPojoClassesRecursively("org.onap.policy.drools.domain.models", + new FilterChain(new FilterNonConcrete(), + new FilterClassName(DroolsPolicy.class.getName()))); + + Validator validator = ValidatorBuilder.create() + .with(new SetterTester(), new GetterTester()).build(); + validator.validate(pojoClasses); + } + + @Test + public void testBuildDomainPolicyNativeDrools() { + /* manually create a native drools policy */ + NativeDroolsPolicy.builder().metadata(Metadata.builder().policyId("policy-id").build()).name("example") + .type("onap.policies.native.Drools") + .typeVersion("1.0.0") + .version("1.0.0") + .properties( + NativeDroolsProperties.builder().controller( + NativeDroolsController.builder().name("example").version("1.0.0").build()) + .rulesArtifact( + NativeDroolsRulesArtifact.builder().groupId("org.onap.policy.controlloop") + .artifactId("example").version("example").build()).build()) + .build(); + } + + @Test + public void testBuildDomainPolicyController() { + /* manually create a controller policy */ + ControllerPolicy.builder().metadata(Metadata.builder().policyId("policy-id").build()).name("example") + .version("1.0.0") + .type("onap.policies.drools.Controller") + .typeVersion("1.0.0") + .properties(ControllerProperties.builder().controllerName("example").sourceTopics( + new ArrayList<>()).sinkTopics(new ArrayList<>()).build()) + .build(); + } + +}
\ No newline at end of file diff --git a/feature-lifecycle/src/test/resources/example.policy.drools.controller.tosca.json b/feature-lifecycle/src/test/resources/example.policy.drools.controller.tosca.json new file mode 100644 index 00000000..b4dd50da --- /dev/null +++ b/feature-lifecycle/src/test/resources/example.policy.drools.controller.tosca.json @@ -0,0 +1,54 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_0_0", + "topology_template": { + "policies": [ + { + "example": { + "type": "onap.policies.drools.Controller", + "type_version": "1.0.0", + "version": "1.0.0", + "name": "example", + "metadata": { + "policy-id": "example" + }, + "properties": { + "controllerName": "example", + "sourceTopics": [ + { + "topicName": "DCAE_TOPIC", + "serialization": [ + { + "eventClass": "org.onap.policy.controlloop.CanonicalOnset", + "eventFilter": "[?($.closedLoopEventStatus == 'ONSET')]", + "customSerializer": { + "customSerializerClass": "org.onap.policy.controlloop.util.Serialization", + "jsonParser": "gson" + } + } + ] + } + ], + "sinkTopics": [ + { + "topicName": "APPC-CL", + "serialization": [ + { + "eventClass": "org.onap.policy.appc.Response", + "eventFilter": "[?($.CommonHeader && $.Status)]", + "customSerializer": { + "customSerializerClass": "org.onap.policy.appc.util.Serialization", + "jsonParser": "gsonPretty" + } + } + ] + } + ], + "customConfig": { + "field1" : "value1" + } + } + } + } + ] + } +}
\ No newline at end of file diff --git a/feature-lifecycle/src/test/resources/example.policy.native.drools.tosca.json b/feature-lifecycle/src/test/resources/example.policy.native.drools.tosca.json new file mode 100644 index 00000000..0313b2ed --- /dev/null +++ b/feature-lifecycle/src/test/resources/example.policy.native.drools.tosca.json @@ -0,0 +1,29 @@ +{ + "tosca_definitions_version": "tosca_simple_yaml_1_0_0", + "topology_template": { + "policies": [ + { + "example": { + "type": "onap.policies.native.Drools", + "type_version": "1.0.0", + "version": "1.0.0", + "name": "example", + "metadata": { + "policy-id": "example" + }, + "properties": { + "rulesArtifact": { + "groupId": "org.onap.policy.controlloop", + "artifactId": "example", + "version": "1.0.0" + }, + "controller": { + "name": "example", + "version": "1.0.0" + } + } + } + } + ] + } +}
\ No newline at end of file diff --git a/policy-utils/pom.xml b/policy-utils/pom.xml index 1bc680ba..f7bbff67 100644 --- a/policy-utils/pom.xml +++ b/policy-utils/pom.xml @@ -42,6 +42,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.onap.policy.common</groupId> <artifactId>utils</artifactId> <version>${policy.common.version}</version> @@ -51,6 +56,21 @@ <artifactId>commons-configuration2</artifactId> <version>2.4</version> </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>gson</artifactId> + <version>${policy.common.version}</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-tosca</artifactId> + <version>${policy.models.version}</version> + </dependency> </dependencies> <build> <plugins> diff --git a/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java new file mode 100644 index 00000000..6e1e0881 --- /dev/null +++ b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java @@ -0,0 +1,233 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.policies; + +import com.worldturner.medeia.api.ValidationFailedException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardValCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Converts Tosca Policies into Domain policies. + * + * <p> + * A Domain Policy is a specialized version of the Tosca Policy that + * conform with a particular domain specification in json schema format. + * A ToscaPolicy is a generic data structure where domain data is contained + * in a Map[String, Object]. This class contains that generic information + * into a concrete domain specific data model for the ToscaPolicy. + * </p> + */ + +@NoArgsConstructor +public class DomainMaker { + + private static final Logger logger = LoggerFactory.getLogger(DomainMaker.class); + + /** + * policy-type -> schema validator map. + */ + private final Map<ToscaPolicyTypeIdentifier, StandardValCoder> validators = new ConcurrentHashMap<>(); + + /** + * non-validation serialization coder. + */ + private final StandardCoder nonValCoder = new StandardCoder(); + + /** + * Does this json conform to a registered policy type schema?. + */ + public boolean isConformant(@NonNull ToscaPolicyTypeIdentifier policyType, @NonNull String json) { + if (!isRegistered(policyType)) { + return false; + } + + return validators.get(policyType).isConformant(json); + } + + /** + * Does this policy conform to its domain specification?. + */ + public boolean isConformant(@NonNull ToscaPolicy policy) { + String rawPolicy = serialize(policy); + if (StringUtils.isBlank(rawPolicy)) { + return false; + } + + return isConformant(policy.getTypeIdentifier(), rawPolicy); + } + + /** + * Does this domain policy conforms to its schema definition?. + */ + public <T> boolean isDomainConformant(@NonNull ToscaPolicyTypeIdentifier policyType, @NonNull T domainPolicy) { + if (!isRegistered(policyType)) { + return false; + } + + try { + return validators.get(policyType).encode(domainPolicy) != null; + } catch (CoderException e) { + logger.info("policy {}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e); + return false; + } + } + + /** + * Check policy conformance to its specification providing a list of errors + * in a ValidationFailedException. + */ + public boolean conformance(@NonNull ToscaPolicy policy) throws ValidationFailedException { + if (!isRegistered(policy.getTypeIdentifier())) { + return false; + } + + String rawPolicy = serialize(policy); + if (StringUtils.isBlank(rawPolicy)) { + return false; + } + + try { + validators.get(policy.getTypeIdentifier()).conformance(rawPolicy); + } catch (CoderException e) { + logger.info("policy {}:{}:{} is not conformant", + policy.getTypeIdentifier(), policy.getName(), policy.getVersion(), e); + if (e.getCause() instanceof ValidationFailedException) { + throw (ValidationFailedException) e.getCause(); + } + return false; + } + + return true; + } + + /** + * Checks a domain policy conformance to its specification providing a list of errors + * in a ValidationFailedException. + */ + public <T> boolean conformance(@NonNull ToscaPolicyTypeIdentifier policyType, T domainPolicy) + throws ValidationFailedException { + + if (!isRegistered(policyType)) { + return false; + } + + try { + validators.get(policyType).encode(domainPolicy); + } catch (CoderException e) { + logger.info("policy {}:{}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e); + if (e.getCause() instanceof ValidationFailedException) { + throw (ValidationFailedException) e.getCause(); + } + return false; + } + + return true; + } + + /** + * Registers a known schema resource for validation. + */ + public boolean registerValidator(@NonNull ToscaPolicyTypeIdentifier policyType) { + // + // A known schema is an schema embedded in a .jar in the classpath under the schemas/ + // resource directory matching the following syntax: schemas/<policy-type>.schema.json. + // + String schema = + ResourceUtils + .getResourceAsString("schemas/" + + policyType.getName() + "-" + policyType.getVersion() + ".schema.json"); + if (schema == null) { + return false; + } + + return registerValidator(policyType, schema); + } + + /** + * Registers/Overrides a new/known schema for a policy type. + */ + public boolean registerValidator(@NonNull ToscaPolicyTypeIdentifier policyType, @NonNull String schema) { + try { + validators.put(policyType, new StandardValCoder(schema, policyType.toString())); + } catch (RuntimeException r) { + logger.info("schema for {} is not valid", policyType, r); + return false; + } + return true; + } + + /** + * Converts a ToscaPolicy into a Domain Policy. + */ + public <T> T convertTo(@NonNull ToscaPolicy toscaPolicy, @NonNull Class<T> clazz) throws CoderException { + return convertTo(toscaPolicy.getTypeIdentifier(), nonValCoder.encode(toscaPolicy), clazz); + } + + /** + * Converts a JSON policy into a Domain Policy. + */ + public <T> T convertTo(@NonNull ToscaPolicyTypeIdentifier policyType, @NonNull String json, @NonNull Class<T> clazz) + throws CoderException { + if (isRegistered(policyType)) { + return validators.get(policyType).decode(json, clazz); + } else { + return nonValCoder.decode(json, clazz); + } + } + + /** + * Converts a Tosca Policy Type specification to a domain-specific json specification. + */ + public String convertToSchema(@NonNull ToscaPolicyType policyType) { + // + // TODO: + // 1. Convert Tosca Policy Type definition schema to suitable json schema. + // 2. Call registerValidator to register + throw new UnsupportedOperationException("schema generation from policy type is not supported"); + } + + public boolean isRegistered(@NonNull ToscaPolicyTypeIdentifier policyType) { + return validators.containsKey(policyType) || registerValidator(policyType); + } + + + private String serialize(@NonNull ToscaPolicy policy) { + String rawPolicy = null; + try { + rawPolicy = nonValCoder.encode(policy); + } catch (CoderException e) { + logger.debug("policy {}:{} is invalid json", policy.getTypeIdentifier(), policy.getIdentifier(), e); + } + return rawPolicy; + } +} diff --git a/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/DomainAPolicy.java b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/DomainAPolicy.java new file mode 100644 index 00000000..04f20b2a --- /dev/null +++ b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/DomainAPolicy.java @@ -0,0 +1,49 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domains.a; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class DomainAPolicy { + private static final long serialVersionUID = -8942432000554391455L; + + @SerializedName("type") + public String type; + + @SerializedName("type_version") + public String typeVersion; + + @SerializedName("version") + public String version; + + @SerializedName("metadata") + public Metadata metadata; + + @SerializedName("properties") + public Properties properties; + + @SerializedName("name") + public String name; +} diff --git a/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Metadata.java b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Metadata.java new file mode 100644 index 00000000..0cad4ff0 --- /dev/null +++ b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Metadata.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domains.a; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class Metadata implements Serializable { + private static final long serialVersionUID = 476541531265304644L; + + @SerializedName("policy-id") + public String policyId; +} diff --git a/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Nested.java b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Nested.java new file mode 100644 index 00000000..eedadeff --- /dev/null +++ b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Nested.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domains.a; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class Nested implements Serializable { + private static final long serialVersionUID = -1203143214137354429L; + + @SerializedName("nested1") + public String nested1; + + @SerializedName("nested2") + public boolean nested2; + + @SerializedName("nested3") + public int nested3; +} diff --git a/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Properties.java b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Properties.java new file mode 100644 index 00000000..3ba66ce9 --- /dev/null +++ b/policy-utils/src/test/java/org/onap/policy/drools/models/domains/a/Properties.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domains.a; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class Properties implements Serializable { + private static final long serialVersionUID = 8476625479607243095L; + + @SerializedName("nested") + public Nested nested; +} diff --git a/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java new file mode 100644 index 00000000..cfacc7ab --- /dev/null +++ b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java @@ -0,0 +1,194 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.policies; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.worldturner.medeia.api.ValidationFailedException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.drools.models.domains.a.DomainAPolicy; +import org.onap.policy.drools.models.domains.a.Metadata; +import org.onap.policy.drools.models.domains.a.Nested; +import org.onap.policy.drools.models.domains.a.Properties; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; + +public class DomainMakerTest { + + private DomainMaker domainMaker; + private StandardCoder nonValCoder; + + @Before + public void setUp() throws Exception { + domainMaker = new DomainMaker(); + nonValCoder = new StandardCoder(); + } + + @Test + public void testIsConformantString() throws IOException { + ToscaPolicyTypeIdentifier policyTypeId = + new ToscaPolicyTypeIdentifier("policy.type.A", "1.0.0"); + String rawJsonPolicyType = + getJsonFromFile("src/test/resources/policyA.json"); + + assertTrue(domainMaker.isConformant(policyTypeId, rawJsonPolicyType)); + + policyTypeId.setVersion("2.0.0"); + assertFalse(domainMaker.isConformant(policyTypeId, rawJsonPolicyType)); + } + + @Test + public void testIsConformantToscaPolicy() throws IOException, CoderException { + ToscaPolicy policy = getToscaPolicy("src/test/resources/policyA.json"); + assertTrue(domainMaker.isConformant(policy)); + + policy.setType("policy.type.Z"); + assertFalse(domainMaker.isConformant(policy)); + } + + @Test + public void testIsDomainConformant() { + ToscaPolicyTypeIdentifier policyTypeId = + new ToscaPolicyTypeIdentifier("policy.type.A", "1.0.0"); + + DomainAPolicy domainAPolicy = createDomainPolicy(); + + assertTrue(domainMaker.isDomainConformant(policyTypeId, domainAPolicy)); + + // integer exceeding max. value + domainAPolicy.getProperties().getNested().setNested3(999); + assertFalse(domainMaker.isDomainConformant(policyTypeId, domainAPolicy)); + domainAPolicy.getProperties().getNested().setNested3(33); // restore good valude + + // not registered schema for policy type + policyTypeId.setVersion("2.0.0"); + assertFalse(domainMaker.isDomainConformant(policyTypeId, domainAPolicy)); + } + + + @Test + public void testConformance() throws IOException, CoderException { + ToscaPolicy policy1 = getToscaPolicy("src/test/resources/policyA.json"); + assertTrue(domainMaker.conformance(policy1)); + + policy1.getProperties().remove("nested"); + assertThatThrownBy(() -> domainMaker.conformance(policy1)) + .isInstanceOf(ValidationFailedException.class) + .hasMessageContaining("Required property nested is missing from object"); + + DomainAPolicy domainAPolicy = createDomainPolicy(); + assertTrue(domainMaker.conformance(policy1.getTypeIdentifier(), domainAPolicy)); + assertDomainPolicy(domainAPolicy); + + domainAPolicy.getProperties().getNested().setNested1(""); + assertThatThrownBy(() -> domainMaker.conformance(policy1.getTypeIdentifier(), domainAPolicy)) + .isInstanceOf(ValidationFailedException.class) + .hasMessageContaining("Pattern ^(.+)$ is not contained in text"); + } + + @Test + public void testRegisterValidator() throws IOException, CoderException { + ToscaPolicyTypeIdentifier policyTypeId = + new ToscaPolicyTypeIdentifier("policy.type.external", "9.9.9"); + + assertTrue(domainMaker.registerValidator(policyTypeId, + getJsonFromFile("src/test/resources/policy.type.external-9.9.9.schema.json"))); + + ToscaPolicy policy = getToscaPolicy("src/test/resources/policyA.json"); + policy.setType("policy.type.external"); + policy.setTypeVersion("9.9.9"); + assertTrue(domainMaker.isConformant(policy)); + + policy.setTypeVersion("1.0.0"); + assertFalse(domainMaker.isConformant(policy)); + } + + @Test + public void testConvertToDomainPolicy() throws IOException, CoderException { + DomainAPolicy domainAPolicy = + domainMaker.convertTo(getToscaPolicy("src/test/resources/policyA.json"), DomainAPolicy.class); + assertDomainPolicy(domainAPolicy); + + assertNotNull(domainMaker.convertTo(getToscaPolicy("src/test/resources/policyA-no-policy-type.json"), + DomainAPolicy.class)); + } + + @Test + public void testConvertToSchema() { + assertThatThrownBy(() -> domainMaker + .convertToSchema(new ToscaPolicyType())) + .isInstanceOf(UnsupportedOperationException.class); + } + + @Test + public void testIsRegistered() { + ToscaPolicyTypeIdentifier policyTypeId1 = + new ToscaPolicyTypeIdentifier("policy.type.A", "1.0.0"); + assertTrue(domainMaker.isRegistered(policyTypeId1)); + + ToscaPolicyTypeIdentifier policyTypeId2 = + new ToscaPolicyTypeIdentifier("policy.type.external", "7.7.9"); + assertFalse(domainMaker.isRegistered(policyTypeId2)); + + } + + private String getJsonFromFile(String filePath) throws IOException { + return new String(Files.readAllBytes(Paths.get(filePath))); + } + + private ToscaPolicy getToscaPolicy(String filePath) throws CoderException, IOException { + String policyJson = getJsonFromFile(filePath); + return new StandardCoder().decode(policyJson, ToscaPolicy.class); + } + + private DomainAPolicy createDomainPolicy() { + return DomainAPolicy.builder().metadata(Metadata.builder().policyId("A").build()) + .name("A") + .version("1.0.0") + .type("policy.type.A") + .typeVersion("1.0.0") + .properties(Properties.builder() + .nested(Nested.builder().nested1("nested1").nested2(true).nested3(50).build()) + .build()).build(); + } + + private void assertDomainPolicy(DomainAPolicy domainAPolicy) { + assertEquals("A", domainAPolicy.getName()); + assertEquals("1.0.0", domainAPolicy.getVersion()); + assertEquals("1.0.0", domainAPolicy.getTypeVersion()); + assertEquals("policy.type.A", domainAPolicy.getType()); + assertEquals("A", domainAPolicy.getMetadata().getPolicyId()); + assertEquals("nested1", domainAPolicy.getProperties().getNested().getNested1()); + assertEquals(true, domainAPolicy.getProperties().getNested().isNested2()); + assertEquals(50, domainAPolicy.getProperties().getNested().getNested3()); + } +}
\ No newline at end of file diff --git a/policy-utils/src/test/resources/policy.type.external-9.9.9.schema.json b/policy-utils/src/test/resources/policy.type.external-9.9.9.schema.json new file mode 100644 index 00000000..d8651eb5 --- /dev/null +++ b/policy-utils/src/test/resources/policy.type.external-9.9.9.schema.json @@ -0,0 +1,7 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/policy.type.external", + "type": "object", + "title": "Domain policy.type.external Policy root schema" +} diff --git a/policy-utils/src/test/resources/policyA-no-policy-type.json b/policy-utils/src/test/resources/policyA-no-policy-type.json new file mode 100644 index 00000000..c92b736c --- /dev/null +++ b/policy-utils/src/test/resources/policyA-no-policy-type.json @@ -0,0 +1,16 @@ +{ + "type": "policy.type.Z", + "type_version": "1.0.0", + "version": "1.0.0", + "metadata": { + "policy-id": "A" + }, + "properties": { + "nested": { + "nested1": "nested1", + "nested2": true, + "nested3": 50 + } + }, + "name": "A" +}
\ No newline at end of file diff --git a/policy-utils/src/test/resources/policyA.json b/policy-utils/src/test/resources/policyA.json new file mode 100644 index 00000000..7afa79d3 --- /dev/null +++ b/policy-utils/src/test/resources/policyA.json @@ -0,0 +1,16 @@ +{ + "type": "policy.type.A", + "type_version": "1.0.0", + "version": "1.0.0", + "metadata": { + "policy-id": "A" + }, + "properties": { + "nested": { + "nested1": "nested1", + "nested2": true, + "nested3": 50 + } + }, + "name": "A" +}
\ No newline at end of file diff --git a/policy-utils/src/test/resources/schemas/policy.type.A-1.0.0.schema.json b/policy-utils/src/test/resources/schemas/policy.type.A-1.0.0.schema.json new file mode 100644 index 00000000..089ec44f --- /dev/null +++ b/policy-utils/src/test/resources/schemas/policy.type.A-1.0.0.schema.json @@ -0,0 +1,89 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/policy.type.A", + "type": "object", + "title": "Domain policy.type.A Policy root schema", + "required": [ + "type", + "type_version", + "version", + "metadata", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "pattern": "^(.+)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Version", + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "required": [ + "nested" + ], + "properties": { + "nested": { + "$id": "#/properties/properties/properties/nested", + "type": "object", + "required": [ + "nested1", + "nested2", + "nested3" + ], + "properties": { + "nested1": { + "$id": "#/properties/properties/properties/nested/properties/nested1", + "type": "string", + "pattern": "^(.+)$" + }, + "nested2": { + "$id": "#/properties/properties/properties/nested/properties/nested2", + "type": "boolean", + "default": true + }, + "nested3": { + "$id": "#/properties/properties/properties/nested/properties/nested3", + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 30 + } + } + } + } + } + } +} |