/* * JBoss, Home of Professional Open Source. * Copyright 2010, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file 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.jboss.as.remoting.management; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM; import static org.jboss.msc.service.ServiceController.Mode.ACTIVE; import static org.jboss.msc.service.ServiceController.Mode.ON_DEMAND; import java.util.NoSuchElementException; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import org.jboss.as.controller.ModelController; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import org.jboss.as.controller.remote.AbstractModelControllerOperationHandlerFactoryService; import org.jboss.as.controller.remote.ModelControllerClientOperationHandlerFactoryService; import org.jboss.as.protocol.mgmt.support.ManagementChannelInitialization; import org.jboss.as.remoting.RemotingServices; import org.jboss.as.remoting.logging.RemotingLogger; import org.jboss.dmr.ModelNode; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceTarget; import org.jboss.remoting3.Endpoint; import org.xnio.OptionMap; /** * Utility class to add remoting services * * @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a> * @author <a href="mailto:kkhan@redhat.com">Kabir Khan</a> */ public final class ManagementRemotingServices extends RemotingServices { private ManagementRemotingServices() { } /** The name of the endpoint service used for management */ public static final ServiceName MANAGEMENT_ENDPOINT = RemotingServices.REMOTING_BASE.append("endpoint", "management"); public static final ServiceName SHUTDOWN_EXECUTOR_NAME = MANAGEMENT_ENDPOINT.append("shutdown", "executor"); /** The name of the external management channel */ public static final String MANAGEMENT_CHANNEL = "management"; /** The name of the channel used between slave and master DCs */ public static final String DOMAIN_CHANNEL = "domain"; /** The name of the channel used for Server to HC comms */ public static final String SERVER_CHANNEL = "server"; public static final String MANAGEMENT_CONNECTOR = "management"; public static final String HTTP_CONNECTOR = "http-management"; public static final String HTTPS_CONNECTOR = "https-management"; /** * Installs a remoting stream server for a domain instance * @param serviceTarget the service target to install the services into * @param endpointName the name of the endpoint to install the stream server into * @param networkInterfaceBinding the network interface binding * @param port the port * @param securityRealm the security real name * @param options the remoting options */ public static void installDomainConnectorServices(final OperationContext context, final ServiceTarget serviceTarget, final ServiceName endpointName, final ServiceName networkInterfaceBinding, final int port, final OptionMap options, final ServiceName securityRealm, final ServiceName saslAuthenticationFactory, final ServiceName sslContext) { ServiceName serverCallbackService = ServiceName.JBOSS.append("host", "controller", "server-inventory", "callback"); installConnectorServicesForNetworkInterfaceBinding(serviceTarget, endpointName, MANAGEMENT_CONNECTOR, networkInterfaceBinding, port, options, securityRealm, saslAuthenticationFactory, sslContext); } /** * Set up the services to create a channel listener. This assumes that an endpoint service called {@code endpointName} exists. * @param serviceTarget the service target to install the services into * @param endpointName the name of the endpoint to install a channel listener into * @param channelName the name of the channel * @param operationHandlerName the name of the operation handler to handle request for this channel * @param options the remoting options * @param onDemand whether to install the services on demand */ public static void installManagementChannelOpenListenerService( final ServiceTarget serviceTarget, final ServiceName endpointName, final String channelName, final ServiceName operationHandlerName, final OptionMap options, final boolean onDemand) { final ManagementChannelOpenListenerService channelOpenListenerService = new ManagementChannelOpenListenerService(channelName, options); final ServiceBuilder<?> builder = serviceTarget.addService(channelOpenListenerService.getServiceName(endpointName), channelOpenListenerService) .addDependency(endpointName, Endpoint.class, channelOpenListenerService.getEndpointInjector()) .addDependency(operationHandlerName, ManagementChannelInitialization.class, channelOpenListenerService.getOperationHandlerInjector()) .addDependency(ManagementChannelRegistryService.SERVICE_NAME, ManagementChannelRegistryService.class, channelOpenListenerService.getRegistry()) .addDependency(SHUTDOWN_EXECUTOR_NAME, ExecutorService.class, channelOpenListenerService.getExecutorServiceInjectedValue()) .setInitialMode(onDemand ? ON_DEMAND : ACTIVE); builder.install(); } public static void removeManagementChannelOpenListenerService(final OperationContext context, final ServiceName endpointName, final String channelName) { context.removeService(RemotingServices.channelServiceName(endpointName, channelName)); } /** * Set up the services to create a channel listener and operation handler service. * @param serviceTarget the service target to install the services into * @param endpointName the endpoint name to install the services into * @param channelName the name of the channel * @param executorServiceName service name of the executor service to use in the operation handler service * @param scheduledExecutorServiceName service name of the scheduled executor service to use in the operation handler service */ public static void installManagementChannelServices( final ServiceTarget serviceTarget, final ServiceName endpointName, final AbstractModelControllerOperationHandlerFactoryService operationHandlerService, final ServiceName modelControllerName, final String channelName, final ServiceName executorServiceName, final ServiceName scheduledExecutorServiceName) { final OptionMap options = OptionMap.EMPTY; final ServiceName operationHandlerName = endpointName.append(channelName).append(ModelControllerClientOperationHandlerFactoryService.OPERATION_HANDLER_NAME_SUFFIX); serviceTarget.addService(operationHandlerName, operationHandlerService) .addDependency(modelControllerName, ModelController.class, operationHandlerService.getModelControllerInjector()) .addDependency(executorServiceName, ExecutorService.class, operationHandlerService.getExecutorInjector()) .addDependency(scheduledExecutorServiceName, ScheduledExecutorService.class, operationHandlerService.getScheduledExecutorInjector()) .setInitialMode(ACTIVE) .install(); installManagementChannelOpenListenerService(serviceTarget, endpointName, channelName, operationHandlerName, options, false); } public static void removeManagementChannelServices(final OperationContext context, final ServiceName endpointName, final String channelName) { removeManagementChannelOpenListenerService(context, endpointName, channelName); final ServiceName operationHandlerName = endpointName.append(channelName).append(ModelControllerClientOperationHandlerFactoryService.OPERATION_HANDLER_NAME_SUFFIX); context.removeService(operationHandlerName); } private static final String USE_MGMT_ENDPOINT = "use-management-endpoint"; /** * Manual check because introducing a capability can't be done without a full refactoring. * This has to go as soon as the management interfaces are redesigned. * @param context the OperationContext * @param otherManagementEndpoint : the address to check that may provide an exposed jboss-remoting endpoint. * @throws OperationFailedException in case we can't remove the management resource. */ public static void isManagementResourceRemoveable(OperationContext context, PathAddress otherManagementEndpoint) throws OperationFailedException { ModelNode remotingConnector; try { remotingConnector = context.readResourceFromRoot( PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, "jmx"), PathElement.pathElement("remoting-connector", "jmx")), false).getModel(); } catch (NoSuchElementException ex) { return; } if (!remotingConnector.hasDefined(USE_MGMT_ENDPOINT) || (remotingConnector.hasDefined(USE_MGMT_ENDPOINT) && context.resolveExpressions(remotingConnector.get(USE_MGMT_ENDPOINT)).asBoolean(true))) { try { context.readResourceFromRoot(otherManagementEndpoint, false); } catch (NoSuchElementException ex) { throw RemotingLogger.ROOT_LOGGER.couldNotRemoveResource(context.getCurrentAddress()); } } } }