Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Derek P. Moore
    @derekm
    Did we ever get a mode in MP Health that allows Map<String, Check> checks such as Hammock supports or the healthchecks RFC calls for?
    (or even Map<String, List<Check>> checks as per strict RFC conformance?)
    Andy McCright
    @andymc12
    I'm not sure on that - that might be a good question for the MP Health channel (if they have one? if not, you could ask on the MP mailing list)
    {
      "checks": {
        "application:info": {
          "data": {
            "name": "starter-app",
            "version": "1.0.0-SNAPSHOT"
          },
          "name": "application:info",
          "state": "UP"
        },
        "system:info": {
          "data": {
            "componentType": "system",
            "hostname": "Dereks-Work-MacBook-Pro.local",
            "address": "10.37.70.112"
          },
          "name": "system:info",
          "state": "UP"
        },
        "application:uptime": {
          "data": {
            "componentType": "component",
            "observedUnit": "ms",
            "observedValue": 6411,
            "time": "2019-11-12T20:40:17.208Z"
          },
          "name": "application:uptime",
          "state": "UP"
        }
      },
      "outcome": "UP"
    }
    (you'll notice we're still on MP Health 1.0!)
    we get this improved output by setting hammock.health.output.format=map in MP Config
    we need to unwrap data objects and we'll be pretty close to the healthchecks RFC
    Derek P. Moore
    @derekm
    just built a generic healthcheck that checks other healthchecks, based on whatever proxy client configs that we already have :)
    Andy McCright
    @andymc12
    nice! that was one of the use cases I gave the health checks guys! :)
    Derek P. Moore
    @derekm
    Adding a mode where it produces a healthcheck for all discovered @Any Instance<BaseServiceClient>
    Every client the app depends on will have a test
    Derek P. Moore
    @derekm
    right now it is:
    public class StarterAppHealth extends RemoteHealthCheckMap {
    
        @Override
        public String getConfigPrefix() {
            return "starterApp";
        }
    
    }
    public abstract class RemoteHealthCheckMap implements HealthCheck {
    
        RemoteHealthCheckClient client;
    
        abstract public String getConfigPrefix();
    
        @Override
        public HealthCheckResponse call() {
            client = new RemoteHealthCheckClient();
            HealthCheckMapResponse check = client.root().health().get();
    
            return HealthCheckResponse
                    .named(getConfigPrefix() + "-health")
                    .withData("target", client.getTarget().getUri().toString())
                    .state(check.outcome == HealthStatus.UP)
                    .build();
        }
    
        class RemoteHealthCheckClient extends BaseServiceClient<RootHealthMapResource> {
    
            @Override
            protected Class<RootHealthMapResource> getRootClass() {
                return RootHealthMapResource.class;
            }
    
            @Override
            protected String getConfigPrefix() {
                return RemoteHealthCheckMap.this.getConfigPrefix();
            }
    
        }
    
    }
    Derek P. Moore
    @derekm
    our BaseServiceClient can wrap either WebResourceFactory or RestClientBuilder
    Derek P. Moore
    @derekm
    How does RestClientBuilder react to an endpoint that doesn't have a content-type header even when the resource definition says it @Produces(MediaType.APPLICATION_JSON)?
    Andy McCright
    @andymc12
    It should attempt to serialize the request entity to JSON using the most applicable MessageBodyWriter it can find - and then it will generate a Content-type: application/json header in the request.
    Derek P. Moore
    @derekm
    I mean on the client side... WebResourceFactory doesn't like endpoints that drop the Content-Type header even if the interface WRF is using says to expect JSON.
    In other words, WRF always assumes octet-stream if content-type header is missing, even if the JAX-RS resource it is using says what the content-type ought to be.
    was wondering if RestClientBuilder had the same issue
    Andy McCright
    @andymc12
    ah - if the client side has @Produces(MediaType.APPLICATION_JSON) then it will expect that the content is JSON, and will attempt to select a MessageBodyReader that handles JSON and the object in the return type. This is now the default in MP Rest Client 1.3 (the default consumes/produces was previously undefined, but now the default is application/json for both).
    if the pre-1.3 client side interfaces does not have @Produces(...), then it would most likely be application/octet-stream but different vendor implementations might have defaulted to something else (text/plain, etc.).
    Derek P. Moore
    @derekm
    awesome, was just checking that MP Rest Client spec would allow proper deserialization when content-type is missing on the response but when the interface knows what it should accept
    btw, I commented on your MP Health issue about client interfaces with our setup: https://github.com/eclipse/microprofile-health/issues/216#issuecomment-555206244
    Andy McCright
    @andymc12
    cool, thanks. I may end up contributing something like that to the MP Health spec if nobody else does.
    Derek P. Moore
    @derekm
    at work we're mostly JSON, but in my personal projects, I prefer to enable content type negotiation (and I want to move into versioned content types, but I need help from JAX-RS there!) ... so I have a lot of @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) in my resource interfaces
    is there a way to tell MP Rest Client in these situations "for this session, use XML"?
    Andy McCright
    @andymc12
    no, in MP Rest Client, all of the content-type negotiation is done via annotation, so it is pretty much static. you'd need to use the JAX-RS Client - which would allow you to specify the media type(s) you want to send/receive
    Derek P. Moore
    @derekm
    My goal is to reuse the same resources and objects on client-side and server-side
    Seems reasonable to allow someone to set a preferred type if resources have multiple types. WebResourceFactory always chooses the 1st in the produces/consumes lists
    Derek P. Moore
    @derekm
    So if I say on a POST resource “consumes(xml, json) produces(json, xml)”, my WebResourceFactory clients will send XML and accept/receive JSON, and my server side will honor it ;)
    But with RestClientBuilder, I want to say “the preferred content type is xml” so that xml happens on both request body content type and accepts header, regardless of annotation values array order
    Ken Finnigan
    @kenfinnigan
    The goal of rest client spec is to be type safe. If you want flexibility, then as Andy mentioned you’re best to stick with the regular JAX-RS Client
    Derek P. Moore
    @derekm
    I don’t want flexibility... I want the same resource definitions on client side and server side
    Derek P. Moore
    @derekm
    I’m not going to write the twice
    I mean: I might be forced to either cripple what I write or write them twice. So far I’m choosing the former in my professional life, but not in my personal life.
    Derek P. Moore
    @derekm

    I organize my projects like:

    starter-app
    ├── starter-app-server
    ├── starter-app-client
    ├── starter-app-resources
    └── starter-app-tests

    starter-app-server depends on starter-app-resources
    starter-app-client depends on starter-app-resources
    starter-app-tests depends on starter-app-client
    starter-app-server & starter-app-tests produce executable jars, the web application and the junit tests that use the client to execute system tests against the deployed web application (this is separate from the server module being thoroughly unit tested during build)

    this way other microservices can depend on starter-app-client & starter-app-resources and guarantee that they're perfectly compatible with starter-app-server
    Derek P. Moore
    @derekm
    additionally, we write our resource definitions such that
    GET /org/:orgId/rep/:repId/project/:projectId
    becomes
    client.root().org().org(orgId)
                 .rep().rep(repId)
                 .project().project(projectId)
                 .get()
    this way you can also: client.root().org().get() to get all orgs or client.root().org().post(org) to create orgs or client.root().org().org(orgId).put(org) to update orgs, etc., very mechanically and 1:1
    with all the benefits of discoverability in sane URL structures and with IDE code assist/type-ahead-find/intellisense
    Derek P. Moore
    @derekm
    since I've established this duality, if I want a more capable server, my client may need to follow suit -- so far at least using the 1st media type in the produces/consumes that have lists is sufficient, so the ability to set a preferred media type may have negligible benefits
    Heiko W. Rupp
    @pilhuhn
    Hey,
    what is the annotation equivalent in MP-rest-client of doing curl -u user:pass http://... ?
    Heiko W. Rupp
    @pilhuhn
    Ok, found it @ClientHeaderParam(name = "Authorization", value = "{lookupAuth}“) and default String lookupAuth() { return "Basic " + Base64.getEncoder().encodeToString(„user:pass“); }
    Heiko W. Rupp
    @pilhuhn
    This is not yet published.
    Andy McCright
    @andymc12
    @pilhuhn that's correct - I can't view the blog post yet, but I'm excited to see it!
    Andy McCright
    @andymc12
    very nice! thanks @pilhuhn !!