From 31f3d128576a7d2a4be206b6f8ba705e4939b98a Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Thu, 3 Aug 2023 13:20:28 +0000 Subject: [PATCH] Make URIParser code more readable Issue-ID: AAI-3655 Signed-off-by: Fiete Ostkamp Change-Id: I26350e7279287c711f38194dbc1e8d302cf9a26d --- aai-annotations/.classpath | 13 ++ .../java/org/onap/aai/parsers/uri/URIParser.java | 159 +++++++++------------ .../org/onap/aai/parsers/uri/URIParserTest.java | 41 ++++++ aai-schema-ingest/.classpath | 7 + 4 files changed, 130 insertions(+), 90 deletions(-) diff --git a/aai-annotations/.classpath b/aai-annotations/.classpath index f0257c5a..123ad540 100644 --- a/aai-annotations/.classpath +++ b/aai-annotations/.classpath @@ -31,6 +31,19 @@ + + + + + + + + + + + + + diff --git a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java index 3ca20c5e..6989a725 100644 --- a/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java +++ b/aai-core/src/main/java/org/onap/aai/parsers/uri/URIParser.java @@ -23,6 +23,7 @@ package org.onap.aai.parsers.uri; import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URISyntaxException; import java.util.Set; import javax.ws.rs.core.MultivaluedHashMap; @@ -33,6 +34,7 @@ import org.onap.aai.edges.enums.EdgeType; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; +import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; import org.onap.aai.parsers.exceptions.DoesNotStartWithValidNamespaceException; import org.onap.aai.rest.RestTokens; import org.onap.aai.schema.enums.ObjectMetadata; @@ -44,15 +46,10 @@ import org.springframework.web.util.UriUtils; public class URIParser { private URI uri = null; - protected Loader loader = null; - protected Loader originalLoader = null; - private URI originalURI = null; - private MultivaluedMap queryParams = null; - private static String aaiExceptionCode = "AAI_3001"; /** @@ -63,10 +60,8 @@ public class URIParser { */ public URIParser(Loader loader, URI uri) { this.uri = uri; - this.originalLoader = loader; // Load the latest version because we need it for cloud region - this.loader = loader; } @@ -83,9 +78,7 @@ public class URIParser { } public Loader getLoader() { - return this.loader; - } /** @@ -106,54 +99,26 @@ public class URIParser { */ public void parse(Parsable p) throws UnsupportedEncodingException, AAIException { try { - boolean isRelative = false; - uri = this.trimURI(uri); - uri = handleCloudRegion(p.getCloudRegionTransform(), uri); + boolean isRelative = uri.getRawPath().startsWith("./"); + uri = formatUri(); if (p.useOriginalLoader()) { this.loader = this.originalLoader; } - this.originalURI = UriBuilder.fromPath(uri.getRawPath()).build(); - if (uri.getRawPath().startsWith("./")) { - uri = new URI(uri.getRawPath().replaceFirst("\\./", "")); - isRelative = true; - } String[] parts = uri.getRawPath().split("/"); Introspector validNamespaces = loader.introspectorFromName("inventory"); - Set keys = null; - String part = ""; Introspector previousObj = null; EdgeType type = EdgeType.TREE; for (int i = 0; i < parts.length;) { - part = parts[i]; + String part = parts[i]; Introspector introspector = null; if (part.equals(RestTokens.COUSIN.toString())) { - if (i == parts.length - 1) { + boolean isPathInvalid = i == parts.length - 1; + if (isPathInvalid) { throw new AAIException("AAI_3000", uri + " not a valid path. Cannot end in " + RestTokens.COUSIN); } - introspector = loader.introspectorFromName(parts[i + 1]); - if (null == previousObj) { - throw new AAIException(aaiExceptionCode); - } - if (previousObj.isContainer() && introspector.isContainer()) { - throw new AAIException("AAI_3000", uri + " not a valid path. Cannot chain plurals together"); - } - MultivaluedMap uriKeys = new MultivaluedHashMap<>(); - if (i == parts.length - 2 && queryParams != null) { - Set queryKeys = queryParams.keySet(); - for (String key : queryKeys) { - uriKeys.put(key, queryParams.get(key)); - - } - } - if (introspector.isContainer()) { - boolean isFinalContainer = i == parts.length - 2; - /* - * Related-to could be COUSIN OR TREE and in some cases BOTH. So Let EdgeRuleBuilder use all the - * edgeTypes - */ - p.processContainer(introspector, EdgeType.ALL, uriKeys, isFinalContainer); - } + boolean isFinalContainer = i == parts.length - 2; + introspector = parseCousin(p, parts[i + 1], previousObj, isFinalContainer); previousObj = introspector; type = EdgeType.ALL; i += 2; @@ -162,38 +127,19 @@ public class URIParser { introspector = loader.introspectorFromName(part); if (introspector != null) { - // previous has current as property - if (previousObj != null && !previousObj.hasChild(introspector) - && !previousObj.getDbName().equals("nodes")) { - throw new AAIException(aaiExceptionCode, uri + " not a valid path. " + part + " not valid"); - } else if (previousObj == null) { - String abstractType = introspector.getMetadata(ObjectMetadata.ABSTRACT); - if (abstractType == null) { - abstractType = ""; - } - // first time through, make sure it starts from a namespace - // ignore abstract types - if (!isRelative && !abstractType.equals("true") && !validNamespaces.hasChild(introspector)) { - throw new DoesNotStartWithValidNamespaceException( - uri + " not a valid path. It does not start from a valid namespace"); - } - } + validatePath(isRelative, validNamespaces, previousObj, part, introspector); - keys = introspector.getKeys(); + Set keys = introspector.getKeys(); if (keys.size() > 0) { MultivaluedMap uriKeys = new MultivaluedHashMap<>(); i++; - if (i == parts.length && queryParams != null) { - Set queryKeys = queryParams.keySet(); - for (String key : queryKeys) { - uriKeys.put(key, queryParams.get(key)); - } + boolean isLastPart = i == parts.length; + if (isLastPart && queryParams != null) { + uriKeys = queryParams; } else { for (String key : keys) { part = UriUtils.decode(parts[i], "UTF-8"); - introspector.setValue(key, part); - // skip this for further processing i++; } @@ -203,15 +149,10 @@ public class URIParser { type = EdgeType.TREE; } else if (introspector.isContainer()) { boolean isFinalContainer = i == parts.length - 1; - MultivaluedMap uriKeys = new MultivaluedHashMap<>(); - - if (isFinalContainer && queryParams != null) { - Set queryKeys = queryParams.keySet(); - for (String key : queryKeys) { - uriKeys.put(key, queryParams.get(key)); - - } - } + MultivaluedMap uriKeys = + isFinalContainer && queryParams != null + ? queryParams + : new MultivaluedHashMap<>(); p.processContainer(introspector, type, uriKeys, isFinalContainer); i++; } else { @@ -233,22 +174,51 @@ public class URIParser { } } - public boolean validate() throws UnsupportedEncodingException, AAIException { - this.parse(new URIValidate()); - return true; + private void validatePath(boolean isRelative, Introspector validNamespaces, Introspector previousObj, + String part, Introspector introspector) throws AAIException, DoesNotStartWithValidNamespaceException { + // previous has current as property + boolean isPathInvalid = previousObj != null && !previousObj.hasChild(introspector) + && !previousObj.getDbName().equals("nodes"); + if (isPathInvalid) { + throw new AAIException(aaiExceptionCode, uri + " not a valid path. " + part + " not valid"); + } + if (previousObj == null) { + String abstractType = introspector.getMetadata(ObjectMetadata.ABSTRACT); + // first time through, make sure it starts from a namespace + // ignore abstract types + if (!isRelative && !"true".equals(abstractType) && !validNamespaces.hasChild(introspector)) { + throw new DoesNotStartWithValidNamespaceException( + uri + " not a valid path. It does not start from a valid namespace"); + } + } } - /** - * Handle cloud region. - * - * @param action the action - * @param uri the uri - * @return the uri - */ - protected URI handleCloudRegion(String action, URI uri) { + private Introspector parseCousin(Parsable p, String name, Introspector previousObj, boolean isFinalContainer) throws AAIException, AAIUnknownObjectException { + Introspector introspector; + if (null == previousObj) { + throw new AAIException(aaiExceptionCode); + } + introspector = loader.introspectorFromName(name); + if (previousObj.isContainer() && introspector.isContainer()) { + throw new AAIException("AAI_3000", uri + " not a valid path. Cannot chain plurals together"); + } - return uri; + if (introspector.isContainer()) { + MultivaluedMap uriKeys = isFinalContainer && queryParams != null + ? queryParams + : new MultivaluedHashMap<>(); + /* + * Related-to could be COUSIN OR TREE and in some cases BOTH. So Let EdgeRuleBuilder use all the + * edgeTypes + */ + p.processContainer(introspector, EdgeType.ALL, uriKeys, isFinalContainer); + } + return introspector; + } + public boolean validate() throws UnsupportedEncodingException, AAIException { + this.parse(new URIValidate()); + return true; } /** @@ -258,7 +228,6 @@ public class URIParser { * @return the uri */ protected URI trimURI(URI uri) { - String result = uri.getRawPath(); if (result.startsWith("/")) { result = result.substring(1, result.length()); @@ -274,4 +243,14 @@ public class URIParser { return UriBuilder.fromPath(result).build(); } + private URI formatUri() throws URISyntaxException { + uri = this.trimURI(uri); + this.originalURI = UriBuilder.fromPath(uri.getRawPath()).build(); + boolean isRelative = uri.getRawPath().startsWith("./"); + if (isRelative) { + uri = new URI(uri.getRawPath().replaceFirst("\\./", "")); + } + return uri; + } + } diff --git a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java index 111772d2..74914cce 100644 --- a/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java +++ b/aai-core/src/test/java/org/onap/aai/parsers/uri/URIParserTest.java @@ -22,23 +22,42 @@ package org.onap.aai.parsers.uri; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.UnsupportedEncodingException; import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import javax.annotation.PostConstruct; +import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.UriBuilder; import javax.xml.bind.JAXBException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; import org.onap.aai.AAISetup; +import org.onap.aai.edges.enums.EdgeType; import org.onap.aai.exceptions.AAIException; +import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; import org.onap.aai.introspection.ModelType; +import org.onap.aai.introspection.exceptions.AAIUnknownObjectException; import org.onap.aai.setup.SchemaVersion; + public class URIParserTest extends AAISetup { private Loader loader; @@ -112,4 +131,26 @@ public class URIParserTest extends AAISetup { new URIToDBKey(loader, uri); } + + @Test + public void verifyParsableInvokation() throws UnsupportedEncodingException, AAIException { + ArgumentCaptor cloudInfrastructureArgument = ArgumentCaptor.forClass(Introspector.class); + ArgumentCaptor containersArgument = ArgumentCaptor.forClass(Introspector.class); + ArgumentCaptor objectArgument = ArgumentCaptor.forClass(Introspector.class); + URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/ctag-pools/ctag-pool/key2/key3") + .build(); + Parsable parsable = mock(Parsable.class); + + URIParser uriParser = new URIParser(loader, uri); + uriParser.parse(parsable); + + verify(parsable).processNamespace(cloudInfrastructureArgument.capture()); + verify(parsable, times(2)).processContainer(containersArgument.capture(),eq(EdgeType.TREE),eq(new MultivaluedHashMap<>()),eq(false)); + verify(parsable, times(2)).processObject(objectArgument.capture(),eq(EdgeType.TREE),eq(new MultivaluedHashMap<>())); + assertEquals("cloud-infrastructure", cloudInfrastructureArgument.getValue().getName()); + assertEquals("complexes", containersArgument.getAllValues().get(0).getName()); + assertEquals("ctag-pools", containersArgument.getAllValues().get(1).getName()); + assertEquals("complex", objectArgument.getAllValues().get(0).getName()); + assertEquals("ctag-pool", objectArgument.getAllValues().get(1).getName()); + } } diff --git a/aai-schema-ingest/.classpath b/aai-schema-ingest/.classpath index 5c8072ec..5070d13d 100644 --- a/aai-schema-ingest/.classpath +++ b/aai-schema-ingest/.classpath @@ -17,6 +17,7 @@ + @@ -37,6 +38,12 @@ + + + + + + -- 2.16.6