From dfd4b46dc557ade131d7d9fefa07b9b7a349e854 Mon Sep 17 00:00:00 2001 From: "Benjamin, Max" Date: Tue, 14 Jul 2020 14:38:48 -0400 Subject: dsl query builder now supports filters dsl query builder now supports filters Issue-ID: SO-3068 Signed-off-by: Benjamin, Max (mb388a) Change-Id: I5b959381c6c0cf8a66109fa510a805ec5e0c1e50 --- .../org/onap/aaiclient/client/aai/AAIClient.java | 19 +++++++++++--- .../aaiclient/client/aai/AAIDSLQueryClient.java | 6 ++--- .../onap/aaiclient/client/aai/AAIRestClient.java | 7 ++++-- .../graphinventory/GraphInventoryClient.java | 15 ++++++++--- .../graphinventory/GraphInventoryQueryClient.java | 4 +++ .../graphinventory/entities/DSLNodeBase.java | 22 +++++++++++++++- .../graphinventory/entities/DSLQueryBuilder.java | 15 +++++++++-- .../client/aai/AAIDSLQueryClientTest.java | 17 +++++++++++++ .../aaiclient/client/aai/AAIRestClientTest.java | 29 +++++++++++++++++++--- .../aaiclient/client/aai/DSLQueryBuilderTest.java | 11 ++++++++ 10 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIDSLQueryClientTest.java diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIClient.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIClient.java index 1cd23614b5..1f747e6c8c 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIClient.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIClient.java @@ -21,11 +21,13 @@ package org.onap.aaiclient.client.aai; import java.net.URI; +import java.util.HashMap; +import java.util.Map; import javax.ws.rs.NotFoundException; import javax.ws.rs.core.UriBuilder; -import org.onap.so.client.RestClient; import org.onap.aaiclient.client.graphinventory.GraphInventoryClient; import org.onap.aaiclient.client.graphinventory.exceptions.GraphInventoryUriComputationException; +import org.onap.so.client.RestClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,11 +38,20 @@ public class AAIClient extends GraphInventoryClient { protected AAIVersion version; protected AAIClient() { - super(AAIProperties.class); + super(AAIProperties.class, new HashMap()); } protected AAIClient(AAIVersion version) { - super(AAIProperties.class); + super(AAIProperties.class, new HashMap()); + this.version = version; + } + + protected AAIClient(Map additionalHeaders) { + super(AAIProperties.class, additionalHeaders); + } + + protected AAIClient(AAIVersion version, Map additionalHeaders) { + super(AAIProperties.class, additionalHeaders); this.version = version; } @@ -54,7 +65,7 @@ public class AAIClient extends GraphInventoryClient { protected RestClient createClient(URI uri) { try { - return new AAIRestClient(getRestProperties(), constructPath(uri)); + return new AAIRestClient(getRestProperties(), constructPath(uri), additionalHeaders); } catch (GraphInventoryUriComputationException | NotFoundException e) { logger.debug("failed to construct A&AI uri", e); throw e; diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIDSLQueryClient.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIDSLQueryClient.java index 238e87392f..378db87d9b 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIDSLQueryClient.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIDSLQueryClient.java @@ -26,16 +26,17 @@ import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; import org.onap.aaiclient.client.graphinventory.GraphInventoryQueryClient; import org.onap.aaiclient.client.graphinventory.entities.DSLQuery; import org.onap.aaiclient.client.graphinventory.entities.uri.GraphInventoryUri; +import com.google.common.collect.ImmutableMap; public class AAIDSLQueryClient extends GraphInventoryQueryClient { public AAIDSLQueryClient() { - super(new AAIClient()); + super(new AAIClient(ImmutableMap.of("X-DslApiVersion", "V2"))); } public AAIDSLQueryClient(AAIVersion version) { - super(new AAIClient(version)); + super(new AAIClient(version, ImmutableMap.of("X-DslApiVersion", "V2"))); } @Override @@ -53,5 +54,4 @@ public class AAIDSLQueryClient public AAIObjectType createType(String name, String uri) { return new AAIFluentTypeReverseLookup().fromName(name, uri); } - } diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIRestClient.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIRestClient.java index 9a8a2a53c0..0f69b0cc8f 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIRestClient.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIRestClient.java @@ -23,18 +23,20 @@ package org.onap.aaiclient.client.aai; import java.net.URI; import java.util.Map; import java.util.Optional; -import org.onap.so.client.ResponseExceptionMapper; import org.onap.aaiclient.client.graphinventory.GraphInventoryPatchConverter; import org.onap.aaiclient.client.graphinventory.GraphInventoryRestClient; import org.onap.logging.filter.base.ONAPComponents; +import org.onap.so.client.ResponseExceptionMapper; public class AAIRestClient extends GraphInventoryRestClient { private final AAIProperties aaiProperties; + private final Map additionalHeaders; - protected AAIRestClient(AAIProperties props, URI uri) { + protected AAIRestClient(AAIProperties props, URI uri, Map additionalHeaders) { super(props, uri); this.aaiProperties = props; + this.additionalHeaders = additionalHeaders; } @Override @@ -46,6 +48,7 @@ public class AAIRestClient extends GraphInventoryRestClient { protected void initializeHeaderMap(Map headerMap) { headerMap.put("X-FromAppId", aaiProperties.getSystemName()); headerMap.put("X-TransactionId", requestId); + headerMap.putAll(additionalHeaders); String auth = aaiProperties.getAuth(); String key = aaiProperties.getKey(); diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryClient.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryClient.java index a2bb8bc141..f8f977d117 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryClient.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryClient.java @@ -21,20 +21,25 @@ package org.onap.aaiclient.client.graphinventory; import java.net.URI; +import java.util.Map; +import org.onap.aaiclient.client.graphinventory.entities.uri.GraphInventoryUri; +import org.onap.aaiclient.client.graphinventory.entities.uri.HttpAwareUri; import org.onap.so.client.RestClient; import org.onap.so.client.RestProperties; import org.onap.so.client.RestPropertiesLoader; -import org.onap.aaiclient.client.graphinventory.entities.uri.GraphInventoryUri; -import org.onap.aaiclient.client.graphinventory.entities.uri.HttpAwareUri; +import com.google.common.collect.ImmutableMap; public abstract class GraphInventoryClient { private RestProperties props; + protected final Map additionalHeaders; - protected GraphInventoryClient(Class propertiesClass) { + protected GraphInventoryClient(Class propertiesClass, + Map additionalHeaders) { RestProperties props = RestPropertiesLoader.getInstance().getNewImpl(propertiesClass); this.props = props; + this.additionalHeaders = additionalHeaders; } protected abstract URI constructPath(URI uri); @@ -64,4 +69,8 @@ public abstract class GraphInventoryClient { public abstract GraphInventoryVersion getVersion(); public abstract String getGraphDBName(); + + public Map getAdditionalHeaders() { + return ImmutableMap.copyOf(this.additionalHeaders); + } } diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryQueryClient.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryQueryClient.java index c749561e5f..a192e3828a 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryQueryClient.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryQueryClient.java @@ -138,4 +138,8 @@ public abstract class GraphInventoryQueryClient> implements QueryStep { protected final String nodeName; + protected final Collection fields; protected final List nodeKeys; protected final StringBuilder query; protected boolean output = false; @@ -37,6 +41,7 @@ public abstract class DSLNodeBase> implements QueryStep this.nodeName = ""; this.nodeKeys = new ArrayList<>(); this.query = new StringBuilder(); + this.fields = new LinkedHashSet<>(); } @@ -44,6 +49,7 @@ public abstract class DSLNodeBase> implements QueryStep this.nodeName = name.typeName(); this.nodeKeys = new ArrayList<>(); this.query = new StringBuilder(); + this.fields = new LinkedHashSet<>(); query.append(nodeName); } @@ -51,6 +57,7 @@ public abstract class DSLNodeBase> implements QueryStep this.nodeName = name.typeName(); this.nodeKeys = Arrays.asList(key); this.query = new StringBuilder(); + this.fields = new LinkedHashSet<>(); query.append(nodeName); } @@ -58,6 +65,7 @@ public abstract class DSLNodeBase> implements QueryStep this.nodeName = copy.nodeName; this.nodeKeys = copy.nodeKeys; this.query = new StringBuilder(copy.query); + this.fields = copy.fields; this.output = copy.output; } @@ -67,6 +75,12 @@ public abstract class DSLNodeBase> implements QueryStep return new DSLOutputNode(this); } + public DSLOutputNode output(String... fields) { + this.output = true; + this.fields.addAll(Arrays.asList(fields)); + return new DSLOutputNode(this); + } + public T and(DSLNodeKey... key) { this.nodeKeys.addAll(Arrays.asList(key)); @@ -77,7 +91,13 @@ public abstract class DSLNodeBase> implements QueryStep public String build() { StringBuilder result = new StringBuilder(query); if (output) { - result.append("*"); + if (fields.isEmpty()) { + result.append("*"); + } else { + String items = + fields.stream().map(item -> String.format("'%s'", item)).collect(Collectors.joining(", ")); + result.append("{").append(items).append("}"); + } } for (DSLNodeKey key : nodeKeys) { result.append(key.build()); diff --git a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLQueryBuilder.java b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLQueryBuilder.java index 762203258a..59e3895ce2 100644 --- a/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLQueryBuilder.java +++ b/graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLQueryBuilder.java @@ -24,6 +24,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Collectors; import org.onap.aaiclient.client.aai.entities.QueryStep; import org.onap.aaiclient.client.graphinventory.GraphInventoryObjectName; @@ -49,6 +50,17 @@ public class DSLQueryBuilder { } public DSLQueryBuilder output() { + callOnLambda(item -> item.output()); + return (DSLQueryBuilder) this; + } + + public DSLQueryBuilder output(String... fields) { + callOnLambda(item -> item.output(fields)); + return (DSLQueryBuilder) this; + } + + protected void callOnLambda(Consumer consumer) { + Object obj = steps.get(steps.size() - 1); if (obj instanceof DSLNodeBase) { ((DSLNodeBase) steps.get(steps.size() - 1)).output(); @@ -60,7 +72,7 @@ public class DSLQueryBuilder { try { o = f.get(obj); if (o instanceof DSLQueryBuilder && ((DSLQueryBuilder) o).steps.get(0) instanceof DSLNodeBase) { - ((DSLNodeBase) ((DSLQueryBuilder) o).steps.get(0)).output(); + consumer.accept(((DSLNodeBase) ((DSLQueryBuilder) o).steps.get(0))); } } catch (IllegalArgumentException | IllegalAccessException e) { } @@ -68,7 +80,6 @@ public class DSLQueryBuilder { break; } } - return (DSLQueryBuilder) this; } @SafeVarargs diff --git a/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIDSLQueryClientTest.java b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIDSLQueryClientTest.java new file mode 100644 index 0000000000..36fc1db57c --- /dev/null +++ b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIDSLQueryClientTest.java @@ -0,0 +1,17 @@ +package org.onap.aaiclient.client.aai; + +import static org.junit.Assert.assertEquals; +import java.net.URISyntaxException; +import org.junit.Test; + +public class AAIDSLQueryClientTest { + + + + @Test + public void verifyHeadersTest() throws URISyntaxException { + + AAIDSLQueryClient client = new AAIDSLQueryClient(); + assertEquals("V2", client.getClient().getAdditionalHeaders().get("X-DslApiVersion")); + } +} diff --git a/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIRestClientTest.java b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIRestClientTest.java index 86738beabb..b73454fe67 100644 --- a/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIRestClientTest.java +++ b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIRestClientTest.java @@ -20,6 +20,13 @@ package org.onap.aaiclient.client.aai; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.matching; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.hamcrest.CoreMatchers.containsString; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -30,6 +37,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.net.URI; import java.net.URISyntaxException; +import java.util.HashMap; import javax.ws.rs.core.Response; import org.junit.Rule; import org.junit.Test; @@ -37,10 +45,12 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import org.onap.so.client.RestClientSSL; +import org.onap.aaiclient.client.defaultproperties.DefaultAAIPropertiesImpl; import org.onap.aaiclient.client.graphinventory.GraphInventoryPatchConverter; import org.onap.aaiclient.client.graphinventory.exceptions.GraphInventoryPatchDepthExceededException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.google.common.collect.ImmutableMap; @RunWith(MockitoJUnitRunner.class) public class AAIRestClientTest { @@ -53,9 +63,12 @@ public class AAIRestClientTest { @Rule public ExpectedException thrown = ExpectedException.none(); + @Rule + public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort()); + @Test public void failPatchOnComplexObject() throws URISyntaxException { - AAIRestClient client = new AAIRestClient(props, new URI("")); + AAIRestClient client = new AAIRestClient(props, new URI(""), new HashMap()); this.thrown.expect(GraphInventoryPatchDepthExceededException.class); this.thrown.expectMessage(containsString("Object exceeds allowed depth for update action")); client.patch( @@ -64,7 +77,7 @@ public class AAIRestClientTest { @Test public void verifyPatchValidation() throws URISyntaxException { - AAIRestClient client = new AAIRestClient(props, new URI("")); + AAIRestClient client = new AAIRestClient(props, new URI(""), new HashMap()); AAIRestClient spy = spy(client); GraphInventoryPatchConverter patchValidatorMock = mock(GraphInventoryPatchConverter.class); doReturn(patchValidatorMock).when(spy).getPatchConverter(); @@ -73,4 +86,14 @@ public class AAIRestClientTest { spy.patch(payload); verify(patchValidatorMock, times(1)).convertPatchFormat(eq((Object) payload)); } + + @Test + public void verifyAdditionalHeadersTest() throws URISyntaxException { + AAIRestClient client = new AAIRestClient(new DefaultAAIPropertiesImpl(wireMockRule.port()), new URI("/test"), + ImmutableMap.of("test", "value")); + wireMockRule.stubFor(get(urlPathEqualTo("/test")).willReturn(aResponse().withStatus(200))); + client.get(); + wireMockRule.verify(getRequestedFor(urlPathEqualTo("/test")).withHeader("X-FromAppId", equalTo("MSO")) + .withHeader("X-TransactionId", matching(".*")).withHeader("test", equalTo("value"))); + } } diff --git a/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/DSLQueryBuilderTest.java b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/DSLQueryBuilderTest.java index 965770c796..9cae761399 100644 --- a/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/DSLQueryBuilderTest.java +++ b/graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/DSLQueryBuilderTest.java @@ -146,4 +146,15 @@ public class DSLQueryBuilderTest { "generic-vnf*('vnf-id', 'vnfId') > " + "[ pserver* > complex*, " + "vserver > pserver* > complex* ]", builder.build().get()); } + + @Test + public void selectOutputFilterTest() { + DSLQueryBuilder builder = + TraversalBuilder.traversal(new DSLStartNode(AAIObjectType.CLOUD_REGION, __.key("cloud-owner", "att-nc")) + .output("cloud-region-id", "a", "b")); + builder.to(__.node(AAIObjectType.PSERVER)).output("x", "y", "z"); + + assertEquals("cloud-region{'cloud-region-id', 'a', 'b'}('cloud-owner', 'att-nc') > pserver{'x', 'y', 'z'}", + builder.build().toString()); + } } -- cgit 1.2.3-korg