b/162942095 Define Parameter Traversal

Change-Id: I91f871ead35889a9067c36743d90ea6aa4534c0a
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 25d8108..cefbaa1 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
@@ -13,6 +13,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 import org.openapi4j.parser.model.v3.ServerVariable;
 import org.openapi4j.parser.model.v3.Tag;
@@ -90,6 +91,17 @@
   }
 
   @Override
+  public void sendParameterTraversals(ImmutableList<Parameter> parameterList) {
+    Optional.ofNullable(parameterList)
+        .ifPresent(
+            parameters ->
+                parameters.forEach(
+                    parameter ->
+                        coordinator.handleTraversalCommand(
+                            factory.create(parameter, traversalPath))));
+  }
+
+  @Override
   public void sendServerTraversals(ImmutableList<Server> serversList) {
     Optional.ofNullable(serversList)
         .ifPresent(
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
index 013073f..428e7ef 100644
--- 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
@@ -36,8 +36,9 @@
     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.
+    traversalHelper.sendParameterTraversals(
+        Immutables.toImmutableList(openApiSchemaObj.getParameters()));
   }
 }
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java
new file mode 100644
index 0000000..869fcb7
--- /dev/null
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java
@@ -0,0 +1,30 @@
+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.Parameter;
+
+/** A {@link Traversal} that traverses a {@link Parameter} object. */
+final class ParameterTraversal extends Traversal<Parameter> implements ParameterTraversalCommand {
+  @Inject
+  ParameterTraversal(
+      TraversalHelperFactory traversalHelperFactory,
+      ExtensionValidationIntegrator extensionValidationIntegrator,
+      @Assisted
+          ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
+      @Assisted Parameter openApiSchemaObj) {
+    super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+  }
+
+  @Override
+  public void traverse() {
+    // TODO(b/161441872): Process extensions.
+
+    // TODO(b/162897637): Send MediaType Traversal
+    // TODO(b/162942899): Send Example Traversal
+  }
+}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversalCommand.java
new file mode 100644
index 0000000..81b4dd6
--- /dev/null
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversalCommand.java
@@ -0,0 +1,4 @@
+package com.apigee.security.oas.extendedvalidator;
+
+/** A {@link TraversalCommand} interface for {@link ParameterTraversal}. */
+public interface ParameterTraversalCommand 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 89e15d6..e857632 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
@@ -10,6 +10,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 import org.openapi4j.parser.model.v3.ServerVariable;
 import org.openapi4j.parser.model.v3.Tag;
@@ -43,6 +44,10 @@
       ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
       String name);
 
+  ParameterTraversalCommand create(
+      Parameter parameter,
+      ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath);
+
   ServerTraversalCommand create(
       Server server,
       ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath);
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 a4a71ca..d69d230 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
@@ -16,6 +16,7 @@
             .implement(
                 OpenApiSpecificationTraversalCommand.class, OpenApiSpecificationTraversal.class)
             .implement(OperationTraversalCommand.class, OperationTraversal.class)
+            .implement(ParameterTraversalCommand.class, ParameterTraversal.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 319252a..3351ad1 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
@@ -8,6 +8,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 import org.openapi4j.parser.model.v3.ServerVariable;
 import org.openapi4j.parser.model.v3.Tag;
@@ -27,6 +28,8 @@
 
   void sendOperationTraversals(ImmutableMap<String, Operation> operations);
 
+  void sendParameterTraversals(ImmutableList<Parameter> parameters);
+
   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 9ce9a18..f42f992 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
@@ -22,6 +22,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 import org.openapi4j.parser.model.v3.ServerVariable;
 import org.openapi4j.parser.model.v3.Tag;
@@ -35,6 +36,8 @@
   private final License license = new License();
   private final OpenApi3 openApiSpec = new OpenApi3();
 
+  private final ImmutableList<Parameter> parameters =
+      ImmutableList.of(new Parameter(), new Parameter(), new Parameter(), new Parameter());
   private final ImmutableList<Server> servers =
       ImmutableList.of(new Server(), new Server(), new Server());
   private final ImmutableList<Tag> tags =
@@ -137,6 +140,19 @@
   }
 
   @Test
+  public void sendParameterTraversals_sendsParameterTraversalCommandsToCoordinator() {
+    traversalHelper.sendParameterTraversals(parameters);
+
+    verify(traversalCoordinator, times(parameters.size()))
+        .handleTraversalCommand(any(ParameterTraversalCommand.class));
+  }
+
+  @Test
+  public void sendParameterTraversals_nullParameter_doesNotFail() {
+    traversalHelper.sendParameterTraversals(null);
+  }
+
+  @Test
   public void sendServerTraversals_sendsServerTraversalCommandsToCoordinator() {
     traversalHelper.sendServerTraversals(servers);
 
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
index e20fc57..05ea8f3 100644
--- 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
@@ -17,6 +17,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 
 @RunWith(JUnit4.class)
@@ -32,6 +33,9 @@
   private final ExternalDocs externalDocs = new ExternalDocs();
   private final ImmutableList servers = ImmutableList.of(new Server(), new Server(), new Server());
 
+  private final ImmutableList parameters =
+      ImmutableList.of(new Parameter(), new Parameter(), new Parameter(), new Parameter());
+
   private OperationTraversal operationTraversal;
 
   /** Sets up live and mocked instances for testing. */
@@ -40,6 +44,7 @@
 
     when(operation.getExternalDocs()).thenReturn(externalDocs);
     when(operation.getServers()).thenReturn(servers);
+    when(operation.getParameters()).thenReturn(parameters);
 
     operationTraversal =
         new OperationTraversal(
@@ -60,6 +65,22 @@
   }
 
   @Test
+  public void traverse_sendsParametersToTraversalHelper() {
+    operationTraversal.traverse();
+
+    verify(traversalHelper).sendParameterTraversals(parameters);
+  }
+
+  @Test
+  public void traverse_nullParametersMember_doesNotFail() {
+    when(operation.getParameters()).thenReturn(null);
+
+    operationTraversal.traverse();
+
+    verify(traversalHelper, atLeastOnce()).sendParameterTraversals(any());
+  }
+
+  @Test
   public void traverse_sendsServersToTraversalHelper() {
     operationTraversal.traverse();
 
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 7e1d85e..17450af 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
@@ -17,6 +17,7 @@
 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.Parameter;
 import org.openapi4j.parser.model.v3.Server;
 import org.openapi4j.parser.model.v3.ServerVariable;
 import org.openapi4j.parser.model.v3.Tag;
@@ -61,6 +62,11 @@
   }
 
   @Test
+  public void create_parameterPassed_returnsNonNullObject() {
+    assertThat(traversalCommandFactory.create(new Parameter(), traversalPath)).isNotNull();
+  }
+
+  @Test
   public void create_serverPassed_returnsNonNullObject() {
     assertThat(traversalCommandFactory.create(new Server(), traversalPath)).isNotNull();
   }