All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.appng.api.messaging.Messaging Maven / Gradle / Ivy

There is a newer version: 1.24.5
Show newest version
/*
 * Copyright 2011-2021 the original author or authors.
 *
 * 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.appng.api.messaging;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;

import org.appng.api.Environment;
import org.appng.api.Platform;
import org.appng.api.Scope;
import org.appng.api.model.Properties;

import lombok.extern.slf4j.Slf4j;

/**
 * A utility class offering static helper methods to create and retrieve a {@link Sender} and to shutdown
 * {@link Sender}s and {@link Receiver}s.
 * 
 * @author Matthias Müller
 *
 * @see Sender
 * @see Receiver
 */
@Slf4j
public class Messaging {

	/**
	 * Name of a system property used to identify the node
	 */
	public static final String APPNG_NODE_ID = "appng.node.id";

	/**
	 * Retrieves the previously created {@link Sender} from the {@link Environment}.
	 * 
	 * @param env
	 *            the {@link Environment} to use
	 * 
	 * @return the {@link Sender}, if available
	 * 
	 * @see #createMessageSender(Environment, ExecutorService)
	 * @see #createMessageSender(Environment, ExecutorService, String, EventHandler, Iterable)
	 */
	public static Sender getMessageSender(Environment env) {
		return env.getAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_SENDER);
	}

	/**
	 * Creates and returns a new {@link Sender} and a corresponding {@link Receiver}. The class name for the receiver is
	 * taken from the platform property {@value org.appng.api.Platform.Property#MESSAGING_RECEIVER}. Uses the system
	 * property {@value #APPNG_NODE_ID} to retrieve the node id for the {@link Serializer}. If this property is absent,
	 * the local host name is used and the property is set.
	 * 
	 * @param env
	 *                 the {@link Environment} to use
	 * @param executor
	 *                 the {@link ExecutorService} to run the {@link Receiver} with
	 * 
	 * @return
	 *         
    *
  • the {@link Sender} (if the platform property * {@value org.appng.api.Platform.Property#MESSAGING_ENABLED} is {@code true} *
  • {@code null} if messaging is disabled or an error occurred while creating the sender *
*/ public static Sender createMessageSender(Environment env, ExecutorService executor) { return createMessageSender(env, executor, getNodeId(env), null, null); } /** * Determines the node id for this node. If the system property {@value #APPNG_NODE_ID} is set, this value is used. * Otherwise, the local host name is used (from {@code java.net.InetAddress.getLocalHost().getHostName()}}). * * @param env * the {@link Environment} to use * * @return the node id for this node */ public static String getNodeId(Environment env) { String nodeId = System.getProperty(APPNG_NODE_ID); if (null == nodeId && getPlatformConfig(env).getBoolean("messagingFallbackToHostName", Boolean.TRUE)) { try { nodeId = InetAddress.getLocalHost().getHostName(); LOGGER.info("system property {} is not set, using local host name {} as fallback", APPNG_NODE_ID, nodeId); System.setProperty(APPNG_NODE_ID, nodeId); } catch (UnknownHostException e) { LOGGER.warn(String.format("error setting system property %s", APPNG_NODE_ID), e); } } return nodeId; } protected static Properties getPlatformConfig(Environment env) { return env.getAttribute(Scope.PLATFORM, Platform.Environment.PLATFORM_CONFIG); } /** * Creates and returns a new {@link Sender} and a corresponding {@link Receiver}. The class name for the receiver is * taken from the platform property {@value org.appng.api.Platform.Property#MESSAGING_RECEIVER}. * * @param env * the {@link Environment} to use * @param executor * the {@link ExecutorService} to run the {@link Receiver} with * @param nodeId * the node id for the {@link Serializer} * @param defaultHandler * the default {@link EventHandler} for the {@link Receiver} (may be {@code null}) * @param handlers * a list of {@link EventHandler}s to be registered at the {@link Receiver} * * @return *
    *
  • the {@link Sender} (if the platform property * {@value org.appng.api.Platform.Property#MESSAGING_ENABLED} is {@code true} *
  • {@code null} if messaging is disabled or an error occurred while creating the sender *
*/ public static Sender createMessageSender(Environment env, ExecutorService executor, String nodeId, EventHandler defaultHandler, Iterable> handlers) { if (isEnabled(env)) { Sender sender = env.getAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_SENDER); if (null == sender) { try { LOGGER.info("node id is {}", nodeId); Serializer eventSerializer = new Serializer(env, nodeId); String messagingReceiverClassName = getPlatformConfig(env) .getString(Platform.Property.MESSAGING_RECEIVER); @SuppressWarnings("unchecked") Class messagingReceiverClass = (Class) Class .forName(messagingReceiverClassName); LOGGER.info("using message receiver {}", messagingReceiverClass); Receiver eventReceiver = messagingReceiverClass.newInstance().configure(eventSerializer); if (null != defaultHandler) { eventReceiver.setDefaultHandler(defaultHandler); } if (null != handlers) { for (EventHandler eventHandler : handlers) { eventReceiver.registerHandler(eventHandler); } } eventReceiver.runWith(executor); sender = eventReceiver.createSender(); LOGGER.info("created message sender {}", sender.getClass().getName()); env.setAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_SENDER, sender); env.setAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_RECEIVER, eventReceiver); return sender; } catch (ReflectiveOperationException e) { LOGGER.error("error while initializing messaging", e); shutdown(env); } } } else { LOGGER.info("messaging is disabled"); } return null; } public static boolean isEnabled(Environment env) { return getPlatformConfig(env).getBoolean(Platform.Property.MESSAGING_ENABLED); } /** * Shuts down the messaging system, i.e. calls {@link Closeable#close()} for the {@link Sender} and the * {@link Receiver} (in case the latter do implement {@link Closeable}) * * @param env * then {@link Environment} to use */ public static void shutdown(Environment env) { close(env.getAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_RECEIVER)); close(env.getAttribute(Scope.PLATFORM, Platform.Environment.MESSAGE_SENDER)); } private static void close(Object o) { if (null != o && o instanceof Closeable) { try { LOGGER.info("Closing {}", o); ((Closeable) o).close(); } catch (IOException e) { LOGGER.error("Error while closing " + o, e); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy