# RTDS Java Library

Java library for using the Airship Real-Time Data Streaming API.
## Resources

* [Github Repo](https://github.com/urbanairship/connect-java-library/)
* [Maven Central](https://mvnrepository.com/artifact/com.urbanairship/connect-client)
* [RTDS API Reference](https://www.airship.com/docs/developer/rest-api/connect/)


## Installation

Add the library using Maven by adding the following lines to your pom.xml:

```xml
<!-- Airship Library Dependency-->
<dependency>
    <groupId>com.urbanairship</groupId>
    <artifactId>connect-client</artifactId>
    <version>VERSION</version>
    <!-- Replace VERSION with the version you want to use -->
</dependency>
```


The client library provides all the components you need to consume a mobile event stream.

### Max strength encryption policy

RTDS requests with this client may experience SSL handshake failures unless using the
**Java Cryptography Extension (JCE) Unlimited Strength** package cipher suite.

If you encounter a generic connection failure `java.lang.RuntimeException`, the max strength encryption policy might be the culprit, and you should ensure this JCE Unlimited Strength package is installed on your system. Use the package that corresponds to your JRE version:

- [JCE Unlimited Strength Jurisdiction Policy Files 7](http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html)
- [JCE Unlimited Strength Jurisdiction Policy Files 8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)

**These files are not required for JRE 9 or for JRE 8u151 or newer.**

## Getting started

The following sections provide information for setting up, consuming, and filtering the stream, 

### Setting up the stream

To set up the stream for consumption, first set the `Creds`, and then create a `StreamQueryDescriptor` and use the descriptor to create a `Stream`.

**Configure the stream**

```java
Creds creds = Creds.newBuilder()
          .setAppKey("key")
          .setToken("token")
          .build();

  StreamQueryDescriptor descriptor = StreamQueryDescriptor.newBuilder()
          .setCreds(creds)
          .build();
```


### Consuming the stream

After the steam is configured, it can be consumed.

**Example stream that disconnects after 60 seconds**

```java
final Stream stream = new Stream(descriptor, Optional.<StartPosition>absent());

  final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

  Runnable stopConsuming = new Runnable() {
      public void run() {
          try {
              stream.close();
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              scheduledExecutorService.shutdown();
          }
      }
  };

  scheduledExecutorService.schedule(stopConsuming, 60, TimeUnit.SECONDS);

  while (stream.hasNext()) {
      String event = stream.next();
      System.out.println("Event: " + event);
  }
```


### Filtering the stream

The following shows various filters and stream customizations:

**Filters and customization example**

```java
Optional<StartPosition> startPosition = Optional.fromNullable(StartPosition.relative(StartPosition.RelativePosition.EARLIEST));

  DeviceFilter device1 = new DeviceFilter(DeviceFilterType.ANDROID_CHANNEL, "152d00c3-c49c-4172-88ce-539c511cf346");
  DeviceFilter device2 = new DeviceFilter(DeviceFilterType.IOS_CHANNEL, "67fa2bad-9e83-4259-b925-bc08c184f72e");
  DeviceFilter device3 = new DeviceFilter(DeviceFilterType.NAMED_USER_ID, "cool_user");

  NotificationFilter notification = new NotificationFilter(NotificationFilter.Type.GROUP_ID, "58179035-dd1f-4b04-b023-5035c6335786");

  Filter filter = Filter.newBuilder()
          .setLatency(20000000)
          .addDevices(device1, device2, device3)
          .addDeviceTypes(DeviceType.ANDROID, DeviceType.IOS)
          .addNotifications(notification)
          .addEventTypes("OPEN")
          .build();

  Subset subset = Subset.createSampleSubset(0.3f);

  StreamQueryDescriptor descriptor = StreamQueryDescriptor.newBuilder()
          .setCreds(creds)
          .addFilters(filter)
          .setSubset(subset)
          .build();

  final Stream stream = new Stream(descriptor, startPosition);
```


`Filter`, `Subset`, and `DeviceFilter` can also be applied to a stream to retrieve whatever information wanted.
