diff options
author | subhash kumar singh <subhash.kumar.singh@huawei.com> | 2018-02-16 13:01:15 +0000 |
---|---|---|
committer | subhash kumar singh <subhash.kumar.singh@huawei.com> | 2018-03-13 09:17:32 +0000 |
commit | a59f5607eaf196e032990b3ca962f2378e45fa52 (patch) | |
tree | a768bd25375a8667d75cd6e157f1906586e1fe3f /validate | |
parent | 1239610d64ddfce2e3d1ff3378adcf96f24ee0a0 (diff) |
Impl Verify feature for CLI
Implement verify feature for CLI. So that command developer
will come up with his mocking file and can use framework to
develope the command.
Change-Id: I0ac22aaa7284626de60c66e56e83bb75ec9d773d
Issue-ID: CLI-74
Signed-off-by: subhash kumar singh <subhash.kumar.singh@huawei.com>
Diffstat (limited to 'validate')
6 files changed, 276 insertions, 245 deletions
diff --git a/validate/validation/pom.xml b/validate/validation/pom.xml index 26f507d6..3dbe456f 100644 --- a/validate/validation/pom.xml +++ b/validate/validation/pom.xml @@ -31,12 +31,6 @@ <name>cli/validate/validation</name> <packaging>jar</packaging> <dependencies> - <dependency> - <groupId>com.github.dreamhead</groupId> - <artifactId>moco-runner</artifactId> - <version>0.11.1</version> - <scope>test</scope> - </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> @@ -83,6 +77,11 @@ <artifactId>cli-products-onap-amsterdam-features-aai</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.6</version> + </dependency> </dependencies> <!-- <build> <plugins> diff --git a/validate/validation/src/test/java/org/onap/cli/moco/OnapCommandHttpMocoServer.java b/validate/validation/src/test/java/org/onap/cli/moco/OnapCommandHttpMocoServer.java deleted file mode 100644 index b1f18681..00000000 --- a/validate/validation/src/test/java/org/onap/cli/moco/OnapCommandHttpMocoServer.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2017 Huawei Technologies Co., Ltd. - * - * 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. - */ - -package org.onap.cli.moco; - -import static com.github.dreamhead.moco.Moco.pathResource; -import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer; -import static com.github.dreamhead.moco.Runner.runner; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import org.onap.cli.fw.error.OnapCommandException; -import org.onap.cli.fw.error.OnapCommandInvalidSample; -import org.onap.cli.fw.registrar.OnapCommandRegistrar; -import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; -import org.onap.cli.main.OnapCli; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.io.Resource; -import org.yaml.snakeyaml.Yaml; - -import com.github.dreamhead.moco.HttpServer; -import com.github.dreamhead.moco.Runner; - -public class OnapCommandHttpMocoServer { - - public static final String SAMPLE_PATTERN = "onap-cli-sample/**/"; - - public static final String SAMPLE_VERSION = "open_cli_sample_version"; - public static final String SAMPLE_VERSION_1_0 = "1.0"; - - public static final String SAMPLE_COMMAND_NAME = "name"; - public static final String SAMPLE_PRODUCT = "version"; - public static final String SAMPLE_LIST = "samples"; - public static final String SAMPLE_DESCRIPTION = "name"; - public static final String SAMPLE_INPUT = "input"; - public static final String SAMPLE_OUTPUT = "output"; - public static final String SAMPLE_MOCO = "moco"; - - private static Logger LOG = LoggerFactory.getLogger(OnapCommandHttpMocoServer.class); - - private String samplesToTest = "*.yaml"; - - private int port = 8141; - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public OnapCommandHttpMocoServer(String samplesToTest) { - this.samplesToTest = samplesToTest; - } - - public OnapCommandHttpMocoServer() { - } - - public static Map<String, List<OnapCommandSample>> discoverYamls(File path) throws IOException { - Map<String, List<OnapCommandSample>> cliProductSamples = new HashMap<>(); - - Stream<Path> walk = Files.walk(path.toPath()); - walk.filter(p -> (p.toString().contains("src/test/resources/onap-cli-sample"))) - .filter(p -> p.toString().endsWith("sample.yaml")) - .forEach(p -> { - collectSamples(new File(p.toUri()), cliProductSamples); - }); - - return cliProductSamples; - } - - private static void collectSamples(File file, Map<String, List<OnapCommandSample>> result) { - OnapCommandHttpMocoServer onapCommandHttpMocoServer = new OnapCommandHttpMocoServer(); - List<OnapCommandSample> loadSamples; - try { - loadSamples = onapCommandHttpMocoServer.loadSamples(file); - loadSamples.stream().forEach(sample -> { - if (!result.containsKey(sample.getProduct())) { - result.put(sample.getProduct(), new ArrayList<>()); - } - result.get(sample.getProduct()).add(sample); - }); - } catch (OnapCommandInvalidSample e) { - LOG.error("Failed to read sample file", e); - } - } - - private List<Resource> dicoverSampleYamls() { - Resource[] resources = new Resource [] {}; - try { - resources = OnapCommandDiscoveryUtils.findResources(SAMPLE_PATTERN + this.samplesToTest); - } catch (IOException e) { - LOG.error("Failed to discover the samples", e); - } - - return Arrays.asList(resources); - } - - private String getValue(Map<String, ?> map, String prpName) { - Object o = map.get(prpName); - if (o != null) { - return o.toString(); - } - - return ""; - } - - public List<OnapCommandSample> loadSamples(InputStream inputStream, String fileName) throws OnapCommandInvalidSample { - List<OnapCommandSample> samples = new ArrayList<>(); - Map<String, ?> values = null; - try { - values = (Map<String, ?>) new Yaml().load(inputStream); - } catch (Exception e) { - throw new OnapCommandInvalidSample(fileName, e); - } - - OnapCommandSample sample = new OnapCommandSample(); - - if (!this.getValue(values, SAMPLE_VERSION).equals(SAMPLE_VERSION_1_0)) { - throw new OnapCommandInvalidSample(fileName, "Invalid sample version " + this.getValue(values, SAMPLE_VERSION)); - } - - sample.setCommandName(this.getValue(values, SAMPLE_COMMAND_NAME)); - sample.setProduct(this.getValue(values, SAMPLE_PRODUCT)); - - //Retrieve the samples - values = (Map<String, Map<String, String>>) values.get(SAMPLE_LIST); - - for (String s: values.keySet()) { - Map<String, ?> sMap = (Map<String, ?>)values.get(s); - sample.setDescription(this.getValue(sMap, SAMPLE_DESCRIPTION)); - sample.setInput(this.getValue(sMap, SAMPLE_INPUT)); - sample.setOutput(this.getValue(sMap, SAMPLE_OUTPUT)); - sample.setMoco(this.getValue(sMap, SAMPLE_MOCO)); - samples.add(sample); - } - - return samples; - } - - public List<OnapCommandSample> loadSamples(Resource file) throws OnapCommandInvalidSample { - try { - return loadSamples(file.getInputStream(), file.getFilename()); - } catch (IOException e) { - throw new OnapCommandInvalidSample(file.getFilename(), e); - } - } - - public List<OnapCommandSample> loadSamples(File file) throws OnapCommandInvalidSample { - try { - return loadSamples(new FileInputStream(file), file.getName()); - } catch (FileNotFoundException e) { - throw new OnapCommandInvalidSample(file.getName(), e); - } - } - private void verifySample(OnapCommandSample sample) throws OnapCommandException { - - List <String> args = new ArrayList<>(); - args.add(sample.getCommandName()); - args.addAll(Arrays.asList(sample.getInput().split(" "))); - - ByteArrayOutputStream bo = new ByteArrayOutputStream(); - System.setOut(new PrintStream(bo)); - - OnapCli cli = new OnapCli(args.toArray(new String []{})); - OnapCommandRegistrar.getRegistrar().setEnabledProductVersion(sample.getProduct()); - cli.handle(); - - String output = new String(bo.toByteArray()); - - assert cli.getExitCode() == 0; - - assert sample.getOutput().equals(output); - } - - public void verifySamples() throws OnapCommandException { - for (Resource rsc : this.dicoverSampleYamls()) { - for(OnapCommandSample sample: this.loadSamples(rsc)) { - - if (!sample.getMoco().isEmpty()) { - HttpServer server = jsonHttpServer(this.getPort(), pathResource(sample.getMoco())); - Runner r = runner(server); - r.start(); - - this.verifySample(sample); - - r.stop(); - } - } - } - } -}
\ No newline at end of file diff --git a/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java b/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java index 6f84c953..a631e3d2 100644 --- a/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java +++ b/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java @@ -16,28 +16,54 @@ package org.onap.cli.validation; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Map; - import org.apache.commons.io.FileUtils; -import org.junit.Ignore; import org.junit.Test; +import org.onap.cli.fw.conf.OnapCommandConstants; import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandInvalidSample; import org.onap.cli.fw.registrar.OnapCommandRegistrar; import org.onap.cli.fw.schema.OnapCommandSchemaInfo; import org.onap.cli.main.OnapCli; -import org.onap.cli.moco.OnapCommandHttpMocoServer; +import org.onap.cli.main.conf.OnapCliConstants; import org.onap.cli.moco.OnapCommandSample; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class OnapValidationTest { + public static final String SAMPLE_VERSION = "open_cli_sample_version"; + public static final String SAMPLE_VERSION_1_0 = "1.0"; + + public static final String SAMPLE_COMMAND_NAME = "name"; + public static final String SAMPLE_PRODUCT = "version"; + public static final String SAMPLE_LIST = "samples"; + public static final String SAMPLE_DESCRIPTION = "name"; + public static final String SAMPLE_INPUT = "input"; + public static final String SAMPLE_OUTPUT = "output"; + public static final String SAMPLE_MOCO = "moco"; + OnapCli cli = null; + private static Logger LOG = LoggerFactory.getLogger(OnapValidationTest.class); + private void handle(String[] args) { cli = new OnapCli(args); cli.handle(); @@ -84,13 +110,6 @@ public class OnapValidationTest { } } - @Ignore - @Test - public void verifyCommandResults() throws OnapCommandException { - OnapCommandHttpMocoServer server = new OnapCommandHttpMocoServer(); - server.verifySamples(); - } - @Test public void collectSampleYamlTest() { try { @@ -98,7 +117,7 @@ public class OnapValidationTest { String sampleFileName = "target/sample.rst"; FileUtils.deleteQuietly(new File(sampleFileName)); - Map<String, List<OnapCommandSample>> discoveredYamls = OnapCommandHttpMocoServer.discoverYamls(root); + Map<String, List<OnapCommandSample>> discoveredYamls = discoverYamls(root); writeSamples(new File(sampleFileName), discoveredYamls); } catch (IOException e) { @@ -127,4 +146,89 @@ public class OnapValidationTest { } } + public static Map<String, List<OnapCommandSample>> discoverYamls(File path) throws IOException { + Map<String, List<OnapCommandSample>> cliProductSamples = new HashMap<>(); + + Stream<Path> walk = Files.walk(path.toPath()); + walk.filter(p -> (p.toString().contains("src/test/resources/onap-cli-sample"))) + .filter(p -> p.toString().endsWith("sample.yaml")) + .forEach(p -> { + collectSamples(new File(p.toUri()), cliProductSamples); + }); + + return cliProductSamples; + } + + private static void collectSamples(File file, Map<String, List<OnapCommandSample>> result) { + List<OnapCommandSample> loadSamples; + try { + loadSamples = loadSamples(file); + loadSamples.stream().forEach(sample -> { + if (!result.containsKey(sample.getProduct())) { + result.put(sample.getProduct(), new ArrayList<>()); + } + result.get(sample.getProduct()).add(sample); + }); + } catch (OnapCommandInvalidSample e) { + LOG.error("Failed to read sample file", e); + } + } + + private static List<OnapCommandSample> loadSamples(File file) throws OnapCommandInvalidSample { + try { + return loadSamples(new FileInputStream(file), file.getName()); + } catch (FileNotFoundException e) { + throw new OnapCommandInvalidSample(file.getName(), e); + } + } + + private static List<OnapCommandSample> loadSamples(InputStream inputStream, String fileName) throws OnapCommandInvalidSample { + List<OnapCommandSample> samples = new ArrayList<>(); + Map<String, ?> values = null; + try { + values = (Map<String, ?>) new Yaml().load(inputStream); + } catch (Exception e) { + throw new OnapCommandInvalidSample(fileName, e); + } + + OnapCommandSample sample = new OnapCommandSample(); + + if (!getValue(values, SAMPLE_VERSION).equals(SAMPLE_VERSION_1_0)) { + throw new OnapCommandInvalidSample(fileName, "Invalid sample version " + getValue(values, SAMPLE_VERSION)); + } + + sample.setCommandName(getValue(values, SAMPLE_COMMAND_NAME)); + sample.setProduct(getValue(values, SAMPLE_PRODUCT)); + + //Retrieve the samples + values = (Map<String, Map<String, String>>) values.get(SAMPLE_LIST); + + for (String s: values.keySet()) { + Map<String, ?> sMap = (Map<String, ?>)values.get(s); + sample.setDescription(getValue(sMap, SAMPLE_DESCRIPTION)); + sample.setInput(getValue(sMap, SAMPLE_INPUT)); + sample.setOutput(getValue(sMap, SAMPLE_OUTPUT)); + sample.setMoco(getValue(sMap, SAMPLE_MOCO)); + samples.add(sample); + } + + return samples; + } + + private static String getValue(Map<String, ?> map, String prpName) { + Object o = map.get(prpName); + if (o != null) { + return o.toString(); + } + + return ""; + } + + @Test + public void testVerify() throws OnapCommandException { + OnapCommandRegistrar.getRegistrar().setEnabledProductVersion("open-cli"); + OnapCli onapCli = new OnapCli(new String[]{"sample-test-verify", "--verify"}); + onapCli.handle(); + assertEquals(OnapCliConstants.EXIT_SUCCESS, onapCli.getExitCode()); + } } diff --git a/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-moco.json b/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-moco.json new file mode 100644 index 00000000..f5e4e444 --- /dev/null +++ b/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-moco.json @@ -0,0 +1,34 @@ +[{ + "request" : { + "method" : "get", + "uri" : "/aai/v11/cloud-infrastructure/cloud-regions", + "headers" : { + "Authorization" : "Basic QUFJOkFBSQ==", + "X-FromAppId" : "onap-cli", + "Accept" : "application/json", + "X-TransactionId" : "req-77c08aa0-662e-4d32-9206-bd569c3bf61b", + "Content-Type" : "application/json" + }, + "json" : null + }, + "response" : { + "status" : 200, + "json" : { + "cloud-region" : [ { + "cloud-owner" : "huawei-cloud", + "cloud-region-id" : "bangalore", + "sriov-automation" : false, + "resource-version" : "1509027332165" + }, { + "cloud-owner" : "Rackspace", + "cloud-region-id" : "RegionOne", + "cloud-type" : "SharedNode", + "owner-defined-type" : "OwnerType", + "cloud-region-version" : "v1", + "cloud-zone" : "CloudZone", + "sriov-automation" : false, + "resource-version" : "1508827902543" + } ] + } + } +}]
\ No newline at end of file diff --git a/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-sample.yaml b/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-sample.yaml new file mode 100644 index 00000000..ffc59961 --- /dev/null +++ b/validate/validation/src/test/resources/open-cli-sample/sample/sample-test-verify-schema-1.1-sample.yaml @@ -0,0 +1,43 @@ +# Copyright 2017-18 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_sample_version: 1.0 +name: sample-test-verify +version: open-cli +samples: + sample1: + name: sample-test-verify + input: + moco: sample-test-verify-schema-1.1-moco.json + output: | + +--------------+------------+------------------+ + |cloud |region |resource-version | + +--------------+------------+------------------+ + |huawei-cloud |bangalore |1509027332165 | + +--------------+------------+------------------+ + |Rackspace |RegionOne |1508827902543 | + +--------------+------------+------------------+ + + sample2: + name: sample-test-verify + input: + moco: sample-test-verify-schema-1.1-moco.json + output: | + +--------------+------------+------------------+ + |cloud |region |resource-version | + +--------------+------------+------------------+ + |huawei-cloud |bangalore |1509027332165 | + +--------------+------------+------------------+ + |Rackspace |RegionOne |1508827902543 | + +--------------+------------+------------------+ diff --git a/validate/validation/src/test/resources/open-cli-schema/sample-test-verify-schema-1.1.yaml b/validate/validation/src/test/resources/open-cli-schema/sample-test-verify-schema-1.1.yaml new file mode 100644 index 00000000..5e3548ed --- /dev/null +++ b/validate/validation/src/test/resources/open-cli-schema/sample-test-verify-schema-1.1.yaml @@ -0,0 +1,72 @@ +# Copyright 2017-18 Huawei Technologies Co., Ltd. +# +# 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. + +open_cli_schema_version: 1.0 +name: sample-test-verify +description: Oclip sample command to test the command features +info: + product: open-cli + service: test + type: cmd + +results: + direction: landscape + attributes: + - name: cloud + description: Onap cloud + scope: short + type: string + - name: region + description: Onap cloud region + scope: short + type: string + - name: tenant + description: Onap cloud tenat + scope: long + type: string + - name: tenant-id + description: Onap cloud tenat id + scope: long + type: string + - name: customer + description: Onap cloud customer + scope: long + type: string + - name: service + description: Onap cloud service + scope: long + type: string + - name: resource-version + description: Onap cloud resource version + scope: short + type: string +http: + service: + auth: basic + mode: direct + request: + uri: /aai/v11/cloud-infrastructure/cloud-regions + method: GET + success_codes: + - 200 + result_map: + cloud: $b{cloud-region.[*].cloud-owner} + region: $b{cloud-region.[*].cloud-region-id} + resource-version: $b{cloud-region.[*].resource-version} + tenant: $b{cloud-region.[*].tenants.tenant.[*].tenant-name} + tenant-id: $b{cloud-region.[*].tenants.tenant.[*].tenant-id} + customer: $b{cloud-region.[*].tenants.tenant.[*].relationship-list.relationship.[*].relationship-data.[?(@.relationship-key == 'customer.global-customer-id')].relationship-value} + service: $b{cloud-region.[*].tenants.tenant.[*].relationship-list.relationship.[*].relationship-data.[?(@.relationship-key == 'service-subscription.service-type')].relationship-value} + sample_response: + body: '{"cloud-region":[{"cloud-owner":"Rackspace","cloud-region-id":"RegionOne","cloud-type":"SharedNode","owner-defined-type":"OwnerType","cloud-region-version":"v1","cloud-zone":"CloudZone","resource-version":"1500729864","tenants":{"tenant":[{"tenant-id":"e69e6d64b44347509c3fc512391f34a6","tenant-name":"onap","resource-version":"1500729865","relationship-list":{"relationship":[{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"Demonstration"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/Demonstration123/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"Demonstration123"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/u1/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"u1"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/u2/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"u2"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/DemoCust_7151e36a-1a57-4993-b513-54134f2b8f19/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"DemoCust_7151e36a-1a57-4993-b513-54134f2b8f19"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/Demonstration/service-subscriptions/service-subscription/vLB/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"Demonstration"},{"relationship-key":"service-subscription.service-type","relationship-value":"vLB"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/Linan/service-subscriptions/service-subscription/vFW/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"Linan"},{"relationship-key":"service-subscription.service-type","relationship-value":"vFW"}]},{"related-to":"service-subscription","related-link":"https://192.168.17.12:8443/aai/v8/business/customers/customer/Linan/service-subscriptions/service-subscription/vLB/","relationship-data":[{"relationship-key":"customer.global-customer-id","relationship-value":"Linan"},{"relationship-key":"service-subscription.service-type","relationship-value":"vLB"}]}]}}]}}]}' |