b/162014527 Define Operation Traversal structure Change-Id: I3f62adf49efaeb53af230f78c9f90b67505d7800
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java index a10f139..25d8108 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java
@@ -12,6 +12,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; +import org.openapi4j.parser.model.v3.Operation; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; import org.openapi4j.parser.model.v3.Tag; @@ -78,6 +79,17 @@ } @Override + public void sendOperationTraversals(ImmutableMap<String, Operation> operations) { + Optional.ofNullable(operations) + .ifPresent( + operationObj -> + operationObj.forEach( + (name, operation) -> + coordinator.handleTraversalCommand( + factory.create(operation, traversalPath, name)))); + } + + @Override public void sendServerTraversals(ImmutableList<Server> serversList) { Optional.ofNullable(serversList) .ifPresent( @@ -88,17 +100,14 @@ } @Override - public void sendServerVariableTraversals( - ImmutableMap<String, ServerVariable> serverVariablesMap) { - Optional.ofNullable(serverVariablesMap) + public void sendServerVariableTraversals(ImmutableMap<String, ServerVariable> serverVariableMap) { + Optional.ofNullable(serverVariableMap) .ifPresent( - serverVariables -> { - serverVariables.forEach( - (name, serverVariable) -> { - coordinator.handleTraversalCommand( - factory.create(serverVariable, name, traversalPath)); - }); - }); + serverVariables -> + serverVariables.forEach( + (name, serverVariable) -> + coordinator.handleTraversalCommand( + factory.create(serverVariable, traversalPath, name)))); } @Override
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java new file mode 100644 index 0000000..013073f --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java
@@ -0,0 +1,43 @@ +package com.apigee.security.oas.extendedvalidator; + +import com.google.common.collect.ImmutableList; +import com.google.inject.assistedinject.Assisted; +import java.util.Map; +import java.util.Optional; +import javax.inject.Inject; +import org.openapi4j.parser.model.OpenApiSchema; +import org.openapi4j.parser.model.v3.Operation; + +/** A {@link Traversal} that traverses an {@link Operation} object. */ +final class OperationTraversal extends Traversal<Operation> implements OperationTraversalCommand { + + @Inject + OperationTraversal( + TraversalHelperFactory traversalHelperFactory, + ExtensionValidationIntegrator extensionValidationIntegrator, + @Assisted + ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath, + @Assisted Operation openApiSchemaObj, + @Assisted String name) { + super( + traversalHelperFactory, + extensionValidationIntegrator, + traversalPath, + openApiSchemaObj, + name); + } + + @Override + public void traverse() { + // TODO(b/161441872): Process extensions. + + TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath()); + + traversalHelper.sendExternalDocsTraversal(openApiSchemaObj.getExternalDocs()); + // TODO(b/162949100): Send Callback Traversals. + traversalHelper.sendServerTraversals(Immutables.toImmutableList(openApiSchemaObj.getServers())); + // TODO(b/162942095): Send Parameter Traversals. + // TODO(b/163024263): Send Response Traversals. + // TODO(b/163024265): Send Security Requirement Traversals. + } +}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversalCommand.java new file mode 100644 index 0000000..5518f63 --- /dev/null +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversalCommand.java
@@ -0,0 +1,4 @@ +package com.apigee.security.oas.extendedvalidator; + +/** A {@link TraversalCommand} interface for {@link OperationTraversal}. */ +public interface OperationTraversalCommand extends TraversalCommand {}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java index 54ea11a..89e15d6 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactory.java
@@ -9,6 +9,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; +import org.openapi4j.parser.model.v3.Operation; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; import org.openapi4j.parser.model.v3.Tag; @@ -37,14 +38,19 @@ OpenApiSpecificationTraversalCommand create(OpenApi3 openApiSpec); + OperationTraversalCommand create( + Operation operation, + ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath, + String name); + ServerTraversalCommand create( Server server, ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath); ServerVariableTraversalCommand create( ServerVariable serverVariable, - String name, - ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath); + ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath, + String name); TagTraversalCommand create( Tag tag,
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java index bcaba34..a4a71ca 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryModule.java
@@ -15,6 +15,7 @@ .implement(LicenseTraversalCommand.class, LicenseTraversal.class) .implement( OpenApiSpecificationTraversalCommand.class, OpenApiSpecificationTraversal.class) + .implement(OperationTraversalCommand.class, OperationTraversal.class) .implement(ServerTraversalCommand.class, ServerTraversal.class) .implement(ServerVariableTraversalCommand.class, ServerVariableTraversal.class) .implement(TagTraversalCommand.class, TagTraversal.class)
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java index 1df3e3c..319252a 100644 --- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java +++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java
@@ -7,6 +7,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; +import org.openapi4j.parser.model.v3.Operation; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; import org.openapi4j.parser.model.v3.Tag; @@ -24,6 +25,8 @@ void sendOpenApiTraversal(OpenApi3 openApiSpec); + void sendOperationTraversals(ImmutableMap<String, Operation> operations); + void sendServerTraversals(ImmutableList<Server> serversList); void sendServerVariableTraversals(ImmutableMap<String, ServerVariable> serverVariables);
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelperTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelperTest.java index 00e2e5d..9ce9a18 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelperTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelperTest.java
@@ -21,6 +21,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; +import org.openapi4j.parser.model.v3.Operation; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; import org.openapi4j.parser.model.v3.Tag; @@ -42,6 +43,8 @@ private final ImmutableMap<String, ServerVariable> serverVariables = ImmutableMap.of( "one", new ServerVariable(), "two", new ServerVariable(), "three", new ServerVariable()); + private final ImmutableMap<String, Operation> operations = + ImmutableMap.of("one", new Operation(), "two", new Operation(), "three", new Operation()); @Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @Mock private TraversalCoordinator traversalCoordinator; @@ -79,7 +82,7 @@ } @Test - public void sendExternalDocsTraversals_nullParameter_doesNotFail() { + public void sendExternalDocsTraversal_nullParameter_doesNotFail() { traversalHelper.sendExternalDocsTraversal(null); } @@ -91,7 +94,7 @@ } @Test - public void sendInfoTraversals_nullParameter_doesNotFail() { + public void sendInfoTraversal_nullParameter_doesNotFail() { traversalHelper.sendInfoTraversal(null); } @@ -103,12 +106,12 @@ } @Test - public void sendLicenseTraversals_nullParameter_doesNotFail() { + public void sendLicenseTraversal_nullParameter_doesNotFail() { traversalHelper.sendLicenseTraversal(null); } @Test - public void sendOpenApi_sendsOpenApiSpecificationTraversalCommandsToCoordinator() { + public void sendOpenApiTraversal_sendsOpenApiSpecificationTraversalCommandToCoordinator() { traversalHelper.sendOpenApiTraversal(openApiSpec); verify(traversalCoordinator) @@ -116,11 +119,24 @@ } @Test - public void sendOpenApi_nullParameter_doesNotFail() { + public void sendOpenApiTraversal_nullParameter_doesNotFail() { traversalHelper.sendOpenApiTraversal(null); } @Test + public void sendOperationTraversals_sendsOperationTraversalCommandsToCoordinator() { + traversalHelper.sendOperationTraversals(operations); + + verify(traversalCoordinator, times(operations.size())) + .handleTraversalCommand(any(OperationTraversalCommand.class)); + } + + @Test + public void sendOperationTraversals_nullParameter_doesNotFail() { + traversalHelper.sendOperationTraversals(null); + } + + @Test public void sendServerTraversals_sendsServerTraversalCommandsToCoordinator() { traversalHelper.sendServerTraversals(servers); @@ -134,7 +150,7 @@ } @Test - public void sendServerVariables_sendsServerVariableTraversalCommandsToCoordinator() { + public void sendServerVariableTraversals_sendsServerVariableTraversalCommandsToCoordinator() { traversalHelper.sendServerVariableTraversals(serverVariables); verify(traversalCoordinator, times(serverVariables.size())) @@ -142,7 +158,7 @@ } @Test - public void sendServerVariables_nullParameter_doesNotFail() { + public void sendServerVariableTraversals_nullParameter_doesNotFail() { traversalHelper.sendServerVariableTraversals(null); }
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java new file mode 100644 index 0000000..e20fc57 --- /dev/null +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java
@@ -0,0 +1,77 @@ +package com.apigee.security.oas.extendedvalidator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.quality.Strictness; +import org.openapi4j.parser.model.v3.ExternalDocs; +import org.openapi4j.parser.model.v3.Operation; +import org.openapi4j.parser.model.v3.Server; + +@RunWith(JUnit4.class) +public class OperationTraversalTest { + + @Rule public final MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + + @Mock private TraversalHelperFactory traversalHelperFactory; + @Mock private TraversalHelper traversalHelper; + @Mock private ExtensionValidationIntegrator extensionValidationIntegrator; + @Mock private Operation operation; + + private final ExternalDocs externalDocs = new ExternalDocs(); + private final ImmutableList servers = ImmutableList.of(new Server(), new Server(), new Server()); + + private OperationTraversal operationTraversal; + + /** Sets up live and mocked instances for testing. */ + @Before + public void setup() { + + when(operation.getExternalDocs()).thenReturn(externalDocs); + when(operation.getServers()).thenReturn(servers); + + operationTraversal = + new OperationTraversal( + traversalHelperFactory, + extensionValidationIntegrator, + ImmutableList.of(), + operation, + "name"); + + when(traversalHelperFactory.create(any(ImmutableList.class))).thenReturn(traversalHelper); + } + + @Test + public void traverse_sendsExternalDocsToTraversalHelper() { + operationTraversal.traverse(); + + verify(traversalHelper).sendExternalDocsTraversal(externalDocs); + } + + @Test + public void traverse_sendsServersToTraversalHelper() { + operationTraversal.traverse(); + + verify(traversalHelper).sendServerTraversals(servers); + } + + @Test + public void traverse_nullServersMember_doesNotFail() { + when(operation.getServers()).thenReturn(null); + + operationTraversal.traverse(); + + verify(traversalHelper, atLeastOnce()).sendServerTraversals(any()); + } +}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java index 9eab5e8..7e1d85e 100644 --- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java +++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalCommandFactoryTest.java
@@ -16,6 +16,7 @@ import org.openapi4j.parser.model.v3.Info; import org.openapi4j.parser.model.v3.License; import org.openapi4j.parser.model.v3.OpenApi3; +import org.openapi4j.parser.model.v3.Operation; import org.openapi4j.parser.model.v3.Server; import org.openapi4j.parser.model.v3.ServerVariable; import org.openapi4j.parser.model.v3.Tag; @@ -30,53 +31,48 @@ traversalPath = ImmutableList.copyOf(new ArrayDeque<>()); @Test - public void - create_openApiSpecificationObjectPassed_returnsOpenApiSpecificationTraversalCommand() { - assertThat(traversalCommandFactory.create(new OpenApi3())) - .isInstanceOf(OpenApiSpecificationTraversalCommand.class); + public void create_contactPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new Contact(), traversalPath)).isNotNull(); } @Test - public void create_infoObjectPassed_returnsInfoTraversalCommand() { - assertThat(traversalCommandFactory.create(new Info(), traversalPath)) - .isInstanceOf(InfoTraversalCommand.class); + public void create_externalDocsPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new ExternalDocs(), traversalPath)).isNotNull(); } @Test - public void create_contactObjectPassed_returnsContactTraversalCommand() { - assertThat(traversalCommandFactory.create(new Contact(), traversalPath)) - .isInstanceOf(ContactTraversalCommand.class); + public void create_infoPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new Info(), traversalPath)).isNotNull(); } @Test - public void create_licenseObjectPassed_returnsLicenseTraversalCommand() { - assertThat(traversalCommandFactory.create(new License(), traversalPath)) - .isInstanceOf(LicenseTraversalCommand.class); + public void create_licensePassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new License(), traversalPath)).isNotNull(); } @Test - public void create_serverObjectPassed_returnsServerTraversalCommand() { - assertThat(traversalCommandFactory.create(new Server(), traversalPath)) - .isInstanceOf(ServerTraversalCommand.class); + public void create_openApiSpecificationPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new OpenApi3())).isNotNull(); } @Test - public void create_nameAndServerVariableObjectPassed_returnsServerVariableTraversalCommand() { - ServerVariableTraversalCommand traversal = - traversalCommandFactory.create(new ServerVariable(), "serverVariableName", traversalPath); - - assertThat(traversal).isInstanceOf(ServerVariableTraversalCommand.class); + public void create_operationAndNamePassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new Operation(), traversalPath, "name")).isNotNull(); } @Test - public void create_tagObjectPassed_returnsTagTraversalCommand() { - assertThat(traversalCommandFactory.create(new Tag(), traversalPath)) - .isInstanceOf(TagTraversalCommand.class); + public void create_serverPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new Server(), traversalPath)).isNotNull(); } @Test - public void create_externalDocsObjectPassed_returnsExternalDocsTraversalCommand() { - assertThat(traversalCommandFactory.create(new ExternalDocs(), traversalPath)) - .isInstanceOf(ExternalDocsTraversalCommand.class); + public void create_serverVariableAndNamePassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new ServerVariable(), traversalPath, "name")) + .isNotNull(); + } + + @Test + public void create_tagPassed_returnsNonNullObject() { + assertThat(traversalCommandFactory.create(new Tag(), traversalPath)).isNotNull(); } }