io.joynr.jeeintegration.messaging.JeeServletMessageReceiver.java Source code

Java tutorial

Introduction

Here is the source code for io.joynr.jeeintegration.messaging.JeeServletMessageReceiver.java

Source

/**
 *
 */
package io.joynr.jeeintegration.messaging;

/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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 java.util.concurrent.CompletionStage;
import java.util.concurrent.Future;

import com.google.common.util.concurrent.Futures;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

import io.joynr.dispatcher.ServletMessageReceiver;
import io.joynr.jeeintegration.httpbridge.HttpBridgeRegistryClient;
import io.joynr.messaging.MessageArrivedListener;
import io.joynr.messaging.MessagingPropertyKeys;
import io.joynr.messaging.ReceiverStatusListener;
import joynr.JoynrMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.joynr.jeeintegration.api.JeeIntegrationPropertyKeys.JEE_ENABLE_HTTP_BRIDGE_CONFIGURATION_KEY;
import static java.lang.String.format;

/**
 * Implementation of a servlet message receiver which is used to register / unregister the channel and also pass on
 * messages and errors to the message listener of the runtime.
 */
@Singleton
public class JeeServletMessageReceiver implements ServletMessageReceiver {

    private static final Logger LOG = LoggerFactory.getLogger(JeeServletMessageReceiver.class);

    private final String channelId;

    private final String hostPath;

    private final String contextRoot;

    private boolean registered = false;

    private MessageArrivedListener messageListener;

    private final HttpBridgeRegistryClient httpBridgeRegistryClient;

    private boolean httpBridgeEnabled;

    @Inject
    public JeeServletMessageReceiver(@Named(MessagingPropertyKeys.CHANNELID) String channelId,
            @Named(MessagingPropertyKeys.PROPERTY_SERVLET_CONTEXT_ROOT) String contextRoot,
            @Named(MessagingPropertyKeys.PROPERTY_SERVLET_HOST_PATH) String hostPath,
            HttpBridgeRegistryClient httpBridgeRegistryClient,
            @Named(JEE_ENABLE_HTTP_BRIDGE_CONFIGURATION_KEY) String httpBridgeEnabled) {
        if (LOG.isDebugEnabled()) {
            LOG.debug(format(
                    "Initialising with:%n\tchannelId: %s%n\tcontextRoot: %s%n\thostPath: %s%n\thttpBridgeRegistryClient: %s",
                    channelId, contextRoot, hostPath, httpBridgeRegistryClient));
        }
        this.channelId = channelId;
        this.hostPath = hostPath;
        this.contextRoot = contextRoot;
        this.httpBridgeRegistryClient = httpBridgeRegistryClient;
        this.httpBridgeEnabled = Boolean.valueOf(httpBridgeEnabled);
    }

    @Override
    public String getChannelId() {
        return channelId;
    }

    @Override
    public void shutdown(boolean clear) {
        if (registered) {
            LOG.info("Shutting down servlet message receiver.");
            registered = false;
        }
    }

    @Override
    public boolean isReady() {
        return messageListener != null;
    }

    @Override
    public boolean deleteChannel() {
        LOG.info(format("Deleting channel %s", channelId));
        return false;
    }

    @Override
    public boolean isStarted() {
        if (LOG.isDebugEnabled()) {
            LOG.debug(format("isStarted called - returning %s", registered));
        }
        return registered;
    }

    @Override
    public void suspend() {
        LOG.info(format("Suspend called on channel %s, but functionality not supported. Ignoring.", channelId));
    }

    @Override
    public void resume() {
        LOG.info(format("Resume called on channel %s, but functionality not supported. Ignoring.", channelId));
    }

    @Override
    public Future<Void> start(MessageArrivedListener messageArrivedListener,
            ReceiverStatusListener... receiverStatusListeners) {
        if (messageArrivedListener == null) {
            throw new IllegalStateException();
        }
        LOG.info("Starting JeeServletMessageReceiver with listener {}", messageArrivedListener);
        this.messageListener = messageArrivedListener;
        if (!registered) {
            registerChannelUrl();
        }
        return Futures.immediateFuture(null);
    }

    @Override
    public boolean switchToLongPolling() {
        LOG.info(format("JEE servlet message receiver does not support long polling. Ignoring."));
        return false;
    }

    @Override
    public void receive(JoynrMessage message) {
        if (message != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug(format(">>>>>> Message arrived on channel %s:%n\t%s%n", channelId, message));
            }
            messageListener.messageArrived(message);
        } else {
            LOG.warn(format("Received null message on channel %s", channelId));
        }
    }

    @Override
    public void onError(JoynrMessage message, Throwable error) {
        if (messageListener != null) {
            messageListener.error(message, error);
        } else {
            LOG.warn(format(
                    "Channel %s dropped message %s because no message listener available.%nError received: %s",
                    channelId, message, error));
        }
    }

    private synchronized void registerChannelUrl() {
        if (!registered) {
            if (hostPath == null) {
                String message = "The system property hostPath must be set with name:port eg. http://localhost:8080";
                IllegalArgumentException illegalArgumentException = new IllegalArgumentException(message);
                LOG.error(message, illegalArgumentException);
                throw illegalArgumentException;
            }
            if (httpBridgeEnabled) {
                LOG.debug("HTTP Bridge enabled - registering channel with endpoint registry.");
                String endpointUrl = hostPath + contextRoot + "/channels/" + channelId + "/";
                CompletionStage<Void> registrationResult = httpBridgeRegistryClient.register(endpointUrl,
                        channelId);
                registrationResult.thenAccept((v) -> {
                    registered = true;
                }).exceptionally((t) -> {
                    LOG.error("Unable to register channel URL.", t);
                    return null;
                });
            } else {
                LOG.debug("HTTP Bridge disabled.");
                registered = true;
            }
        }
    }
}