/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.wildfly.extension.messaging.activemq; import static org.wildfly.extension.messaging.activemq.logging.MessagingLogger.ROOT_LOGGER; import static org.jboss.as.naming.deployment.ContextNames.BindInfo; import javax.naming.InitialContext; import org.jboss.as.naming.ContextListAndJndiViewManagedReferenceFactory; import org.jboss.as.naming.ContextListManagedReferenceFactory; import org.jboss.as.naming.ManagedReference; import org.jboss.as.naming.ManagedReferenceFactory; import org.jboss.as.naming.ServiceBasedNamingStore; import org.jboss.as.naming.ValueManagedReference; import org.jboss.as.naming.ValueManagedReferenceFactory; import org.jboss.as.naming.deployment.ContextNames; import org.jboss.as.naming.service.BinderService; import org.jboss.msc.service.AbstractServiceListener; import org.jboss.msc.service.Service; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.value.ImmediateValue; import org.jboss.msc.value.Values; /** * Utility class to install BinderService (either to bind actual objects or create alias on another binding). * * @author <a href="http://jmesnil.net">Jeff Mesnil</a> (c) 2013 Red Hat Inc. */ public class BinderServiceUtil { /** * Install a binder service to bind the {@code obj} using the binding {@code name}. * @param serviceTarget * @param name the binding name * @param obj the object that must be bound */ public static void installBinderService(final ServiceTarget serviceTarget, final String name, final Object obj) { final BindInfo bindInfo = ContextNames.bindInfoFor(name); final BinderService binderService = new BinderService(bindInfo.getBindName()); serviceTarget.addService(bindInfo.getBinderServiceName(), binderService) .addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector()) .addInjection(binderService.getManagedObjectInjector(), new ValueManagedReferenceFactory(Values.immediateValue(obj))) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); } /** * Install a binder service to bind the value of the {@code service} using the binding {@code name}. * @param serviceTarget * @param name the binding name * @param service the service whose value must be bound */ public static void installBinderService(final ServiceTarget serviceTarget, final String name, final Service<?> service, final ServiceName... dependencies) { final BindInfo bindInfo = ContextNames.bindInfoFor(name); final BinderService binderService = new BinderService(bindInfo.getBindName()); final ServiceBuilder serviceBuilder = serviceTarget.addService(bindInfo.getBinderServiceName(), binderService) .addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector()) .addInjection(binderService.getManagedObjectInjector(), new ValueManagedReferenceFactory(service)) // we set it in passive mode so that missing dependencies (which is possible/valid when it's a backup HornetQ server and the services // haven't been activated on it due to the presence of a different live server) don't cause jms-topic/jms-queue add operations // to fail .setInitialMode(ServiceController.Mode.PASSIVE); if (dependencies != null && dependencies.length > 0) { serviceBuilder.addDependencies(dependencies); } serviceBuilder.install(); } public static void installAliasBinderService(final ServiceTarget serviceTarget, final BindInfo bindInfo, final String alias) { final BindInfo aliasBindInfo = ContextNames.bindInfoFor(alias); final BinderService aliasBinderService = new BinderService(alias); aliasBinderService.getManagedObjectInjector().inject(new AliasManagedReferenceFactory(bindInfo.getAbsoluteJndiName())); serviceTarget.addService(aliasBindInfo.getBinderServiceName(), aliasBinderService) .addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, aliasBinderService.getNamingStoreInjector()) .addDependency(bindInfo.getBinderServiceName()) .addListener(new AbstractServiceListener<ManagedReferenceFactory>() { @Override public void transition(ServiceController<? extends ManagedReferenceFactory> controller, ServiceController.Transition transition) { switch (transition) { case STARTING_to_UP: { ROOT_LOGGER.boundJndiName(alias); break; } case STOPPING_to_DOWN: { ROOT_LOGGER.unboundJndiName(alias); break; } case REMOVING_to_REMOVED: { ROOT_LOGGER.debugf("Removed messaging object [%s]", alias); break; } } } }) .install(); } private static final class AliasManagedReferenceFactory implements ContextListAndJndiViewManagedReferenceFactory { private final String name; /** * @param name original JNDI name */ public AliasManagedReferenceFactory(String name) { this.name = name; } @Override public ManagedReference getReference() { try { final Object value = new InitialContext().lookup(name); return new ValueManagedReference(new ImmediateValue<Object>(value)); } catch (Exception e) { throw new RuntimeException(e); } } @Override public String getInstanceClassName() { final Object value = getReference().getInstance(); return value != null ? value.getClass().getName() : ContextListManagedReferenceFactory.DEFAULT_INSTANCE_CLASS_NAME; } @Override public String getJndiViewInstanceValue() { return String.valueOf(getReference().getInstance()); } } }