From: Robert Varga Date: Sat, 31 May 2014 07:34:09 +0000 (+0200) Subject: BUG-614: convert NotificationBrokerImpl X-Git-Tag: release/helium~734 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=357ebddddbb29d3ed35685516dc184e0603e2def;hp=82eb3f94c133e091ca5dd2f26450da9f121c12ca BUG-614: convert NotificationBrokerImpl This does a straight xtend->java conversion by moving xtend-generated java files into the repository instead of xtend. This is the first step in optimizing NotificationBrokerImpl. Change-Id: Ie8dc1dfb6c5b9e80a8d79a5de31410100b35c7fc Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GeneratedListenerRegistration.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GeneratedListenerRegistration.java new file mode 100644 index 0000000000..cc8471f7b4 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GeneratedListenerRegistration.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl; + +import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; +import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.NotificationListener; + +public class GeneratedListenerRegistration extends AbstractObjectRegistration implements ListenerRegistration { + private final NotificationInvoker _invoker; + + public NotificationInvoker getInvoker() { + return this._invoker; + } + + private NotificationBrokerImpl notificationBroker; + + public GeneratedListenerRegistration(final NotificationListener instance, final NotificationInvoker invoker, final NotificationBrokerImpl broker) { + super(instance); + this._invoker = invoker; + this.notificationBroker = broker; + } + + @Override + protected void removeRegistration() { + this.notificationBroker.unregisterListener(this); + this.notificationBroker = null; + NotificationInvoker _invoker = this.getInvoker(); + _invoker.close(); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenericNotificationRegistration.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenericNotificationRegistration.java new file mode 100644 index 0000000000..956783130c --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenericNotificationRegistration.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl; + +import org.opendaylight.controller.sal.binding.api.NotificationListener; +import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.Notification; + +public class GenericNotificationRegistration extends AbstractObjectRegistration> implements ListenerRegistration> { + private final Class _type; + + public Class getType() { + return this._type; + } + + private NotificationBrokerImpl notificationBroker; + + public GenericNotificationRegistration(final Class type, final NotificationListener instance, final NotificationBrokerImpl broker) { + super(instance); + this._type = type; + this.notificationBroker = broker; + } + + @Override + protected void removeRegistration() { + this.notificationBroker.unregisterListener(this); + this.notificationBroker = null; + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java new file mode 100644 index 0000000000..6de878f851 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java @@ -0,0 +1,214 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import org.eclipse.xtext.xbase.lib.Conversions; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.Functions.Function0; +import org.eclipse.xtext.xbase.lib.Functions.Function1; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.opendaylight.controller.sal.binding.api.NotificationListener; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; +import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Objects; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; + +public class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { + private final ListenerRegistry interestListeners = new Function0>() { + @Override + public ListenerRegistry apply() { + ListenerRegistry _create = ListenerRegistry.create(); + return _create; + } + }.apply(); + + private final Multimap,NotificationListener> listeners; + + private ExecutorService _executor; + + public ExecutorService getExecutor() { + return this._executor; + } + + public void setExecutor(final ExecutorService executor) { + this._executor = executor; + } + + private final Logger logger = new Function0() { + @Override + public Logger apply() { + Logger _logger = LoggerFactory.getLogger(NotificationBrokerImpl.class); + return _logger; + } + }.apply(); + + public NotificationBrokerImpl() { + HashMultimap,NotificationListener> _create = HashMultimap., NotificationListener>create(); + SetMultimap,NotificationListener> _synchronizedSetMultimap = Multimaps., NotificationListener>synchronizedSetMultimap(_create); + this.listeners = _synchronizedSetMultimap; + } + + @Deprecated + public NotificationBrokerImpl(final ExecutorService executor) { + HashMultimap,NotificationListener> _create = HashMultimap., NotificationListener>create(); + SetMultimap,NotificationListener> _synchronizedSetMultimap = Multimaps., NotificationListener>synchronizedSetMultimap(_create); + this.listeners = _synchronizedSetMultimap; + this.setExecutor(executor); + } + + public Iterable> getNotificationTypes(final Notification notification) { + Class _class = notification.getClass(); + Class[] _interfaces = _class.getInterfaces(); + final Function1,Boolean> _function = new Function1,Boolean>() { + @Override + public Boolean apply(final Class it) { + boolean _and = false; + boolean _notEquals = (!Objects.equal(it, Notification.class)); + if (!_notEquals) { + _and = false; + } else { + boolean _isAssignableFrom = Notification.class.isAssignableFrom(it); + _and = (_notEquals && _isAssignableFrom); + } + return Boolean.valueOf(_and); + } + }; + Iterable> _filter = IterableExtensions.>filter(((Iterable>)Conversions.doWrapArray(_interfaces)), _function); + return _filter; + } + + @Override + public void publish(final Notification notification) { + ExecutorService _executor = this.getExecutor(); + this.publish(notification, _executor); + } + + @Override + public void publish(final Notification notification, final ExecutorService service) { + final Iterable> allTypes = this.getNotificationTypes(notification); + Iterable> listenerToNotify = Collections.>emptySet(); + for (final Class type : allTypes) { + Collection> _get = this.listeners.get(((Class) type)); + Iterable> _plus = Iterables.>concat(listenerToNotify, _get); + listenerToNotify = _plus; + } + final Function1,NotifyTask> _function = new Function1,NotifyTask>() { + @Override + public NotifyTask apply(final NotificationListener it) { + NotifyTask _notifyTask = new NotifyTask(it, notification); + return _notifyTask; + } + }; + Iterable _map = IterableExtensions., NotifyTask>map(listenerToNotify, _function); + final Set tasks = IterableExtensions.toSet(_map); + ExecutorService _executor = this.getExecutor(); + this.submitAll(_executor, tasks); + } + + public ImmutableSet> submitAll(final ExecutorService service, final Set tasks) { + final Builder> ret = ImmutableSet.>builder(); + for (final NotifyTask task : tasks) { + Future _submit = service.submit(task); + ret.add(_submit); + } + return ret.build(); + } + + @Override + public Registration> registerNotificationListener(final Class notificationType, final NotificationListener listener) { + GenericNotificationRegistration _genericNotificationRegistration = new GenericNotificationRegistration(notificationType, listener, this); + final GenericNotificationRegistration reg = _genericNotificationRegistration; + this.listeners.put(notificationType, listener); + this.announceNotificationSubscription(notificationType); + return reg; + } + + public void announceNotificationSubscription(final Class notification) { + for (final ListenerRegistration listener : this.interestListeners) { + try { + NotificationInterestListener _instance = listener.getInstance(); + _instance.onNotificationSubscribtion(notification); + } catch (final Throwable _t) { + if (_t instanceof Exception) { + final Exception e = (Exception)_t; + String _message = e.getMessage(); + this.logger.error("", _message); + } else { + throw Exceptions.sneakyThrow(_t); + } + } + } + } + + @Override + public Registration registerNotificationListener(final org.opendaylight.yangtools.yang.binding.NotificationListener listener) { + final NotificationInvoker invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); + Set> _supportedNotifications = invoker.getSupportedNotifications(); + for (final Class notifyType : _supportedNotifications) { + { + NotificationListener _invocationProxy = invoker.getInvocationProxy(); + this.listeners.put(notifyType, _invocationProxy); + this.announceNotificationSubscription(notifyType); + } + } + GeneratedListenerRegistration _generatedListenerRegistration = new GeneratedListenerRegistration(listener, invoker, this); + final GeneratedListenerRegistration registration = _generatedListenerRegistration; + return (registration); + } + + protected boolean unregisterListener(final GenericNotificationRegistration reg) { + Class _type = reg.getType(); + NotificationListener _instance = reg.getInstance(); + boolean _remove = this.listeners.remove(_type, _instance); + return _remove; + } + + protected void unregisterListener(final GeneratedListenerRegistration reg) { + NotificationInvoker _invoker = reg.getInvoker(); + Set> _supportedNotifications = _invoker.getSupportedNotifications(); + for (final Class notifyType : _supportedNotifications) { + NotificationInvoker _invoker_1 = reg.getInvoker(); + NotificationListener _invocationProxy = _invoker_1.getInvocationProxy(); + this.listeners.remove(notifyType, _invocationProxy); + } + } + + @Override + public void close() { + } + + @Override + public ListenerRegistration registerInterestListener(final NotificationInterestListener interestListener) { + final ListenerRegistration registration = this.interestListeners.register(interestListener); + Set> _keySet = this.listeners.keySet(); + for (final Class notification : _keySet) { + interestListener.onNotificationSubscribtion(notification); + } + return registration; + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend deleted file mode 100644 index 6d675b4b5e..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl - -import com.google.common.collect.HashMultimap -import com.google.common.collect.ImmutableSet -import com.google.common.collect.Multimap -import com.google.common.collect.Multimaps -import java.util.Collections -import java.util.concurrent.Callable -import java.util.concurrent.ExecutorService -import java.util.concurrent.Future -import java.util.Set -import org.opendaylight.controller.sal.binding.api.NotificationListener -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener -import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder -import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker -import org.opendaylight.yangtools.concepts.AbstractObjectRegistration -import org.opendaylight.yangtools.concepts.ListenerRegistration -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.concepts.util.ListenerRegistry -import org.opendaylight.yangtools.yang.binding.Notification -import org.slf4j.LoggerFactory - -class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { - - val ListenerRegistry interestListeners = ListenerRegistry.create; - - val Multimap, NotificationListener> listeners; - - @Property - var ExecutorService executor; - - val logger = LoggerFactory.getLogger(NotificationBrokerImpl) - - new() { - listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()) - } - - @Deprecated - new(ExecutorService executor) { - listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()) - this.executor = executor; - } - - def getNotificationTypes(Notification notification) { - notification.class.interfaces.filter[it != Notification && Notification.isAssignableFrom(it)] - } - - override publish(Notification notification) { - publish(notification, executor) - } - - override publish(Notification notification, ExecutorService service) { - val allTypes = notification.notificationTypes - - var Iterable> listenerToNotify = Collections.emptySet(); - for (type : allTypes) { - listenerToNotify = listenerToNotify + listeners.get(type as Class) - } - val tasks = listenerToNotify.map[new NotifyTask(it, notification)].toSet; - submitAll(executor,tasks); - } - - def submitAll(ExecutorService service, Set tasks) { - val ret = ImmutableSet.>builder(); - for(task : tasks) { - ret.add(service.submit(task)); - } - return ret.build(); - } - - override registerNotificationListener(Class notificationType, - NotificationListener listener) { - val reg = new GenericNotificationRegistration(notificationType, listener, this); - listeners.put(notificationType, listener); - announceNotificationSubscription(notificationType); - return reg; - } - - def announceNotificationSubscription(Class notification) { - for (listener : interestListeners) { - try { - listener.instance.onNotificationSubscribtion(notification); - } catch (Exception e) { - logger.error("", e.message) - } - } - } - - override registerNotificationListener( - org.opendaylight.yangtools.yang.binding.NotificationListener listener) { - val invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); - for (notifyType : invoker.supportedNotifications) { - listeners.put(notifyType, invoker.invocationProxy) - announceNotificationSubscription(notifyType) - } - val registration = new GeneratedListenerRegistration(listener, invoker,this); - return registration as Registration; - } - - protected def unregisterListener(GenericNotificationRegistration reg) { - listeners.remove(reg.type, reg.instance); - } - - protected def unregisterListener(GeneratedListenerRegistration reg) { - for (notifyType : reg.invoker.supportedNotifications) { - listeners.remove(notifyType, reg.invoker.invocationProxy) - } - } - - override close() { - //FIXME: implement properly. - } - - override registerInterestListener(NotificationInterestListener interestListener) { - val registration = interestListeners.register(interestListener); - - for(notification : listeners.keySet) { - interestListener.onNotificationSubscribtion(notification); - } - return registration - } -} - -class GenericNotificationRegistration extends AbstractObjectRegistration> implements ListenerRegistration> { - - @Property - val Class type; - - var NotificationBrokerImpl notificationBroker; - - public new(Class type, NotificationListener instance, NotificationBrokerImpl broker) { - super(instance); - _type = type; - notificationBroker = broker; - } - - override protected removeRegistration() { - notificationBroker.unregisterListener(this); - notificationBroker = null; - } -} - -class GeneratedListenerRegistration extends AbstractObjectRegistration implements ListenerRegistration { - - @Property - val NotificationInvoker invoker; - - var NotificationBrokerImpl notificationBroker; - - - new(org.opendaylight.yangtools.yang.binding.NotificationListener instance, NotificationInvoker invoker, NotificationBrokerImpl broker) { - super(instance); - _invoker = invoker; - notificationBroker = broker; - } - - override protected removeRegistration() { - notificationBroker.unregisterListener(this); - notificationBroker = null; - invoker.close(); - } -} - -@Data -class NotifyTask implements Callable { - - private static val log = LoggerFactory.getLogger(NotifyTask); - - @SuppressWarnings("rawtypes") - val NotificationListener listener; - val Notification notification; - - override call() { - //Only logging the complete notification in debug mode - try { - if(log.isDebugEnabled){ - log.debug("Delivering notification {} to {}",notification,listener); - } else { - log.trace("Delivering notification {} to {}",notification.class.name,listener); - } - listener.onNotification(notification); - if(log.isDebugEnabled){ - log.debug("Notification delivered {} to {}",notification,listener); - } else { - log.trace("Notification delivered {} to {}",notification.class.name,listener); - } - } catch (Exception e) { - log.error("Unhandled exception thrown by listener: {}", listener, e); - } - return null; - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotifyTask.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotifyTask.java new file mode 100644 index 0000000000..9471616f01 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotifyTask.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl; + +import java.util.concurrent.Callable; + +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.Functions.Function0; +import org.eclipse.xtext.xbase.lib.util.ToStringHelper; +import org.opendaylight.controller.sal.binding.api.NotificationListener; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotifyTask implements Callable { + private static Logger log = new Function0() { + @Override + public Logger apply() { + Logger _logger = LoggerFactory.getLogger(NotifyTask.class); + return _logger; + } + }.apply(); + + @SuppressWarnings("rawtypes") + private final NotificationListener _listener; + + public NotificationListener getListener() { + return this._listener; + } + + private final Notification _notification; + + public Notification getNotification() { + return this._notification; + } + + @Override + public Object call() { + try { + boolean _isDebugEnabled = NotifyTask.log.isDebugEnabled(); + if (_isDebugEnabled) { + Notification _notification = this.getNotification(); + NotificationListener _listener = this.getListener(); + NotifyTask.log.debug("Delivering notification {} to {}", _notification, _listener); + } else { + Notification _notification_1 = this.getNotification(); + Class _class = _notification_1.getClass(); + String _name = _class.getName(); + NotificationListener _listener_1 = this.getListener(); + NotifyTask.log.trace("Delivering notification {} to {}", _name, _listener_1); + } + NotificationListener _listener_2 = this.getListener(); + Notification _notification_2 = this.getNotification(); + _listener_2.onNotification(_notification_2); + boolean _isDebugEnabled_1 = NotifyTask.log.isDebugEnabled(); + if (_isDebugEnabled_1) { + Notification _notification_3 = this.getNotification(); + NotificationListener _listener_3 = this.getListener(); + NotifyTask.log.debug("Notification delivered {} to {}", _notification_3, _listener_3); + } else { + Notification _notification_4 = this.getNotification(); + Class _class_1 = _notification_4.getClass(); + String _name_1 = _class_1.getName(); + NotificationListener _listener_4 = this.getListener(); + NotifyTask.log.trace("Notification delivered {} to {}", _name_1, _listener_4); + } + } catch (final Throwable _t) { + if (_t instanceof Exception) { + final Exception e = (Exception)_t; + NotificationListener _listener_5 = this.getListener(); + NotifyTask.log.error("Unhandled exception thrown by listener: {}", _listener_5, e); + } else { + throw Exceptions.sneakyThrow(_t); + } + } + return null; + } + + public NotifyTask(final NotificationListener listener, final Notification notification) { + super(); + this._listener = listener; + this._notification = notification; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((_listener== null) ? 0 : _listener.hashCode()); + result = prime * result + ((_notification== null) ? 0 : _notification.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NotifyTask other = (NotifyTask) obj; + if (_listener == null) { + if (other._listener != null) + return false; + } else if (!_listener.equals(other._listener)) + return false; + if (_notification == null) { + if (other._notification != null) + return false; + } else if (!_notification.equals(other._notification)) + return false; + return true; + } + + @Override + public String toString() { + String result = new ToStringHelper().toString(this); + return result; + } +}