@Override
 public HostFileRepository getRemoteFileRepository() {
   if (hostControllerInfo.isMasterDomainController()) {
     throw MESSAGES.cannotAccessRemoteFileRepository();
   }
   return remoteFileRepository;
 }
 @Override
 public FileRepository getRemoteFileRepository() {
   if (hostControllerInfo.isMasterDomainController()) {
     throw new IllegalStateException(
         "Cannot access a remote file repository from the master domain controller");
   }
   return remoteFileRepository;
 }
  @Override
  public void registerRemoteHost(
      final String hostName,
      final ManagementChannelHandler handler,
      final Transformers transformers,
      Long remoteConnectionId,
      DomainControllerRuntimeIgnoreTransformationEntry runtimeIgnoreTransformation)
      throws SlaveRegistrationException {
    if (!hostControllerInfo.isMasterDomainController()) {
      throw SlaveRegistrationException.forHostIsNotMaster();
    }

    if (runningModeControl.getRunningMode() == RunningMode.ADMIN_ONLY) {
      throw SlaveRegistrationException.forMasterInAdminOnlyMode(
          runningModeControl.getRunningMode());
    }

    final PathElement pe = PathElement.pathElement(ModelDescriptionConstants.HOST, hostName);
    final PathAddress addr = PathAddress.pathAddress(pe);
    ProxyController existingController = modelNodeRegistration.getProxyController(addr);

    if (existingController != null || hostControllerInfo.getLocalHostName().equals(pe.getValue())) {
      throw SlaveRegistrationException.forHostAlreadyExists(pe.getValue());
    }

    SlaveHostPinger pinger =
        remoteConnectionId == null
            ? null
            : new SlaveHostPinger(hostName, handler, pingScheduler, remoteConnectionId);
    hostRegistrationMap.put(hostName, new HostRegistration(remoteConnectionId, handler, pinger));

    // Create the proxy controller
    final TransformingProxyController hostControllerClient =
        TransformingProxyController.Factory.create(
            handler, transformers, addr, ProxyOperationAddressTranslator.HOST);

    modelNodeRegistration.registerProxyController(pe, hostControllerClient);
    runtimeIgnoreTransformationRegistry.registerHost(hostName, runtimeIgnoreTransformation);
    hostProxies.put(hostName, hostControllerClient);
    //        if (pinger != null) {
    //            pinger.schedulePing(SlaveHostPinger.STD_TIMEOUT, SlaveHostPinger.STD_INTERVAL);
    //        }
  }
  @Override
  public void registerRemoteHost(ProxyController hostControllerClient)
      throws SlaveRegistrationException {
    if (!hostControllerInfo.isMasterDomainController()) {
      throw SlaveRegistrationException.forHostIsNotMaster();
    }

    if (runningModeControl.getRunningMode() == RunningMode.ADMIN_ONLY) {
      throw SlaveRegistrationException.forMasterInAdminOnlyMode(
          runningModeControl.getRunningMode());
    }
    PathAddress pa = hostControllerClient.getProxyNodeAddress();
    PathElement pe = pa.getElement(0);
    ProxyController existingController = modelNodeRegistration.getProxyController(pa);

    if (existingController != null || hostControllerInfo.getLocalHostName().equals(pe.getValue())) {
      throw SlaveRegistrationException.forHostAlreadyExists(pe.getValue());
    }
    modelNodeRegistration.registerProxyController(pe, hostControllerClient);
    hostProxies.put(pe.getValue(), hostControllerClient);

    Logger.getLogger("org.jboss.domain").info("Registered remote slave host " + pe.getValue());
  }
  // See superclass start. This method is invoked from a separate non-MSC thread after start. So we
  // can do a fair
  // bit of stuff
  @Override
  protected void boot(final BootContext context) throws ConfigurationPersistenceException {

    final ServiceTarget serviceTarget = context.getServiceTarget();
    boolean ok = false;
    boolean reachedServers = false;
    try {
      // Install server inventory callback
      ServerInventoryCallbackService.install(serviceTarget);

      // Parse the host.xml and invoke all the ops. The ops should rollback on any Stage.RUNTIME
      // failure
      // We run the first op ("add-host") separately to let it set up the host
      // ManagementResourceRegistration
      List<ModelNode> hostBootOps = hostControllerConfigurationPersister.load();
      ModelNode addHostOp = hostBootOps.remove(0);
      ok = boot(Collections.singletonList(addHostOp), true);
      ok = ok && boot(hostBootOps, true);

      final RunningMode currentRunningMode = runningModeControl.getRunningMode();

      if (ok) {

        // Now we know our discovery configuration.
        List<DiscoveryOption> discoveryOptions =
            hostControllerInfo.getRemoteDomainControllerDiscoveryOptions();
        if (hostControllerInfo.isMasterDomainController() && (discoveryOptions != null)) {
          // Install the discovery service
          DiscoveryService.install(
              serviceTarget,
              discoveryOptions,
              hostControllerInfo.getNativeManagementInterface(),
              hostControllerInfo.getNativeManagementPort(),
              hostControllerInfo.isMasterDomainController());
        }

        // Now we know our management interface configuration. Install the server inventory
        Future<ServerInventory> inventoryFuture =
            ServerInventoryService.install(
                serviceTarget,
                this,
                runningModeControl,
                environment,
                extensionRegistry,
                hostControllerInfo.getNativeManagementInterface(),
                hostControllerInfo.getNativeManagementPort());

        if (!hostControllerInfo.isMasterDomainController() && !environment.isUseCachedDc()) {
          serverInventory = getFuture(inventoryFuture);

          if ((discoveryOptions != null) && !discoveryOptions.isEmpty()) {
            Future<MasterDomainControllerClient> clientFuture =
                RemoteDomainConnectionService.install(
                    serviceTarget,
                    getValue(),
                    extensionRegistry,
                    hostControllerInfo,
                    environment.getProductConfig(),
                    hostControllerInfo.getRemoteDomainControllerSecurityRealm(),
                    remoteFileRepository,
                    ignoredRegistry,
                    new InternalExecutor(),
                    this,
                    environment);
            MasterDomainControllerClient masterDomainControllerClient = getFuture(clientFuture);
            // Registers us with the master and gets down the master copy of the domain model to our
            // DC
            // TODO make sure that the RDCS checks env.isUseCachedDC, and if true falls through to
            // that
            // BES 2012/02/04 Comment ^^^ implies the semantic is to use isUseCachedDC as a fallback
            // to
            // a failure to connect as opposed to being an instruction to not connect at all. I
            // believe
            // the current impl is the latter. Don't change this without a discussion first, as the
            // current semantic is a reasonable one.
            try {
              masterDomainControllerClient.register();
            } catch (Exception e) {
              // We could not connect to the host
              ROOT_LOGGER.cannotConnectToMaster(e);
              System.exit(ExitCodes.HOST_CONTROLLER_ABORT_EXIT_CODE);
            }
          } else if (currentRunningMode != RunningMode.ADMIN_ONLY) {
            // Invalid configuration; no way to get the domain config
            ROOT_LOGGER.noDomainControllerConfigurationProvided(
                currentRunningMode, CommandLineConstants.ADMIN_ONLY, RunningMode.ADMIN_ONLY);
            System.exit(ExitCodes.HOST_CONTROLLER_ABORT_EXIT_CODE);
          }

        } else {

          if (environment.isUseCachedDc()) {
            remoteFileRepository.setRemoteFileRepositoryExecutor(
                new RemoteDomainConnectionService.RemoteFileRepositoryExecutor() {
                  @Override
                  public File getFile(
                      String relativePath, byte repoId, HostFileRepository localFileRepository) {
                    return localFileRepository.getFile(relativePath);
                  }
                });
          }

          // parse the domain.xml and load the steps
          // TODO look at having LocalDomainControllerAdd do this, using Stage.IMMEDIATE for the
          // steps
          ConfigurationPersister domainPersister =
              hostControllerConfigurationPersister.getDomainPersister();
          ok = boot(domainPersister.load(), false);

          if (!ok && runningModeControl.getRunningMode().equals(RunningMode.ADMIN_ONLY)) {
            ROOT_LOGGER.reportAdminOnlyDomainXmlFailure();
            ok = true;
          }

          if (ok) {
            InternalExecutor executor = new InternalExecutor();
            ManagementRemotingServices.installManagementChannelServices(
                serviceTarget,
                ManagementRemotingServices.MANAGEMENT_ENDPOINT,
                new MasterDomainControllerOperationHandlerService(
                    this, executor, executor, runtimeIgnoreTransformationRegistry),
                DomainModelControllerService.SERVICE_NAME,
                ManagementRemotingServices.DOMAIN_CHANNEL,
                null,
                null);
            serverInventory = getFuture(inventoryFuture);
          }
        }
      }

      if (ok) {
        // Install the server > host operation handler
        ServerToHostOperationHandlerFactoryService.install(
            serviceTarget,
            ServerInventoryService.SERVICE_NAME,
            proxyExecutor,
            new InternalExecutor(),
            this,
            expressionResolver);

        // demand native mgmt services
        serviceTarget
            .addService(ServiceName.JBOSS.append("native-mgmt-startup"), Service.NULL)
            .addDependency(
                ManagementRemotingServices.channelServiceName(
                    ManagementRemotingServices.MANAGEMENT_ENDPOINT,
                    ManagementRemotingServices.SERVER_CHANNEL))
            .setInitialMode(ServiceController.Mode.ACTIVE)
            .install();

        // demand http mgmt services
        serviceTarget
            .addService(ServiceName.JBOSS.append("http-mgmt-startup"), Service.NULL)
            .addDependency(
                ServiceBuilder.DependencyType.OPTIONAL, _UndertowHttpManagementService.SERVICE_NAME)
            .setInitialMode(ServiceController.Mode.ACTIVE)
            .install();

        reachedServers = true;
        if (currentRunningMode == RunningMode.NORMAL) {
          startServers();
        }
      }

    } catch (Exception e) {
      ROOT_LOGGER.caughtExceptionDuringBoot(e);
      if (!reachedServers) {
        ok = false;
      }
    } finally {
      if (ok) {
        try {
          finishBoot();
        } finally {
          // Trigger the started message
          bootstrapListener.printBootStatistics();
        }
      } else {
        // Die!
        ROOT_LOGGER.unsuccessfulBoot();
        System.exit(ExitCodes.HOST_CONTROLLER_ABORT_EXIT_CODE);
      }
    }
  }
  // See superclass start. This method is invoked from a separate non-MSC thread after start. So we
  // can do a fair
  // bit of stuff
  @Override
  protected void boot(final BootContext context) throws ConfigurationPersistenceException {

    final ServiceTarget serviceTarget = context.getServiceTarget();
    try {
      super.boot(
          hostControllerConfigurationPersister
              .load()); // This parses the host.xml and invokes all ops

      final RunningMode currentRunningMode = runningModeControl.getRunningMode();

      // Now we know our management interface configuration. Install the server inventory
      Future<ServerInventory> inventoryFuture =
          ServerInventoryService.install(
              serviceTarget,
              this,
              environment,
              hostControllerInfo.getNativeManagementInterface(),
              hostControllerInfo.getNativeManagementPort());

      // Install the core remoting endpoint and listener
      ManagementRemotingServices.installRemotingEndpoint(
          serviceTarget,
          ManagementRemotingServices.MANAGEMENT_ENDPOINT,
          hostControllerInfo.getLocalHostName(),
          EndpointService.EndpointType.MANAGEMENT,
          null,
          null);

      if (!hostControllerInfo.isMasterDomainController() && !environment.isUseCachedDc()) {
        serverInventory = getFuture(inventoryFuture);

        if (hostControllerInfo.getRemoteDomainControllerHost() != null) {
          Future<MasterDomainControllerClient> clientFuture =
              RemoteDomainConnectionService.install(
                  serviceTarget,
                  getValue(),
                  hostControllerInfo.getLocalHostName(),
                  hostControllerInfo.getRemoteDomainControllerHost(),
                  hostControllerInfo.getRemoteDomainControllertPort(),
                  hostControllerInfo.getRemoteDomainControllerSecurityRealm(),
                  remoteFileRepository);
          MasterDomainControllerClient masterDomainControllerClient = getFuture(clientFuture);
          // Registers us with the master and gets down the master copy of the domain model to our
          // DC
          // TODO make sure that the RDCS checks env.isUseCachedDC, and if true falls through to
          // that
          try {
            masterDomainControllerClient.register();
          } catch (IllegalStateException e) {
            // We could not connect to the host
            log.error(HostControllerMessages.MESSAGES.cannotConnectToMaster(e));
            System.exit(ExitCodes.HOST_CONTROLLER_ABORT_EXIT_CODE);
          }
        } else if (currentRunningMode != RunningMode.ADMIN_ONLY) {
          // We could not connect to the host
          log.error(
              HostControllerMessages.MESSAGES.noDomainControllerConfigurationProvided(
                  currentRunningMode, CommandLineConstants.ADMIN_ONLY, RunningMode.ADMIN_ONLY));
          System.exit(ExitCodes.HOST_CONTROLLER_ABORT_EXIT_CODE);
        }

      } else {
        // TODO look at having LocalDomainControllerAdd do this, using Stage.IMMEDIATE for the steps
        // parse the domain.xml and load the steps
        ConfigurationPersister domainPersister =
            hostControllerConfigurationPersister.getDomainPersister();
        super.boot(domainPersister.load());

        ManagementRemotingServices.installManagementChannelServices(
            serviceTarget,
            ManagementRemotingServices.MANAGEMENT_ENDPOINT,
            new MasterDomainControllerOperationHandlerService(this, this),
            DomainModelControllerService.SERVICE_NAME,
            ManagementRemotingServices.DOMAIN_CHANNEL,
            null,
            null);
        serverInventory = getFuture(inventoryFuture);
      }

      // TODO look into adding some of these services in the handlers, but ON-DEMAND.
      // Then here just add some simple service that demands them

      ServerToHostOperationHandlerFactoryService.install(
          serviceTarget, ServerInventoryService.SERVICE_NAME, proxyExecutor);

      NativeManagementAddHandler.installNativeManagementServices(
          serviceTarget, hostControllerInfo, null, null);

      if (hostControllerInfo.getHttpManagementInterface() != null) {
        HttpManagementAddHandler.installHttpManagementServices(
            serviceTarget, hostControllerInfo, environment, null);
      }

      if (currentRunningMode == RunningMode.NORMAL) {
        startServers();
      }

      // TODO when to call hostControllerConfigurationPersister.successful boot? Look into this for
      // standalone as well; may be broken now
    } finally {
      try {
        finishBoot();
      } finally {
        bootstrapListener.tick();
      }
    }
  }
  @Override
  public void registerOperations(ManagementResourceRegistration hostRegistration) {
    super.registerOperations(hostRegistration);
    hostRegistration.registerOperationHandler(
        NamespaceAddHandler.DEFINITION, NamespaceAddHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        NamespaceRemoveHandler.DEFINITION, NamespaceRemoveHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        SchemaLocationAddHandler.DEFINITION, SchemaLocationAddHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        SchemaLocationRemoveHandler.DEFINITION, SchemaLocationRemoveHandler.INSTANCE);

    hostRegistration.registerOperationHandler(
        ValidateAddressOperationHandler.DEFINITION, ValidateAddressOperationHandler.INSTANCE);

    hostRegistration.registerOperationHandler(
        ResolveExpressionHandler.DEFINITION, ResolveExpressionHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        ResolveExpressionOnHostHandler.DEFINITION, ResolveExpressionOnHostHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        SpecifiedInterfaceResolveHandler.DEFINITION, SpecifiedInterfaceResolveHandler.INSTANCE);
    hostRegistration.registerOperationHandler(
        CleanObsoleteContentHandler.DEFINITION,
        CleanObsoleteContentHandler.createOperation(contentRepository));

    XmlMarshallingHandler xmh =
        new HostXmlMarshallingHandler(
            configurationPersister.getHostPersister(), hostControllerInfo);
    hostRegistration.registerOperationHandler(XmlMarshallingHandler.DEFINITION, xmh);

    StartServersHandler ssh =
        new StartServersHandler(environment, serverInventory, runningModeControl);
    hostRegistration.registerOperationHandler(StartServersHandler.DEFINITION, ssh);

    HostShutdownHandler hsh = new HostShutdownHandler(domainController);
    hostRegistration.registerOperationHandler(HostShutdownHandler.DEFINITION, hsh);

    HostProcessReloadHandler reloadHandler =
        new HostProcessReloadHandler(
            HostControllerService.HC_SERVICE_NAME, runningModeControl, processState);
    hostRegistration.registerOperationHandler(
        HostProcessReloadHandler.getDefinition(hostControllerInfo), reloadHandler);

    DomainServerLifecycleHandlers.initializeServerInventory(serverInventory);
    DomainSocketBindingGroupRemoveHandler.INSTANCE.initializeServerInventory(serverInventory);

    ValidateOperationHandler validateOperationHandler =
        hostControllerInfo.isMasterDomainController()
            ? ValidateOperationHandler.INSTANCE
            : ValidateOperationHandler.SLAVE_HC_INSTANCE;
    hostRegistration.registerOperationHandler(
        ValidateOperationHandler.DEFINITION_PRIVATE, validateOperationHandler);

    SnapshotDeleteHandler snapshotDelete =
        new SnapshotDeleteHandler(configurationPersister.getHostPersister());
    hostRegistration.registerOperationHandler(SnapshotDeleteHandler.DEFINITION, snapshotDelete);
    SnapshotListHandler snapshotList =
        new SnapshotListHandler(configurationPersister.getHostPersister());
    hostRegistration.registerOperationHandler(SnapshotListHandler.DEFINITION, snapshotList);
    SnapshotTakeHandler snapshotTake =
        new SnapshotTakeHandler(configurationPersister.getHostPersister());
    hostRegistration.registerOperationHandler(SnapshotTakeHandler.DEFINITION, snapshotTake);

    ignoredRegistry.registerResources(hostRegistration);

    // Platform MBeans
    PlatformMBeanResourceRegistrar.registerPlatformMBeanResources(hostRegistration);
  }