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

com.butor.notif.DefaultNotifManager Maven / Gradle / Ivy

Go to download

This project is a module of butor framework. Used to manage notification between subscribed consumers and producers.

There is a newer version: 1.0.31
Show newest version
/**
 * Copyright 2013-2019 Butor Inc.
 *
 * 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 com.butor.notif;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import javax.mail.internet.AddressException;

import org.butor.json.JsonHelper;
import org.butor.utils.ApplicationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

/**
 * @author asawan
 * 
 */
public class DefaultNotifManager implements NotifManager, Runnable {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private boolean shutdown = false;
	private Thread lock = null;
	private EventBus notifRelayBus;
	private Map notifSessions = Maps.newConcurrentMap();
	private NotifSessionFilter notifSessionFilter;
	public DefaultNotifManager(ExecutorService executor, EventBus notifRelayBus, 
			NotifSessionFilter notifSessionFilter) throws IllegalArgumentException, AddressException {
		this.notifRelayBus = Preconditions.checkNotNull(notifRelayBus);
		this.notifSessionFilter = Preconditions.checkNotNull(notifSessionFilter);
		notifRelayBus.register(this);
		Preconditions.checkNotNull(executor);
		executor.execute(this);
	}

	public void addSession(NotifSession session) {
		if (shutdown) {
			ApplicationException.exception("Manager is shutdown. cannot add session!");
		}
		session.setMutex(lock);
		session.setNotifManager(this);
		notifSessions.put(session.getId(), session);
	}

	public void removeSession(String sessionId) {
		NotifSession ns = notifSessions.remove(sessionId);
		if (ns != null) {
			ns.shutdown();
		}
	}

	@Override
	public void run() {
		lock = Thread.currentThread();
		while (!shutdown) {
			try {
				boolean hadMessages = false;
				Iterator it = notifSessions.values().iterator();
				while (it.hasNext()) {
					NotifSession ns = it.next();
					hadMessages = hadMessages || ns.post();
				}

				if (!hadMessages) {
					synchronized (lock) {
						try {
							Thread.currentThread().wait(5000);//maxT
						} catch (InterruptedException e) {
							//OK
						}
					}
				}

			} catch (Throwable th) {
				logger.warn("Failed!", th);
			}
		}
		for (NotifSession ns : notifSessions.values()) {
			ns.shutdown();
		}
		logger.info("shutdown done.");
	}
	public void shutdown() {
		shutdown = true;
	}

	/**
	 * handle server (topic) notif via EventBus
	 * 
	 * @param notif InboundNotif
	 */
	@Subscribe
	public void handleInboundNotif(InboundNotif notif) {
		if (notif == null) {
			return;
		}
		String serializedNotif = new JsonHelper().serialize(notif);
		synchronized (lock) {
			Iterator it = notifSessions.values().iterator();
			while (it.hasNext()) {
				NotifSession ns = it.next();
				if (notifSessionFilter.accept(notif, ns)) {
					ns.add(notif, serializedNotif);
				}
			}
			lock.notify();
		}
	}
	@Override
	public void post(Notification notif) {
		if (notif == null) {
			return;
		}
		String serializedNotif = new JsonHelper().serialize(notif);
		synchronized (lock) {
			Iterator it = notifSessions.values().iterator();
			while (it.hasNext()) {
				NotifSession ns = it.next();
				if (notifSessionFilter.accept(notif, ns)) {
					ns.add(notif, serializedNotif);
				}
			}
			lock.notify();
		}
	}


	/**
	 * handle client notif via websocket
	 * 
	 * @param notif OutboundNotif
	 */
	@Override
	public void handleClientNotif(OutboundNotif notif) {
		notifRelayBus.post(notif);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy