org.zodiark.subscriber.SubscriberTest.java Source code

Java tutorial

Introduction

Here is the source code for org.zodiark.subscriber.SubscriberTest.java

Source

/*
 * Copyright 2013-2014 High-Level Technologies
 *
 * 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.
 */
package org.zodiark.subscriber;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.zodiark.protocol.ActorValue;
import org.zodiark.protocol.Envelope;
import org.zodiark.protocol.From;
import org.zodiark.protocol.Message;
import org.zodiark.protocol.Path;
import org.zodiark.protocol.Paths;
import org.zodiark.server.ZodiarkServer;
import org.zodiark.service.action.Action;
import org.zodiark.service.publisher.PublisherResults;
import org.zodiark.service.session.StreamingRequest;
import org.zodiark.service.subscriber.SubscriberResults;
import org.zodiark.service.util.StreamingRequestImpl;
import org.zodiark.service.util.Time;
import org.zodiark.service.wowza.WowzaMessage;
import org.zodiark.service.wowza.WowzaUUID;
import org.zodiark.wowza.OnEnvelopHandler;
import org.zodiark.wowza.ZodiarkClient;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;

public class SubscriberTest {

    private final ObjectMapper mapper = new ObjectMapper();

    public final static int findFreePort() {
        ServerSocket socket = null;

        try {
            socket = new ServerSocket(0);

            return socket.getLocalPort();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return 8080;
    }

    private ZodiarkServer server;
    private int port = findFreePort();

    @BeforeMethod
    public void startZodiark() {
        server = new ZodiarkServer().listen(URI.create("http://127.0.0.1:" + port)).on();
    }

    @AfterMethod
    public void stopZodiark() {
        if (server != null)
            server.off();
    }

    @Test(enabled = false)
    public void createSessionTest() throws IOException, InterruptedException {
        final AtomicReference<SubscriberResults> answer = new AtomicReference<>();
        final ZodiarkClient publisherClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch latch = new CountDownLatch(1);

        publisherClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                answer.set(mapper.readValue(e.getMessage().getData(), SubscriberResults.class));
                latch.countDown();
                return true;
            }
        }).open();

        Envelope createSessionMessage = Envelope
                .newClientToServerRequest(new Message(new Path(Paths.DB_POST_SUBSCRIBER_SESSION_CREATE),
                        mapper.writeValueAsString(new UserPassword("foo", "bar"))));
        createSessionMessage.setFrom(new From(ActorValue.SUBSCRIBER));
        publisherClient.send(createSessionMessage);
        latch.await();
        assertEquals("OK", answer.get().getResults());
    }

    @Test(enabled = false)
    public void joinStreamingSession() throws IOException, InterruptedException {
        final ZodiarkClient wowzaClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch connected = new CountDownLatch(1);
        final AtomicReference<String> uuid = new AtomicReference<>();
        final AtomicReference<String> paths = new AtomicReference<>();

        // =============== Wowza

        paths.set("");
        wowzaClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {

                Message m = e.getMessage();
                switch (m.getPath()) {
                case Paths.WOWZA_CONNECT:
                    // Connected. Listen
                    uuid.set(e.getUuid());
                    break;
                case Paths.SERVER_VALIDATE_OK:
                    Envelope publisherOk = Envelope
                            .newClientToServerRequest(new Message(new Path(paths.get()), e.getMessage().getData()));
                    wowzaClient.send(publisherOk);
                    break;
                default:
                    // ERROR
                }

                connected.countDown();
                return false;
            }
        }).open();

        Envelope wowzaConnect = Envelope.newClientToServerRequest(new Message(new Path(Paths.WOWZA_CONNECT),
                mapper.writeValueAsString(new UserPassword("wowza", "bar"))));
        wowzaClient.send(wowzaConnect);
        connected.await();

        // ================ Publisher

        final AtomicReference<PublisherResults> answer = new AtomicReference<>();
        final ZodiarkClient publisherClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> publisherUUID = new AtomicReference<>();
        publisherClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                answer.set(mapper.readValue(e.getMessage().getData(), PublisherResults.class));
                publisherUUID.set(e.getUuid());
                latch.countDown();
                return true;
            }
        }).open();

        Envelope createSessionMessage = Envelope.newClientToServerRequest(
                new Message(new Path(""), mapper.writeValueAsString(new UserPassword("publisherex", "bar"))));
        createSessionMessage.setFrom(new From(ActorValue.PUBLISHER));
        publisherClient.send(createSessionMessage);
        latch.await();
        assertEquals("OK", answer.get().getResults());
        answer.set(null);

        final CountDownLatch tlatch = new CountDownLatch(1);
        publisherClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                answer.set(mapper.readValue(e.getMessage().getData(), PublisherResults.class));
                tlatch.countDown();
                return true;
            }
        });

        Envelope startStreamingSession = Envelope
                .newClientToServerRequest(new Message(new Path(Paths.VALIDATE_PUBLISHER_STREAMING_SESSION),
                        mapper.writeValueAsString(new WowzaUUID(uuid.get()))));
        createSessionMessage.setFrom(new From(ActorValue.PUBLISHER));
        publisherClient.send(startStreamingSession);

        tlatch.await();

        assertEquals("OK", answer.get().getResults());

        // ================ Subscriber

        paths.set(Paths.JOIN_SUBSCRIBER_STREAMING_SESSION);
        final AtomicReference<SubscriberResults> sanswer = new AtomicReference<>();
        final ZodiarkClient subscriberClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch platch = new CountDownLatch(1);
        final AtomicReference<String> subscriberUUID = new AtomicReference<>();

        subscriberClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                sanswer.set(mapper.readValue(e.getMessage().getData(), SubscriberResults.class));
                subscriberUUID.set(e.getUuid());
                platch.countDown();
                return true;
            }
        }).open();

        createSessionMessage = Envelope.newClientToServerRequest(subscriberUUID.get(),
                new Message(new Path(Paths.DB_POST_SUBSCRIBER_SESSION_CREATE),
                        mapper.writeValueAsString(new UserPassword("123456", "bar"))));
        createSessionMessage.setFrom(new From(ActorValue.SUBSCRIBER));
        subscriberClient.send(createSessionMessage);
        platch.await();
        assertEquals("OK", sanswer.get().getResults());
        sanswer.set(null);

        final CountDownLatch elatch = new CountDownLatch(1);
        subscriberClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                sanswer.set(mapper.readValue(e.getMessage().getData(), SubscriberResults.class));
                elatch.countDown();
                return true;
            }
        });

        StreamingRequest request = new StreamingRequestImpl(publisherUUID.get(), uuid.get());

        startStreamingSession = Envelope.newClientToServerRequest(subscriberUUID.get(), new Message(
                new Path(Paths.VALIDATE_SUBSCRIBER_STREAMING_SESSION), mapper.writeValueAsString(request)));
        createSessionMessage.setFrom(new From(ActorValue.SUBSCRIBER));
        subscriberClient.send(startStreamingSession);

        elatch.await();

        assertEquals("OK", sanswer.get().getResults());

    }

    @Test(enabled = false)
    public void sucessfulRequestForAction() throws IOException, InterruptedException {
        final CountDownLatch completed = new CountDownLatch(1);

        final ZodiarkClient wowzaClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch connected = new CountDownLatch(1);
        final AtomicReference<String> uuid = new AtomicReference<>();
        final AtomicReference<String> paths = new AtomicReference<>();

        // =============== Wowza

        paths.set("");
        wowzaClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {

                Message m = e.getMessage();
                switch (m.getPath()) {
                case Paths.WOWZA_CONNECT:
                    // Connected. Listen
                    uuid.set(e.getUuid());
                    break;
                case Paths.SERVER_VALIDATE_OK:
                    Envelope publisherOk = Envelope.newClientToServerRequest(e.getUuid(),
                            new Message(new Path(paths.get()), e.getMessage().getData()));
                    wowzaClient.send(publisherOk);
                    break;
                case Paths.WOWZA_OBFUSCATE:
                    WowzaMessage wm = mapper.readValue(m.getData(), WowzaMessage.class);
                    Envelope ok = Envelope.newClientToServerRequest(e.getUuid(),
                            new Message(new Path(Paths.WOWZA_OBFUSCATE_OK), e.getMessage().getData()));
                    System.out.println("Obfuscating Subscribers");
                    wowzaClient.send(ok);
                case Paths.WOWZA_DEOBFUSCATE:
                    wm = mapper.readValue(m.getData(), WowzaMessage.class);
                    System.out.println("De-obfuscating Subscribers");
                    ok = Envelope.newClientToServerRequest(e.getUuid(),
                            new Message(new Path(Paths.WOWZA_DEOBFUSCATE_OK), e.getMessage().getData()));
                    wowzaClient.send(ok);
                default:
                    // ERROR
                }

                connected.countDown();
                return false;
            }
        }).open();

        Envelope wowzaConnect = Envelope.newClientToServerRequest(new Message(new Path(Paths.WOWZA_CONNECT),
                mapper.writeValueAsString(new UserPassword("wowza", "bar"))));
        wowzaClient.send(wowzaConnect);
        connected.await();

        // ================ Publisher

        final AtomicReference<PublisherResults> answer = new AtomicReference<>();
        final ZodiarkClient publisherClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> publisherUUID = new AtomicReference<>();
        publisherClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                answer.set(mapper.readValue(e.getMessage().getData(), PublisherResults.class));
                publisherUUID.set(e.getUuid());
                latch.countDown();
                return true;
            }
        }).open();

        // ================ Publisher create the session

        Envelope createSessionMessage = Envelope.newClientToServerRequest(
                new Message(new Path(""), mapper.writeValueAsString(new UserPassword("publisherex", "bar"))));
        createSessionMessage.setFrom(new From(ActorValue.PUBLISHER));
        publisherClient.send(createSessionMessage);
        latch.await();
        assertEquals("OK", answer.get().getResults());
        answer.set(null);

        final CountDownLatch tlatch = new CountDownLatch(1);
        final AtomicReference<String> finalMessage = new AtomicReference<>();

        publisherClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {

                switch (e.getMessage().getPath()) {
                case Paths.BEGIN_STREAMING_SESSION:
                    answer.set(mapper.readValue(e.getMessage().getData(), PublisherResults.class));
                    tlatch.countDown();
                    break;
                case Paths.PUBLISHER_ACTION_ACCEPT:
                    Action a = mapper.readValue(e.getMessage().getData(), Action.class);
                    Envelope publisherOk = Envelope.newClientToServerRequest(e.getUuid(),
                            new Message(new Path(Paths.ZODIARK_ACTION_ACCEPTED), e.getMessage().getData()));
                    publisherClient.send(publisherOk);
                    break;
                case Paths.ACTION_START:
                    // Start action
                    PublisherResults results = mapper.readValue(e.getMessage().getData(), PublisherResults.class);
                    System.out.println("==> Start Action " + results.getResults());

                    publisherOk = Envelope.newClientToServerRequest(e.getUuid(),
                            new Message(new Path(Paths.ACTION_START_OK), e.getMessage().getData()));
                    publisherClient.send(publisherOk);
                    break;
                case Paths.ACTION_TIMER:
                    Time t = mapper.readValue(e.getMessage().getData(), Time.class);
                    System.out.println("Publisher ===>" + t);
                    break;
                case Paths.ACTION_COMPLETED:
                    results = mapper.readValue(e.getMessage().getData(), PublisherResults.class);
                    System.out.println("Publisher Action completed");
                    completed.countDown();
                    break;
                case Paths.PUBLISHER_ABOUT_READY:
                    results = mapper.readValue(e.getMessage().getData(), PublisherResults.class);

                    finalMessage.set(results.getResults());
                    break;
                }
                return false;
            }
        });

        // ================ Prepare for streaming, handshake with Wowza

        Envelope startStreamingSession = Envelope
                .newClientToServerRequest(new Message(new Path(Paths.VALIDATE_PUBLISHER_STREAMING_SESSION),
                        mapper.writeValueAsString(new WowzaUUID(uuid.get()))));
        createSessionMessage.setFrom(new From(ActorValue.PUBLISHER));
        publisherClient.send(startStreamingSession);

        tlatch.await();

        assertEquals("OK", answer.get().getResults());

        // ================ Subscriber

        paths.set(Paths.JOIN_SUBSCRIBER_STREAMING_SESSION);
        final AtomicReference<SubscriberResults> sanswer = new AtomicReference<>();
        final ZodiarkClient subscriberClient = new ZodiarkClient.Builder().path("http://127.0.0.1:" + port).build();
        final CountDownLatch platch = new CountDownLatch(1);
        final AtomicReference<String> subscriberUUID = new AtomicReference<>();

        subscriberClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                sanswer.set(mapper.readValue(e.getMessage().getData(), SubscriberResults.class));
                subscriberUUID.set(e.getUuid());
                platch.countDown();
                return true;
            }
        }).open();

        // ================ Subscriber create the session

        createSessionMessage = Envelope.newClientToServerRequest(subscriberUUID.get(),
                new Message(new Path(Paths.DB_POST_SUBSCRIBER_SESSION_CREATE),
                        mapper.writeValueAsString(new UserPassword("123456", "bar"))));
        createSessionMessage.setFrom(new From(ActorValue.SUBSCRIBER));
        subscriberClient.send(createSessionMessage);
        platch.await();
        assertEquals("OK", sanswer.get().getResults());
        sanswer.set(null);

        final CountDownLatch elatch = new CountDownLatch(1);
        subscriberClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                sanswer.set(mapper.readValue(e.getMessage().getData(), SubscriberResults.class));
                elatch.countDown();
                return true;
            }
        });

        // ================ Join the Publisher Session

        StreamingRequest request = new StreamingRequestImpl(publisherUUID.get(), uuid.get());
        startStreamingSession = Envelope.newClientToServerRequest(subscriberUUID.get(), new Message(
                new Path(Paths.VALIDATE_SUBSCRIBER_STREAMING_SESSION), mapper.writeValueAsString(request)));
        startStreamingSession.setFrom(new From(ActorValue.SUBSCRIBER));
        subscriberClient.send(startStreamingSession);

        elatch.await();

        assertEquals("OK", sanswer.get().getResults());

        // ================ Ask for an Action the Publisher Session

        Action action = new Action();
        action.setPath("/action/doSomething");
        action.setData("{ \"foo\":\"bar\"");
        Envelope e = Envelope.newClientToServerRequest(subscriberUUID.get(),
                new Message(new Path(Paths.SUBSCRIBER_ACTION), mapper.writeValueAsString(action)));
        e.setFrom(new From(ActorValue.SUBSCRIBER));
        final CountDownLatch actionLatch = new CountDownLatch(1);
        final AtomicReference<Envelope> response = new AtomicReference<>();
        final AtomicBoolean timerCalled = new AtomicBoolean();
        subscriberClient.handler(new OnEnvelopHandler() {
            @Override
            public boolean onEnvelop(Envelope e) throws IOException {
                switch (e.getMessage().getPath()) {
                case Paths.MESSAGE_ACTION_VALIDATE:
                    response.set(e);
                    actionLatch.countDown();
                    break;
                case Paths.ACTION_TIMER:
                    Time t = mapper.readValue(e.getMessage().getData(), Time.class);
                    System.out.println("Subscriber ===>" + t);
                    timerCalled.set(true);
                    break;
                case Paths.ACTION_COMPLETED:
                    SubscriberResults results = mapper.readValue(e.getMessage().getData(), SubscriberResults.class);
                    System.out.println("Action completed");
                    break;
                }

                return false;
            }
        });
        subscriberClient.send(e);

        actionLatch.await();

        assertEquals(Paths.MESSAGE_ACTION_VALIDATE, response.get().getMessage().getPath());
        assertEquals("{\"results\":\"OK\",\"uuid\":null}", response.get().getMessage().getData());

        completed.await();

        assertTrue(timerCalled.get());
        assertEquals("READY", finalMessage.get());
    }

}