com.devicehive.handler.notification.NotificationSubscribeInsertIntegrationTest.java Source code

Java tutorial

Introduction

Here is the source code for com.devicehive.handler.notification.NotificationSubscribeInsertIntegrationTest.java

Source

package com.devicehive.handler.notification;

/*
 * #%L
 * DeviceHive Backend Logic
 * %%
 * Copyright (C) 2016 DataArt
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import com.devicehive.base.AbstractSpringTest;
import com.devicehive.model.DeviceNotification;
import com.devicehive.model.eventbus.events.NotificationEvent;
import com.devicehive.model.rpc.*;
import com.devicehive.shim.api.Body;
import com.devicehive.shim.api.Request;
import com.devicehive.shim.api.Response;
import com.devicehive.shim.api.client.RpcClient;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.UUID.randomUUID;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class NotificationSubscribeInsertIntegrationTest extends AbstractSpringTest {

    @Autowired
    private RpcClient client;

    @Test
    public void shouldSubscribeToDeviceNotifications() throws Exception {
        String device1 = randomUUID().toString();
        String device2 = randomUUID().toString();

        String subscriber1 = randomUUID().toString();
        String subscriber2 = randomUUID().toString();
        String subscriber3 = randomUUID().toString();

        NotificationSubscribeRequest sr1 = new NotificationSubscribeRequest(subscriber1, device1, null, null);
        Request r1 = Request.newBuilder().withBody(sr1).withSingleReply(false).build();
        TestCallback c1 = new TestCallback();
        client.call(r1, c1);

        NotificationSubscribeRequest sr2 = new NotificationSubscribeRequest(subscriber1, device2,
                Collections.singleton("temperature"), null);
        Request r2 = Request.newBuilder().withBody(sr2).withSingleReply(false).build();
        TestCallback c2 = new TestCallback();
        client.call(r2, c2);

        NotificationSubscribeRequest sr3 = new NotificationSubscribeRequest(subscriber2, device2, null, null);
        Request r3 = Request.newBuilder().withBody(sr3).withSingleReply(false).build();
        TestCallback c3 = new TestCallback();
        client.call(r3, c3);

        NotificationSubscribeRequest sr4 = new NotificationSubscribeRequest(subscriber2, device1,
                Collections.singleton("vibration"), null);
        Request r4 = Request.newBuilder().withBody(sr4).withSingleReply(false).build();
        TestCallback c4 = new TestCallback();
        client.call(r4, c4);

        NotificationSubscribeRequest sr5 = new NotificationSubscribeRequest(subscriber3, randomUUID().toString(),
                null, null);
        Request r5 = Request.newBuilder().withBody(sr5).withSingleReply(false).build();
        TestCallback c5 = new TestCallback();
        client.call(r5, c5);

        //wait subsribers to subscribe
        Stream.of(c1.subscribeFuture, c2.subscribeFuture, c3.subscribeFuture, c4.subscribeFuture,
                c5.subscribeFuture).forEach(CompletableFuture::join);

        //devices send notifications
        List<CompletableFuture<Response>> futures = Stream.of(device1, device2).flatMap(device -> {
            List<CompletableFuture<Response>> list = Stream.of("temperature", "vibration").map(name -> {
                DeviceNotification notification = new DeviceNotification();
                notification.setId(0);
                notification.setNotification(name);
                notification.setDeviceGuid(device);
                NotificationInsertRequest event = new NotificationInsertRequest(notification);
                CompletableFuture<Response> f = new CompletableFuture<>();
                client.call(Request.newBuilder().withBody(event).build(), f::complete);
                return f;
            }).collect(Collectors.toList());
            return list.stream();
        }).collect(Collectors.toList());

        //wait notifications delivered
        futures.forEach(CompletableFuture::join);

        assertThat(c1.notifications, hasSize(2));
        c1.notifications.forEach(event -> {
            assertNotNull(event.getNotification());
            assertEquals(event.getNotification().getDeviceGuid(), device1);
            assertEquals(event.getNotification().getId(), Long.valueOf(0));
        });
        Set<String> names = c1.notifications.stream().map(n -> n.getNotification().getNotification())
                .collect(Collectors.toSet());
        assertThat(names, containsInAnyOrder("temperature", "vibration"));

        assertThat(c2.notifications, hasSize(1));
        NotificationEvent e = c2.notifications.stream().findFirst().get();
        assertNotNull(e.getNotification());
        assertEquals(e.getNotification().getDeviceGuid(), device2);
        assertEquals(e.getNotification().getId(), Long.valueOf(0));
        assertEquals(e.getNotification().getNotification(), "temperature");

        assertThat(c3.notifications, hasSize(2));
        c3.notifications.forEach(event -> {
            assertNotNull(event.getNotification());
            assertEquals(event.getNotification().getDeviceGuid(), device2);
            assertEquals(event.getNotification().getId(), Long.valueOf(0));
        });
        names = c3.notifications.stream().map(n -> n.getNotification().getNotification())
                .collect(Collectors.toSet());
        assertThat(names, containsInAnyOrder("temperature", "vibration"));

        assertThat(c4.notifications, hasSize(1));
        e = c4.notifications.stream().findFirst().get();
        assertNotNull(e.getNotification());
        assertEquals(e.getNotification().getDeviceGuid(), device1);
        assertEquals(e.getNotification().getId(), Long.valueOf(0));
        assertEquals(e.getNotification().getNotification(), "vibration");

        assertThat(c5.notifications, is(empty()));
    }

    @Test
    @Ignore
    public void shouldUnsubscribeFromNotifications() throws Exception {
        String device1 = randomUUID().toString();

        String subscriber1 = randomUUID().toString();
        String subscriber2 = randomUUID().toString();

        NotificationSubscribeRequest sr1 = new NotificationSubscribeRequest(subscriber1, device1, null, null);
        Request r1 = Request.newBuilder().withBody(sr1).withSingleReply(false).build();
        TestCallback c1 = new TestCallback();
        client.call(r1, c1);

        NotificationSubscribeRequest sr2 = new NotificationSubscribeRequest(subscriber2, device1, null, null);
        Request r2 = Request.newBuilder().withBody(sr2).withSingleReply(false).build();
        TestCallback c2 = new TestCallback();
        client.call(r2, c2);

        Stream.of(c1.subscribeFuture, c2.subscribeFuture).forEach(CompletableFuture::join);

        DeviceNotification notification = new DeviceNotification();
        notification.setId(0);
        notification.setNotification("temperature");
        notification.setDeviceGuid(device1);
        NotificationInsertRequest event = new NotificationInsertRequest(notification);
        CompletableFuture<Response> f1 = new CompletableFuture<>();
        client.call(Request.newBuilder().withBody(event).build(), f1::complete);

        f1.get(15, TimeUnit.SECONDS);

        assertThat(c1.notifications, hasSize(1));
        assertThat(c2.notifications, hasSize(1));

        NotificationUnsubscribeRequest ur = new NotificationUnsubscribeRequest(sr1.getSubscriptionId(), null);
        Request r3 = Request.newBuilder().withBody(ur).withSingleReply(false).build();
        client.call(r3, c1);

        c1.subscribeFuture.join();

        DeviceNotification notification2 = new DeviceNotification();
        notification2.setId(1);
        notification2.setNotification("temperature");
        notification2.setDeviceGuid(device1);
        NotificationInsertRequest event2 = new NotificationInsertRequest(notification2);
        CompletableFuture<Response> f2 = new CompletableFuture<>();
        client.call(Request.newBuilder().withBody(event2).build(), f2::complete);

        f2.join();

        assertThat(c1.notifications, hasSize(1));
        assertThat(c2.notifications, hasSize(2));
    }

    public static class TestCallback implements Consumer<Response> {

        private CompletableFuture<Body> subscribeFuture;
        private Set<NotificationEvent> notifications;

        public TestCallback() {
            this.subscribeFuture = new CompletableFuture<>();
            this.notifications = new HashSet<>();
        }

        @Override
        public void accept(Response response) {
            if (response.getBody().getAction().equals(Action.NOTIFICATION_SUBSCRIBE_RESPONSE.name())
                    || response.getBody().getAction().equals(Action.NOTIFICATION_UNSUBSCRIBE_RESPONSE.name())) {
                subscribeFuture.complete(response.getBody());
            } else if (response.getBody().getAction().equals(Action.NOTIFICATION_EVENT.name())) {
                notifications.add((NotificationEvent) response.getBody());
            } else {
                throw new IllegalArgumentException("Unexpected response " + response);
            }
        }
    }

}