From da3ffabb02a1b1823557dcf179fbef613706dfc4 Mon Sep 17 00:00:00 2001 From: "pramod.jamkhedkar" Date: Wed, 28 Aug 2019 15:11:22 -0400 Subject: Changes drl files Changes to the DRL file to change the rules to support custom query. Added new VdnsControlLoop test for custom query, and supporting yaml request Issue-ID: POLICY-1858 Change-Id: Ic1b9e771bd36fe0642e9a3439189076a4906a4b8 Signed-off-by: pramod.jamkhedkar --- .../org/onap/policy/template/demo/SupportUtil.java | 132 ++++++----- .../template/demo/VdnsControlLoopCqTest.java | 263 +++++++++++++++++++++ .../yaml/policy_ControlLoop_SO_Cq-test.yaml | 47 ++++ 3 files changed, 389 insertions(+), 53 deletions(-) create mode 100644 controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VdnsControlLoopCqTest.java create mode 100644 controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO_Cq-test.yaml (limited to 'controlloop/templates/template.demo/src') diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/SupportUtil.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/SupportUtil.java index a4e8bef65..ab57fdf86 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/SupportUtil.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/SupportUtil.java @@ -53,7 +53,6 @@ import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; - public final class SupportUtil { private static final String OPSHISTPUPROP = "OperationsHistoryPU"; @@ -155,11 +154,12 @@ public final class SupportUtil { * @return the Kie session * @throws IOException if the container cannot be built */ - public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, String policyScope, - String policyName, String policyVersion, String yamlSpecification) throws IOException { + public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, + String policyScope, String policyName, String policyVersion, String yamlSpecification) + throws IOException { - RuleSpec spec = new RuleSpec(droolsTemplate, closedLoopControlName, policyScope, policyName, policyVersion, - yamlSpecification); + RuleSpec spec = new RuleSpec(droolsTemplate, closedLoopControlName, policyScope, policyName, + policyVersion, yamlSpecification); return buildContainer(policyVersion, new RuleSpec[] {spec}); } @@ -172,7 +172,8 @@ public final class SupportUtil { * @return the Kie session * @throws IOException if the container cannot be built */ - public static KieSession buildContainer(String policyVersion, RuleSpec[] specifications) throws IOException { + public static KieSession buildContainer(String policyVersion, RuleSpec[] specifications) + throws IOException { // // Get our Drools Kie factory // @@ -196,7 +197,8 @@ public final class SupportUtil { * @param specifications new rule specifications * @throws IOException if the container cannot be built */ - public static void updateContainer(String policyVersion, RuleSpec[] specifications) throws IOException { + public static void updateContainer(String policyVersion, RuleSpec[] specifications) + throws IOException { ReleaseId releaseId = buildPolicy(policyVersion, specifications); logger.debug(releaseId.toString()); @@ -211,20 +213,22 @@ public final class SupportUtil { * @return the release * @throws IOException if the container cannot be built */ - private static ReleaseId buildPolicy(String policyVersion, RuleSpec[] specifications) throws IOException { + private static ReleaseId buildPolicy(String policyVersion, RuleSpec[] specifications) + throws IOException { // // Generate our drools rule from our template // KieFileSystem kfs = kieServices.newKieFileSystem(); ReleaseId releaseId = kieServices.getRepository().getDefaultReleaseId(); - releaseId = kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), policyVersion); + releaseId = kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), + policyVersion); kfs.generateAndWritePomXML(releaseId); for (RuleSpec spec : specifications) { String drlContents = spec.generateRules(); kfs.write("src/main/resources/" + spec.policyName + ".drl", - kieServices.getResources().newByteArrayResource(drlContents.getBytes())); + kieServices.getResources().newByteArrayResource(drlContents.getBytes())); } // @@ -247,97 +251,119 @@ public final class SupportUtil { private static KieSession setupSession(KieSession kieSession) { - // // Create XACML Guard policy from YAML - // We prepare 4 Guards. Notice that Rebuilds recipe has two Guards (for checking policy combining algorithm) + // We prepare 4 Guards. Notice that Rebuilds recipe has two Guards (for checking policy + // combining algorithm) // - PolicyGuardYamlToXacml.fromYamlToXacml("src/test/resources/yaml/policy_guard_appc_restart.yaml", - "src/main/resources/frequency_limiter_template.xml", - "src/test/resources/xacml/autogenerated_frequency_limiter_restart.xml"); - - PolicyGuardYamlToXacml.fromYamlToXacml("src/test/resources/yaml/policy_guard_appc_rebuild.yaml", - "src/main/resources/frequency_limiter_template.xml", - "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild.xml"); - - PolicyGuardYamlToXacml.fromYamlToXacml("src/test/resources/yaml/policy_guard_appc_rebuild_1.yaml", - "src/main/resources/frequency_limiter_template.xml", - "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild_1.xml"); - - PolicyGuardYamlToXacml.fromYamlToXacml("src/test/resources/yaml/policy_guard_appc_migrate.yaml", - "src/main/resources/frequency_limiter_template.xml", - "src/test/resources/xacml/autogenerated_frequency_limiter_migrate.xml"); - - PolicyGuardYamlToXacml.fromYamlToXacml("src/test/resources/yaml/policy_guard_appc_modifyconfig.yaml", - "src/main/resources/frequency_limiter_template.xml", - "src/test/resources/xacml/autogenerated_frequency_limiter_modifyconfig.xml"); + PolicyGuardYamlToXacml.fromYamlToXacml( + "src/test/resources/yaml/policy_guard_appc_restart.yaml", + "src/main/resources/frequency_limiter_template.xml", + "src/test/resources/xacml/autogenerated_frequency_limiter_restart.xml"); + + PolicyGuardYamlToXacml.fromYamlToXacml( + "src/test/resources/yaml/policy_guard_appc_rebuild.yaml", + "src/main/resources/frequency_limiter_template.xml", + "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild.xml"); + + PolicyGuardYamlToXacml.fromYamlToXacml( + "src/test/resources/yaml/policy_guard_appc_rebuild_1.yaml", + "src/main/resources/frequency_limiter_template.xml", + "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild_1.xml"); + + PolicyGuardYamlToXacml.fromYamlToXacml( + "src/test/resources/yaml/policy_guard_appc_migrate.yaml", + "src/main/resources/frequency_limiter_template.xml", + "src/test/resources/xacml/autogenerated_frequency_limiter_migrate.xml"); + + PolicyGuardYamlToXacml.fromYamlToXacml( + "src/test/resources/yaml/policy_guard_appc_modifyconfig.yaml", + "src/main/resources/frequency_limiter_template.xml", + "src/test/resources/xacml/autogenerated_frequency_limiter_modifyconfig.xml"); PolicyGuardYamlToXacml.fromYamlToXacmlBlacklist( - "src/test/resources/yaml/policy_guard_appc_restart_blacklist.yaml", - "src/main/resources/blacklist_template.xml", - "src/test/resources/xacml/autogenerated_blacklist.xml"); + "src/test/resources/yaml/policy_guard_appc_restart_blacklist.yaml", + "src/main/resources/blacklist_template.xml", + "src/test/resources/xacml/autogenerated_blacklist.xml"); // // Creating an embedded XACML PDP // - System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/xacml/xacml_guard.properties"); + System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, + "src/test/resources/xacml/xacml_guard.properties"); return kieSession; } /** - * Set the A&AI properties. + * Set the A&AI properties. */ public static void setAaiProps() { - PolicyEngineConstants.getManager().setEnvironmentProperty("aai.url", "http://localhost:6666"); + PolicyEngineConstants.getManager().setEnvironmentProperty("aai.url", + "http://localhost:6666"); PolicyEngineConstants.getManager().setEnvironmentProperty("aai.username", "AAI"); PolicyEngineConstants.getManager().setEnvironmentProperty("aai.password", "AAI"); } /** - * Set the SO properties. + * Set the SO properties. */ public static void setSoProps() { - PolicyEngineConstants.getManager().setEnvironmentProperty("so.url", "http://localhost:6667"); + PolicyEngineConstants.getManager().setEnvironmentProperty("so.url", + "http://localhost:6667"); PolicyEngineConstants.getManager().setEnvironmentProperty("so.username", "SO"); PolicyEngineConstants.getManager().setEnvironmentProperty("so.password", "SO"); } /** - * Set the SDNC properties. + * Set the SDNC properties. */ public static void setSdncProps() { - PolicyEngineConstants.getManager().setEnvironmentProperty("sdnc.url", "http://localhost:6670/restconf/operations"); + PolicyEngineConstants.getManager().setEnvironmentProperty("sdnc.url", + "http://localhost:6670/restconf/operations"); PolicyEngineConstants.getManager().setEnvironmentProperty("sdnc.username", "sdnc"); PolicyEngineConstants.getManager().setEnvironmentProperty("sdnc.password", "sdnc"); } /** - * Set the Guard properties. + * Set the Guard properties. */ public static void setGuardProps() { /* * Guard PDP-x connection Properties */ - PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_URL, - "http://localhost:6669/policy/pdpx/v1/decision"); - PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER, "python"); - PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS, "test"); - PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_DISABLED, - "false"); + PolicyEngineConstants.getManager().setEnvironmentProperty( + org.onap.policy.guard.Util.PROP_GUARD_URL, + "http://localhost:6669/policy/pdpx/v1/decision"); + PolicyEngineConstants.getManager() + .setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER, "python"); + PolicyEngineConstants.getManager() + .setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS, "test"); + PolicyEngineConstants.getManager() + .setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_DISABLED, "false"); + } + + /** + * Sets the value of customQuery Environment property. + * + * @param value of the custom query boolean. + */ + public static void setCustomQuery(String value) { + PolicyEngineConstants.getManager().setEnvironmentProperty("aai.customQuery", value); } /** - * Set the VFC properties. + * Set the VFC properties. */ public static void setVfcProps() { - PolicyEngineConstants.getManager().setEnvironmentProperty("vfc.url", "http://localhost:6668/api/nslcm/v1"); + PolicyEngineConstants.getManager().setEnvironmentProperty("vfc.url", + "http://localhost:6668/api/nslcm/v1"); PolicyEngineConstants.getManager().setEnvironmentProperty("vfc.username", "VFC"); PolicyEngineConstants.getManager().setEnvironmentProperty("vfc.password", "VFC"); } /** - * Set the operation history properties. + * Set the operation history properties. */ public static void setPuProp() { System.setProperty(OPSHISTPUPROP, "OperationsHistoryPUTest"); @@ -364,8 +390,8 @@ public final class SupportUtil { * @param policyVersion policy version * @param yamlSpecification incoming yaml specification */ - public RuleSpec(String droolsTemplate, String closedLoopControlName, String policyScope, String policyName, - String policyVersion, String yamlSpecification) { + public RuleSpec(String droolsTemplate, String closedLoopControlName, String policyScope, + String policyName, String policyVersion, String yamlSpecification) { this.droolsTemplate = droolsTemplate; this.closedLoopControlName = closedLoopControlName; diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VdnsControlLoopCqTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VdnsControlLoopCqTest.java new file mode 100644 index 000000000..da22ac00f --- /dev/null +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VdnsControlLoopCqTest.java @@ -0,0 +1,263 @@ +/*- + * ============LICENSE_START======================================================= + * demo + * ================================================================================ + * Copyright (C) 2019 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.template.demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.time.Instant; +import java.util.HashMap; +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicListener; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.controlloop.ControlLoopEventStatus; +import org.onap.policy.controlloop.ControlLoopNotificationType; +import org.onap.policy.controlloop.VirtualControlLoopEvent; +import org.onap.policy.controlloop.VirtualControlLoopNotification; +import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.so.SoRequest; + +public class VdnsControlLoopCqTest extends ControlLoopBase implements TopicListener { + + /** + * Setup the simulator. + */ + @BeforeClass + public static void setUpBeforeClass() { + ControlLoopBase.setUpBeforeClass( + "../archetype-cl-amsterdam/src/main/resources/archetype-resources/" + + "src/main/resources/__closedLoopControlName__.drl", + "src/test/resources/yaml/policy_ControlLoop_SO_Cq-test.yaml", "type=operational", + "CL_vDNS", "v2.0"); + SupportUtil.setCustomQuery("true"); + } + + @AfterClass + public static void tearDownAfterClass() { + SupportUtil.setCustomQuery("false"); + ControlLoopBase.tearDownAfterClass(); + } + + @Test + public void successTest() { + + /* + * Allows the PolicyEngine to callback to this object to notify that there is an event ready + * to be pulled from the queue + */ + for (TopicSink sink : noopTopics) { + assertTrue(sink.start()); + sink.register(this); + } + + /* + * Create a unique requestId + */ + requestId = UUID.randomUUID(); + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off processing + * through the rules + */ + sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET); + + kieSession.fireUntilHalt(); + + // allow object clean-up + kieSession.fireAllRules(); + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + } + + @Test + public void aaiGetFailTest() { + + /* + * Allows the PolicyEngine to callback to this object to notify that there is an event ready + * to be pulled from the queue + */ + for (TopicSink sink : noopTopics) { + assertTrue(sink.start()); + sink.register(this); + } + + /* + * Create a unique requestId + */ + requestId = UUID.randomUUID(); + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off processing + * through the rules + */ + sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, "getFail"); + + try { + kieSession.fireUntilHalt(); + + // allow object clean-up + kieSession.fireAllRules(); + + } catch (Exception e) { + e.printStackTrace(); + logger.warn(e.toString()); + fail(e.getMessage()); + } + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) + */ + @Override + public void onTopicEvent(CommInfrastructure commType, String topic, String event) { + /* + * Pull the object that was sent out to DMAAP and make sure it is a ControlLoopNoticiation + * of type active + */ + Object obj = null; + if ("POLICY-CL-MGT".equals(topic)) { + obj = org.onap.policy.controlloop.util.Serialization.gsonJunit.fromJson(event, + org.onap.policy.controlloop.VirtualControlLoopNotification.class); + } + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.getPolicyName(); + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue( + ControlLoopNotificationType.ACTIVE.equals(notification.getNotification())); + } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue( + ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("Sending guard query")); + } else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue( + ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().toLowerCase().endsWith("permit")); + } else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue( + ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SO")); + } else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } else if (policyName.endsWith("SO.RESPONSE")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS + .equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SO")); + } else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + if ("error".equals(notification.getAai().get("vserver.vserver-name"))) { + assertEquals(ControlLoopNotificationType.FINAL_FAILURE, + notification.getNotification()); + } else if ("getFail".equals(notification.getAai().get("vserver.vserver-name"))) { + assertEquals(ControlLoopNotificationType.FINAL_FAILURE, + notification.getNotification()); + } else { + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS + .equals(notification.getNotification())); + } + kieSession.halt(); + } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } else if (obj instanceof SoRequest) { + logger.debug("\n============ SO received the request!!! ===========\n"); + } + } + + /** + * This method is used to simulate event messages from DCAE that start the control loop (onset + * message) or end the control loop (abatement message). + * + * @param policy the controlLoopName comes from the policy + * @param requestId the requestId for this event + * @param status could be onset or abated + */ + protected void sendEvent(ControlLoopPolicy policy, UUID requestId, + ControlLoopEventStatus status) { + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName()); + event.setRequestId(requestId); + event.setTarget("vserver.vserver-name"); + event.setClosedLoopAlarmStart(Instant.now()); + event.setAai(new HashMap<>()); + event.getAai().put("vserver.vserver-name", "Ete_vFWCLvFWSNK_7ba1fbde_0"); + event.getAai().put("vserver.is-closed-loop-disabled", "false"); + event.getAai().put("vserver.prov-status", "ACTIVE"); + event.setClosedLoopEventStatus(status); + kieSession.insert(event); + } + + protected void sendEvent(ControlLoopPolicy policy, UUID requestId, + ControlLoopEventStatus status, String vserverName) { + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName()); + event.setRequestId(requestId); + event.setTarget("vserver.vserver-name"); + event.setClosedLoopAlarmStart(Instant.now()); + event.setAai(new HashMap<>()); + event.getAai().put("vserver.vserver-name", vserverName); + event.setClosedLoopEventStatus(status); + kieSession.insert(event); + } +} diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO_Cq-test.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO_Cq-test.yaml new file mode 100644 index 000000000..16c031f33 --- /dev/null +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO_Cq-test.yaml @@ -0,0 +1,47 @@ +# Copyright 2019 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. +controlLoop: + version: 2.0.0 + controlLoopName: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3 + services: + - serviceName: d4738992-6497-4dca-9db9 + serviceInvariantUUID: dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f + serviceUUID: 2eea06c6-e1d3-4c3a-b9c4-478c506eeedf + trigger_policy: unique-policy-id-1-scale-up + timeout: 60 + +policies: + - id: unique-policy-id-1-scale-up + name: Create a new VF Module + description: + actor: SO + recipe: VF Module Create + target: + type: VFMODULE + modelInvariantId: e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e + modelVersionId: 94b18b1d-cc91-4f43-911a-e6348665f292 + modelName: VfwclVfwsnkBbefb8ce2bde..base_vfw..module-0 + modelVersion: 1 + modelCustomizationId: 47958575-138f-452a-8c8d-d89b595f8164 + payload: + requestParameters: '{"usePreload":true,"userParams":[]}' + configurationParameters: '[{"ip-addr":"$.vf-module-topology.vf-module-parameters.param[9]","oam-ip-addr":"$.vf-module-topology.vf-module-parameters.param[16]","enabled":"$.vf-module-topology.vf-module-parameters.param[23]"}]' + retry: 0 + timeout: 30 + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard -- cgit 1.2.3-korg