#  Scorpio NGSI-LD Broker

[![FIWARE Core](https://nexus.lab.fiware.org/static/badges/chapters/core.svg)](https://www.fiware.org/developers/catalogue/)
[![License: BSD-3-Clause](https://img.shields.io/badge/license-BSD%203%20Clause-blue.svg)](https://spdx.org/licenses/BSD-3-Clause.html)
[![fiware](https://nexus.lab.fiware.org/repository/raw/public/badges/stackoverflow/fiware.svg)](https://stackoverflow.com/questions/tagged/fiware)
![NGSI-LD badge](https://img.shields.io/badge/NGSI-LD-red.svg)

[![Quay badge](https://img.shields.io/badge/quay.io-fiware%2Fscorpio-grey?logo=red%20hat&labelColor=EE0000)](https://quay.io/repository/fiware/scorpio)
[![Docker badge](https://img.shields.io/badge/docker-scorpiobroker%2Fall--in--one--runner-blue?logo=docker)](https://hub.docker.com/r/scorpiobroker/all-in-one-runner)

[![Documentation badge](https://img.shields.io/readthedocs/scorpio.svg)](https://scorpio.readthedocs.io/en/latest/?badge=latest)
![Status](https://nexus.lab.fiware.org/static/badges/statuses/full.svg)
![NGSI-LD Test Suite Java](https://github.com/scorpiobroker/scorpiobroker/actions/workflows/api-test.yml/badge.svg)
![NGSI-LD Test Suite Ubuntu](https://github.com/scorpiobroker/scorpiobroker/actions/workflows/api-test-ubuntu.yml/badge.svg)
![PMD](https://github.com/scorpiobroker/scorpiobroker/actions/workflows/pmd.yml/badge.svg)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4781/badge)](https://bestpractices.coreinfrastructure.org/projects/4781)

Hello there!

Welcome to the Scorpio NGSI-LD Broker.
You are currently in the Scorpios main branch.

To get you quickly started you can just choose on of the provided docker-compose files and start it up.
 - [java based all-in-one runner](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-java-aaio-kafka.yml)
 - [java based all-in-one runner without kafka integration, no scaling but less resource requirements](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-java-aaio.yml)
 - [java based distributed microservices](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-java-dist-kafka.yml)
 - [ubuntu native all-in-one runner](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-ubuntu-aaio-kafka.yml)
 - [ubuntu native all-in-one runner without kafka integration, no scaling but less resource requirements](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-ubuntu-aaio.yml)
 - [ubuntu native distributed microservices](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/compose-files/docker-compose-ubuntu-dist-kafka.yml)

If you have a local PostgreSQL (and Kafka) setup you can also download pre builds for Ubuntu, Windows and MacOS from the [releases](https://github.com/ScorpioBroker/ScorpioBroker/releases)

To get a good collection of NGSI-LD operations and examples we recommend to have a look at our [test suite](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/api-test.json).
It is Postman based and you can just import it together with the respective environment settings [all-in-one](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/api-test-aaio-environment.json) or [distributed](https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/development-quarkus/api-test-dist-environment.json)

We also provide all docker images on the [Amazon Public ECR](https://gallery.ecr.aws/scorpiobroker?page=1)

Scorpio is an NGSI-LD compliant context broker developed by NEC Laboratories Europe and NEC Technologies India. It implements the full [NGSI-LD API](https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.02.02_60/gs_CIM009v010202p.pdf) as specified by the ETSI Industry Specification Group on cross cutting Context Information Management ([ETSI ISG CIM](https://www.etsi.org/committee/cim)).

The NGSI-LD API enables the management, access and discovery of context information. Context information consists of *entities* (e.g. a building) and their *properties* (e.g. address and geographic location) and *relationships* (e.g. owner). Thus Scorpio enables applications and services to request context information – what they need, when they need it and how they need it.

The functionalities of the NGSI-LD API include:
- Create, update, append and delete context infomration.
- Query context information, including filtering, geographic scoping and paging.
- Subscribe to changes in context information and receive asynchronous notifications.
- Register and discover sources of context information, which allows building distributed and federated deployments.

Scorpio is a FIWARE Generic Enabler. Therefore, it can be integrated as part of any platform “Powered by FIWARE”. FIWARE is a curated framework of open source platform components which can be assembled together with other third-party platform components to accelerate the development of Smart Solutions. The roadmap of this FIWARE GE is described [here](./docs/roadmap.md).

You can find more info at the [FIWARE developers](https://developers.fiware.org/) website and the [FIWARE](https://fiware.org/) website.
The complete list of FIWARE GEs and Incubated FIWARE GEs can be found in the [FIWARE Catalogue](https://catalogue.fiware.org/).

| :books: [Documentation](https://scorpio.rtfd.io/) | :mortar_board: [Academy](https://fiware-academy.readthedocs.io/en/latest/core/scorpio) |  [quay.io](https://quay.io/repository/fiware/scorpio) | :whale: [Docker Hub](https://hub.docker.com/r/scorpiobroker) | :dart: [Roadmap](./docs/roadmap.md) |
| ------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | --- |

## Content

-   [Background](#background)
-   [Installation](#installation-and-building)
-   [Usage](#usage)
-   [API Walkthrough](#api-walkthrough)
-   [Tests](#tests)
-   [Further Resources](#further-resources)
-   [Credit where credit is due](#credit-where-credit-is-due)
-   [Code of conduct](#code-of-conduct)
-   [License](#license)

## Background

Scorpio is an NGSI-LD Broker that allows managing and requesting context information. It supports the following functionalities:
- Context Producers can manage their context – creating, updating, appending and deleting context information.
- Context Consumers can request the context information they require, either identifying the entity or discover relevant entities by providing the entity type, possibly filtering according to property value, existing relationship and/or geographic scope provided as a GeoJSON feature.
- Two interaction styles are supported, a synchronous query-response, and an asynchronous subscribe / notify, where notifications can be based on a change in property or relationship, or on a fixed time interval.
-  Scorpio implements NGSI-LD’s optional temporal interface for requesting historic information, e.g. the property values measured within a specified time interval.
- Scorpio supports multiple deployment configurations including centralized, distributed and federated ones. In addition to the Context Producers mentioned above, there can be Context Sources that themselves implement the NGSI-LD interface. These Context Sources can register themselves with the information they can provide on request (not the information (values) itself). A Scorpio Broker in a distributed setting can then discover the Context Sources that may have information for answering a request based on their registrations, request and aggregate the information from different Context Sources and provide it to the requesting Context Consumer.
- In a federated setting the Context Source can itself be an NGSI-LD Broker. Federations can be used to combine information from multiple providers that want to (partially) share information. An important difference is then typically in the granularity of the registration, e.g. “I have information about entities of entity type building within a geographic area”, instead of “I have information about Building A”
- Scorpio supports all the mentioned deployment configurations. Thus it provides scalability and the possibility of extending scenarios in an evolutionary way. For example two separate deployments can be combined or for scalability reasons different brokers can be used – completely transparent to Context Consumers that can still use a single point of access.

## Installation and Building

Scorpio is developed in Java using Quarkus as microservice framework and Apache Maven as build tool. It requires Apache Kafka as a message bus and Postgres with PostGIS extensions as database.

The easiest way to get Scorpio running is using docker-compose. Please have a look [here](./compose-files) for examples.

## Configuration

Scorpio can be configured via environment variables. Please have a look [here](./AllInOneRunner/src/main/resources/application.properties) for a full list of config options.
To configure via environment variable provide the config option in all capital letters and replace the dot with an underscore. So e.g. quarkus.http.port becomes QUARKUS_HTTP_PORT.

The most common parameters are the following.
#The port for the HTTP API
quarkus.http.port=9090
#The PostgreSQL related settings
dbhost=localhost
dbport=5432
dbuser=ngb
dbpass=ngb
dbname=ngb (This is the name of the default database. Tenant databases will be prefixed with this setting.)
#Kafka related settings
bushost=localhost
busport=9092
#Settings used by the auto registry and federation feature. This should be the public reachable name or IP of the Scorpio installation.
gateway.host=localhost
gateway.port=9090

## Usage

By default the broker runs on port 9090 the base URL for interaction with the broker would be than
http://localhost:9090/ngsi-ld/v1/

### Simple Example

Generally speaking you can Create entities by sending an HTTP POST request to http://localhost:9090/ngsi-ld/v1/entities/
with a payload like this

```json
{
    "id": "urn:ngsi-ld:testunit:123",
    "type": "AirQualityObserved",
    "dateObserved": {
        "type": "Property",
        "value": {
            "@type": "DateTime",
            "@value": "2018-08-07T12:00:00Z"
        }
    },
    "NO2": {
        "type": "Property",
        "value": 22,
        "unitCode": "GP",
        "accuracy": {
            "type": "Property",
            "value": 0.95
        }
    },
    "refPointOfInterest": {
        "type": "Relationship",
        "object": "urn:ngsi-ld:PointOfInterest:RZ:MainSquare"
    },
    "@context": [
        "https://schema.lab.fiware.org/ld/context",
        "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld"
    ]
}
```

In the given example the `@context` is in the payload therefore you have to set the `ContentType` header to
`application/ld+json`

To receive entities you can send an HTTP GET to

`http://localhost:9090/ngsi-ld/v1/entities/<entityId>`

or run a query by sending a GET like this

```text
http://localhost:9090/ngsi-ld/v1/entities/?type=Vehicle&limit=2
Accept: application/ld+json
Link: <http://<HOSTNAME_OF_WHERE_YOU_HAVE_AN_ATCONTEXT>/aggregatedContext.jsonld>; rel="http://www.w3.org/ns/json-ld#context";type="application/ld+json"
```

## API Walkthrough

More detailed examples of what you can do with the NGSI-LD API provided by Scorpio can be found in the [API Walkthrough](./docs/en/source/API_walkthrough.rst).

## Tests
Scorpio has two sets of tests. We use JUnit for unit tests and the FIWARE NGSI-LD Testsuite, which is npm test based, for system tests.
Further details about testing can be found in the [Testing Guide](./docs/en/source/testing.rst).

## Further resources

For more detailed explaination on NGSI-LD or JSON-LD. Please look at the
-  [ETSI Specification](https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.02.02_60/gs_CIM009v010202p.pdf)
-  [ETSI Primer](https://www.etsi.org/deliver/etsi_gr/CIM/001_099/008/01.01.01_60/gr_CIM008v010101p.pdf)
-  [JSON-LD website](https://json-ld.org/)
-  [Scorpio in FIWARE Academy](https://fiware-academy.readthedocs.io/en/latest/core/scorpio/index.html)
  -  [FIWARE 601: Introduction to Linked Data](https://fiware-tutorials.readthedocs.io/en/latest/linked-data)
  -  [FIWARE 602: Linked Data Relationships and Data Models](https://fiware-tutorials.readthedocs.io/en/latest/relationships-linked-data)

-  [FIWARE global summit: The Scorpio NGSI-LD Broker. Features and supported architectures](https://www.slideshare.net/FI-WARE/fiware-global-summit-the-scorpio-ngsild-broker-features-and-supported-architectures)
-  [FIWARE global summit: NGSI-LD. An evolution from NGSI V2](https://www.slideshare.net/FI-WARE/fiware-global-summit-ngsild-an-evolution-from-ngsiv2)

You can find a set of example calls, as a Postman collection, in the Examples folder. These examples use 2 Variables

- gatewayServer, which has to be `<brokerIP>:<brokerPort>`. When using default settings locally it would be localhost:9090
- link, which is for the examples providing @context via the Link header. For the examples we host an example @context. Set link to https://raw.githubusercontent.com/ScorpioBroker/ScorpioBroker/master/Examples/index.json

## Acknowledgements

### EU Acknowledgetment
This activity has received funding from the European Union’s Horizon 2020 research and innovation programme under Grant Agreement No. 2020-EU-IA-0274 (SALTED), No. INEA/CEF/ICT/A2019/2063604 (ODALA), No. 731993 (Autopilot), No. 814918 (Fed4IoT) and No. 767498 (MIDIH, Open Call (MoLe).

- [ODALA project](https://odalaproject.eu/)
- [SALTED project](https://salted-project.eu/)
- [AUTOPILOT project: Automated driving Progressed by Internet Of Things](https://autopilot-project.eu/)
- [Fed4IoT project](https://fed4iot.org/)
- [MIDIH Project](https://midih.eu/), Open Call (MoLe)

## Credit where credit is due
We like to thank everyone who has contributed to Scorpio. This goes for the entire Scorpio Devlopment Team as well as all external contributor.
For a complete list have a look at the [CREDITS](./CREDITS) file.

## Code of conduct
As part of the FIWARE Community we try our best to adhere to the [FIWARE Code of Conduct](https://www.fiware.org/foundation/code-of-conduct/) and expect the same from contributors.

This includes pull requests, issues, comments, code and in code comments.

As owner of this repo we limit communication here purely to Scorpio and NGSI-LD related topics.

We are all humans coming from different cultural backgrounds. We all have our different quirks, habits and mannerisms. Therefor misunderstandings can happen. We will give everyone the benefit of doubt that communication is done with good intentions in mind trying to advance Scorpio and NGSI-LD. We expect the same from contributors.
However if someone is repeatedly trying to provoke, attack a person, shift discussions or ridicule someone we WILL make use of our house right and put an end to this.

If there is a dispute to be resolved we as owners of this repo have the final word.
## License

Scorpio is licensed under [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html).
For contributions this [contribution license](CONTRIBUTING.md) applies.

© 2021 NEC


[![FINOS - Incubating](https://cdn.jsdelivr.net/gh/finos/contrib-toolbox@master/images/badge-incubating.svg)](https://finosfoundation.atlassian.net/wiki/display/FINOS/Incubating)
[![Maven Central](https://img.shields.io/maven-central/v/org.finos.legend.pure/legend-pure-ide-light.svg)](https://central.sonatype.com/namespace/org.finos.legend.pure)
![Build CI](https://github.com/finos/legend-pure/workflows/Build%20CI/badge.svg)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=legend-pure&metric=security_rating&token=69394360757d5e1356312ddfee658a6b205e2c97)](https://sonarcloud.io/dashboard?id=legend-pure)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=legend-pure&metric=bugs&token=69394360757d5e1356312ddfee658a6b205e2c97)](https://sonarcloud.io/dashboard?id=legend-pure)

# legend-pure

Underlying language for Legend

## Development setup

This application uses Maven 3.6+ and JDK 11. Simply run `mvn install` to compile.

## Roadmap

Visit our [roadmap](https://github.com/finos/legend#roadmap) to know more about the upcoming features.

## Contributing

Visit Legend [Contribution Guide](https://github.com/finos/legend/blob/master/CONTRIBUTING.md) to learn how to contribute to Legend.

## License

Copyright 2020 Goldman Sachs

Distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).

SPDX-License-Identifier: [Apache-2.0](https://spdx.org/licenses/Apache-2.0)


# Micronaut Micrometer

[![Maven Central](https://img.shields.io/maven-central/v/io.micronaut.micrometer/micronaut-micrometer-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.micronaut.micrometer%22%20AND%20a:%22micronaut-micrometer-core%22)
[![Build Status](https://github.com/micronaut-projects/micronaut-micrometer/workflows/Java%20CI/badge.svg)](https://github.com/micronaut-projects/micronaut-micrometer/actions)
[![Revved up by Develocity](https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.micronaut.io/scans)

This project includes integration between [Micronaut](http://micronaut.io) and [Micrometer](https://micrometer.io).

## Documentation

See the [Documentation](https://micronaut-projects.github.io/micronaut-micrometer/latest/guide) for more information.

## Snapshots and Releases

Snaphots are automatically published to [JFrog OSS](https://oss.jfrog.org/artifactory/oss-snapshot-local/) using [Github Actions](https://github.com/micronaut-projects/micronaut-micrometer/actions).

See the documentation in the [Micronaut Docs](https://docs.micronaut.io/latest/guide/index.html#usingsnapshots) for how to configure your build to use snapshots.

Releases are published to JCenter and Maven Central via [Github Actions](https://github.com/micronaut-projects/micronaut-micrometer/actions).

A release is performed with the following steps:

- [Edit the version](https://github.com/micronaut-projects/micronaut-micrometer/edit/master/gradle.properties) specified by `projectVersion` in `gradle.properties` to a semantic, unreleased version. Example `1.0.0`
- [Create a new release](https://github.com/micronaut-projects/micronaut-micrometer/releases/new). The Git Tag should start with `v`. For example `v1.0.0`.
- [Monitor the Workflow](https://github.com/micronaut-projects/micronaut-micrometer/actions?query=workflow%3ARelease) to check it passed successfully.
- Celebrate!


### This is the Java version of Prebid Server. See the Prebid Server [Feature List](https://docs.prebid.org/prebid-server/features/pbs-feature-idx.html) and [FAQ entry](https://docs.prebid.org/faq/prebid-server-faq.html#why-are-there-two-versions-of-prebid-server-are-they-kept-in-sync) to understand the differences between PBS-Java and [PBS-Go](https://github.com/prebid/prebid-server).

# Prebid Server (Java)

[![GitHub version](https://badge.fury.io/gh/prebid%2fprebid-server-java.svg)](http://badge.fury.io/gh/prebid%2fprebid-server-java)
[![GitHub contributors](https://img.shields.io/github/contributors/prebid/prebid-server-java.svg)](https://GitHub.com/prebid/prebid-server-java/contributors/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/prebid/prebid-server-java/blob/master/docs/contributing.md)
[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/prebid/prebid-server-java.svg)](https://GitHub.com/prebid/prebid-server-java/pull/)

Prebid Server is an open source implementation of Server-Side Header Bidding.
It is managed by Prebid.org,
and upholds the principles from the [Prebid Code of Conduct](https://prebid.org/wrapper_code_of_conduct.html).

This project does not support the same set of Bidders as Prebid.js, although there is overlap.
The current set can be found in the [adapters](./src/main/java/org/prebid/server/bidder) package. If you don't see the one you want, feel free to [contribute it](docs/developers/add-new-bidder.md).

For more information, see:

- [What is Prebid?](https://prebid.org/why-prebid/)
- [Getting started with Prebid Server](https://docs.prebid.org/prebid-server/overview/prebid-server-overview.html)
- [Current Bidders](https://docs.prebid.org/dev-docs/pbs-bidders.html)

Please consider [registering your Prebid Server](https://docs.prebid.org/prebid-server/hosting/pbs-hosting.html#optional-registration) to get on the mailing list for updates, etc.

# Getting Started

The server makes the following assumptions:
- No ranking or decisioning is performed by this server. It just proxies requests.
- No ad quality management (e.g., malware, viruses, deceptive creatives) is performed by this server.
- This server does no fraud scanning and does nothing to prevent bad traffic.
- This server logs errors but not requests.
- This server has no user profiling or user data collection capabilities.

This project is built upon [Vert.x](http://vertx.io) to achieve high request throughput.
We use [Maven](https://maven.apache.org) and attempt to introduce minimal dependencies.

When running, the server responds to several HTTP [endpoints](docs/endpoints).

## Building

Follow next steps to create JAR file which can be deployed locally.

- Install prerequsites
  - Java SDK: Oracle's or Corretto. Let us know if there's a distribution PBS-Java doesn't work with.
  - Maven

- Clone the project:
```bash
git clone https://github.com/prebid/prebid-server-java.git
```

- Move to project directory:
```bash
cd prebid-server-java
```

And from this step there are two common use cases, which can be chosen depending on your goals

1. Create prebid-server JAR only

- First, make sure nothing's running on your local port 8080 or 8090
- Run below command to build project:
```bash
mvn clean package
```

2. Create prebid-server JAR with modules
- Run below command to build project:
```bash
mvn clean package --file extra/pom.xml
```
For more information how to build the server follow [documentation](docs/build.md).

## Configuration

The source code includes an example configuration file `sample/prebid-config.yaml`.
Also, check the account settings file `sample/sample-app-settings.yaml`.

For more information how to configure the server follow [documentation](docs/config.md). There are many settings you'll want to consider such as which bidders you're going to enable, privacy defaults, admin endpoints, etc.

## Running

Run your local server with the command:
```bash
java -jar target/prebid-server.jar --spring.config.additional-location=sample/prebid-config.yaml
```
For more options how to start the server, please follow [documentation](docs/run.md).

## Running prebuilt .jar
Starting from PBS Java v2.9, you can download prebuilt .jar packages from [Release Notes](https://github.com/prebid/prebid-server-java/releases) page, instead of building them by yourself.
This prebuilt packages are delivered with or without extra modules.

## Verifying

To check the server is started go to [http://localhost:8080/status](http://localhost:8080/status)
and verify response status is `200 OK`.

There are a couple of 'hello world' test requests described in sample/requests/README.txt

## Running Docker image

Starting from PBS Java v2.9, you can download prebuilt Docker images from [GitHub Packages](https://github.com/orgs/prebid/packages?repo_name=prebid-server-java) page,
and use them instead of plain .jar files. This prebuilt images are delivered with or without extra modules.

In order to run such image correctly, you should attach PBS config file. Easiest way is to mount config file into container,
using [--mount or --volume (-v) Docker CLI arguments](https://docs.docker.com/engine/reference/commandline/run/).
Keep in mind, that config file should be mounted into specific location: ```/app/prebid-server/``` or ```/app/prebid-server/conf/```.

# Documentation

## Development
- [Endpoints](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html)
- [Adding new bidder](https://docs.prebid.org/prebid-server/developers/add-new-bidder-java.html)
- [Adding new analytics module](https://docs.prebid.org/prebid-server/developers/pbs-build-an-analytics-adapter.html#adding-an-analytics-adapter-in-pbs-java)
- [Adding viewability support](docs/developers/add-viewability-vendors.md)
- [Auction result post-processing](docs/auction-result-post-processing.md)
- [Cookie Syncs](https://docs.prebid.org/prebid-server/developers/pbs-cookie-sync.html)
- [Stored Requests](docs/developers/stored-requests.md)
- [Unit Tests](docs/developers/unit-tests.md)
- [Functional Tests](docs/developers/functional-tests.md)
- [GDPR](docs/gdpr.md)

## Maintenance
- [Build for local](docs/build.md)
- [Build for AWS](docs/build-aws.md)
- [Configure application](docs/config.md)
  - [Full list of configuration options](docs/config-app.md)
  - [Application settings](docs/application-settings.md)
- [Run with optimizations](docs/run.md)
- [Metrics](docs/metrics.md)

## Contributing
- [Contributing](docs/developers/contributing.md)
- [Code Style](docs/developers/code-style.md)
- [Code Review](docs/developers/code-reviews.md)
- [Versioning](docs/developers/versioning.md)


![Iterable logo](https://raw.githubusercontent.com/Iterable/iterable-android-sdk/master/images/Iterable-Logo.png "Iterable Logo")

[![License](https://img.shields.io/github/license/iterable/iterable-android-sdk)](https://opensource.org/licenses/MIT)
[![Build Status](https://travis-ci.org/Iterable/iterable-android-sdk.svg?branch=master)](https://travis-ci.org/Iterable/iterable-android-sdk)
[![codecov](https://codecov.io/gh/Iterable/iterable-android-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/Iterable/iterable-android-sdk)

# Iterable's Android SDK

[Iterable](https://www.iterable.com) is a growth marketing platform that helps
you to create better experiences for—and deeper relationships with—your
customers. Use it to send customized email, SMS, push notification, in-app
message and web push notifications to your customers.

This SDK helps you integrate your Android apps with Iterable.

## Supported Android versions

Iterable's Android SDK supports Android versions 4.1.2 (API level 16) and higher.

## Installation

For installation instructions, read [Iterable's Android SDK](https://support.iterable.com/hc/articles/360035019712).

## Features

To learn more about various SDK features, read:

- [Identifying the User](https://support.iterable.com/hc/articles/360035402531)
- [Updating User Profiles](https://support.iterable.com/hc/articles/360035402611)
- [Tracking Events](https://support.iterable.com/hc/articles/360035395671)
- [Setting up Android Push Notifications](https://support.iterable.com/hc/articles/115000331943)
- [In-App Messages on Android](https://support.iterable.com/hc/articles/360035537231)
- [Setting up Mobile Inbox on Android](https://support.iterable.com/hc/articles/360038744152)
- [Customizing Mobile Inbox on Android](https://support.iterable.com/hc/articles/360039189931)
- [Android App Links](https://support.iterable.com/hc/articles/360035127392)
- [Deep Links in Push Notifications](https://support.iterable.com/hc/articles/360035453971)
- [Embedded Messages with Iterable's Android SDK](https://support.iterable.com/hc/articles/23061877893652)

## Sample projects

For sample code, take a look at:

- [Inbox Customization](https://github.com/Iterable/iterable-android-sdk/tree/master/sample-apps/inbox-customization)

## Release notes, support and troubleshooting

Release notes:

- [Release Notes - Iterable's Android SDK](https://support.iterable.com/hc/articles/360027543332) -
  Release notes for significant updates to the SDK. Also, information about
  deprecation dates and support windows.
- [GitHub — Releases](https://github.com/Iterable/iterable-android-sdk/releases) -
  This repository's **Releases** page. Release notes for all versions of the SDK.

Support policies:

- Iterable's [SDK Support Policy](https://support.iterable.com/hc/articles/360046136171)
- Iterable's [Beta SDK Disclaimer](https://support.iterable.com/hc/articles/360034753412)

Troubleshooting:

- [Testing and Troubleshooting Iterable's Mobile SDKs](https://support.iterable.com/hc/articles/360035392251)
- [Frequently Asked Questions](https://support.iterable.com/hc/articles/360035624191)
  for mobile developers integrating with Iterable

Questions? Contact your Iterable customer success manager.

## License

This SDK is released under the MIT License. For more information, read [LICENSE](LICENSE.md).

## Want to contribute?

This library is open source, and we will look at issue reports and pull requests.
For more information, read [CONTRIBUTING](CONTRIBUTING.md).


# Microsoft Graph Core SDK for Java

[![Download](https://img.shields.io/maven-central/v/com.microsoft.graph/microsoft-graph-core.svg)](https://search.maven.org/artifact/com.microsoft.graph/microsoft-graph-core) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=microsoftgraph_msgraph-sdk-java-core&metric=coverage)](https://sonarcloud.io/dashboard?id=microsoftgraph_msgraph-sdk-java-core) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=microsoftgraph_msgraph-sdk-java-core&metric=alert_status)](https://sonarcloud.io/dashboard?id=microsoftgraph_msgraph-sdk-java-core)

Get started with the Microsoft Graph Core SDK for Java by integrating the [Microsoft Graph API](https://developer.microsoft.com/en-us/graph/get-started/java) into your Java and Android application! You can also have a look at the [Javadoc](https://docs.microsoft.com/en-us/java/api/com.microsoft.graph.httpcore?view=graph-core-java)

## Samples and usage guide

- [Middleware usage](https://github.com/microsoftgraph/msgraph-sdk-design/)
- [Batching](https://docs.microsoft.com/en-us/graph/sdks/batch-requests?tabs=java)

## 1. Installation

### 1.1 Install via Gradle

Add the repository and a compile dependency for `microsoft-graph-core` to your project's `build.gradle`:

```groovy
repositories {
    mavenCentral()
}

dependencies {
    // Include the sdk as a dependency
    // x-release-please-start-version
    implementation 'com.microsoft.graph:microsoft-graph-core:3.1.14'
    // x-release-please-end
    // This dependency is only needed if you are using the TokenCredentialAuthProvider
    implementation 'com.azure:azure-identity:1.11.0'
}
```

### 1.2 Install via Maven

Add the dependency in `dependencies` in pom.xml

```xml
<dependency>
    <!-- Include the sdk as a dependency -->
    <groupId>com.microsoft.graph</groupId>
    <artifactId>microsoft-graph-core</artifactId>
    <!--x-release-please-start-version-->
    <version>3.1.14</version>
    <!--x-release-please-end-->
    <!-- This dependency is only needed if you are using the TokenCredentialAuthProvider -->
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>1.11.0</version>
</dependency>
```

### 1.3 Enable ProGuard (Android)

The nature of the Graph API is such that the SDK needs quite a large set of classes to describe its functionality. You need to ensure that [ProGuard](https://developer.android.com/studio/build/shrink-code.html) is enabled on your project. Otherwise, you will incur long build times for functionality that is not necessarily relevant to your particular application. If you are still hitting the 64K method limit, you can also enable [multidexing](https://developer.android.com/studio/build/multidex.html).

## 2. Getting started

### 2.1 Register your application

Register your application by following the steps at [Register your app with the Microsoft Identity Platform](https://docs.microsoft.com/graph/auth-register-app-v2).

### 2.2 Create an IAuthenticationProvider object

An instance of the **HttpClients** class handles building client. To create a new instance of this class, you need to provide an instance of `IAuthenticationProvider`, which can authenticate requests to Microsoft Graph.

For an example of how to get an authentication provider, see [choose a Microsoft Graph authentication provider](https://docs.microsoft.com/graph/sdks/choose-authentication-providers?tabs=Java).

### 2.3 Get a HttpClients object

You must get a **HttpClients** object to make requests against the service.

```java
OkHttpClient client = HttpClients.createDefault(iAuthenticationProvider);
```

## 3. Make requests against the service

After you have a HttpClients that is authenticated, you can begin making calls against the service. The requests against the service look like our [REST API](https://developer.microsoft.com/en-us/graph/docs/concepts/overview).

### 3.1 Get the user's details

To retrieve the user's details

```java
Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/").build();

client.newCall(request).enqueue(new Callback() {
	@Override
	public void onResponse(Call call, Response response) throws IOException {
		String responseBody = response.body().string();
		// Your processing with the response body
	}

	@Override
	public void onFailure(Call call, IOException e) {
		e.printStackTrace();
	}
});
```

### 3.2 Get the user's drive

To retrieve the user's drive:

```java
Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/drive").build();

client.newCall(request).enqueue(new Callback() {
	@Override
	public void onResponse(Call call, Response response) throws IOException {
		String responseBody = response.body().string();
		// Your processing with the response body
	}

	@Override
	public void onFailure(Call call, IOException e) {
		e.printStackTrace();
	}
});
```

## 4. Issues

For known issues, see [issues](https://github.com/MicrosoftGraph/msgraph-sdk-java-core/issues).

## 5. Contributions

The Microsoft Graph SDK is open for contribution. To contribute to this project, see [Contributing](https://github.com/microsoftgraph/msgraph-sdk-java-core/blob/main/CONTRIBUTING.md).

## 6. Supported Java versions

The Microsoft Graph SDK for Java library is supported at runtime for Java 8 and [Android API revision 26](http://source.android.com/source/build-numbers.html) or greater.

## 7. License

Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the [MIT license](LICENSE).

## 8. Third-party notices

[Third-party notices](THIRD%20PARTY%20NOTICES)


# Micronaut Cache

[![Maven Central](https://img.shields.io/maven-central/v/io.micronaut.cache/micronaut-cache-ehcache.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.micronaut.cache%22%20AND%20a:%22micronaut-cache-ehcache%22)
[![Build Status](https://github.com/micronaut-projects/micronaut-cache/workflows/Java%20CI/badge.svg)](https://github.com/micronaut-projects/micronaut-cache/actions)
[![Revved up by Develocity](https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.micronaut.io/scans)

This project includes caching support for [Micronaut](http://micronaut.io).

## Documentation

See the [stable](https://micronaut-projects.github.io/micronaut-cache/latest/guide) or [snapshot](https://micronaut-projects.github.io/micronaut-cache/snapshot/guide) documentation for more information.

See the [Snapshot Documentation](https://micronaut-projects.github.io/micronaut-cache/snapshot/guide) for the
current development docs.

## Snapshots and Releases

Snaphots are automatically published to [JFrog OSS](https://oss.jfrog.org/artifactory/oss-snapshot-local/) using [Github Actions](https://github.com/micronaut-projects/micronaut-openapi/actions).

See the documentation in the [Micronaut Docs](https://docs.micronaut.io/latest/guide/index.html#usingsnapshots) for how to configure your build to use snapshots.

Releases are published to JCenter and Maven Central via [Github Actions](https://github.com/micronaut-projects/micronaut-cache/actions).

A release is performed with the following steps:

* [Publish the draft release](https://github.com/micronaut-projects/micronaut-cache/releases). There should be already a draft release created, edit and publish it. The Git Tag should start with `v`. For example `v1.0.0`.
* [Monitor the Workflow](https://github.com/micronaut-projects/micronaut-cache/actions?query=workflow%3ARelease) to check it passed successfully.
* Celebrate!


# General Metadata Architecture

[![release](https://img.shields.io/github/v/release/linkedin/datahub-gma)](https://github.com/linkedin/datahub-gma/releases/)
[![build & test](https://github.com/linkedin/datahub-gma/workflows/build%20&%20test/badge.svg?branch=master&event=push)](https://github.com/linkedin/datahub-gma/actions?query=workflow%3A%22build+%26+test%22+branch%3Amaster+event%3Apush)
[![codecov](https://codecov.io/gh/linkedin/datahub-gma/graph/badge.svg?token=VYJOBVTD00)](https://codecov.io/gh/linkedin/datahub-gma)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](https://join.slack.com/t/datahubspace/shared_invite/zt-dkzbxfck-dzNl96vBzB06pJpbRwP6RA)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/linkedin/datahub-gma/blob/master/docs/CONTRIBUTING.md)
[![License](https://img.shields.io/github/license/linkedin/datahub-gma)](LICENSE)

---

[Documentation](#documentation) | [Roadmap](docs/roadmap.md) | [FAQ](docs/faq.md)

---

> 📣 We've moved from Bintray to [Artifactory](https://linkedin.jfrog.io/artifactory/datahub-gma/)!
>
> As of version [0.2.45](https://github.com/linkedin/datahub-gma/releases/tag/v0.2.45), we are only publishing versions
> to LinkedIn's Artifactory instance rather than Bintray, which is approaching end of life.

## Introduction

General Metadata Architecture (GMA) is the backend for [DataHub](https://github.com/linkedin/datahub), LinkedIn's
generalized metadata search & discovery tool. To learn more about DataHub, check out its
[GitHub page](https://github.com/linkedin/datahub).

You should also visit [GMA Architecture](docs/architecture/architecture.md) to get a better understanding of how GMA is
implemented.

This repository contains the _partial_ source code for GMA. It originally lived in the same GitHub repository as
DataHub. We're still in the process of moving it all over.

## Documentation

- [GMA Developer's Guide](docs/developers.md)
- [GMA Architecture](docs/architecture/architecture.md)

## Releases

See [Releases](https://github.com/linkedin/datahub-gma/releases) page for more details. We follow the
[SemVer Specification](https://semver.org) when versioning the releases and adopt the
[Keep a Changelog convention](https://keepachangelog.com/) for the changelog format.

## FAQs

Frequently Asked Questions about DataHub can be found [here](docs/faq.md).

## Features & Roadmap

Check out GMA's [Features](docs/features.md) & [Roadmap](docs/roadmap.md).

## Contributing

We welcome contributions from the community. Please refer to our [Contributing Guidelines](docs/CONTRIBUTING.md) for
more details. We also have a [contrib](contrib) directory for incubating experimental features.

## Community

Join our [slack workspace](https://join.slack.com/t/datahubspace/shared_invite/zt-dkzbxfck-dzNl96vBzB06pJpbRwP6RA) for
discussions and important announcements.


# tracing-java [![Download](https://api.bintray.com/packages/palantir/releases/tracing-java/images/download.svg) ](https://bintray.com/palantir/releases/tracing-java/_latestVersion)

[Zipkin](https://github.com/openzipkin/zipkin)-style call tracing libraries.

- **com.palantir.tracing:tracing** - The key `Tracer` class, which stores trace information in a ThreadLocal.  Also includes classes for convenient integration with SLF4J and executor services.
- **com.palantir.tracing:tracing-api** - constants and pure data objects
- **com.palantir.tracing:tracing-jaxrs** - utilities to wrap `StreamingOutput` responses with a new trace.
- **com.palantir.tracing:tracing-okhttp3** - `OkhttpTraceInterceptor`, which adds the appropriate headers to outgoing requests.
- **com.palantir.tracing:tracing-jersey** - `TraceEnrichingFilter`, a jaxrs filter which reads headers from incoming requests and writes headers to outgoing responses.  A traceId is stored in the jaxrs request context under the key `com.palantir.tracing.traceId`.
- **com.palantir.tracing:tracing-undertow** - `TracedOperationHandler`, an Undertow handler reads headers from incoming requests and writes headers to outgoing responses.
- **com.palantir.tracing:tracing-test-utils** - JUnit classes to render traces and also allow snapshot testing them.

Clients and servers propagate call trace ids across JVM boundaries according to the
[Zipkin](https://github.com/openzipkin/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. We enhance
the Zipkin spec in one regard; with outgoing traces we additionally send an `X-OrigSpanId: <Originating Span ID>`
header which enables request logs to be considered a useful subset of the trace events, even on unsampled requests.

## Usage

Example of how to use the `tracing` library:

```groovy
// build.gradle
dependencies {
  compile "com.palantir.tracing:tracing:$version"
}
```

```java
try (CloseableTracer span = CloseableTracer.startSpan("do work")) {
    Thread.sleep(100);
    doWork();
}
```

At the end of this try-with-resources block, any registered SpanObservers will be notified with a single immutable `Span` object. The above example demonstrates how to instrument chunks of code that start and finish on one thread. For cross-thread tracing, see `DetachedSpan`.

## Logging with SLF4J

By default, the instrumentation forwards trace and span information through HTTP headers, but does not emit completed
spans to a log file or to Zipkin.  Span observers are static (similar to SLF4J appenders) and can be configured as
follows:

```java
// Emit all completed spans to the provided span observer:
Tracer.subscribe("SLF4J" /* user-defined name */, spanObserver);

// No longer emit span events to SLF4J:
Tracer.unsubscribe("SLF4J");
```
Note that span observers are static; a server typically subscribes span observers in its initialization phase.
Libraries should never register span observers (since they can trample observers registered by consumers of the library
whose themselves register observers).

## tracing-test-utils

You can set up 'snapshot testing' by adding the `@TestTracing` annotation to a test method (this requires JUnit 5).

```diff
 import org.junit.jupiter.api.Test;
 import com.palantir.tracing.TestTracing;

 public class MyTest {
     @Test
+    @TestTracing(snapshot = true)
     public void foo() {
     }
 }
```

When you run this test for the first time, it will capture all spans and write them to a file `src/test/resources/tracing/MyTest/foo`, which should be checked-in to Git.  This file will be used as a 'golden master', and all future runs will be compared against it.

```
{"traceId":"7e1014caf8a7278e","parentSpanId":"972f9b3a09431b67","spanId":"f701b7f815176ec2","operation":"healthcheck: SERVICE_DEPENDENCY","startTimeMicroSeconds":1566902887342052,"durationNanoSeconds":20377272,"metadata":{}}
...
```

If your production code changes and starts producing different spans, the test will fail and render two HTML visualizations: `expected.html` and `actual.html`.

Snapshot-testing is not available in JUnit4, but you can still see a HTML visualization of your traces using the `RenderTracingRule`:

```diff
 import org.junit.Test;
 import com.palantir.tracing.RenderTracingRule;

 public class MyTest {

+    @Rule
+    public final RenderTracingRule rule = new RenderTracingRule();

     @Test
     public void foo() {
     }
 }
```

## License

This repository is made available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).


# Document Management Store App
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://travis-ci.org/hmcts/document-management-store-app.svg?branch=master)](https://travis-ci.org/hmcts/document-management-store-app)
[![codecov](https://codecov.io/gh/hmcts/document-management-store-app/branch/master/graph/badge.svg)](https://codecov.io/gh/hmcts/document-management-store-app)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/04bae03fe36b43759ea4f2df7c48fd43)](https://www.codacy.com/app/HMCTS/document-management-store-app)
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/04bae03fe36b43759ea4f2df7c48fd43)](https://www.codacy.com/app/HMCTS/document-management-store-app)
[![Known Vulnerabilities](https://snyk.io/test/github/hmcts/document-management-store-app/badge.svg)](https://snyk.io/test/github/hmcts/document-management-store-app)

Document Management is a backend service to store and retrieve documents.

### Tech

It uses:

* Java
* Spring boot
* Junit, Mockito and SpringBootTest and Powermockito
* Gradle
* [lombok project](https://projectlombok.org/) - Lombok project

### Plugins
* [lombok plugin](https://plugins.jetbrains.com/idea/plugin/6317-lombok-plugin) - Lombok IDEA plugin

#### Environment variables
The following environment variables are required:

| Name | Default | Description |
|------|---------|-------------|
| IDAM_USER_BASE_URI | - | Base URL for IdAM's User API service (idam-app). `http://localhost:4501` for the dockerised local instance or tunneled `dev` instance. |
| IDAM_S2S_BASE_URI | - | Base URL for IdAM's S2S API service (service-auth-provider). `http://localhost:4502` for the dockerised local instance or tunneled `dev` instance. |
| MAX_FILE_SIZE | 100MB | Max file size |

**Note:** The MAX_FILE_SIZE enforces limit on the document upload in the document management backend service.
Additionally, the max request content length (including file sizes) need to be configured for the IIS web server (on
Azure) via *maxAllowedContentLength* property for request filter in **web.config** (config file within source
repository).

## Setup
```bash
# Get the connection string for Azure Blob Store and put it in place of getOneFromPortalAzure in application.yaml
# Do not commit it!!!
azure:
  storage:
      connection-string: ${STORAGEACCOUNT_PRIMARY_CONNECTION_STRING:getOneFromPortalAzure}
```

```bash
# Cloning repo and running though docker
git clone https://github.com/hmcts/document-management-store-app.git
cd document-management-store-app/

az login
az acr login --name hmctspublic && az acr login --name hmctsprivate

docker-compose -f docker-compose-dev.yml pull
docker-compose -f docker-compose-dev.yml up -d

#Run below script to create the Batch related tables for local set up ONLY
./bin/create-batch-related-tables-postresql.sh

# Run application
./gradlew bootRun
```
### Integration
There is currently a Java Client available here:
https://github.com/hmcts/document-management-client

### Swagger UI
To view our REST API go to http://{HOST}/swagger-ui/index.html
On local machine with server up and running, link to swagger is as below
> http://localhost:4603/swagger-ui/index.html
> if running on AAT, replace localhost with ingressHost data inside values.yaml class in the necessary component, making sure port number is also removed.

### API Endpoints
A list of our endpoints can be found here
> https://hmcts.github.io/reform-api-docs/swagger.html?url=https://hmcts.github.io/reform-api-docs/specs/document-management-store-app.json

### Functional Tests
To use the functional tests locally for large .mp4 and .doc files please first download them
from here : [Large Files](https://portal.azure.com/#blade/Microsoft_Azure_Storage/ContainerMenuBlade/overview/storageAccountId/%2Fsubscriptions%2Fbf308a5c-0624-4334-8ff8-8dca9fd43783%2FresourceGroups%2Fdm-store-sandbox%2Fproviders%2FMicrosoft.Storage%2FstorageAccounts%2Fdmstorefiles/path/dm-store-files/etag/%220x8D83471B8B0648C%22/defaultEncryptionScope/%24account-encryption-key/denyEncryptionScopeOverride//defaultId//publicAccessVal/None)
and place them under your resources folder document-management-store-app/src/functionalTest/resources
This would make them available to be used in the Functional Test -
```bash
MV1 (R1) As authenticated user I should not be able to upload files that exceed permitted sizes
```
- Ensure the @Pending annotation is removed before running the test locally.
- Revert your changes after tests are run  as these are for running the above F-Test on local only.

### Contract Tests (Pact)
For Executing the contract provider test  execute
```./gradlew contractTest```
For Publishing the verification results to broker execute
```./gradlew runProviderPactVerification```


# Conjure-Java [![License](https://img.shields.io/badge/License-Apache%202.0-lightgrey.svg)](https://opensource.org/licenses/Apache-2.0)

_CLI to generate Java POJOs and interfaces from [Conjure API definitions](https://github.com/palantir/conjure)._

Note that all Java APIs in this repository (including `conjure-java-core`) are considered "internal" in the sense that
they may change at any time and without prior warning or deprecation notice. These packages are published for
convenience, but users must assume responsibility for adapting their code when dependencies change.

## Usage

The recommended way to use conjure-java is via a build tool like [gradle-conjure](https://github.com/palantir/gradle-conjure). However, if you don't want to use gradle-conjure, there is also an executable which conforms to [RFC 002](https://palantir.github.io/conjure/#/docs/rfc/002-contract-for-conjure-generators), published on [maven central](https://mvnrepository.com/artifact/com.palantir.conjure.java/conjure-java).

    Usage: conjure-java generate [...options] <input> <output>

    Generate Java bindings for a Conjure API
        <input>      Path to the input IR file
        <output>     Output directory for generated source

    Options:
        --objects    Generate POJOs for Conjure type definitions
        --jersey     Generate jax-rs annotated interfaces for client or server-usage
        --undertow   Generate undertow handlers and interfaces for server-usage
        --requireNotNullAuthAndBodyParams
                     Generate @NotNull annotations for AuthHeaders and request body params
        --undertowServicePrefixes
                     Generate service interfaces for Undertow with class names prefixed 'Undertow'
        --undertowListenableFutures
                     Generate Undertow services which return Guava ListenableFuture for asynchronous processing
        --useImmutableBytes
                     Generate binary fields using the immutable 'Bytes' type instead of 'ByteBuffer'
        --strictObjects
                     Generate POJOs that by default will fail to deserialize unknown fields
        --nonNullCollections
                     Generate POJOs that by default will fail to deserialize collections with null values
        --useStagedBuilders
                     Generates compile-time safe builders to ensure all attributes are set, except those of type list,
                     set, map, or optional. If --useStrictStagedBuilders is set, this option is ignored.
        --useStrictStagedBuilders
                     Generates compile-time safe builders to ensure all attributes are set.
        --jakartaPackages
                     Generates jax-rs annotated interfaces which use the newer 'jakarta` packages instead of the
                     legacy 'javax' packages.
        --externalFallbackTypes
                     Java external type imports are generated using their fallback type.

### Known Tag Values

#### Endpoint Tags

* `incubating`: Describes an endpoint as incubating and likely to change. These endpoints are generated with an `@Incubating` annotation.
* `server-request-context`: Opt into an additional [RequestContext](conjure-undertow-lib/src/main/java/com/palantir/conjure/java/undertow/lib/RequestContext.java) parameter in conjure-undertow interfaces, which allows request metadata to be read, and additional arguments to be associated with the request log.
* `server-async`: Opt into [asynchronous request processing](#asynchronous-request-processing) in conjure-undertow. The generated interface returns a `ListenableFuture` of the defined return type, allowing processing to occur in the background without blocking the request thread.
* `deprecated-for-removal`: For endpoint definitions that [are marked deprecated](https://github.com/palantir/conjure/blob/master/docs/spec/conjure_definitions.md#endpointdefinition), indicates that the endpoint will be removed in a future release. This has the effect of Java code being generated with an `@Deprecated(forRemoval = true)` annotation on the endpoint method in the Dialogue service interface.

#### Endpoint Argument Tags

* `server-squelch`: Opts out of attaching safe non-body parameters to the request. By default, all known log-safe non-body inputs are included.

_The following argument tags are deprecated, replaced by `safety` declarations._
* `safe`: Annotates parameters as `@Safe` to log using safe-logging annotations. Implementations may add this data to the request log.
* `unsafe`: Annotates parameters as `@Unsafe` to log using safe-logging annotations. Implementations may add this data to the request log.

### Feature Flags

Conjure-java supports feature flags to enable additional opt-in features. To enable features provided by a feature
flag, simply supply the feature flag as an additional parameter when executing conjure-java. Available feature flags
can be found in the [Options](./conjure-java-core/src/main/java/com/palantir/conjure/java/Options.java) class.

## Example generated objects

Conjure-java objects are always immutable and thread-safe.  Fields are never null; instead, Java 8 Optionals are used. JSON serialization is handled using [Jackson](https://github.com/FasterXML/jackson) annotations.

- **Conjure object: [ManyFieldExample](./conjure-java-core/src/integrationInput/java/com/palantir/product/ManyFieldExample.java)**

  Objects can only be instantiated using the builder pattern:

    ```java
    ManyFieldExample example = ManyFieldExample.builder()
            .string("foo")
            .integer(123)
            .optionalItem("bar")
            .addAllItems(iterable)
            .build();
    ```

    Or using Jackson via [`conjure-jackson-serialization`](https://github.com/palantir/conjure-java-runtime):

    ```java
    ObjectMapper mapper = ObjectMappers.newServerObjectMapper();
    ManyFieldExample fromJson = mapper.readValue("{\"string\":\"foo\", ...}", ManyFieldExample.class);
    ```

- **Conjure union: [UnionTypeExample](./conjure-java-core/src/integrationInput/java/com/palantir/product/UnionTypeExample.java)**

    Union types can be one of a few variants. To interact with a union value, users should use the `.accept` method and define a Visitor that handles each of the possible variants, including the possibility of an unknown variant.

    ```java
    Foo output = unionTypeExample.accept(new Visitor<Foo>() {

        public Foo visitStringExample(StringExample value) {
            // your logic here!
        }

        public Foo visitSet(Set<String> value) {}

        // ...

        public Foo visitUnknown(String unknownType) {}

    });
    ```

    Visitors may seem clunky in Java, but they have the upside of compile-time assurance that you've handled all the possible variants.  If you upgrade an API dependency and the API author added a new variant, the Java compiler will force you to explicitly deal with this new variant.  We intentionally avoid `switch` statements and `instanceof` checks for this exact reason.

    There is also a more concise visitor builders pattern that can be used to create a visitor:

    ```java
    Foo output = unionTypeExample.accept(Visitor.<Foo>builder()
        .stringExample(value -> ...)
        .set(value -> ...)
        .throwOnUnknown()
        .build());
    });
    ```

- **Conjure enum: [EnumExample](./conjure-java-core/src/integrationInput/java/com/palantir/product/EnumExample.java)**

  Enums are subtly different from regular Java enums because they tolerate deserializing unknown values.  This is important because it ensures server authors can add new variants to an enum without causing runtime errors for consumers that use older API jars.

  ```java
  EnumExample one = EnumExample.ONE;
  System.out.println(one); // prints: 'ONE'

  EnumExample fromJson = mapper.readValue("\"XYZ\"", EnumExample.class);
  System.out.println(fromJson); // prints: 'XYZ'
  ```

- **Conjure alias: [StringAliasExample](./conjure-java-core/src/integrationInput/java/com/palantir/product/StringAliasExample.java)**

  Aliases have exactly the same JSON representation as their inner type, so they are useful for making error-prone function signatures more bulletproof:

  ```diff
  -doSomething(String, String, String);
  +doSomething(ProductId, UserId, EmailAddress);
  ```

## Example Jersey interfaces

Conjure-java generates Java interfaces with [JAX-RS](http://jax-rs-spec.java.net/) annotations, so they can be used on the client side or on the server-side.

Example jersey interface: [EteService](./conjure-java-core/src/integrationInput/java/com/palantir/product/EteService.java)

```java
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/")
@Generated("com.palantir.conjure.java.services.JerseyServiceGenerator")
public interface EteService {
    @GET
    @Path("base/string")
    String string(@HeaderParam("Authorization") AuthHeader authHeader);
}
```

### Jersey clients

Use [conjure-java-runtime's `JaxRsClient`](https://github.com/palantir/conjure-java-runtime#conjure-java-jaxrs-client) which configures Feign with sensible defaults:

```java
RecipeBookService recipes = JaxRsClient.create(
        RecipeBookService.class,
        userAgent,
        hostMetrics,
        clientConfiguration);

List<Recipe> results = recipes.getRecipes();
```

### Jersey servers

You need a [Jersey](https://jersey.github.io/)-compatible server. We recommend Dropwizard (which is based on Jetty), but Grizzly, Tomcat, etc should also work fine.  Use [conjure-java-runtime's `ConjureJerseyFeature`](https://github.com/palantir/conjure-java-runtime#conjure-java-jersey-server) to configure Jackson and Exception mappers appropriately.  Then, you just need to implement the interface:

```java
public final class RecipeBookResource implements RecipeBookService {

    @Override
    public List<Recipe> getRecipes() {
        // ...
    }
}
```

Then in your server main method, [register your resource](https://github.com/dropwizard/dropwizard/blob/caab32042c0f930d290b35248282c5623ea6cd82/docs/source/getting-started.rst#registering-a-resource). For example, using Dropwizard:

```diff
 public void run(YourConfiguration configuration, Environment environment) {
     // ...
+    environment.jersey().register(new RecipeBookResource());
 }
```

## Undertow

In the undertow setting, for a `ServiceName` conjure defined service, conjure will generate an interface: `ServiceName` to be extended by your resource and an [UndertowService](https://github.com/palantir/conjure-java/blob/develop/conjure-undertow-lib/src/main/java/com/palantir/conjure/java/undertow/lib/UndertowService.java) named `ServiceNameEndpoints`

To avoid conflicts with the equivalent jersey interface (when you are generating both), use in your build.gradle:

```groovy
conjure {
    java {
        undertowServicePrefixes = true
    }
}
```

With this option, Undertow generated interfaces will be prefixed with `Undertow`. Here the interface would be called: `UndertowServiceName`

To use the generated handlers:

```java
public static void main(String[] args) {
    Undertow server = Undertow.builder()
            .addHttpListener(8080, "0.0.0.0")
            .setHandler(ConjureHandler.builder()
                    .services(RecipeBookServiceEndpoints.of(new RecipeBookResource()))
                    .build())
            .build();
    server.start();
}
```

### Asynchronous Request Processing

The Conjure Undertow generator supports asynchronous request processing allowing all service methods to return a
[Guava ListenableFuture](https://github.com/google/guava/wiki/ListenableFutureExplained). These methods may be
implemented synchronously by replacing `return object` with `return Futures.immediateFuture(object)`.

Asynchronous request processing decouples the HTTP request lifecycle from server task threads, allowing you to replace
waiting on shared resources with callbacks, reducing the number of required threads.

This feature is enabled on individual endpoints using the `server-async` endpoint tag:

```yaml
getEvents:
  http: GET /events
  returns: list<Event>
  tags:
    - server-async
```

Or for all endpoints using the `undertowListenableFutures` generator flag:
```groovy
conjure {
    java {
        undertowListenableFutures = true
    }
}
```

#### Timeouts

By default, asynchronous request processing imposes a 3-minute timeout on the asynchronous component of the
request, canceling the return future after this duration is exceeded. A custom duration may be used by
extending the tag value using the form `server-async{timeout=5 minutes}`.

#### Examples

*Asynchronous request processing is helpful for endpoints which do not need a thread for the entirety of
the request.*

:+1: Delegation to an asynchronous client, for instance dialogue :+1:

```java
@Override
public ListenableFuture<String> getValue() {
    // Assuming this dialogue client was compiled with --undertowListenableFutures
    return dialogueClient.getValue();
}
```

:+1: Long polling :+1:

Long polling provides lower latency than simple repeated polling, but requests take a long time relative
to computation. A single thread can often handle updating all polling requests without blocking N request
threads waiting for results.

```java
@Override
public ListenableFuture<String> getValue() {
    SettableFuture<String> result = SettableFuture.create();
    registerFuture(result);
    return result;
}
```

:-1: Not for delegation to synchronous operations, Feign clients for example :-1:

This example is less efficient than `return Futures.immediateFuture(feignClient.getValue())` because you pay an
additional cost to switch threads, and maintain an additional executor beyond the configured server thread pool.

```java
ListeningExecutor executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

@Override
public ListenableFuture<String> getValue() {
    // BAD: do not do this!
    return executor.submit(() -> feignClient.getValue());
}
```

:-1: Not waiting on another thread :-1:

This is even less efficient than the previous example because it requires two entire threads for the duration
of the request. It's reasonable to defer computation to an executor bounded to the work, but you should
wrap the executor with `MoreExecutors.listeningDecorator` and return the future to avoid blocking a server
worker thread for both the queued and execution durations of the task.

```java
ExecutorService executor = Executors.newFixedThreadPool(CORES);

@Override
public ListenableFuture<BigInteger> getValue() {
    // BAD: do not do this!
    Future<BigInteger> future = executor.submit(() -> complexComputation());
    BigInteger result = Uninterruptibles.getUninterruptibly(future);
    return Futures.immediateFuture(result);
}
```

### Request Metadata

The [RequestContext](conjure-undertow-lib/src/main/java/com/palantir/conjure/java/undertow/lib/RequestContext.java) may be requested on an opt-in basis per-endpoint using the `server-request-context`
conjure endpoint `tag`:

```yaml
services:
  ExampleService:
    name: Example
    package: com.palantir.example
    base-path: /example

    endpoints:
      context:
        http: GET /ping
        returns: string
        tags: [server-request-context]
```

This tag generates an additional parameter in the generated service interface:

```java
public interface ExampleService {
  String ping(RequestContext context);
}
```

Implementations may read arbitrary headers and query parameters, or associate additional data with the request log:

```java
import java.util.concurrent.atomic.AtomicInteger;

public final class ExampleResource implements ExampleService {
  private final AtomicInteger requestIndex = new AtomicInteger();

  @Override
  public String ping(RequestContext context) {
    // Apply a unique index value to the request log:
    context.requestArg(SafeArg.of("requestNumber", requestIndex.getAndIncrement()));
    // Read the User-Agent header from the current request:
    String userAgent = context.firstHeader("User-Agent");
    // And add it to the request log:
    context.requestArg(SafeArg.of("userAgent", userAgent));
    return "pong";
  }
}
```

### Conjure-Undertow Annotation Processor

The conjure-undertow annotation processor generates Undertow handler for services that can not easily be represented
using Conjure. You can find more details in the [respective readme](conjure-undertow-annotations/readme.md).

## conjure-lib `Bytes` class

By default, conjure-java will use `java.nio.ByteByffer` to represent fields of Conjure type `binary`.  However, the ByteBuffer class has many subtleties, including interior mutability.

To avoid many of these foot-guns, we recommend using the `useImmutableBytes` feature flag to opt-in to using the [`com.palantir.conjure.java.lib.Bytes`](conjure-lib/src/main/java/com/palantir/conjure/java/lib/Bytes.java) class.
This will become the default behaviour in a future major release of conjure-java.

## Contributing

For instructions on how to set up your local development environment, check out the [Contributing document](./CONTRIBUTING.md).

## License
This project is made available under the [Apache 2.0 License](/LICENSE).


# Dialogue [![License](https://img.shields.io/badge/License-Apache%202.0-lightgrey.svg)](https://opensource.org/licenses/Apache-2.0)

_Dialogue is a client-side library for HTTP-based RPC, designed to work well with [Conjure](https://palantir.github.io/conjure)-defined APIs._

## Features

- **ConcurrencyLimiters**: additive increase multiplicative decrease (AIMD) concurrency limiters ensure bursty traffic doesn't overload upstream servers.
- **Client-side node selection**: by making load balancing decisions in the client, Dialogue avoids the necessity for an L7 proxy (and its associated latency penalty).
- **Queue**: in the case where all nodes are limited (e.g. during a spike in traffic), requests are added to a FIFO queue and processed as soon as the one of the ConcurrencyLimiters has capacity.
- **Retries**: requests are retried a constant number of times, if possible.
- **Live reloading**: uris can be added or removed without losing ConcurrencyLimiter or node selection states.
- **Content decoding**: JSON, [SMILE](https://github.com/FasterXML/jackson-dataformats-binary/tree/master/smile) and [CBOR](https://github.com/FasterXML/jackson-dataformats-binary/tree/master/cbor) are supported by default, with user-defined encodings also supported.
- **Streaming**: requests and responses are streamed without buffering the entire body into memory.

## Observability

- **Zipkin-style tracing**: internal operations are instrumented using Zipkin-style [tracing-java spans](https://github.com/palantir/tracing-java), and `X-B3-TraceId` headers are propagated
- **Metrics**: Timers, meters, and gauges are defined using [metric-schema](https://github.com/palantir/dialogue/blob/develop/dialogue-core/src/main/metrics/dialogue-core-metrics.yml) and stored in a [Tritium TaggedMetricRegistry](https://github.com/palantir/tritium).
- **Structured logging**: SLF4J logs are designed to be rendered as JSON, with every parameter declaratively named.

## Usage

Dialogue works best with Conjure-generated client bindings, i.e. for a given Conjure-defined `FooService`, the
[conjure-java](https://github.com/palantir/conjure-java) code generator produces two java interfaces:
`FooServiceBlocking` and `FooServiceAsync`. See the [conjure-java generated client bindings][] section below for more
details.

### Production usage

Your server framework should provide an abstraction to create clients that handle uri live-reloading and reuse connection pools. For example, in Witchcraft, you can create a `FooServiceBlocking` like so:

```java
FooServiceBlocking fooService = witchcraft.conjureClients().client(FooServiceBlocking.class, "foo-service").get();

// network call:
List<Item> items = fooService.getItems();
```

The non-blocking instance can be constructed similarly:

```java
FooServiceAsync fooService = witchcraft.conjureClients().client(FooServiceAsync.class, "foo-service").get();

ListenableFuture<List<Item>> items = fooService.getItems();
```

### Under the hood

If the Witchcraft method above is not available, you can construct clients manually using a factory provided by
`com.palantir.dialogue:dialogue-clients`.

```java
DialogueClients.ReloadingFactory clients = DialogueClients.create(servicesConfigBlockRefreshable).withUserAgent(agent);

FooServiceBlocking client = clients.get(FooServiceBlocking.class, "foo-service");
FooServiceAsync client2 = clients.get(FooServiceAsync.class, "foo-service");
```

It's important to construct the ReloadingFactory _once_ for the lifetime of your JVM, and construct all clients from
this single clientfactory instance. This ensures that underlying Apache connection pools are reused correctly, and that
many clients all talking to the same URI will share the same concurrency limiter.

This abstraction uses [Apache HttpClient](https://hc.apache.org/httpcomponents-client-ga/) under the hood, as it is a reliable and performant HTTP client. (See alternatives below.)

_It is possible to construct a `DialogueChannel` manually which allows you to use alternative raw clients such as OkHttp
instead of Apache._

[conjure-java generated client bindings]: #conjure-java-generated-client-bindings
## conjure-java generated client bindings

Dialogue works best with generated client bindings, i.e. for a given Conjure-defined `FooService`, the [conjure-java](https://github.com/palantir/conjure-java) code generator can produce two java interfaces: `FooServiceBlocking` and `FooServiceAsync`. Generating these at compile-time means that making a request involves zero reflection - all serializers and deserializers are already set up in advance, so that zero efficiency compromises are made. A sample `getThing` endpoint with some path params, query params and a request body looks like this:

```java
@Override
public ListenableFuture<Thing> getThing(
        AuthHeader authHeader, String pathParam, List<ResourceIdentifier> queryKey, MyRequest body) {
    Request.Builder _request = Request.builder();
    _request.putHeaderParams("Authorization", plainSerDe.serializeBearerToken(authHeader.getBearerToken()));
    _request.putPathParams("path", plainSerDe.serializeString(pathParam));
    for (ResourceIdentifier queryKeyElement : queryKey) {
        _request.putQueryParams("queryKey", plainSerDe.serializeRid(queryKeyElement));
    }
    _request.body(myRequestSerializer.serialize(body));
    return runtime.clients()
            .call(channel, DialogueSampleEndpoints.getThing, _request.build(), thingDeserializer);
}
```

## Blocking or async

Of the two generated interfaces `FooServiceBlocking` and `FooServiceAync`, the blocking version is usually appropriate for 98% of use-cases, and results in much simpler control flow and error-handling. The async version returns Guava [`ListenableFutures`](https://github.com/google/guava/wiki/ListenableFutureExplained), making it a lot more fiddly to use. `Futures.addCallback` and `FluentFuture` are your friends here.

[dialogue-annotations-processor generated client bindings]: #dialogue-annotations-processor-generated-client-bindings

## dialogue-annotations-processor generated client bindings

``dialogue-annotations-processor`` is a retrofit replacement for use-cases where a service needs to talk to a
non-conjure server.

To set up the annotation, simply add (make sure you are
using [gradle-processors](https://github.com/palantir/gradle-processors)):

```gradle
dependencies {
    annotationProcessor 'com.palantir.dialogue:dialogue-annotations-processor'
    implementation 'com.palantir.dialogue:dialogue-annotations'
}
```

Next, create an annotated interface that describes the service you need to talk to, appropriately annotated
with ``@DialogueService``:

```java
import com.palantir.dialogue.DialogueService;
import com.palantir.dialogue.HttpMethod;
import com.palantir.dialogue.RequestBody;
import com.palantir.dialogue.Response;
import com.palantir.dialogue.annotations.Request;
import java.util.OptionalInt;
import java.util.UUID;

@DialogueService(MyServiceDialogueServiceFactory.class)
public interface MyService {

    @Request(method = HttpMethod.POST, path = "/params/{myPathParam}/{myPathParam2}", accept=MyCustomResponseDeserializer.class)
    MyCustomResponse params(
            @Request.QueryParam("q") String query,
            // Path parameter variable name must match the request path component
            @Request.PathParam UUID myPathParam,
            @Request.PathParam(encoder = MyCustomParamTypeEncoder.class) MyCustomParamType myPathParam2,
            // converts a custom type into a Multimap<String, String>
            @Request.QueryMap(encoder = MyCustomQueryTypeEncoder.class) MyCustomQueryParamType myCustomQueryParam,
            @Request.Header("Custom-Header") int requestHeaderValue,
            // Headers can be optional
            @Request.Header("Custom-Optional-Header") OptionalInt maybeRequestHeaderValue,
            // converts a custom type into a Multimap<String, String>
            @Request.HeaderMap(encoder = MyCustomHeaderTypeEncoder.class) MyCustomHeaderParamType myCustomHeaderParam,
            // Custom encoding classes may be provided for the request and response.
            @Request.Body(MySerializableTypeBodySerializer.class) MySerializableType body);
}
```

Features:

* Async request handling: simply make your method return ```ListenableFuture<Foo>```.
* Custom parameter types: ```@Request.(Header|PathParam|QueryParam)(encoder=MyCustomParamTypeEncoder.class)```.
* Custom serialization/deserialization: add ```@Request.Body(MySerializableTypeBodySerializer.class)```
  or ```@Request(accept=MyCustomResponseDeserializer.class)```.
* Custom serialization from ```Map```, ```Multimap```, and custom types into query parameters and header parameters. This functions
  similarly to the Feign ```QueryMap``` and ```HeaderMap``` features, but with added control of customizing the serialization.
* Authentication: builtin ```Authorization``` header handling if an annotated method has an ```AuthHeader``` parameter.

See more examples [on how to define clients](dialogue-annotations-example/src/main/java/com/palantir/myservice/example/MyService.java) and [use the generated code](dialogue-annotations-example/src/test/java/com/palantir/myservice/example/MyServiceIntegrationTest.java).

## Design

Dialogue is built around the `Channel` abstraction, with many different internal implementations that often add a little bit of behaviour and then delegate to another inner Channel.

```java
public interface Channel {
    ListenableFuture<Response> execute(Endpoint endpoint, Request request);
}
```

For example, the [TraceEnrichingChannel](dialogue-core/src/main/java/com/palantir/dialogue/core/TraceEnrichingChannel.java) just augments the request with zipkin-style tracing headers and then calls a delegate.

_This API is influenced by gRPC's [Java library](https://github.com/grpc/grpc-java), which has a similar [Channel](https://github.com/grpc/grpc-java/blob/master/api/src/main/java/io/grpc/Channel.java) concept._

## Behaviour

### Concurrency limits

Every request passes through a pair of [AIMD](https://en.wikipedia.org/wiki/Additive_increase/multiplicative_decrease)
concurrency limiters.
There are two types of concurrency limiter: per-host, and per-endpoint. The former is based on failures that
indicate the target host is in a degraded state, and the latter is based on failures that are coupled to
an individual endpoint.
Each concurrency limiter operates in conjunction with a queue to stage pending requests until a
permit becomes available.

#### Limiter Diagram

```
+---------+   +----------+      +-------------+    +--------------------+   +--------------------------+   +----------------------------+
| Request +-->+Request Queue+-->+Node Selector+--->+Host Limiter (node0)+-->+Endpoint Queue(node0,ping)+-->+Endpoint Limiter(node0,ping)+---------+
+---------+   +----------+      +--------------+   +---------------------+  +--------------------------+   +----------------------------+         |
                                               |                         |                                                                        |
                                               |                         |  +---------------------------+  +-----------------------------+        |
                                               |                         +->+Endpoint Queue(node0,hello)+->+Endpoint Limiter(node0,hello)+----v   v
                                               |                            +---------------------------+  +-----------------------------+   +----+-------+
                                               |                                                                                |HTTP Request|
                                               |                                                                                +--+-+-------+
                                               |   +--------------------+   +--------------------------+   +----------------------------+       ^ ^
                                               +-->+Host Limiter (node1)+-->+Endpoint Queue(node1,ping)+-->+Endpoint Limiter(node1,ping)+-------+ |
                                                   +---------------------+  +--------------------------+   +----------------------------+         |
                                                                         |                                                                        |
                                                                         |  +---------------------------+  +-----------------------------+        |
                                                                         +->+Endpoint Queue(node1,hello)+->+Endpoint Limiter(node1,hello)+--------+
                                                                            +---------------------------+  +-----------------------------+
```

#### Host limits

Each host has a concurrency limiter which protects servers by stopping requests getting out the door on the client-side.
Permits are decreased after receiving 308 or 501-599 response, or encountering a network error (`IOException`).
Otherwise, they are increased.

#### Endpoint limits

Each endpoint has a concurrency limiter which is distinct for each host. This allows servers to provide backpressure with
additional specificity in the form of 429 status QoS responses. Permits are decreased after
receiving a 429 or 500 response code. Otherwise, they are increased.

### Node selection strategies
When configured with multiple uris, Dialogue has several strategies for choosing which upstream to route requests to.
The default strategy is `PIN_UNTIL_ERROR`, although users can choose alternatives such as `ROUND_ROBIN` when building a ClientConfiguration
object. Note that the choice of an appropriate strategy usually depends on the _upstream_ server's behaviour, i.e. if its
performance relies heavily on warm caches, or if successive requests must land on the same node to successfully complete
a transaction. To solve this problem without needing code changes in all clients, servers can recommend a
NodeSelectionStrategy (see below).

### Server-recommended node selection strategies
Servers can inform clients of their recommended strategies by including the
`Node-Selection-Strategy` response header. Values are separated by commas and are ordered by preference. See [available strategies](dialogue-core/src/main/java/com/palantir/dialogue/core/DialogueNodeSelectionStrategy.java).
```
Node-Selection-Strategy: BALANCED,PIN_UNTIL_ERROR
```
When the header is present, it takes precedence over user-selected strategies. Servers are free to omit this value.

### NodeSelectionStrategy.ROUND_ROBIN
Used to balance requests across many servers better than the
default PIN_UNTIL_ERROR. The actual algorithm has evolved from naive Round Robin, then to Random Selection and now
makes smarter decisions based on stats about each host (see
[BalancedNodeSelectionStrategyChannel.java](dialogue-core/src/main/java/com/palantir/dialogue/core/BalancedNodeSelectionStrategyChannel.java)). This fixes a dramatic failure
mode when a single server is very slow (this can be seen empirically in the simulations). Note that unlike concurrency limiters, this node selection strategy never *prevents* a request getting out the door,
it just *ranks* hosts to try to deliver the best possible client-perceived response time (and success rate).

Specifically, it keeps track of the number of in flight requests for each host, and also records every failure it sees for each host. A
request is then routed to the host with the lowest `inflight + 10*recent_failures`.

The ROUND_ROBIN strategy is _not_ appropriate for transactional use cases where successive requests must land on the
same node, and it's also not optimal for use-cases where there are many nodes and cache affinity is very important.

### Sticky requests

Dialogue channels can be configured to stick to a single host: after the first request is successfully executed on a host,
all subsequent requests will be routed to the same host. This strategy is useful for transactional workflows,
where all requests tied to a particular transaction may need to be executed on the same host.

The implementation reuses the same [limiter pipeline](#limiter-diagram), with some adjustments (simplified to show a single host/endpoint only):

```
Sticky Request +-->+Per Sticky Channel queue+-->+Per Sticky Channel Limiter+-->+Node Selector+--->+Host Limiter (node0)+-->+Endpoint Queue(node0,ping)+-->+Endpoint Limiter(node0,ping)
```

Each sticky channel gets its own queue. If a sticky channel has no requests in-flight, ``Host Limiter`` is sidestepped (the request is let through regardless of current concurrency limits).
This means there is a potential for many low-bandwidth sticky channels to compete with regular channels.

## Supported Per-Endpoint Conjure Tags

* `dialogue-disable-endpoint-concurrency-limiting`: Opts a single endpoint out of per-endpoint concurrency limiting, however per-host concurrency limiting continues to apply!
* `prefer-compressed-response`: Forces requests to always include `Accept-Encoding: gzip`, rather than attempting to opt out of response compression for in-environment requests. This usually shouldn't be used because compression can be much more expensive than network transfer.
* `compress-request`: Request bodies are gzip compressed. This requires prior knowledge that the receiving server handles `Content-Encoding: gzip` request bodies.

## Alternative HTTP clients

Dialogue is not coupled to a single HTTP client library - this repo contains implementations based on [OkHttp](https://square.github.io/okhttp/), Java's [HttpURLConnection](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html), the new Java11 HttpClient as well as the aforementioned [Apache HttpClient](https://hc.apache.org/httpcomponents-client-ga/).  We endorse the Apache client because it performed the best in our benchmarks and affords granular control over connection pools.

## History

Dialogue is the product of years of learning from operating thousands of Java servers across hundreds of deployments. [Previous incarnations](https://github.com/palantir/conjure-java-runtime) relied on Feign, Retrofit2 and OkHttp.

## Contributing

For instructions on how to set up your local development environment, check out the
[CONTRIBUTING.md](./CONTRIBUTING.md).


# Apache Camel Karaf

[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.camel.karaf/karaf/badge.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/org.apache.camel.karaf/karaf)

[Apache Camel](http://camel.apache.org/) is a powerful open source integration framework based on known
Enterprise Integration Patterns with powerful bean integration.

This project provides Apache Karaf support for Apache Camel.