From 69b33c5a39c11992a26678a424723dafc521db5b Mon Sep 17 00:00:00 2001 From: "Benjamin, Max (mb388a)" Date: Fri, 8 Feb 2019 17:39:18 -0500 Subject: add DSL endpoint support to A&AI Client add DSL endpoint support to A&AI Client Change-Id: I4e5772354d1d79a343bfac78b4a10ca0c00e3edf Issue-ID: SO-1485 Signed-off-by: Benjamin, Max (mb388a) --- .../java/org/onap/so/client/aai/AAIDSLQuery.java | 83 ++++++++++++++++++++ .../java/org/onap/so/client/aai/AAIObjectType.java | 1 + .../org/onap/so/client/aai/entities/DSLNode.java | 55 +++++++++++++ .../onap/so/client/aai/entities/DSLNodeKey.java | 49 ++++++++++++ .../org/onap/so/client/aai/entities/DSLQuery.java | 27 +++++++ .../so/client/aai/entities/DSLQueryBuilder.java | 91 ++++++++++++++++++++++ .../org/onap/so/client/aai/entities/QueryStep.java | 8 ++ .../java/org/onap/so/client/aai/entities/__.java | 39 ++++++++++ .../onap/so/client/aai/DSLQueryBuilderTest.java | 63 +++++++++++++++ 9 files changed, 416 insertions(+) create mode 100644 common/src/main/java/org/onap/so/client/aai/AAIDSLQuery.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/DSLNode.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/DSLNodeKey.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/DSLQuery.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/DSLQueryBuilder.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/QueryStep.java create mode 100644 common/src/main/java/org/onap/so/client/aai/entities/__.java create mode 100644 common/src/test/java/org/onap/so/client/aai/DSLQueryBuilderTest.java diff --git a/common/src/main/java/org/onap/so/client/aai/AAIDSLQuery.java b/common/src/main/java/org/onap/so/client/aai/AAIDSLQuery.java new file mode 100644 index 0000000000..52bae20ff3 --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/AAIDSLQuery.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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.so.client.aai; + +import java.util.Optional; + +import org.onap.so.client.RestClient; +import org.onap.so.client.aai.entities.DSLQuery; +import org.onap.so.client.aai.entities.uri.AAIUriFactory; +import org.onap.so.client.graphinventory.Format; +import org.onap.so.client.graphinventory.entities.uri.GraphInventoryUri; + +public class AAIDSLQuery extends AAIClient { + + private Optional depth = Optional.empty(); + private boolean nodesOnly = false; + private Optional subgraph = Optional.empty(); + + public AAIDSLQuery() { + super(); + } + + public AAIDSLQuery(AAIVersion version) { + super(); + this.version = version; + } + + public String query(Format format, DSLQuery query) { + return this.createClient(AAIUriFactory.createResourceUri(AAIObjectType.DSL).queryParam("format", format.toString())) + .put(query, String.class); + } + + public AAIDSLQuery depth (String depth) { + this.depth = Optional.of(depth); + return this; + } + public AAIDSLQuery nodesOnly() { + this.nodesOnly = true; + return this; + } + public AAIDSLQuery subgraph(AAISubgraphType type){ + + subgraph = Optional.of(type); + + return this; + } + + protected GraphInventoryUri setupQueryParams(GraphInventoryUri uri) { + GraphInventoryUri clone = uri.clone(); + if (this.depth.isPresent()) { + clone.queryParam("depth", depth.get()); + } + if (this.nodesOnly) { + clone.queryParam("nodesOnly", ""); + } + if (this.subgraph.isPresent()) { + clone.queryParam("subgraph", this.subgraph.get().toString()); + } + return clone; + } + @Override + protected RestClient createClient(GraphInventoryUri uri) { + return super.createClient(setupQueryParams(uri)); + } +} diff --git a/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java b/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java index 66ff59d94f..14d7f43911 100644 --- a/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java +++ b/common/src/main/java/org/onap/so/client/aai/AAIObjectType.java @@ -134,6 +134,7 @@ public class AAIObjectType implements GraphInventoryObjectType, Serializable { public static final AAIObjectType AGGREGATE_ROUTE = new AAIObjectType(AAINamespaceConstants.NETWORK, AggregateRoute.class); public static final AAIObjectType L_INTERFACE = new AAIObjectType(AAIObjectType.VSERVER.uriTemplate(), LInterface.class); public static final AAIObjectType UNKNOWN = new AAIObjectType("", "", "unknown"); + public static final AAIObjectType DSL = new AAIObjectType("/dsl", "", "dsl"); private final String uriTemplate; private final String parentUri; diff --git a/common/src/main/java/org/onap/so/client/aai/entities/DSLNode.java b/common/src/main/java/org/onap/so/client/aai/entities/DSLNode.java new file mode 100644 index 0000000000..0c2a3ebd69 --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/DSLNode.java @@ -0,0 +1,55 @@ +package org.onap.so.client.aai.entities; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.onap.so.client.graphinventory.GraphInventoryObjectName; + +public class DSLNode implements QueryStep { + + private final String nodeName; + private final List nodeKeys; + private final StringBuilder query = new StringBuilder(); + private boolean output = false; + + public DSLNode() { + this.nodeName = ""; + this.nodeKeys = new ArrayList<>(); + + } + public DSLNode(GraphInventoryObjectName name) { + this.nodeName = name.typeName(); + this.nodeKeys = new ArrayList<>(); + query.append(nodeName); + } + public DSLNode(GraphInventoryObjectName name, DSLNodeKey... key) { + this.nodeName = name.typeName(); + this.nodeKeys = Arrays.asList(key); + query.append(nodeName); + } + + public DSLNode output() { + this.output = true; + + return this; + } + + public DSLNode and(DSLNodeKey... key) { + this.nodeKeys.addAll(Arrays.asList(key)); + + return this; + } + + @Override + public String build() { + if (output) { + query.append("*"); + } + for (DSLNodeKey key : nodeKeys) { + query.append(key.build()); + } + + return query.toString(); + } +} diff --git a/common/src/main/java/org/onap/so/client/aai/entities/DSLNodeKey.java b/common/src/main/java/org/onap/so/client/aai/entities/DSLNodeKey.java new file mode 100644 index 0000000000..9ee8526c7b --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/DSLNodeKey.java @@ -0,0 +1,49 @@ +package org.onap.so.client.aai.entities; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.google.common.base.Joiner; + + +public class DSLNodeKey implements QueryStep { + + private boolean not = false; + private final StringBuilder query = new StringBuilder(); + private final String keyName; + private final List values; + public DSLNodeKey(String keyName, String... value) { + + this.keyName = keyName; + this.values = Arrays.asList(value); + } + + public DSLNodeKey not() { + + this.not = true; + return this; + } + + @Override + public String build() { + + if (not) { + query.append(" !"); + } + query.append("('").append(keyName).append("', "); + List temp = new ArrayList<>(); + for (String item : values) { + if (item.equals("null")) { + temp.add(String.format("' %s '", item)); + } else if (item.equals("")){ + temp.add("' '"); + } else { + temp.add(String.format("'%s'", item)); + } + } + query.append(Joiner.on(", ").join(temp)).append(")"); + + return query.toString(); + } +} diff --git a/common/src/main/java/org/onap/so/client/aai/entities/DSLQuery.java b/common/src/main/java/org/onap/so/client/aai/entities/DSLQuery.java new file mode 100644 index 0000000000..1d079ed12b --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/DSLQuery.java @@ -0,0 +1,27 @@ +package org.onap.so.client.aai.entities; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class DSLQuery { + + private String dsl; + + public DSLQuery() { + + } + + public DSLQuery(String dsl) { + this.dsl = dsl; + } + + public String getDsl() { + return dsl; + } + + public void setDsl(String dsl) { + this.dsl = dsl; + } + + +} diff --git a/common/src/main/java/org/onap/so/client/aai/entities/DSLQueryBuilder.java b/common/src/main/java/org/onap/so/client/aai/entities/DSLQueryBuilder.java new file mode 100644 index 0000000000..4d3e708c3f --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/DSLQueryBuilder.java @@ -0,0 +1,91 @@ +package org.onap.so.client.aai.entities; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import com.google.common.base.Joiner; + + +public class DSLQueryBuilder implements QueryStep { + + private List steps = new ArrayList<>(); + + + public DSLQueryBuilder() { + + } + public DSLQueryBuilder(DSLNode node) { + steps.add(node); + } + + public DSLQueryBuilder node(DSLNode node) { + steps.add(node); + + return (DSLQueryBuilder) this; + } + public DSLQueryBuilder output() { + if (steps.get(steps.size() -1) instanceof DSLNode) { + ((DSLNode)steps.get(steps.size() -1)).output(); + } + return this; + } + + public DSLQueryBuilder union(final DSLQueryBuilder... union) { + + List> unions = Arrays.asList(union); + steps.add(() -> { + StringBuilder query = new StringBuilder(); + + query.append("> [ ").append( + Joiner.on(", ").join( + unions.stream().map(item -> item.build()).collect(Collectors.toList()))) + .append(" ]"); + return query.toString(); + }); + + return (DSLQueryBuilder) this; + } + + public DSLQueryBuilder where(DSLQueryBuilder where) { + + steps.add(() -> { + StringBuilder query = new StringBuilder(); + query.append(where.build()).append(")"); + String result = query.toString(); + if (!result.startsWith(">")) { + result = "> " + result; + } + return "(" + result; + }); + return this; + } + + public DSLQueryBuilder to(DSLQueryBuilder to) { + steps.add(() -> { + StringBuilder query = new StringBuilder(); + + query.append("> ").append(to.build()); + return query.toString(); + }); + return this; + } + + public String limit(int limit) { + return compile() + " LIMIT " + limit; + } + + @Override + public String build() { + return compile(); + } + + private String compile() { + return Joiner.on(" ").join(steps.stream().map(item -> item.build()).collect(Collectors.toList())); + } + + protected QueryStep getFirst() { + return steps.get(0); + } +} diff --git a/common/src/main/java/org/onap/so/client/aai/entities/QueryStep.java b/common/src/main/java/org/onap/so/client/aai/entities/QueryStep.java new file mode 100644 index 0000000000..38d0924312 --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/QueryStep.java @@ -0,0 +1,8 @@ +package org.onap.so.client.aai.entities; + +@FunctionalInterface +public interface QueryStep { + + + public String build(); +} diff --git a/common/src/main/java/org/onap/so/client/aai/entities/__.java b/common/src/main/java/org/onap/so/client/aai/entities/__.java new file mode 100644 index 0000000000..e4fa990a7e --- /dev/null +++ b/common/src/main/java/org/onap/so/client/aai/entities/__.java @@ -0,0 +1,39 @@ +package org.onap.so.client.aai.entities; + +import org.onap.so.client.graphinventory.GraphInventoryObjectName; + +public class __ { + + protected __() { + + } + + public static DSLQueryBuilder identity() { + return new DSLQueryBuilder<>(); + } + public static DSLQueryBuilder start(DSLNode node) { + return new DSLQueryBuilder<>(node); + } + public static DSLQueryBuilder node(GraphInventoryObjectName name) { + + return __.start(new DSLNode(name)); + } + + public static DSLQueryBuilder node(GraphInventoryObjectName name, DSLNodeKey... key) { + return __.start(new DSLNode(name, key)); + } + + public static DSLNodeKey key(String keyName, String... value) { + return new DSLNodeKey(keyName, value); + } + + public static DSLQueryBuilder union(final DSLQueryBuilder... traversal) { + + return __.identity().union(traversal); + } + +public static DSLQueryBuilder where(DSLQueryBuilder traversal) { + + return __.identity().where(traversal); + } +} diff --git a/common/src/test/java/org/onap/so/client/aai/DSLQueryBuilderTest.java b/common/src/test/java/org/onap/so/client/aai/DSLQueryBuilderTest.java new file mode 100644 index 0000000000..f325e6eb2f --- /dev/null +++ b/common/src/test/java/org/onap/so/client/aai/DSLQueryBuilderTest.java @@ -0,0 +1,63 @@ +package org.onap.so.client.aai; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.onap.so.client.aai.entities.DSLNode; +import org.onap.so.client.aai.entities.DSLQueryBuilder; +import org.onap.so.client.aai.entities.__; + +public class DSLQueryBuilderTest { + + + @Test + public void whereTest() { + DSLQueryBuilder builder = new DSLQueryBuilder<>(new DSLNode(AAIObjectType.CLOUD_REGION, + __.key("cloud-owner", "att-nc"), + __.key("cloud-region-id", "test"))); + + builder.to(__.node(AAIObjectType.VLAN_TAG)).where( + __.node(AAIObjectType.OWNING_ENTITY, + __.key("owning-entity-name", "name") + ) + ).to(__.node(AAIObjectType.VLAN_TAG, __.key("vlan-id-outer", "108")).output()); + + assertEquals("cloud-region('cloud-owner', 'att-nc')('cloud-region-id', 'test') > " + + "vlan-tag (> owning-entity('owning-entity-name', 'name')) > " + + "vlan-tag*('vlan-id-outer', '108')", builder.build()); + } + + @Test + public void unionTest() { + DSLQueryBuilder builder = new DSLQueryBuilder<>(new DSLNode(AAIObjectType.GENERIC_VNF, + __.key("vnf-id", "vnfId")).output()); + + builder.union(__.node(AAIObjectType.PSERVER).output().to(__.node(AAIObjectType.COMPLEX).output()), + __.node(AAIObjectType.VSERVER).to(__.node(AAIObjectType.PSERVER).output().to(__.node(AAIObjectType.COMPLEX).output()))); + + assertEquals("generic-vnf*('vnf-id', 'vnfId') > " + "[ pserver* > complex*, " + + "vserver > pserver* > complex* ]", builder.build()); + } + + @Test + public void whereUnionTest() { + DSLQueryBuilder builder = new DSLQueryBuilder<>(new DSLNode(AAIObjectType.GENERIC_VNF, + __.key("vnf-id", "vnfId")).output()); + + builder.where( + __.union( + __.node(AAIObjectType.PSERVER, __.key("hostname", "hostname1")), + __.node(AAIObjectType.VSERVER).to(__.node(AAIObjectType.PSERVER, __.key("hostname", "hostname1"))))); + + assertEquals("generic-vnf*('vnf-id', 'vnfId') (> [ pserver('hostname', 'hostname1'), " + + "vserver > pserver('hostname', 'hostname1') ])", builder.build()); + } + + @Test + public void notNullTest() { + DSLQueryBuilder builder = new DSLQueryBuilder<>(new DSLNode(AAIObjectType.CLOUD_REGION, + __.key("cloud-owner", "", "null").not()).output()); + + assertEquals("cloud-region* !('cloud-owner', ' ', ' null ')", builder.build()); + } +} -- cgit 1.2.3-korg