dsl query builder now supports filters 72/110172/1
authorBenjamin, Max <max.benjamin@att.com>
Tue, 14 Jul 2020 18:38:48 +0000 (14:38 -0400)
committerBenjamin, Max (mb388a) <mb388a@att.com>
Tue, 14 Jul 2020 18:38:49 +0000 (14:38 -0400)
dsl query builder now supports filters

Issue-ID: SO-3068
Signed-off-by: Benjamin, Max (mb388a) <mb388a@att.com>
Change-Id: I5b959381c6c0cf8a66109fa510a805ec5e0c1e50

graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIClient.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIDSLQueryClient.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/aai/AAIRestClient.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryClient.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/GraphInventoryQueryClient.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLNodeBase.java
graph-inventory/aai-client/src/main/java/org/onap/aaiclient/client/graphinventory/entities/DSLQueryBuilder.java
graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIDSLQueryClientTest.java [new file with mode: 0644]
graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/AAIRestClientTest.java
graph-inventory/aai-client/src/test/java/org/onap/aaiclient/client/aai/DSLQueryBuilderTest.java

index 1cd2361..1f747e6 100644 (file)
 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<String, String>());
     }
 
     protected AAIClient(AAIVersion version) {
-        super(AAIProperties.class);
+        super(AAIProperties.class, new HashMap<String, String>());
+        this.version = version;
+    }
+
+    protected AAIClient(Map<String, String> additionalHeaders) {
+        super(AAIProperties.class, additionalHeaders);
+    }
+
+    protected AAIClient(AAIVersion version, Map<String, String> 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;
index 238e873..378db87 100644 (file)
@@ -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<AAIDSLQueryClient, DSLQuery, AAIResultWrapper, AAIObjectType> {
 
     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);
     }
-
 }
index 9a8a2a5..0f69b0c 100644 (file)
@@ -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<String, String> additionalHeaders;
 
-    protected AAIRestClient(AAIProperties props, URI uri) {
+    protected AAIRestClient(AAIProperties props, URI uri, Map<String, String> additionalHeaders) {
         super(props, uri);
         this.aaiProperties = props;
+        this.additionalHeaders = additionalHeaders;
     }
 
     @Override
@@ -46,6 +48,7 @@ public class AAIRestClient extends GraphInventoryRestClient {
     protected void initializeHeaderMap(Map<String, String> headerMap) {
         headerMap.put("X-FromAppId", aaiProperties.getSystemName());
         headerMap.put("X-TransactionId", requestId);
+        headerMap.putAll(additionalHeaders);
         String auth = aaiProperties.getAuth();
         String key = aaiProperties.getKey();
 
index a2bb8bc..f8f977d 100644 (file)
 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<String, String> additionalHeaders;
 
-    protected GraphInventoryClient(Class<? extends RestProperties> propertiesClass) {
+    protected GraphInventoryClient(Class<? extends RestProperties> propertiesClass,
+            Map<String, String> 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<String, String> getAdditionalHeaders() {
+        return ImmutableMap.copyOf(this.additionalHeaders);
+    }
 }
index c749561..a192e38 100644 (file)
@@ -138,4 +138,8 @@ public abstract class GraphInventoryQueryClient<S, I, Wrapper extends GraphInven
         }
         return clone;
     }
+
+    public GraphInventoryClient getClient() {
+        return this.client;
+    }
 }
index c071e24..5c88e8e 100644 (file)
@@ -22,13 +22,17 @@ package org.onap.aaiclient.client.graphinventory.entities;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.stream.Collectors;
 import org.onap.aaiclient.client.aai.entities.QueryStep;
 import org.onap.aaiclient.client.graphinventory.GraphInventoryObjectName;
 
 public abstract class DSLNodeBase<T extends DSLNodeBase<?>> implements QueryStep {
 
     protected final String nodeName;
+    protected final Collection<String> fields;
     protected final List<DSLNodeKey> nodeKeys;
     protected final StringBuilder query;
     protected boolean output = false;
@@ -37,6 +41,7 @@ public abstract class DSLNodeBase<T extends 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<T extends 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<T extends 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<T extends 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<T extends 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<T extends 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());
index 7622032..59e3895 100644 (file)
@@ -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<S, E> {
     }
 
     public DSLQueryBuilder<S, Node> output() {
+        callOnLambda(item -> item.output());
+        return (DSLQueryBuilder<S, Node>) this;
+    }
+
+    public DSLQueryBuilder<S, Node> output(String... fields) {
+        callOnLambda(item -> item.output(fields));
+        return (DSLQueryBuilder<S, Node>) this;
+    }
+
+    protected void callOnLambda(Consumer<DSLNodeBase> 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<S, E> {
                 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<S, E> {
                 break;
             }
         }
-        return (DSLQueryBuilder<S, Node>) 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 (file)
index 0000000..36fc1db
--- /dev/null
@@ -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"));
+    }
+}
index 86738be..b73454f 100644 (file)
 
 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<String, String>());
         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<String, String>());
         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")));
+    }
 }
index 965770c..9cae761 100644 (file)
@@ -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<Output, Output> 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());
+    }
 }