Coder Social home page Coder Social logo

microprofile-rest-client's Issues

WildFly Swarm Implementation "Method not supported"

I'm using WildFly Swarm's implementation (2018.2.0) but I always receive the following exception for a simple GET method.
Checking their source code, most of the methods have no real implementation and they just throw this exception, like getEntity()

2018-02-17 00:22:08,681 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /game/users: java.lang.RuntimeException: method call not supported
at org.wildfly.swarm.microprofile.restclient.PartialResponse.notSupported(PartialResponse.java:69)
at org.wildfly.swarm.microprofile.restclient.PartialResponse.getEntity(PartialResponse.java:65)
at org.jboss.resteasy.core.ExceptionHandler.unwrapException(ExceptionHandler.java:128)
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:222)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:179)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:422)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:213)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:228)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.swarm.generated.FaviconErrorHandler.handleRequest(FaviconErrorHandler.java:61)
at io.undertow.server.handlers.PathHandler.handleRequest(PathHandler.java:94)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

Enable support for global provider registration

Issue #35 expose the need for a global or system-wide registration of providers. In the OpenTracing example, the OpenTracing implementation could easily add a ClientRequestFilter that would start the tracing, but then user code would be responsible for registering the filter. Instead, there should be a mechanism that allows automatic registration of providers to be used for all rest clients.

I'd propose using the ServiceLoader mechanism to search the classpath for instances of an interface that would register these providers. In this way, OpenTracing could add an implementation of that interface to register their filter. Likewise, other features (Fault Tolerance, Metrics, or even user-specific features) could register their own providers.

Deployment Exceptions

Need to handle cases where the application code is in error - these should be documented in the spec and tested in the TCK. Here are a few of the exceptions we should cover (please add more as we think of them):

  • Multiple HTTP method annotations on the same interface method (i.e. @GET @PUT public Object someMethod()
  • Invalid URI templating (i.e. @GET @Path("/blah") public Object someMethod(@PathParam("{someParam}") - in this case there is no path parameter defined
  • No @Path annotation on the passed-in interface

TCK not working quite right on servlet based containers

With the change to use Wiremock on the client side, the tests for the TCK no longer work correctly on servlet based containers (most of the MP Impls are servlet based). We need to address this to allow the injection of clients to continue to work.

Some ideas we had:

  • Reset to use wiremock as a dependency in the WAR file
  • Ensure that all impls are deploying to a container (similar to how the JWT spec works)

Create client from OpenApi definitions on the server side

OpenAPI / Swagger has swagger-codegen which can take a swagger.json file to generate clients for many available languages.
The swagger.json file itself can be automatically be created from the JAX-RS interfaces that are annotated with OpenAPI annotations.

In fact the swagger.json could be skipped in the annotation case and an api-processor could do the work. I have done something similar for docs generation in the past for RHQ : https://github.com/rhq-project/rhq/tree/master/modules/helpers/rest-docs-generator it emits an intermediate XML format though, which then gets turned into DocBook.

RestClientBuilderResolver needs additional doPrivs around calls to get ClassLoaders

The instance method has a doPriv for getting the thread context classloader, but if that is null, it then attempts to get the RestClientBuilderResolver's classloader without privilege. Also, in the loadSpi method there is a call to cl.getParent() that also needs to be wrapped in a doPriv.

Implementors should be able to work around this issue by providing the API jar with sufficient permissions (i.e. creating a permissions.perm file in an OSGi bundle), but this ought to be fixed in the next rev of the MP Rest Client spec.

HATEOAS and rest client

Microprofile rest client is still rather new and it is hard to find example for some specific usage, and that is way I'm asking here.
Problem that I now facing is how to use rest client when rest endpoint implements HATEOAS. In this example bellow we have some endpoint https://localhost1/rest/management that produces output :

{
    "departmentId": 10,
    "departmentName": "Administration",
    "locationId": 1700,
    "managerId": 200,
    "links": [
        {
            "href": "https://localhost2/rest/employees",
            "rel": "employees",
            "type" : "GET"
        }
    ]
}

My question is about how to implement rest client interface that gets content from resource(s) that is defined in links.

Do we need to build new client interface(we cannot override base url for client interface already created?) for each link in links? Is building new client interface expensive operation, because we can have a lot of links?

It would be nice that solution for given problem can be implemented with microprofile rest client CDI support.

Any guidance to existing documentation, example or pointer in direction to solve problem are welcome.

Thanks on your very good work on Microprofile project.

Arguable use of ParamConverterProvider

Some tests (see discussion on #69) make use of ParamConverterProvider to change the request parameter values on the client side, prior to the actual HTTP request.

I think using a ParamConverter for these purposes is arguable or even wrong. The spec only references ParamConverter for injection cases to supply values to resource fields annotated with @<X>Param. See section 3.2 in https://github.com/jax-rs/spec/blob/master/spec.pdf.

IMO the following tests make invalid use of a ParamConverterProvider and should be changed to not depend on the a ParamConverter, which seems to be a server-side extension point only:

  • InvokeWithBuiltProvidersTest
  • InvokeWithRegisteredProvidersTest
  • CDIInvokeWithRegisteredProvidersTest

@andymc12 Thoughts?

Prep for new release process

Prepare the MP Rest Client for the new release process. The Jenkins job to use is at https://ci.eclipse.org/microprofile/view/Release/job/MicroProfile%20Releases/

  1. Ensure that your pom files are valid. Review the OSSRH guide
  2. Change your distribution management section to use OSSRH:
    <distributionManagement>
        <repository>
            <id>ossrh</id>
            <name>Sonatype OSSRH - Release Staging Area</name>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
        </repository>
        <snapshotRepository>
            <id>ossrh</id>
            <name>Sonatype OSSRH Snapshots</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
            <uniqueVersion>true</uniqueVersion>
        </snapshotRepository>
    </distributionManagement>
  1. Create a release profile:
    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>attach-sources</id>
                                <goals>
                                    <goal>jar-no-fork</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>attach-javadocs</id>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>sign-artifacts</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
  1. Configure the release plugin to match:
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-release-plugin</artifactId>
                    <version>2.5.3</version>
                    <configuration>
                        <autoVersionSubmodules>true</autoVersionSubmodules>
                        <localCheckout>true</localCheckout>
                        <useReleaseProfile>false</useReleaseProfile>
                        <arguments>${arguments} -Prelease</arguments>
                    </configuration>
                </plugin>

Add url and other attributes to the RestClient qualifier

Current version 1.0.1 requires that the URL and other attributes like scope and providers for an injected client proxy is specified using an external MP Config value under a generated config key.

I suggest to allow specifying the URL also in the code as the default value, using a non-binding attribute of the RestClient qualifier, such as:

@Inject
@RestClient(url="http://localhost/myservice", providers = {MyProvider.class, AnotherProvider.class})
MyService myService

Registration of JAX-RS Features

Clarify in the spec that providers and features should both be registered in a client, both via builder and via annotation.

Create separate API/SPI components

Create separate API and SPI. The current RestClientBuilder represents an API that end users interact with. Create a new SPI that implementers will satisfy that can be used in OSGi and non-OSGi aware environments.

Below is an agreed upon list of changes:

  • Create a new RestClientBuilderProvider abstract class in a new spi package:
    • It should have the logic of doing the ServiceLoader based look up
    • Exposes static method that creates a builder
    • Have a static method that sets the provider
    • Have an instance level method to create a builder
    • The static method for creating a new builder should load the service if not already loaded, and call the instance method on that loaded service. If set provider was called, it should use that instance instead of a SerivceLoader look up.
  • Migrate RestClientBuilder to be an interface
    • It has a static method that just delegates down to the SPI to avoid end users calling the SPI

Prefer URI to URL

Given that JAX-RS normally uses URI instead of URL, RestClientBuilder should have a method

RestClientBuilder baseUri(URI uri);

in addition to

RestClientBuilder baseUrl(URL url);

and there may be good reasons to deprecate the latter.

Replace handles method

Replace the current handles method so that instead of the Response just pass in the response status code and the headers of the response.

Define a new name for RegisterProviders

We're introducing an annotation to use when registering providers. It was decided that the name @RegisterProviders wasn't great, but didn't have a better name. So for now we're introducing it with this name, however we want to reevaluate before end of release.

So this ticket serves as a placeholder for that change, and will be closed within 1.0 regardless of results.

TCK Issue : Stub and Rest Client URL mismatch

1- AsyncMethodTest#testExecutorService method stub is created with path "/execSvc" and Rest Client interface "SimpleGetApiAsync" path is "/" blank which cause 404 Not Found error.

2- The same issue, I have observed with test AsyncMethodTest#testAsyncInvocationInterceptorProvider method where stub is created for path "/asyncIntercept", Rest Client interface "SimpleGetApiAsync" final updated path (using filter) is "/808" and finally verification is done for "/asyncIntercept/808".

If it is not an issue, please share the info about, how it is expected to work behind the scene.

Inverse ExceptionMappers

JAX-RS defines an ExceptionMapper that converts an Exception into a Response object.

We should be able to define a mapping of the inverse, by the HTTP response code, what exception to throw.

ResponseExceptionMapper.toThrowable() returns null

I don't understand the motivation to allow for null return values on ResponseExceptionMapper.toThrowable(). Can some explain the rationale behind this? To me this looks like an invitation to NPE's and it really complicates the ResponseMapper selection, i.e. you might have cases where the priority would determine another mapper, but because this particular one return null, you need to fallback to one with higher priority values.

Various TCK bugs

The TCK tests will fail, atleast not behave consistently, because the built in providers will tend to have the same default priority as a JAX-RS runtime's providers.

This means that our message body readers/writers will have the same priority as the default ones.

Revamp how Wiremock is used

Need to figure out how to simplify the Wiremock runtime so that it doesn't add extra dependencies:

  • Do we package in the wiremock server runtimes?
  • Can we change the runtime to standalone start up the wiremock server? - possibly via maven https://github.com/deliverymind/wiremock-maven-plugin
  • Can we use @RunAsClient to avoid adding the wiremock runtime to the servers?

Need to ensure we meet the goal of one command to run the tests.

Specify bootstrap API

Create a bootstrap API, not CDI specific, that allows a user to create a rest client proxy from an interface that has JAX-RS annotations on it.

Registering providers via both builder and annotation

There exists an ambiguity in the spec, on what happens when providers are registered via both builder and via annotation.

It was agreed at a high level we need to consider:

  • Allowing builder to override interface (builder removes providers declared by interface)
  • Allowing interface to override builder (interface removes providers declared by builder)
  • Do we allow both of these or only one?
  • How do we aggregate and order the set of providers?

Need to propagate HTTP headers and cookies

If microservice A wants to call microservice B via the rest client "remote interface" for B, there should be an option to flow along the HTTP headers and cookies, from the inbound request to A, to the outbound request to B. Automatically forwarding along security credentials, like an Authentication header, or an LTPA SSO cookie, is one key scenario, though there are likely others too. Without this, a secured microservice B will reject the calls from A, if the Auth header, or the SSO cookie, don't flow along on the requests from microservice to microservice.

I was thinking a new CDI annotation, perhaps named @PropagateHeaders, could be defined at the point of injection. It probably needs to take the HttpServletRequest as a param (so it has something to get the inbound headers/cookies from) or maybe use of an @PostContruct annotation.

I don't have all the answers - I just know we need a way to tell the rest client that it needs to not lose the security (or other) headers/cookies that flowed in to microservice A, when it calls microservice B. This is possibly related to whatever resolution occurs for issue #16.

Need package-level javadoc description

The package level javadoc description for the 1.0.X and dev streams have no description in the Javadocs - http://download.eclipse.org/microprofile/microprofile-rest-client-1.0.1/apidocs/

specifically:
http://download.eclipse.org/microprofile/microprofile-rest-client-1.0.1/apidocs/org/eclipse/microprofile/rest/client/package-summary.html (only lists Emily as the author)
all the rest have no description at all, for example:
http://download.eclipse.org/microprofile/microprofile-rest-client-1.0.1/apidocs/org/eclipse/microprofile/rest/client/annotation/package-summary.html

This should be changed by adding javadoc comments to the package-info.java files.

Add TCK tests for CDI configuration

We integrate with MP Config to allow external config of proxies. We test for URL and Scope, but we don't test for providers. We should add tests for the providers.

Need package-info.java classes in all sub-packages

We have a package-info.java class in the org.eclipse.microprofile.rest.client root package, but not in any of the sub-packages. This file is required in order to generate OSGi bundles with the correct package version.

Without these files, the 1.0.1 release updated all of the sub-packages to be version 1.0.1 (because when there is no package-info.java file) the builds will use the bundle version as the package version, but this is incorrect and could mislead users.

The 1.0.1 release is already out and is incorrect. I think that in order to resolve this, we should add package-info.java files indicating that all sub-package versions should be 1.0.1. Then move on from there - i.e. if we make a change that breaks an API user, we increment the major version; if we make a change that breaks an implementor, we increment the minor version; if we make any other changes, we increment the micro version.

Integration with CDI

Explain how to bootstrap a client that is just an interface into a CDI bean, without requiring custom producers.

Filter support

Explain how JAX-RS client request filters, client response filters are applied.
Determine if another filter type is required.

Integration with config spec

Once CDI has been declared, explain how to bootstrap with the config spec in place, matching on config keys and how to potentially override the client.

Handle the case of a checked exceptions

Explain what happens when a check exception is meant to be thrown:

  • The method declares checked exception and the mapper returns a proper checked exception
  • The method does not declare a checked exception, but the mapper returns a checked exception

Based on review notes, what we're leaning towards:

  • If the mapper returns a checked exception and the checked exception (or parent of this exception) is declared in the method, then that exception is still thrown.
  • If the mapper returns a checked exception, and it does not match the declared exceptions on the method, then we ignore it (potentially implementation specific to log it) and move to the next mapper.

Make @RegisterRestClient a bean-defining annotation

Currently, the @RegisterRestClient annotation on an interface is not auto-scanned by CDI unless the same interface is also annotated by @Dependent or a CDI scope annotation - without this annotation, some implementations will see an ambiguous bean deployment failure when trying to inject a type-safe instance of the interface into an injection point qualified with @RestClient.

By making the @RegisterRestClient annotation bean-defining, the user can leave off the @Dependent or scope annotations, and injection of the rest client will succeed.

This issue will be resolved by pull request #83.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.