Added TCK tests for Feature and DynamicFeature services

Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/DynamicFeatureResource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/DynamicFeatureResource.java
new file mode 100644
index 0000000..928e874
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/DynamicFeatureResource.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.jaxrs31.spec.extensions;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+
+@Path("/")
+public class DynamicFeatureResource {
+
+    @GET
+    @Path("dynamicFeature")
+    public Response getDynamicFeature() {
+        return Response.ok().build();
+    }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/JAXRSClientIT.java
new file mode 100644
index 0000000..41e763e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/JAXRSClientIT.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.jaxrs31.spec.extensions;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.client.JdkLoggingFilter;
+import jakarta.ws.rs.tck.jaxrs21.spec.completionstage.CompletionStageResource;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.io.IOException;
+import java.util.concurrent.Future;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 31L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_jaxrs31_spec_jdkservices_web");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+    StringAsset dynamicFeatureServiceFile = new StringAsset(TckDynamicFeature.class.getName());
+    StringAsset featureServiceFile = new StringAsset(TckFeature.class.getName());
+    String prefix = "classes/META-INF/services/";
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_jaxrs31_spec_jdkservices_web.war");
+    archive.addClasses(TSAppConfig.class, DynamicFeatureResource.class,
+            TckFeature.class, TckFeature.TckFeatureFilter.class,
+            TckDynamicFeature.class, TckDynamicFeature.TckDynamicFeatureFilter.class);
+    archive.addAsWebInfResource(dynamicFeatureServiceFile, prefix + DynamicFeature.class.getName());
+    archive.addAsWebInfResource(featureServiceFile, prefix + Feature.class.getName());
+    return archive;
+
+  }
+
+  /* Run test */
+
+  /*
+   * @testName: featureIsRegisteredTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:137;
+   * 
+   * @test_Strategy:
+   */
+  @Test
+  public void featureIsRegisteredTest() throws Fault {
+    try (Response response = ClientBuilder.newClient().target(getAbsoluteUrl("staticFeature")).request().get()) {
+      assertEquals(200, response.getStatus());
+      assertEquals(TckFeature.class.getName(), response.readEntity(String.class));
+    } catch (Exception e) {
+      fault(e);
+    }
+  }
+
+  /*
+   * @testName: dynamicFeatureIsRegisteredTest
+   *
+   * @assertion_ids: JAXRS:SPEC:137;
+   *
+   * @test_Strategy:
+   */
+  @Test
+  public void dynamicFeatureIsRegisteredTest() throws Fault {
+    try (Response response = ClientBuilder.newClient().target(getAbsoluteUrl("dynamicFeature")).request().get()) {
+      assertEquals(200, response.getStatus());
+      assertEquals(TckDynamicFeature.class.getName(), response.readEntity(String.class));
+    } catch (Exception e) {
+      fault(e);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TSAppConfig.java
new file mode 100644
index 0000000..b729cd9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TSAppConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.jaxrs31.spec.extensions;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@ApplicationPath("/")
+public class TSAppConfig extends Application {
+  public Set<Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<>();
+    resources.add(DynamicFeatureResource.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckDynamicFeature.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckDynamicFeature.java
new file mode 100644
index 0000000..8394694
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckDynamicFeature.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.jaxrs31.spec.extensions;
+
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.container.ResourceInfo;
+import jakarta.ws.rs.core.FeatureContext;
+
+import java.io.IOException;
+
+public class TckDynamicFeature implements DynamicFeature {
+    @Override
+    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+        context.register(TckDynamicFeatureFilter.class);
+    }
+
+    public static class TckDynamicFeatureFilter implements ContainerResponseFilter {
+
+        @Override
+        public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+            if (requestContext.getUriInfo().getRequestUri().toASCIIString().contains("dynamicFeature")) {
+                responseContext.setEntity(TckDynamicFeature.class.getName());
+            }
+        }
+    }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckFeature.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckFeature.java
new file mode 100644
index 0000000..08b82d1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/jaxrs31/spec/extensions/TckFeature.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.jaxrs31.spec.extensions;
+
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.Response;
+
+import java.io.IOException;
+
+public class TckFeature implements Feature {
+    @Override
+    public boolean configure(FeatureContext context) {
+        context.register(TckFeatureFilter.class);
+        return true;
+    }
+
+    @PreMatching
+    public static class TckFeatureFilter implements ContainerRequestFilter {
+        @Override
+        public void filter(ContainerRequestContext requestContext) throws IOException {
+            if (requestContext.getUriInfo().getRequestUri().toASCIIString().contains("staticFeature")) {
+                requestContext.abortWith(Response.ok(TckFeature.class.getName()).build());
+            }
+        }
+    }
+}
diff --git a/jersey-tck/pom.xml b/jersey-tck/pom.xml
index 0ac8ccb..dbae351 100644
--- a/jersey-tck/pom.xml
+++ b/jersey-tck/pom.xml
@@ -25,13 +25,19 @@
     <version>3.1.0</version>
     <packaging>pom</packaging>
 
+    <parent>
+        <groupId>jakarta.ws.rs</groupId>
+        <artifactId>all</artifactId>
+        <version>3.1.0</version>
+    </parent>
+
     <name>Jakarta RESTful WS Compliance</name>
     <description>This test verifies the compliance of Eclipse Jersey with Jakarta REST</description>
 
     <properties>
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
-        <jersey.version>3.0.0</jersey.version>
+        <jersey.version>3.1.0-M1</jersey.version>
         <glassfish.container.version>6.1.0</glassfish.container.version>
         <jakarta.platform.version>9.1.0</jakarta.platform.version>
         <junit.jupiter.version>5.7.2</junit.jupiter.version>