예제 #1
0
  private void performRecoveryEnvBoottime(
      OperationContext context, ModelNode model, final boolean jts, List<ServiceName> deps)
      throws OperationFailedException {
    // recovery environment
    final String recoveryBindingName =
        TransactionSubsystemRootResourceDefinition.BINDING
            .resolveModelAttribute(context, model)
            .asString();
    final String recoveryStatusBindingName =
        TransactionSubsystemRootResourceDefinition.STATUS_BINDING
            .resolveModelAttribute(context, model)
            .asString();
    final boolean recoveryListener =
        TransactionSubsystemRootResourceDefinition.RECOVERY_LISTENER
            .resolveModelAttribute(context, model)
            .asBoolean();

    // XATerminator has no deps, so just add it in there
    final XATerminatorService xaTerminatorService = new XATerminatorService(jts);
    context
        .getServiceTarget()
        .addService(TxnServices.JBOSS_TXN_XA_TERMINATOR, xaTerminatorService)
        .setInitialMode(Mode.ACTIVE)
        .install();

    final ArjunaRecoveryManagerService recoveryManagerService =
        new ArjunaRecoveryManagerService(recoveryListener, jts);
    final ServiceBuilder<RecoveryManagerService> recoveryManagerServiceServiceBuilder =
        context
            .getServiceTarget()
            .addService(TxnServices.JBOSS_TXN_ARJUNA_RECOVERY_MANAGER, recoveryManagerService);
    // add dependency on JTA environment bean
    recoveryManagerServiceServiceBuilder.addDependencies(deps);

    if (jts) {
      recoveryManagerServiceServiceBuilder.addDependency(
          ServiceName.JBOSS.append("iiop-openjdk", "orb-service"),
          ORB.class,
          recoveryManagerService.getOrbInjector());
    }

    recoveryManagerServiceServiceBuilder
        .addDependency(
            SocketBinding.JBOSS_BINDING_NAME.append(recoveryBindingName),
            SocketBinding.class,
            recoveryManagerService.getRecoveryBindingInjector())
        .addDependency(
            SocketBinding.JBOSS_BINDING_NAME.append(recoveryStatusBindingName),
            SocketBinding.class,
            recoveryManagerService.getStatusBindingInjector())
        .addDependency(
            SocketBindingManager.SOCKET_BINDING_MANAGER,
            SocketBindingManager.class,
            recoveryManagerService.getBindingManager())
        .addDependency(TxnServices.JBOSS_TXN_CORE_ENVIRONMENT)
        .addDependency(TxnServices.JBOSS_TXN_ARJUNA_OBJECTSTORE_ENVIRONMENT)
        .setInitialMode(ServiceController.Mode.ACTIVE)
        .install();
  }
예제 #2
0
  @Override
  protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model)
      throws OperationFailedException {

    ServiceRegistry registry = context.getServiceRegistry(false);
    final ServiceName serviceName =
        MessagingServices.getActiveMQServiceName(
            PathAddress.pathAddress(operation.get(ModelDescriptionConstants.OP_ADDR)));
    ServiceController<?> service = registry.getService(serviceName);
    if (service != null) {
      context.reloadRequired();
    } else {
      final PathAddress address = PathAddress.pathAddress(operation.require(OP_ADDR));
      final String name = address.getLastElement().getValue();

      final ServiceTarget target = context.getServiceTarget();
      if (model.hasDefined(JGROUPS_CHANNEL.getName())) {
        // nothing to do, in that case, the clustering.jgroups subsystem will have setup the stack
      } else if (model.hasDefined(RemoteTransportDefinition.SOCKET_BINDING.getName())) {
        final GroupBindingService bindingService = new GroupBindingService();
        target
            .addService(
                GroupBindingService.getBroadcastBaseServiceName(serviceName).append(name),
                bindingService)
            .addDependency(
                SocketBinding.JBOSS_BINDING_NAME.append(model.get(SOCKET_BINDING).asString()),
                SocketBinding.class,
                bindingService.getBindingRef())
            .install();
      }
    }
  }
 public AbstractProtocolConfigurationBuilder<P> setSocketBinding(String socketBindingName) {
   if (socketBindingName != null) {
     this.socketBinding =
         new InjectedValueDependency<>(
             SocketBinding.JBOSS_BINDING_NAME.append(socketBindingName), SocketBinding.class);
   }
   return this;
 }
예제 #4
0
  @Override
  protected void performRuntime(
      OperationContext context,
      ModelNode operation,
      ModelNode model,
      ServiceVerificationHandler verificationHandler,
      List<ServiceController<?>> newControllers)
      throws OperationFailedException {
    final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
    final PathAddress parent = address.subAddress(0, address.size() - 1);
    String name = address.getLastElement().getValue();
    String bindingRef =
        ListenerResourceDefinition.SOCKET_BINDING.resolveModelAttribute(context, model).asString();
    String workerName =
        ListenerResourceDefinition.WORKER.resolveModelAttribute(context, model).asString();
    String bufferPoolName =
        ListenerResourceDefinition.BUFFER_POOL.resolveModelAttribute(context, model).asString();
    boolean enabled =
        ListenerResourceDefinition.ENABLED.resolveModelAttribute(context, model).asBoolean();
    OptionMap listenerOptions =
        OptionList.resolveOptions(context, model, ListenerResourceDefinition.LISTENER_OPTIONS);
    OptionMap socketOptions =
        OptionList.resolveOptions(context, model, ListenerResourceDefinition.SOCKET_OPTIONS);
    String serverName = parent.getLastElement().getValue();
    final ServiceName listenerServiceName = UndertowService.listenerName(name);
    final ListenerService<? extends ListenerService> service =
        createService(name, serverName, context, model, listenerOptions, socketOptions);
    final ServiceBuilder<? extends ListenerService> serviceBuilder =
        context.getServiceTarget().addService(listenerServiceName, service);
    serviceBuilder
        .addDependency(IOServices.WORKER.append(workerName), XnioWorker.class, service.getWorker())
        .addDependency(
            SocketBinding.JBOSS_BINDING_NAME.append(bindingRef),
            SocketBinding.class,
            service.getBinding())
        .addDependency(
            IOServices.BUFFER_POOL.append(bufferPoolName), Pool.class, service.getBufferPool())
        .addDependency(
            UndertowService.SERVER.append(serverName), Server.class, service.getServerService());

    configureAdditionalDependencies(context, serviceBuilder, model, service);
    serviceBuilder.setInitialMode(
        enabled ? ServiceController.Mode.ACTIVE : ServiceController.Mode.NEVER);

    serviceBuilder.addListener(verificationHandler);
    final ServiceController<? extends ListenerService> serviceController = serviceBuilder.install();
    if (newControllers != null) {
      newControllers.add(serviceController);
    }
  }
예제 #5
0
  protected void performRuntime(
      OperationContext context,
      ModelNode operation,
      ModelNode model,
      ServiceVerificationHandler verificationHandler,
      List<ServiceController<?>> newControllers)
      throws OperationFailedException {
    // TODO SASL and properties
    final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
    final String connectorName = address.getLastElement().getValue();

    final ServiceTarget target = context.getServiceTarget();

    ServiceName socketBindingName =
        SocketBinding.JBOSS_BINDING_NAME.append(
            ConnectorResource.SOCKET_BINDING_ATTRIBUTE.validateOperation(model).asString());
    RemotingServices.installConnectorServicesForSocketBinding(
        target,
        RemotingServices.SUBSYSTEM_ENDPOINT,
        connectorName,
        socketBindingName,
        null,
        null,
        verificationHandler,
        newControllers);

    // TODO AuthenticationHandler
    //
    //        final ConnectorService connectorService = new ConnectorService();
    //        connectorService.setOptionMap(createOptionMap(operation));
    //
    //        // Register the service with the container and inject dependencies.
    //        final ServiceName connectorName = RemotingServices.connectorServiceName(name);
    //        try {
    //            newControllers.add(target.addService(connectorName, connectorService)
    //                    .addDependency(connectorName.append("auth-provider"),
    // ServerAuthenticationProvider.class, connectorService.getAuthenticationProviderInjector())
    //                    .addDependency(RemotingServices.SUBSYSTEM_ENDPOINT, Endpoint.class,
    // connectorService.getEndpointInjector())
    //                    .addListener(verificationHandler)
    //                    .setInitialMode(ServiceController.Mode.ACTIVE)
    //                    .install());
    //
    //            // TODO create XNIO connector service from socket-binding, with dependency on
    // connectorName
    //        } catch (ServiceRegistryException e) {
    //            throw new OperationFailedException(new ModelNode().set(e.getLocalizedMessage()));
    //        }
  }
예제 #6
0
  private void performCoreEnvironmentBootTime(OperationContext context, ModelNode coreEnvModel)
      throws OperationFailedException {

    // Configure the core configuration.
    final String nodeIdentifier =
        TransactionSubsystemRootResourceDefinition.NODE_IDENTIFIER
            .resolveModelAttribute(context, coreEnvModel)
            .asString();
    TransactionLogger.ROOT_LOGGER.debugf("nodeIdentifier=%s%n", nodeIdentifier);
    final CoreEnvironmentService coreEnvironmentService =
        new CoreEnvironmentService(nodeIdentifier);

    String socketBindingName = null;
    if (TransactionSubsystemRootResourceDefinition.PROCESS_ID_UUID
        .resolveModelAttribute(context, coreEnvModel)
        .asBoolean(false)) {
      // Use the UUID based id
      UuidProcessId id = new UuidProcessId();
      coreEnvironmentService.setProcessImplementation(id);
    } else {
      // Use the socket process id
      coreEnvironmentService.setProcessImplementationClassName(ProcessIdType.SOCKET.getClazz());
      socketBindingName =
          TransactionSubsystemRootResourceDefinition.PROCESS_ID_SOCKET_BINDING
              .resolveModelAttribute(context, coreEnvModel)
              .asString();
      int ports =
          TransactionSubsystemRootResourceDefinition.PROCESS_ID_SOCKET_MAX_PORTS
              .resolveModelAttribute(context, coreEnvModel)
              .asInt();
      coreEnvironmentService.setSocketProcessIdMaxPorts(ports);
    }

    final ServiceBuilder<?> coreEnvBuilder =
        context
            .getServiceTarget()
            .addService(TxnServices.JBOSS_TXN_CORE_ENVIRONMENT, coreEnvironmentService);
    if (socketBindingName != null) {
      // Add a dependency on the socket id binding
      ServiceName bindingName = SocketBinding.JBOSS_BINDING_NAME.append(socketBindingName);
      coreEnvBuilder.addDependency(
          bindingName,
          SocketBinding.class,
          coreEnvironmentService.getSocketProcessBindingInjector());
    }
    coreEnvBuilder.setInitialMode(ServiceController.Mode.ACTIVE).install();
  }
예제 #7
0
  @Override
  protected void performRuntime(
      OperationContext context,
      ModelNode operation,
      ModelNode model,
      ServiceVerificationHandler verificationHandler,
      List<ServiceController<?>> newControllers)
      throws OperationFailedException {

    final ModelNode fullModel =
        Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
    // Use ModClusterExtension.configurationPath here so if we change the PathElement components,
    // we don't have to change this code
    final ModelNode unresolvedConfig =
        fullModel.get(
            ModClusterExtension.configurationPath.getKey(),
            ModClusterExtension.configurationPath.getValue());
    final ModelNode resolvedConfig = resolveConfig(context, unresolvedConfig);

    // Add mod_cluster service
    final ModClusterService service = new ModClusterService(resolvedConfig);
    final ServiceBuilder<ModCluster> serviceBuilder =
        context
            .getServiceTarget()
            .addService(ModClusterService.NAME, service)
            .addDependency(WebSubsystemServices.JBOSS_WEB, WebServer.class, service.getWebServer())
            .addDependency(
                SocketBindingManager.SOCKET_BINDING_MANAGER,
                SocketBindingManager.class,
                service.getBindingManager())
            .addListener(verificationHandler)
            .setInitialMode(Mode.ACTIVE);
    final ModelNode bindingRefNode =
        resolvedConfig.get(ModClusterConfigResourceDefinition.ADVERTISE_SOCKET.getName());
    final String bindingRef = bindingRefNode.isDefined() ? bindingRefNode.asString() : null;
    if (bindingRef != null) {
      serviceBuilder.addDependency(
          SocketBinding.JBOSS_BINDING_NAME.append(bindingRef),
          SocketBinding.class,
          service.getBinding());
    }

    newControllers.add(serviceBuilder.install());
  }
 @Override
 public Builder<P> configure(OperationContext context, ModelNode model)
     throws OperationFailedException {
   this.module =
       ModelNodes.asModuleIdentifier(MODULE.getDefinition().resolveModelAttribute(context, model));
   String binding =
       ModelNodes.asString(SOCKET_BINDING.getDefinition().resolveModelAttribute(context, model));
   if (binding != null) {
     this.socketBinding =
         new InjectedValueDependency<>(
             SocketBinding.JBOSS_BINDING_NAME.append(binding), SocketBinding.class);
   }
   for (Property property :
       ModelNodes.asPropertyList(
           PROPERTIES.getDefinition().resolveModelAttribute(context, model))) {
     this.properties.put(property.getName(), property.getValue().asString());
   }
   return this;
 }
예제 #9
0
  public static ServiceController<SocketBinding> installBindingService(
      OperationContext context, ModelNode resolvedConfig, String name) throws UnknownHostException {
    final ServiceTarget serviceTarget = context.getServiceTarget();

    final String intf =
        resolvedConfig.get(INTERFACE).isDefined() ? resolvedConfig.get(INTERFACE).asString() : null;
    final int port = resolvedConfig.get(PORT).asInt();
    final boolean fixedPort = resolvedConfig.get(FIXED_PORT).asBoolean(false);
    final String mcastAddr =
        resolvedConfig.get(MULTICAST_ADDRESS).isDefined()
            ? resolvedConfig.get(MULTICAST_ADDRESS).asString()
            : null;
    final int mcastPort =
        resolvedConfig.get(MULTICAST_PORT).isDefined()
            ? resolvedConfig.get(MULTICAST_PORT).asInt()
            : 0;
    final InetAddress mcastInet = mcastAddr == null ? null : InetAddress.getByName(mcastAddr);

    final SocketBindingService service =
        new SocketBindingService(name, port, fixedPort, mcastInet, mcastPort);
    final ServiceBuilder<SocketBinding> builder =
        serviceTarget.addService(SocketBinding.JBOSS_BINDING_NAME.append(name), service);
    if (intf != null) {
      builder.addDependency(
          NetworkInterfaceService.JBOSS_NETWORK_INTERFACE.append(intf),
          NetworkInterfaceBinding.class,
          service.getInterfaceBinding());
    }
    return builder
        .addDependency(
            SocketBindingManager.SOCKET_BINDING_MANAGER,
            SocketBindingManager.class,
            service.getSocketBindings())
        .setInitialMode(Mode.ON_DEMAND)
        .install();
  }
예제 #10
0
  static ServiceController<FilterService> install(
      String name, ServiceTarget serviceTarget, ModelNode model, OperationContext operationContext)
      throws OperationFailedException {
    String securityKey = null;
    ModelNode securityKeyNode =
        ModClusterDefinition.SECURITY_KEY.resolveModelAttribute(operationContext, model);
    if (securityKeyNode.isDefined()) {
      securityKey = securityKeyNode.asString();
    }

    String managementAccessPredicateString = null;
    ModelNode managementAccessPredicateNode =
        ModClusterDefinition.MANAGEMENT_ACCESS_PREDICATE.resolveModelAttribute(
            operationContext, model);
    if (managementAccessPredicateNode.isDefined()) {
      managementAccessPredicateString = managementAccessPredicateNode.asString();
    }
    Predicate managementAccessPredicate = null;
    if (managementAccessPredicateString != null) {
      managementAccessPredicate =
          PredicateParser.parse(
              managementAccessPredicateString, ModClusterService.class.getClassLoader());
    }
    final ModelNode securityRealm =
        ModClusterDefinition.SECURITY_REALM.resolveModelAttribute(operationContext, model);

    ModClusterService service =
        new ModClusterService(
            model,
            ModClusterDefinition.HEALTH_CHECK_INTERVAL
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.MAX_REQUEST_TIME
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.BROKEN_NODE_TIMEOUT
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.ADVERTISE_FREQUENCY
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.ADVERTISE_PATH
                .resolveModelAttribute(operationContext, model)
                .asString(),
            ModClusterDefinition.ADVERTISE_PROTOCOL
                .resolveModelAttribute(operationContext, model)
                .asString(),
            securityKey,
            managementAccessPredicate,
            ModClusterDefinition.CONNECTIONS_PER_THREAD
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.CACHED_CONNECTIONS_PER_THREAD
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.CONNECTION_IDLE_TIMEOUT
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.REQUEST_QUEUE_SIZE
                .resolveModelAttribute(operationContext, model)
                .asInt(),
            ModClusterDefinition.USE_ALIAS
                .resolveModelAttribute(operationContext, model)
                .asBoolean());
    ServiceBuilder<FilterService> builder =
        serviceTarget.addService(UndertowService.FILTER.append(name), service);
    builder.addDependency(
        SocketBinding.JBOSS_BINDING_NAME.append(
            ModClusterDefinition.MANAGEMENT_SOCKET_BINDING
                .resolveModelAttribute(operationContext, model)
                .asString()),
        SocketBinding.class,
        service.managementSocketBinding);
    builder.addDependency(
        SocketBinding.JBOSS_BINDING_NAME.append(
            ModClusterDefinition.ADVERTISE_SOCKET_BINDING
                .resolveModelAttribute(operationContext, model)
                .asString()),
        SocketBinding.class,
        service.advertiseSocketBinding);
    builder.addDependency(
        IOServices.WORKER.append(
            ModClusterDefinition.WORKER.resolveModelAttribute(operationContext, model).asString()),
        XnioWorker.class,
        service.workerInjectedValue);

    if (securityRealm.isDefined()) {
      SecurityRealm.ServiceUtil.addDependency(
          builder, service.securityRealm, securityRealm.asString(), false);
    }

    return builder.install();
  }
  static void installHttpManagementConnector(
      final OperationContext context,
      final ModelNode model,
      final ServiceTarget serviceTarget,
      final ServiceVerificationHandler verificationHandler,
      final List<ServiceController<?>> newControllers)
      throws OperationFailedException {

    ServiceName socketBindingServiceName = null;
    ServiceName secureSocketBindingServiceName = null;
    ServiceName interfaceSvcName = null;
    int port = -1;
    int securePort = -1;

    final ModelNode interfaceModelNode = validateResolvedModel(INTERFACE, context, model);
    if (interfaceModelNode.isDefined()) {
      // Legacy config
      String interfaceName = interfaceModelNode.asString();
      interfaceSvcName = NetworkInterfaceService.JBOSS_NETWORK_INTERFACE.append(interfaceName);
      final ModelNode portNode = HTTP_PORT.resolveModelAttribute(context, model);
      port = portNode.isDefined() ? portNode.asInt() : -1;
      final ModelNode securePortNode = HTTPS_PORT.resolveModelAttribute(context, model);
      securePort = securePortNode.isDefined() ? securePortNode.asInt() : -1;

      // Log the config
      if (securePort > -1) {
        if (port > -1) {
          ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnPortAndSecurePort(
              interfaceName, port, securePort);
        } else {
          ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnSecurePort(
              interfaceName, securePort);
        }
      } else if (port > -1) {
        ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnPort(interfaceName, port);
      }
    } else {
      // Socket-binding reference based config
      final ModelNode socketBindingNode = SOCKET_BINDING.resolveModelAttribute(context, model);
      if (socketBindingNode.isDefined()) {
        final String bindingName = socketBindingNode.asString();
        socketBindingServiceName = SocketBinding.JBOSS_BINDING_NAME.append(bindingName);
      }
      final ModelNode secureSocketBindingNode =
          SECURE_SOCKET_BINDING.resolveModelAttribute(context, model);
      if (secureSocketBindingNode.isDefined()) {
        final String bindingName = secureSocketBindingNode.asString();
        secureSocketBindingServiceName = SocketBinding.JBOSS_BINDING_NAME.append(bindingName);
      }

      // Log the config
      if (socketBindingServiceName != null) {
        if (secureSocketBindingServiceName != null) {
          ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnSocketAndSecureSocket(
              socketBindingServiceName.getSimpleName(),
              secureSocketBindingServiceName.getSimpleName());
        } else {
          ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnSocket(
              socketBindingServiceName.getSimpleName());
        }
      } else if (secureSocketBindingServiceName != null) {
        ServerLogger.ROOT_LOGGER.creatingHttpManagementServiceOnSecureSocket(
            secureSocketBindingServiceName.getSimpleName());
      }
    }

    ServiceName realmSvcName = null;
    final ModelNode realmNode = SECURITY_REALM.resolveModelAttribute(context, model);
    if (realmNode.isDefined()) {
      realmSvcName = SecurityRealmService.BASE_SERVICE_NAME.append(realmNode.asString());
    } else {
      ServerLogger.ROOT_LOGGER.httpManagementInterfaceIsUnsecured();
    }
    boolean consoleEnabled = model.get(ModelDescriptionConstants.CONSOLE_ENABLED).asBoolean(true);
    ConsoleMode consoleMode;
    if (consoleEnabled) {
      consoleMode =
          context.getRunningMode() == RunningMode.ADMIN_ONLY
              ? ConsoleMode.ADMIN_ONLY
              : ConsoleMode.CONSOLE;
    } else {
      consoleMode = ConsoleMode.NO_CONSOLE;
    }

    ServerEnvironment environment =
        (ServerEnvironment)
            context
                .getServiceRegistry(false)
                .getRequiredService(ServerEnvironmentService.SERVICE_NAME)
                .getValue();
    final HttpManagementService service =
        new HttpManagementService(consoleMode, environment.getProductConfig().getConsoleSlot());
    ServiceBuilder<HttpManagement> builder =
        serviceTarget
            .addService(HttpManagementService.SERVICE_NAME, service)
            .addDependency(
                Services.JBOSS_SERVER_CONTROLLER,
                ModelController.class,
                service.getModelControllerInjector())
            .addDependency(
                SocketBindingManagerImpl.SOCKET_BINDING_MANAGER,
                SocketBindingManager.class,
                service.getSocketBindingManagerInjector())
            .addDependency(
                ControlledProcessStateService.SERVICE_NAME,
                ControlledProcessStateService.class,
                service.getControlledProcessStateServiceInjector())
            .addInjection(
                service.getExecutorServiceInjector(),
                Executors.newCachedThreadPool(
                    new JBossThreadFactory(
                        new ThreadGroup("HttpManagementService-threads"),
                        Boolean.FALSE,
                        null,
                        "%G - %t",
                        null,
                        null,
                        AccessController.getContext())));

    if (interfaceSvcName != null) {
      builder
          .addDependency(
              interfaceSvcName, NetworkInterfaceBinding.class, service.getInterfaceInjector())
          .addInjection(service.getPortInjector(), port)
          .addInjection(service.getSecurePortInjector(), securePort);
    } else {
      if (socketBindingServiceName != null) {
        builder.addDependency(
            socketBindingServiceName, SocketBinding.class, service.getSocketBindingInjector());
      }
      if (secureSocketBindingServiceName != null) {
        builder.addDependency(
            secureSocketBindingServiceName,
            SocketBinding.class,
            service.getSecureSocketBindingInjector());
      }
    }

    if (realmSvcName != null) {
      builder.addDependency(
          realmSvcName, SecurityRealmService.class, service.getSecurityRealmInjector());
    }

    if (verificationHandler != null) {
      builder.addListener(verificationHandler);
    }
    ServiceController<?> controller = builder.install();
    if (newControllers != null) {
      newControllers.add(controller);
    }
  }