Opinionated libraries for HTTP&JSON-based RPC using Retrofit, Feign, OkHttp as clients and Jetty/Jersey as servers

Overview

Autorelease

CircleCI Build Status Download

Conjure Java Runtime (formerly http-remoting)

This repository provides an opinionated set of libraries for defining and creating RESTish/RPC servers and clients based on Feign or Retrofit as a client and Dropwizard/Jersey with JAX-RS service definitions as a server. Refer to the API Contract section for details on the contract between clients and servers. This library requires Java 8.

Core libraries:

  • conjure-java-jaxrs-client: Clients for JAX-RS-defined service interfaces
  • conjure-java-retrofit2-client: Clients for Retrofit-defined service interfaces
  • conjure-java-jersey-server: Configuration library for Dropwizard/Jersey servers
  • conjure-java-runtime-api: API classes for service configuration, tracing, and error propagation

Usage

Maven artifacts are published to JCenter. Example Gradle dependency configuration:

repositories {
  jcenter()
}

dependencies {
  compile "com.palantir.conjure.java.runtime:conjure-java-jaxrs-client:$version"
  compile "com.palantir.conjure.java.runtime:conjure-java-retrofit2-client:$version"
  compile "com.palantir.conjure.java.runtime:conjure-java-jersey-server:$version"
}

conjure-java-jaxrs-client

Provides the JaxRsClient factory for creating Feign-based clients for JAX-RS APIs. SSL configuration is mandatory for all clients, plain-text HTTP is not supported. Example:

SslConfiguration sslConfig = SslConfiguration.of(Paths.get("path/to/trustStore"));
UserAgent userAgent = UserAgent.of(UserAgent.Agent.of("my-user-agent", "1.0.0"));
ClientConfiguration config = ClientConfigurations.of(
        ImmutableList.copyOf("https://url-to-server:6789"),
        SslSocketFactories.createSslSocketFactory(sslConfig),
        SslSocketFactories.createX509TrustManager(sslConfig));
HostMetricsRegistry hostMetricsRegistry = new HostMetricsRegistry();  // can call .getMetrics() and then collect them to a central metrics repository
MyService service = JaxRsClient.create(MyService.class, userAgent, hostMetricsRegistry, config);

The JaxRsClient#create factory comes in two flavours: one for creating immutable clients given a fixed ClientConfiguration, and one for creating mutable clients whose configuration (e.g., server URLs, timeouts, SSL configuration, etc.) changes when the underlying ClientConfiguration changes.

conjure-java-retrofit2-client

Similar to conjure-java-jaxrs-client, but generates clients using the Retrofit library. Example:

ClientConfiguration config = ... as above ... ;
UserAgent userAgent = ... as above ... ;
HostMetricsRegistry hostMetricsRegistry = new HostMetricsRegistry();  // can call .getMetrics() and then collect them to a central metrics repository
MyService service = Retrofit2Client.create(MyService.class, userAgent, hostMetricsRegistry, config);

conjure-java-jersey-server

Provides Dropwizard/Jersey configuration for handling conjure types, and also exception mappers for translating common runtime exceptions as well as our own ServiceException (see the errors section) to appropriate HTTP error codes. A Dropwizard server is configured for conjure as follows:

public class MyServer extends Application<Configuration> {
    @Override
    public final void run(Configuration config, final Environment env) throws Exception {
        env.jersey().register(ConjureJerseyFeature.INSTANCE);
        env.jersey().register(new MyResource());
    }
}

tracing

Provides Zipkin-style call tracing libraries. All JaxRsClient and Retrofit2Client instances are instrumented by default. Jersey server instrumentation is enabled via the ConjureJerseyFeature (see above).

Please refer to tracing-java for more details on the tracing library usage.

service-config (conjure-java-runtime-api)

Provides utilities for setting up service clients from file-based configuration. Example:

# config.yml
services:
  security:
    # default truststore for all clients
    trustStorePath: path/to/trustStore.jks
  myService:  # the key used in `factory.get("myService")` below
    uris:
      - https://my-server/
    # optionally set a myService-specific truststore
    # security:
    #   trustStorePath: path/to/trustStore.jks
ServiceConfigBlock config = readFromYaml("config.yml");
ServiceConfigurationFactory factory = ServiceConfigurationFactory.of(config);
HostMetricsRegistry hostMetricsRegistry = new HostMetricsRegistry();
MyService client = JaxRsClient.create(MyService.class, UserAgents.parse("my-agent"), hostMetricsRegistry, ClientConfigurations.of(factory.get("myService")));

keystores and ssl-config (conjure-java-runtime-api)

Provides utilities for interacting with Java trust stores and key stores and acquiring SSLSocketFactory instances using those stores, as well as a configuration class for use in server configuration files.

The SslConfiguration class specifies the configuration that should be used for a particular SSLContext. The configuration is required to include information for creating a trust store and can optionally be provided with information for creating a key store (for client authentication).

The configuration consists of the following properties:

  • trustStorePath: path to a file that contains the trust store information. The format of the file is specified by the trustStoreType property.
  • trustStoreType: the type of the trust store. See section below for details. The default value is JKS.
  • (optional) keyStorePath: path to a file that contains the key store information. If unspecified, no key store will be associated with this configuration.
  • (optional) keyStorePassword: password for the key store. Will be used to read the keystore provided by keyStorePath (if relevant for the format), and will also be used as the password for the in-memory key store created by this configuration. Required if keyStorePath is specified.
  • (optional) keyStoreType: the type of the key store. See section below for details. The default value is JKS.
  • (optional) keyStoreAlias: specifies the alias of the key that should be read from the key store (relevant for file formats that contain multiple keys). If unspecified, the first key returned by the store is used.

An SslConfiguration object can be constructed using the static of() factory methods of the class, or by using the SslConfiguration.Builder builder. SslConfiguration objects can be serialized and deserialized as JSON.

Once an SslConfiguration object is obtained, it can be passed as an argument to the SslSocketFactories.createSslSocketFactory method to create an SSLSocketFactory object that can be used to configure Java SSL connections.

Store Types

The following values are supported as store types:

  • JKS: a trust store or key store in JKS format. When used as a trust store, the TrustedCertificateEntry entries are used as certificates. When used as a key store, the PrivateKeyEntry specified by the keyStoreAlias parameter (or the first such entry returned if the parameter is not specifeid) is used as the private key.
  • PEM: for trust stores, an X.509 certificate file in PEM format, or a directory of such files. For key stores, a PEM file that contains a PKCS#1 RSA private key or PKCS#8 followed by the certificates that form the trust chain for the key in PEM format, or a directory of such files. In either case, if a directory is specified, every non-hidden file in the directory must be a file of the specified format (they will all be read).
  • PKCS12: a trust store or key store in PKCS12 format. Behavior is the same as for the JKS type, but operates on stores in PKCS12 format.
  • Puppet: a directory whose content conforms to the Puppet SSLdir format. For trust stores, the certificates in the certs directory are added to the trust store. For key stores, the PEM files in the private_keys directory are added as the private keys and the corresponding files in certs are used as the trust chain for the key.

errors (conjure-java-runtime-api)

Provides utilities for relaying service errors across service boundaries (see below).

API Contract

conjure-java-runtime makes the following opinionated customizations to the standard Dropwizard/Feign/Retrofit behavior.

Object serialization/deserialization

All parameters and return values of application/json endpoints are serialized/deserialized to/from JSON using a Jackson ObjectMapper with GuavaModule, ShimJdk7Module (same as Jackson’s Jdk7Module, but avoids Jackson 2.6 requirement) and Jdk8Module. Servers must not expose parameters or return values that cannot be handled by this object mapper.

Error propagation

Servers should use the ServiceException class to propagate application-specific errors to its callers. The ServiceException class exposes standard error codes that clients can handle in a well-defined manner; further, ServiceException implements SafeLoggable and thus allows logging infrastructure to handle "unsafe" and "safe" exception parameters appropriately. Typically, services define its error types as follows:

class Errors {
  private static final ErrorType DATASET_NOT_FOUND =
    ErrorType.create(ErrorType.Code.INVALID_ARGUMENT, "MyApplication:DatasetNotFound");

  static ServiceException datasetNotFound(DatasetId datasetId, String userName) {
    // Both the safe and unsafe params will be sent back to the client; the client needs
    // to decide themselves if any of these are safe to log. We're only marking things as
    // safe or unsafe for this server to log.
    return new ServiceException(
            DATASET_NOT_FOUND, SafeArg.of("datasetId", datasetId), UnsafeArg.of("userName", userName));
  }
}

void someMethod(String datasetId, String userName) {
  if (!exists(datasetId)) {
    throw Errors.datasetNotFound(datasetId, userName);
  }
}

The ConjureJerseyFeature installs an exception mapper for ServiceException. The exception mapper sets the response media type to application/json and returns as response body a JSON representation of a SerializableError capturing the error code, error name, and error parameters. The resulting JSON response is:

{
  "errorCode": "INVALID_ARGUMENT",
  "errorName": "MyApplication:DatasetNotFound",
  "errorInstanceId": "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx",
  "parameters": {
    "datasetId": "123abc",
    "userName": "yourUserName"
  }
}

Both JaxRsClient and Retrofit2Client intercept non-successful HTTP responses and throw a RemoteException wrapping the deserialized server-side SerializableError. The error codes and names of the ServiceException and SerializableError are defined by the service API, and clients should handle errors based on the error code and name:

try {
    service.someMethod();
catch (RemoteException e) {
    if (e.getError().errorName().equals("MyApplication:DatasetNotFound")) {
        handleError(e.getError().parameters().get("datasetId"));
    } else {
        throw new RuntimeException("Failed to call someMethod()", e);
    }
}

Frontends receiving such errors should use a combination of error code, error name, and parameters to display localized, user friendly error information. For example, the above error could be surfaced as "The requested dataset with id 123abc could not be found".

To support legacy server implementations, the ConjureJerseyFeature also installs exception mappers for IllegalArgumentException, NoContentException, RuntimeException and WebApplicationException. The exceptions typically yield SerializableErrors with exceptionClass=errorCode=<exception classname> and message=errorName=<exception message>. Clients should refrain from displaying the message or errorName fields to user directly. Services should prefer to throw ServiceExceptions instead of the above, since they are easier to consume for clients and support transmitting exception parameters in a safe way.

RemoteException vs ServiceException vs SerializableError vs ErrorType
  • ErrorType is a record type, meant to be used as 'compile time constants' - essentially used by services to define the 'enum' of their service exceptions
  • SerializableError defines the wire format for serializing ServiceExceptions in HTTP response bodies and contains the error code, error instance id, and application-defined parameters
  • ServiceException is a final subclass of Exception, thrown by the server
  • RemoteException is what the client sees if a remote call results in the server internally throwing a ServiceException

The workflow is:

  • Server code throws an instance of ServiceException, containing some ErrorType
  • The com.palantir.conjure.java.server.jersey.ServiceExceptionMapper exception mapper
    • determines the response code for this service exception
    • converts this into a SerializableError
    • serializes this into the response body as JSON
  • The client sees a RemoteException, which contains the SerializableError which was sent over the wire
  • The client can inspect the SerializableError and choose to act
  • If the client is itself a server and does not handle the RemoteException, a SerializableError error will be sent as the response with and errorCode of INTERNAL, errorName of Default:Internal, the same errorInstanceId as the original RemoteException and no parameters.

Serialization of Optional and Nullable objects

@Nullable or Optional<?> fields in complex types are serialized using the standard Jackson mechanism:

  • a present value is serialized as itself (in particular, without being wrapped in a JSON object representing the Optional object)
  • an absent value is serialized as a JSON null. For example, assume a Java type of the form
public final class ComplexType {
    private final Optional<ComplexType> nested;
    private final Optional<String> string;
}

, and an instance

ComplexType value = new ComplexType(
        Optional.of(
                new ComplexType(
                        Optional.<ComplexType>absent(),
                        Optional.<String>absent(),
        Optional.of("baz"));

The JSON-serialized representation of this object is:

{"nested":{"nested":null,"string":null},"string":"baz"}

Optional return values

When a call to a service interface declaring an Optional<T> return value with media type application/json yields:

  • a Optional#empty return value, then the HTTP response has error code 204 and an empty response body.
  • a non-empty return value, then the HTTP response has error code 200 and the body carries the deserialized T object directly, rather than a deserialized Optional<T> object.

JaxRsClients intercept such responses, deserialize the T-typed return value and return it to the caller wrapped as an Optional<T>. No is no equivalent concept for Retrofit2Clients.

Call tracing

Clients and servers propagate call trace ids across JVM boundaries according to the Zipkin specification. In particular, clients insert X-B3-TraceId: <Trace ID> HTTP headers into all requests which get propagated by Jetty servers into subsequent client invocations.

Endpoints returning plain strings

Endpoints returning plain strings should produce media type text/plain. Return type Optional<String> is only supported for media type application/json.

Quality of service: retry, failover, throttling, backpressure

Flow control in Conjure is a collaborative effort between servers and clients.

Servers advertise an overloaded state using 429/503 responses, which clients interpret by throttling the number of in-flight requests they will send (currently according to an additive increase, multiplicative decrease based algorithm). Requests are retried a fixed number of times, scheduled with an exponential backoff algorithm.

Concurrency permits are only released when the response body is closed, so large streaming responses are correctly tracked.

conjure-java-runtime servers can use the QosException class to advertise the following conditions:

  • throttle: Returns a Throttle exception indicating that the calling client should throttle its requests. The client may retry against an arbitrary node of this service.
  • retryOther: Returns a RetryOther exception indicating that the calling client should retry against the given node of this service.
  • unavailable: An exception indicating that (this node of) this service is currently unavailable and the client may try again at a later time, possibly against a different node of this service.

The QosExceptions have a stable mapping to HTTP status codes and response headers:

  • throttle: 429 Too Many Requests, plus optional Retry-After header
  • retryOther: 308 Permanent Redirect, plus Location header indicating the target host
  • unavailable: 503 Unavailable

conjure-java-runtime clients (both Retrofit2 and JaxRs) handle the above error codes and take the appropriate action:

  • throttle: reschedule the request with a delay: either the indicated Retry-After period, or a configured exponential backoff
  • retryOther: retry the request against the indicated service node; all request parameters and headers are maintained
  • unavailable: retry the request on a different host after a configurable exponential delay

Additionally, connection errors (e.g., connection refused or DNS errors) yield a retry against a different node of the service. Retries pick a target host by cycling through the list of URLs configured for a Service (see ClientConfiguration#uris). Note that the "current" URL is maintained across calls; for example, if a first call yields a retryOther/308 redirect, then any subsequent calls will be made against that URL. Similarly, if the first URL yields a DNS error and the retried call succeeds against the URL from the list, then subsequent calls are made against that URL.

The number of retries for 503 and connection errors can be configured via ClientConfiguration#maxNumRetries or ServiceConfiguration#maxNumRetries, defaulting to 4.

Metrics

The HostMetricsRegistry uses HostMetrics to track per-host response metrics. HostMetrics provides the following metrics:

  • get1xx(): A timer of 1xx responses.
  • get2xx(): A timer of 2xx responses.
  • get3xx(): A timer of 3xx responses.
  • get4xx(): A timer of 4xx responses, excluding 429s.
  • get5xx(): A timer of 5xx responses, excluding 503s.
  • getQos(): A timer of 429 and 503 responses.
  • getOther(): A timer of all other responses.
  • getIoExceptions(): A timer of all failed requests.

License

This repository is made available under the Apache 2.0 License.

Comments
  • Add call tracing

    Add call tracing

    All remoting calls will now emit standard Zipkin-style tracing headers for traceId and spanId.

    Additionally, applications including the tracing library can start and stop traces inside the application using Traces.deriveTrace(String) and a completion call to emit a span Traces.complete(). (Traces must happen within a single thread, work dispatched to executors may not track correctly given current implementation details.)

    Servers can interpret, load, and will automatically continue passing the same trace identifier by installing the TraceInheritingFilter Jersey resource. Calls that did not include a trace will emit an identified trace as a result of installing the filter.

    opened by markelliot 32
  • Consider propagating certain remote exceptions

    Consider propagating certain remote exceptions

    What happened?

    Service A calls Service B which throws a 403 Unauthorized exception. Currently Service A will rethrow that a an Internal Error (see: https://github.com/palantir/conjure-java-runtime/blob/develop/conjure-java-jersey-server/src/main/java/com/palantir/conjure/java/server/jersey/RemoteExceptionMapper.java) .

    What did you want to happen?

    We started mapping RemoteExceptions to Internal Errors here: https://github.com/palantir/conjure-java-runtime/pull/801. We'd like to continue to do that, though there seems to be some class of RemoteExceptions that may be acceptable to propagate. An initial proposal would be to propagate 403s directly, rather than remapping.

    opened by ellisjoe 28
  • Retrofit can return CompletableFutures

    Retrofit can return CompletableFutures

    Remote calls are currently indistinguishable from local calls, which makes them hard to use.

    Additionally, Retrofit currently sucks to use; the Call api is hard to use and throws IOExceptions.

    This lets it return CompletableFutures, which is better than Feign and

    All of the AsyncCallTracker crap is just there to maintain backcompat; the current method used to throw a RemoteException is wholly incompatible with anything async.


    This change is Reviewable

    opened by j-baker 21
  • Decode general web exceptions

    Decode general web exceptions

    Previously, exceptions corresponding to specific HTTP error codes (e.g. BadRequestException) would be properly decoded, but more general exceptions that just hold a status value (e.g. ClientErrorException) would fail to decode.

    We now handle:

    • WebApplicationException
    • ServerErrorException
    • ClientErrorException

    Fixes #24

    opened by Cannoliopsida 20
  • [improvement] Introduce QoS propagation via disabling AutomaticRetryOnQoS

    [improvement] Introduce QoS propagation via disabling AutomaticRetryOnQoS

    Similar to #991, this PR aims to provide a way to propagate 429s and 503s to caller so they can handle the QoS exception.

    Before this PR

    A 429 always results in either a successful retry or a SafeIoException when the maximum retry count is reached. Sometimes the client does not have enough context to decide how to handle a 429 and wants to propagate the 429 to an upstream client.

    After this PR

    When ClientConfiguration.automaticRetryOnQoS is disabled, 429s and 503s are not retried. Instead, the client propagates QosException.Throttle and QosException.Unavailable (429/503) to the caller. Consumers should use this when an upstream service has better context on how to handle the QoS error. This delegates the responsibility to the upstream service, which should use an appropriate conjure client to handle the response.

    For example, let us imagine a proxy server that serves both interactive and long-running background requests by dispatching requests to some backend. Interactive requests should be retried relatively few times in comparison to background jobs which run for minutes our even hours. The proxy server should use a backend client that propagates the QoS responses instead of retrying so the proxy client can handle them appropriately. There is no risk of retry storms because the retries are isolated to one layer, the proxy client.

    Note that QosException.RetryOther (308) is not propagated. If the proxy server is exposed on the front door but the backend is not, it makes no sense to redirect the caller to a new backend. The client will still follow redirects.

    Implementation strategy

    The OkHttp layer propagates the QoS by setting the future to the response and Feign and Retrofit2 will decode the response into the appropriate QosException.

    opened by jonsyu1 18
  • [improvement] Do not retry on read timeout

    [improvement] Do not retry on read timeout

    Fixes #1084

    Before this PR

    An expensive request that always times out was retried at multiple levels of the stack, causing a retry storm.

    For example, the client makes an expensive request that goes through services A -> B -> C. A times out and retries the request 3 times. Each attempt causes B to time out and retry its request to C 3 times.

    After this PR

    ==COMMIT_MSG== Do not retry requests that time out on reading the response headers. ==COMMIT_MSG==

    Retrying on other IOExceptions is still desirable because it eventually produces a SafeIoException that results in a 500. Timeout failures are different because the caller will time out before the callee can produce a 500. We do not want to set the retry count to 0 because we still want other IOExceptions to be retried.

    Possible downsides?

    In some pathological cases, a timed out request could work the next try, but it's not worth the common case of causing retry storms.

    merge when ready 
    opened by jonsyu1 17
  • Initialize Brave Zipkin tracing for Dropwizard servers and JAX RS clients

    Initialize Brave Zipkin tracing for Dropwizard servers and JAX RS clients

    Introduces a Tracer wrapping Brave to produce Zipkin traces and spans to the "tracing" slf4j logger.

    Typically a Dropwizard server should call com.palantir.remoting1.servers.DropwizardServers#configure as part of startup initialization, which will take care of registering the Brave singleton tracer in com.palantir.remoting1.servers.Tracers#activeTracer as a Jersey server interceptor.

    JAX RS clients created via com.palantir.remoting1.jaxrs.JaxRsClient#builder(com.palantir.remoting1.clients.ClientConfig) will inherit the active tracer by default, or can provide their own via ClientConfig.

    Similarly the Tracer allows for initiating local traces with its API.

    Addresses #115

    opened by schlosna 16
  • Add metric for internal server error not caused by remote exceptions

    Add metric for internal server error not caused by remote exceptions

    ==COMMIT_MSG== Add conjure.server.exception metric for internal server errors not caused by remote exceptions ==COMMIT_MSG==

    A conjure server will return a HTTP 500 for three reasons:

    • The server threw an exception while processing the request (eg RuntimeException)
    • The server received a 500 from another server and the RemoteExceptionMapper caused it to propagate the 500
    • The server received a 400 from another server and the RemoteExceptionMapper caused it to return a 500 since it wasn't properly handled by the service

    Currently all of those events are captured in the metric for 500 responses. This PR will add a metric to only surface the first scenario (ie 500s NOT caused by RemoteExceptions). This will help owners of a service determine if 500s are due to an issue with their service or issues with a dependent service.

    For ex:

    caller/browser -> [server A] -> [server B]
    

    I would like this metric to increment when Server A throws a 500 because it has a bug, but NOT when Server A throws a 500 because it received a 500 from Server B.

    As far as the implementation, I'm open to suggestions here. I thought adding this to the ExceptionMapper classes would be most straightforward. However that required changing the ConjureJerseyFeature to be class instead of an enum, and adding a constructor that takes in a TaggedMetricRegistry. Unfortunately this breaks the public API (https://github.com/palantir/conjure-java-runtime#conjure-java-jersey-server), so if there's a less intrusive way of adding this metric, I'm happy to make changes.

    merge when ready autorelease 
    opened by parker89 14
  • Allow direct proxy configuration

    Allow direct proxy configuration

    This allows users to bypass the proxy settings set at the JVM with -Dhttps.proxyHost/-Dhttps.proxyPort. This can be useful if you are using a third-party library which needs to make proxied http calls, but the library does not allow you to set an external proxy.

    Previously okhttp would default to using a direct connection if the proxy failed, but that changed in 3.5.0 (https://github.com/square/okhttp/blob/master/CHANGELOG.md)


    This change is Reviewable

    opened by leeavital 14
  • Upgrade Feign

    Upgrade Feign

    Fixes #790 Fixes #1330 Fixes #1331

    Possible downsides?

    This upgrade causes a regression in the handling of optional<string> header parameters when the value is an empty string. Before this PR these parameters would be serialized as a present header with an empty string value. After this PR these parameters will be omitted from the request and the server will deserialize the parameter as an absent optional value.

    However, this PR does fix the incorrect handling of absent optional values (all types of optional values are affected by this bug). This tradeoff seems like a net positive, see https://github.com/palantir/conjure-java-runtime/issues/790#issuecomment-557247520. We're correcting the behavior of absent optional values of any type at the cost of empty string optional values.

    long-lived 
    opened by pkoenig10 13
  • `unknown enum constant` warning during compilation

    `unknown enum constant` warning during compilation

    When I compile a project using http-remoting1 and/or http-remoting2, this warning appears:

    warning: unknown enum constant ImplementationVisibility.PACKAGE reason: class file for org.immutables.value.Value$Style$ImplementationVisibility not found
    

    It happens when the project is not using the Immutables processor.

    This has been fixed in other projects like so: https://github.com/palantir/docker-compose-rule/issues/96

    There was also an open PR on this repo a while ago: https://github.com/palantir/http-remoting/pull/117

    Is it possible to fix this in http-remoting 1 and 2?

    opened by SerialVelocity 13
  • Excavator:  Upgrade dependencies

    Excavator: Upgrade dependencies

    excavator is a bot for automating changes across repositories.

    Changes produced by the roomba/versions-props-latest check.

    To enable or disable this check, please contact the maintainers of Excavator.

    merge when ready no changelog 
    opened by svc-excavator-bot 0
  • Migrate off JUnit 4 vintage

    Migrate off JUnit 4 vintage

    Before this PR

    JUnit 5 excavator https://github.com/palantir/conjure-java-runtime/pull/2485 is blocked due to incompatibilities with JUnit 4 vintage usage.

    After this PR

    ==COMMIT_MSG== Migrate off JUnit 4 vintage ==COMMIT_MSG==

    Possible downsides?

    merge when ready no changelog 
    opened by schlosna 2
  • Support duration based retries

    Support duration based retries

    What happened?

    Retry behavior is exposed via backoff duration and number of retries. Clients can specify waiting for up to 300ms before the first retry, up to 600ms before the next retry and so on until they run out retries.

    Clients should think about how long they're willing to try rather than how many times they are willing to try. For example, an interactive dashboards are willing to retry for up to 10 seconds whereas long-running pipelines are willing to retry up to 20 minutes. While we can approximate this behavior with the existing controls by tuning the backoff duration and retry count, we're tuning a distribution, not a specific duration. For example, the expected time spent retrying could be 20 minutes but if we're unlucky, the total time spent retrying could be less than 2 minutes. This leads to clients that are pathologically overly sensitive to 429s from the server.

    What did you want to happen?

    Support duration based retries where the client specifies how long they're willing to retry. This allows the client to express their retry contract in a consistent, easy to understand way. We still get all the benefits of employing jitter to stagger retries, but the implementation details are hidden away from the client. The client tries for 20 minutes and then gives up saying that it has tried for 20 minutes. This means a lot more than giving up saying that it has tried 10 times.

    opened by jonsyu1 0
  • Excavator:  Switch to JUnit 5 to parallelize tests and speed up CI

    Excavator: Switch to JUnit 5 to parallelize tests and speed up CI

    excavator is a bot for automating changes across repositories.

    Changes produced by the roomba/junit5 check.

    To enable or disable this check, please contact the maintainers of Excavator.

    merge when ready no changelog 
    opened by svc-excavator-bot 0
  • Excavator:  Upgrade buildscript dependencies

    Excavator: Upgrade buildscript dependencies

    excavator is a bot for automating changes across repositories.

    Changes produced by the roomba/roomba-lint check.

    To enable or disable this check, please contact the maintainers of Excavator.

    merge when ready no changelog 
    opened by svc-excavator-bot 0
  • Accept keystore password also for truststore.

    Accept keystore password also for truststore.

    What happened?

    keytool (and the JDK in general) is moving away from the proprietary JKS format and over to the wider used standardized PKCS12 format (JEP 229). The default format for keytool for example, is as of JDK 9, PKCS12 instead of JKS.

    One difference between these two formats is that PKCS12 requires password protection also for public certificates. (At least to the extent of my knowledge. I've managed to create a PKCS12 keystore programatically with an empty password, but not without a password.)

    In a JKS keystore you may have noticed that keytool -list can show public certificates, even if you just hit enter at the password prompt. As for PKCS12 keystores this is not the case.

    In our SslSocketFactories class we've hardcoded the choice to use no password at all when loading the truststore:

    https://github.com/palantir/conjure-java-runtime/blob/478f5d184e2961fa72fcef54bf24a7346f25df7b/keystores/src/main/java/com/palantir/conjure/java/config/ssl/SslSocketFactories.java#L261

    What did you want to happen?

    I would suggest we extend the SslConfiguration class which now accepts...

    • trustStorePath
    • keyStorePath
    • keyStorePassword

    ...to also include

    • trustStorePassword

    and make use of this value when loading truststore certificates in the line linked above.

    opened by aioobe 2
Releases(7.39.0)
  • 7.39.0(Oct 21, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Deprecate less secure ciphers using classic Diffie-Hellman key exchange (DHE) | https://github.com/palantir/conjure-java-runtime/pull/2482 |

    Source code(tar.gz)
    Source code(zip)
  • 7.38.0(Aug 24, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Add @ForbidJavax Annotation | https://github.com/palantir/conjure-java-runtime/pull/2442 |

    Source code(tar.gz)
    Source code(zip)
  • 7.37.0(Aug 17, 2022)

  • 7.36.0(Aug 15, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Add conjure-java-jersey-jakarta-server | https://github.com/palantir/conjure-java-runtime/pull/2440 |

    Source code(tar.gz)
    Source code(zip)
  • 7.35.0(Aug 11, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | CompatibleJaxRsContract exceptions retain causal exception | https://github.com/palantir/conjure-java-runtime/pull/2437 |

    Source code(tar.gz)
    Source code(zip)
  • 7.34.0(Aug 9, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | conjure-java-jaxrs-client supports javax and jakarta annotations | https://github.com/palantir/conjure-java-runtime/pull/2436 |

    Source code(tar.gz)
    Source code(zip)
  • 7.33.0(Apr 1, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Fail if annotated server resource is used as a client | https://github.com/palantir/conjure-java-runtime/pull/2324 |

    Source code(tar.gz)
    Source code(zip)
  • 7.32.0(Mar 31, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Add marker annotations to indicate JaxRs client or service usage | https://github.com/palantir/conjure-java-runtime/pull/2320 |

    Source code(tar.gz)
    Source code(zip)
  • 7.31.0(Mar 29, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | WebApplicationExceptionMapper treats redirection as informational | https://github.com/palantir/conjure-java-runtime/pull/2316 |

    Source code(tar.gz)
    Source code(zip)
  • 7.30.0(Mar 22, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Metrics to determine when a feign client dangerously buffers data | https://github.com/palantir/conjure-java-runtime/pull/2304 |

    Source code(tar.gz)
    Source code(zip)
  • 7.29.0(Feb 25, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Expose deprecated cipher info | https://github.com/palantir/conjure-java-runtime/pull/2272 |

    Source code(tar.gz)
    Source code(zip)
  • 7.28.0(Feb 24, 2022)

  • 7.27.0(Feb 23, 2022)

  • 7.26.0(Feb 23, 2022)

  • 7.25.0(Feb 17, 2022)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Expand the supported cipher suite list to include TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 | https://github.com/palantir/conjure-java-runtime/pull/2258 |

    Source code(tar.gz)
    Source code(zip)
  • 7.24.0(Jan 19, 2022)

  • 7.23.0(Jan 19, 2022)

  • 7.22.0(Dec 9, 2021)

  • 7.21.0(Dec 3, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Exception mappers interpolate the errorInstanceId and errorName parameters | https://github.com/palantir/conjure-java-runtime/pull/2186 |

    Source code(tar.gz)
    Source code(zip)
  • 7.20.0(Nov 17, 2021)

  • 7.19.0(Nov 15, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Implement SOCKS proxy support | https://github.com/palantir/conjure-java-runtime/pull/2126 |

    Source code(tar.gz)
    Source code(zip)
  • 7.18.0(Nov 11, 2021)

  • 7.17.0(Nov 4, 2021)

  • 7.16.0(Oct 21, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Opt out of invasive object-mapper optimizations by default in jdk16+ | https://github.com/palantir/conjure-java-runtime/pull/2137 |

    Source code(tar.gz)
    Source code(zip)
  • 7.15.0(Oct 18, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | Smile encoding now uses the raw binary format. | https://github.com/palantir/conjure-java-runtime/pull/2134 |

    Source code(tar.gz)
    Source code(zip)
  • 7.14.0(Sep 22, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Fix | JaxRsClient.create methods produce clients with reasonable equals | https://github.com/palantir/conjure-java-runtime/pull/2115 |

    Source code(tar.gz)
    Source code(zip)
  • 7.13.0(Sep 14, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | CJR CipherSuites list is more restrictive, avoiding less secure ciphers | https://github.com/palantir/conjure-java-runtime/pull/2104 |

    Source code(tar.gz)
    Source code(zip)
  • 7.12.0(Sep 10, 2021)

    | Type | Description | Link | | ---- | ----------- | ---- | | Improvement | DialogueFeignClient Endpoint implements modern renderPath | https://github.com/palantir/conjure-java-runtime/pull/2100 |

    Source code(tar.gz)
    Source code(zip)
  • 7.11.0(Jul 26, 2021)

  • 7.10.0(Jul 14, 2021)

Owner
Palantir Technologies
Palantir Technologies
LINE 4.1k Jan 2, 2023
Apache Dubbo is a high-performance, java based, open source RPC framework.

Apache Dubbo Project Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit official site for quick start and document

The Apache Software Foundation 38.3k Jan 9, 2023
A simple rpc framework.

werpc 微RPC 介绍 A simple rpc framework —— werpc. RPC(Remote Procedure Call):远程过程调用,像调用本地方法一样调用远程过程。采用Client-Server结构,通过request-response消息模式实现。 RPC框架就是指封

stubbornwdb 29 Dec 5, 2022
Java client for Consul HTTP API

consul-api Java client for Consul HTTP API (http://consul.io) Supports all API endpoints (http://www.consul.io/docs/agent/http.html), all consistency

Ecwid 402 Jan 6, 2023
Library which allows the use and rendering of Blockbench models and animations in a Minecraft server by using generated resource packs and armorstands

Hephaestus Engine Hephaestus Engine is a library which allows the visualization of block bench models and animations in a Minecraft server by the use

Unnamed Team 109 Dec 21, 2022
Annotation/Reflection Based Bukkit Command API. Containing many features such as help-service, command providers, tab completion, and many more!

CommandAPI Annotation/Reflection Based Command API that just does what you want it to do without any problems. Importing Maven <repository> <id>

damt 1 Jun 13, 2022
Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

AOL 936 Dec 19, 2022
Takin is an Java-based, open-source system designed to measure online or test environmental performance test for full-links, Especially for microservices

Takin is an Java-based, open-source system designed to measure online environmental performance test for full-links, Especially for microservices. Through Takin, middlewares and applications can identify real online traffic and test traffic, ensure that they enter the right databases.

ShulieTech 1.2k Dec 21, 2022
Sample application demonstrating an order fulfillment system decomposed into multiple independant components (e.g. microservices). Showing concrete implementation alternatives using e.g. Java, Spring Boot, Apache Kafka, Camunda, Zeebe, ...

Sample application demonstrating an order fulfillment system decomposed into multiple independant components (e.g. microservices). Showing concrete implementation alternatives using e.g. Java, Spring Boot, Apache Kafka, Camunda, Zeebe, ...

Bernd Ruecker 1.2k Dec 14, 2022
AWS Service registry for resilient mid-tier load balancing and failover.

Eureka Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose

Netflix, Inc. 11.6k Dec 30, 2022
A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)

Sentinel: The Sentinel of Your Microservices Introduction As distributed systems become increasingly popular, the reliability between services is beco

Alibaba 20.4k Dec 31, 2022
ColocationSim: Simulate Colocation Datacenter in a Fine Granularity with Microservices and Interference Modeling

ColocationSim Introduction 将在线作业和离线作业混合部署在同一集群(简称混部,Colocation)提升数据中心资源利用率的主流方法,如何在保证在线作业性能的前提下最大化集群的资源利用率成为混部相关研究中最主要问题。混部作业调度算法从集群层面解决这一问题,是学术界、企业界的

null 93 Jan 4, 2023
Govern Service is a lightweight, low-cost service registration, service discovery, and configuration service SDK.

Govern Service is a lightweight, low-cost service registration, service discovery, and configuration service SDK. By using Redis in the existing infrastructure (I believe you have already deployed Redis), it doesn’t need to bring extra to the operation and maintenance deployment. Cost and burden. With the high performance of Redis, Govern Service provides ultra-high TPS&QPS (10W+/s JMH Benchmark).

Ahoo Wang 61 Nov 22, 2022
CoSky is a lightweight, low-cost service registration, service discovery, and configuration service SDK.

High-performance, low-cost microservice governance platform. Service Discovery and Configuration Service

Ahoo Wang 61 Nov 22, 2022
Source Code for 'Pro Java Microservices with Quarkus and Kubernetes' by Nebrass Lamouchi

Apress Source Code This repository accompanies Pro Java Microservices with Quarkus and Kubernetes by Nebrass Lamouchi (Apress, 2021). Download the fil

Apress 24 Oct 31, 2022
Eclipse Jetty® - Web Container & Clients - supports HTTP/2, HTTP/1.1, HTTP/1.0, websocket, servlets, and more

Eclipse Jetty Canonical Repository This is the canonical repository for the Jetty project, feel free to fork and contribute now! Submitting a patch or

Eclipse Foundation 3.5k Dec 28, 2022
Feign makes writing java http clients easier

Feign makes writing java http clients easier Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign's first goal

null 8.5k Dec 30, 2022
Feign makes writing java http clients easier

Feign makes writing java http clients easier Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign's first goal

null 8.5k Jan 1, 2023
Feign makes writing java http clients easier

Feign makes writing java http clients easier Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign's first goal

null 8.5k Jan 2, 2023
Feign makes writing java http clients easier

Feign makes writing java http clients easier Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign's first goal

null 6.8k Mar 13, 2021