/**
 * @author <a href="mailto:[email protected]">Tomaz Cerar</a>
 * @author <a href="mailto:[email protected]">James R. Perkins</a>
 */
class AsyncHandlerResourceDefinition extends AbstractHandlerDefinition {

  public static final String ADD_SUBHANDLER_OPERATION_NAME = "assign-subhandler";
  public static final String REMOVE_SUBHANDLER_OPERATION_NAME = "unassign-subhandler";
  public static final String ASYNC_HANDLER = "async-handler";
  static final PathElement ASYNC_HANDLER_PATH = PathElement.pathElement(ASYNC_HANDLER);

  static final SimpleOperationDefinition ADD_HANDLER =
      new SimpleOperationDefinitionBuilder(ADD_HANDLER_OPERATION_NAME, HANDLER_RESOLVER)
          .setParameters(CommonAttributes.HANDLER_NAME)
          .build();

  static final SimpleOperationDefinition REMOVE_HANDLER =
      new SimpleOperationDefinitionBuilder(REMOVE_HANDLER_OPERATION_NAME, HANDLER_RESOLVER)
          .setParameters(CommonAttributes.HANDLER_NAME)
          .build();

  static final SimpleOperationDefinition LEGACY_ADD_HANDLER =
      new SimpleOperationDefinitionBuilder(ADD_SUBHANDLER_OPERATION_NAME, HANDLER_RESOLVER)
          .setDeprecated(ModelVersion.create(1, 2, 0))
          .setParameters(CommonAttributes.HANDLER_NAME)
          .build();

  static final SimpleOperationDefinition LEGACY_REMOVE_HANDLER =
      new SimpleOperationDefinitionBuilder(REMOVE_SUBHANDLER_OPERATION_NAME, HANDLER_RESOLVER)
          .setDeprecated(ModelVersion.create(1, 2, 0))
          .setParameters(CommonAttributes.HANDLER_NAME)
          .build();

  public static final PropertyAttributeDefinition QUEUE_LENGTH =
      PropertyAttributeDefinition.Builder.of("queue-length", ModelType.INT)
          .setAllowExpression(true)
          .setAttributeMarshaller(ElementAttributeMarshaller.VALUE_ATTRIBUTE_MARSHALLER)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .setPropertyName("queueLength")
          .setValidator(new IntRangeValidator(1, false))
          .build();

  public static final PropertyAttributeDefinition OVERFLOW_ACTION =
      PropertyAttributeDefinition.Builder.of("overflow-action", ModelType.STRING)
          .setAllowExpression(true)
          .setAttributeMarshaller(
              new DefaultAttributeMarshaller() {
                @Override
                public void marshallAsElement(
                    final AttributeDefinition attribute,
                    final ModelNode resourceModel,
                    final boolean marshallDefault,
                    final XMLStreamWriter writer)
                    throws XMLStreamException {
                  if (isMarshallable(attribute, resourceModel, marshallDefault)) {
                    writer.writeStartElement(attribute.getXmlName());
                    String content =
                        resourceModel
                            .get(attribute.getName())
                            .asString()
                            .toLowerCase(Locale.ENGLISH);
                    writer.writeAttribute("value", content);
                    writer.writeEndElement();
                  }
                }
              })
          .setDefaultValue(new ModelNode(OverflowAction.BLOCK.name()))
          .setPropertyName("overflowAction")
          .setResolver(OverflowActionResolver.INSTANCE)
          .setValidator(EnumValidator.create(OverflowAction.class, false, false))
          .build();

  public static final LogHandlerListAttributeDefinition SUBHANDLERS =
      LogHandlerListAttributeDefinition.Builder.of("subhandlers")
          .setAllowExpression(false)
          .setAllowNull(true)
          .build();

  static final AttributeDefinition[] ATTRIBUTES =
      Logging.join(DEFAULT_ATTRIBUTES, QUEUE_LENGTH, OVERFLOW_ACTION, SUBHANDLERS);

  public AsyncHandlerResourceDefinition(final boolean includeLegacyAttributes) {
    super(
        ASYNC_HANDLER_PATH,
        AsyncHandler.class,
        (includeLegacyAttributes ? Logging.join(ATTRIBUTES, LEGACY_ATTRIBUTES) : ATTRIBUTES),
        QUEUE_LENGTH);
  }

  @Override
  public void registerOperations(final ManagementResourceRegistration registration) {
    super.registerOperations(registration);

    registration.registerOperationHandler(LEGACY_ADD_HANDLER, HandlerOperations.ADD_SUBHANDLER);
    registration.registerOperationHandler(
        LEGACY_REMOVE_HANDLER, HandlerOperations.REMOVE_SUBHANDLER);
    registration.registerOperationHandler(ADD_HANDLER, HandlerOperations.ADD_SUBHANDLER);
    registration.registerOperationHandler(REMOVE_HANDLER, HandlerOperations.REMOVE_SUBHANDLER);
  }

  /**
   * Add the transformers for the async handler.
   *
   * @param subsystemBuilder the default subsystem builder
   * @param loggingProfileBuilder the logging profile builder
   * @return the builder created for the resource
   */
  static ResourceTransformationDescriptionBuilder addTransformers(
      final ResourceTransformationDescriptionBuilder subsystemBuilder,
      final ResourceTransformationDescriptionBuilder loggingProfileBuilder) {
    // Register the logger resource
    final ResourceTransformationDescriptionBuilder child =
        subsystemBuilder
            .addChildResource(ASYNC_HANDLER_PATH)
            .getAttributeBuilder()
            .addRejectCheck(
                RejectAttributeChecker.SIMPLE_EXPRESSIONS, QUEUE_LENGTH, OVERFLOW_ACTION)
            .end()
            .addOperationTransformationOverride(ADD_HANDLER_OPERATION_NAME)
            .setCustomOperationTransformer(LoggingOperationTransformer.INSTANCE)
            .end()
            .addOperationTransformationOverride(REMOVE_HANDLER_OPERATION_NAME)
            .setCustomOperationTransformer(LoggingOperationTransformer.INSTANCE)
            .end();

    // Reject logging profile resources
    loggingProfileBuilder.rejectChildResource(ASYNC_HANDLER_PATH);

    return registerTransformers(child);
  }
}
/** A {@link org.jboss.as.controller.ResourceDefinition} for JNDI bindings */
public class NamingBindingResourceDefinition extends SimpleResourceDefinition {

  static final NamingBindingResourceDefinition INSTANCE = new NamingBindingResourceDefinition();

  static final SimpleAttributeDefinition BINDING_TYPE =
      new SimpleAttributeDefinitionBuilder(
              NamingSubsystemModel.BINDING_TYPE, ModelType.STRING, false)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .setValidator(EnumValidator.create(BindingType.class, false, false))
          .build();

  static final SimpleAttributeDefinition VALUE =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.VALUE, ModelType.STRING, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final SimpleAttributeDefinition TYPE =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.TYPE, ModelType.STRING, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final SimpleAttributeDefinition CLASS =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.CLASS, ModelType.STRING, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final SimpleAttributeDefinition MODULE =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.MODULE, ModelType.STRING, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final SimpleAttributeDefinition LOOKUP =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.LOOKUP, ModelType.STRING, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final PropertiesAttributeDefinition ENVIRONMENT =
      new PropertiesAttributeDefinition.Builder(NamingSubsystemModel.ENVIRONMENT, true)
          .setAllowExpression(true)
          .build();

  static final SimpleAttributeDefinition CACHE =
      new SimpleAttributeDefinitionBuilder(NamingSubsystemModel.CACHE, ModelType.BOOLEAN, true)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final AttributeDefinition[] ATTRIBUTES = {
    BINDING_TYPE, VALUE, TYPE, CLASS, MODULE, LOOKUP, ENVIRONMENT, CACHE
  };

  private static final List<AccessConstraintDefinition> ACCESS_CONSTRAINTS;

  static {
    List<AccessConstraintDefinition> constraints = new ArrayList<AccessConstraintDefinition>();
    constraints.add(NamingExtension.NAMING_BINDING_APPLICATION_CONSTRAINT);
    constraints.add(NamingExtension.NAMING_BINDING_SENSITIVITY_CONSTRAINT);
    ACCESS_CONSTRAINTS = Collections.unmodifiableList(constraints);
  }

  private NamingBindingResourceDefinition() {
    super(
        NamingSubsystemModel.BINDING_PATH,
        NamingExtension.getResourceDescriptionResolver(NamingSubsystemModel.BINDING),
        NamingBindingAdd.INSTANCE,
        NamingBindingRemove.INSTANCE);
  }

  @Override
  public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
    OperationStepHandler writeHandler = new WriteAttributeHandler(ATTRIBUTES);
    for (AttributeDefinition attr : ATTRIBUTES) {
      resourceRegistration.registerReadWriteAttribute(attr, null, writeHandler);
    }
  }

  @Override
  public void registerOperations(ManagementResourceRegistration resourceRegistration) {
    super.registerOperations(resourceRegistration);
    SimpleOperationDefinitionBuilder builder =
        new SimpleOperationDefinitionBuilder(
                NamingSubsystemModel.REBIND, getResourceDescriptionResolver())
            .addParameter(BINDING_TYPE)
            .addParameter(TYPE)
            .addParameter(VALUE)
            .addParameter(CLASS)
            .addParameter(MODULE)
            .addParameter(LOOKUP)
            .addParameter(ENVIRONMENT);
    resourceRegistration.registerOperationHandler(
        builder.build(),
        new OperationStepHandler() {
          @Override
          public void execute(OperationContext context, ModelNode operation)
              throws OperationFailedException {
            context.addStep(
                new OperationStepHandler() {
                  @Override
                  public void execute(OperationContext context, ModelNode operation)
                      throws OperationFailedException {

                    validateResourceModel(operation, false);
                    Resource resource = context.readResourceForUpdate(PathAddress.EMPTY_ADDRESS);
                    ModelNode model = resource.getModel();
                    for (AttributeDefinition attr : ATTRIBUTES) {
                      attr.validateAndSet(operation, model);
                    }

                    context.addStep(
                        new OperationStepHandler() {
                          @Override
                          public void execute(OperationContext context, ModelNode operation)
                              throws OperationFailedException {
                            final String name = context.getCurrentAddressValue();
                            final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name);
                            ServiceController<ManagedReferenceFactory> service =
                                (ServiceController<ManagedReferenceFactory>)
                                    context
                                        .getServiceRegistry(false)
                                        .getService(bindInfo.getBinderServiceName());
                            if (service == null) {
                              context.reloadRequired();
                              return;
                            }
                            NamingBindingAdd.INSTANCE.doRebind(
                                context, operation, (BinderService) service.getService());
                          }
                        },
                        OperationContext.Stage.RUNTIME);
                  }
                },
                OperationContext.Stage.MODEL);
          }
        });
  }

  @Override
  public List<AccessConstraintDefinition> getAccessConstraints() {
    return ACCESS_CONSTRAINTS;
  }

  public void registerTransformers_2_0(ResourceTransformationDescriptionBuilder builder) {
    builder.addOperationTransformationOverride(NamingSubsystemModel.REBIND).setReject();
  }

  private static class WriteAttributeHandler extends ReloadRequiredWriteAttributeHandler {
    private WriteAttributeHandler(AttributeDefinition... definitions) {
      super(definitions);
    }

    @Override
    protected void validateUpdatedModel(OperationContext context, Resource model)
        throws OperationFailedException {
      super.validateUpdatedModel(context, model);
      validateResourceModel(model.getModel(), true);
    }
  }

  static void validateResourceModel(ModelNode modelNode, boolean allowExternal)
      throws OperationFailedException {
    final BindingType type =
        BindingType.forName(modelNode.require(NamingSubsystemModel.BINDING_TYPE).asString());
    if (type == BindingType.SIMPLE) {
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.VALUE.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.VALUE.getName());
      }
      if (modelNode.hasDefined(NamingBindingResourceDefinition.CACHE.getName())
          && modelNode.get(NamingBindingResourceDefinition.CACHE.getName()).asBoolean()) {
        throw NamingLogger.ROOT_LOGGER.cacheNotValidForBindingType(type);
      }
    } else if (type == BindingType.OBJECT_FACTORY) {
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.MODULE.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.MODULE.getName());
      }
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.CLASS.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.CLASS.getName());
      }
      if (modelNode.hasDefined(NamingBindingResourceDefinition.CACHE.getName())
          && modelNode.get(NamingBindingResourceDefinition.CACHE.getName()).asBoolean()) {
        throw NamingLogger.ROOT_LOGGER.cacheNotValidForBindingType(type);
      }
    } else if (type == BindingType.EXTERNAL_CONTEXT) {
      if (!allowExternal) {
        throw NamingLogger.ROOT_LOGGER.cannotRebindExternalContext();
      }
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.MODULE.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.MODULE.getName());
      }
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.CLASS.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.CLASS.getName());
      }
    } else if (type == BindingType.LOOKUP) {
      if (!modelNode.hasDefined(NamingBindingResourceDefinition.LOOKUP.getName())) {
        throw NamingLogger.ROOT_LOGGER.bindingTypeRequiresAttributeDefined(
            type, NamingBindingResourceDefinition.LOOKUP.getName());
      }
      if (modelNode.hasDefined(NamingBindingResourceDefinition.CACHE.getName())
          && modelNode.get(NamingBindingResourceDefinition.CACHE.getName()).asBoolean()) {
        throw NamingLogger.ROOT_LOGGER.cacheNotValidForBindingType(type);
      }
    } else {
      throw NamingLogger.ROOT_LOGGER.unknownBindingType(type.toString());
    }
  }
}
/** @author <a href="mailto:[email protected]">Tomaz Cerar</a> (c) 2012 Red Hat Inc. */
public class HostResourceDefinition extends SimpleResourceDefinition {

  public static final SimpleAttributeDefinition NAME =
      new SimpleAttributeDefinitionBuilder(ModelDescriptionConstants.NAME, ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .addAccessConstraint(SensitiveTargetAccessConstraintDefinition.DOMAIN_NAMES)
          .build();

  static final SimpleAttributeDefinition PRODUCT_NAME =
      new SimpleAttributeDefinitionBuilder(ModelDescriptionConstants.PRODUCT_NAME, ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .build();

  static final SimpleAttributeDefinition RELEASE_VERSION =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.RELEASE_VERSION, ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .build();

  static final SimpleAttributeDefinition RELEASE_CODENAME =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.RELEASE_CODENAME, ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .build();
  static final SimpleAttributeDefinition PRODUCT_VERSION =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.PRODUCT_VERSION, ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .build();
  static final SimpleAttributeDefinition MANAGEMENT_MAJOR_VERSION =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.MANAGEMENT_MAJOR_VERSION, ModelType.INT)
          .setMinSize(1)
          .build();
  static final SimpleAttributeDefinition MANAGEMENT_MINOR_VERSION =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.MANAGEMENT_MINOR_VERSION, ModelType.INT)
          .setMinSize(1)
          .build();
  static final SimpleAttributeDefinition MANAGEMENT_MICRO_VERSION =
      new SimpleAttributeDefinitionBuilder(
              ModelDescriptionConstants.MANAGEMENT_MICRO_VERSION, ModelType.INT)
          .setMinSize(1)
          .build();
  // This is just there for bw compatibility, it had no read handler before this change
  static final SimpleAttributeDefinition SERVER_STATE =
      new SimpleAttributeDefinitionBuilder("server-state", ModelType.STRING)
          .setAllowNull(true)
          .setMinSize(1)
          .setStorageRuntime()
          .build();

  public static final SimpleAttributeDefinition HOST_STATE =
      new SimpleAttributeDefinitionBuilder(ModelDescriptionConstants.HOST_STATE, ModelType.STRING)
          .setMinSize(1)
          .setStorageRuntime()
          .build();
  public static final SimpleAttributeDefinition DIRECTORY_GROUPING =
      SimpleAttributeDefinitionBuilder.create(
              ModelDescriptionConstants.DIRECTORY_GROUPING, ModelType.STRING, true)
          .addFlag(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .setDefaultValue(DirectoryGrouping.defaultValue().toModelNode())
          .setValidator(EnumValidator.create(DirectoryGrouping.class, true, true))
          .setAllowExpression(true)
          .build();
  public static final SimpleAttributeDefinition MASTER =
      SimpleAttributeDefinitionBuilder.create(
              ModelDescriptionConstants.MASTER, ModelType.BOOLEAN, true)
          .setDefaultValue(new ModelNode(false))
          .setStorageRuntime()
          .setResourceOnly()
          .build();

  public static final ObjectTypeAttributeDefinition DC_LOCAL =
      new ObjectTypeAttributeDefinition.Builder(ModelDescriptionConstants.LOCAL).build();

  public static final ObjectTypeAttributeDefinition DC_REMOTE =
      new ObjectTypeAttributeDefinition.Builder(
              ModelDescriptionConstants.REMOTE,
              RemoteDomainControllerAddHandler.PROTOCOL,
              RemoteDomainControllerAddHandler.HOST,
              RemoteDomainControllerAddHandler.PORT,
              RemoteDomainControllerAddHandler.USERNAME,
              RemoteDomainControllerAddHandler.SECURITY_REALM,
              RemoteDomainControllerAddHandler.SECURITY_REALM,
              RemoteDomainControllerAddHandler.IGNORE_UNUSED_CONFIG,
              RemoteDomainControllerAddHandler.ADMIN_ONLY_POLICY)
          .build();

  public static final ObjectTypeAttributeDefinition DOMAIN_CONTROLLER =
      new ObjectTypeAttributeDefinition.Builder(
              ModelDescriptionConstants.DOMAIN_CONTROLLER, DC_LOCAL, DC_REMOTE)
          .setAllowNull(false)
          .addAccessConstraint(SensitiveTargetAccessConstraintDefinition.DOMAIN_CONTROLLER)
          .build();

  private final HostControllerConfigurationPersister configurationPersister;
  private final HostControllerEnvironment environment;
  private final HostRunningModeControl runningModeControl;
  private final HostFileRepository localFileRepository;
  private final LocalHostControllerInfoImpl hostControllerInfo;
  private final ServerInventory serverInventory;
  private final HostFileRepository remoteFileRepository;
  private final ContentRepository contentRepository;
  private final DomainController domainController;
  private final ExtensionRegistry extensionRegistry;
  private final AbstractVaultReader vaultReader;
  private final IgnoredDomainResourceRegistry ignoredRegistry;
  private final ControlledProcessState processState;
  private final PathManagerService pathManager;
  private final DelegatingConfigurableAuthorizer authorizer;
  private final ManagedAuditLogger auditLogger;
  private final BootErrorCollector bootErrorCollector;

  public HostResourceDefinition(
      final String hostName,
      final HostControllerConfigurationPersister configurationPersister,
      final HostControllerEnvironment environment,
      final HostRunningModeControl runningModeControl,
      final HostFileRepository localFileRepository,
      final LocalHostControllerInfoImpl hostControllerInfo,
      final ServerInventory serverInventory,
      final HostFileRepository remoteFileRepository,
      final ContentRepository contentRepository,
      final DomainController domainController,
      final ExtensionRegistry extensionRegistry,
      final AbstractVaultReader vaultReader,
      final IgnoredDomainResourceRegistry ignoredRegistry,
      final ControlledProcessState processState,
      final PathManagerService pathManager,
      final DelegatingConfigurableAuthorizer authorizer,
      final ManagedAuditLogger auditLogger,
      final BootErrorCollector bootErrorCollector) {
    super(PathElement.pathElement(HOST, hostName), HostModelUtil.getResourceDescriptionResolver());
    this.configurationPersister = configurationPersister;
    this.environment = environment;
    this.runningModeControl = runningModeControl;
    this.localFileRepository = localFileRepository;
    this.hostControllerInfo = hostControllerInfo;
    this.serverInventory = serverInventory;
    this.remoteFileRepository = remoteFileRepository;
    this.contentRepository = contentRepository;
    this.domainController = domainController;
    this.extensionRegistry = extensionRegistry;
    this.vaultReader = vaultReader;
    this.ignoredRegistry = ignoredRegistry;
    this.processState = processState;
    this.pathManager = pathManager;
    this.authorizer = authorizer;
    this.auditLogger = auditLogger;
    this.bootErrorCollector = bootErrorCollector;
  }

  @Override
  public void registerAttributes(ManagementResourceRegistration hostRegistration) {
    super.registerAttributes(hostRegistration);
    hostRegistration.registerReadWriteAttribute(
        DIRECTORY_GROUPING,
        null,
        new ReloadRequiredWriteAttributeHandler(DIRECTORY_GROUPING) {
          @Override
          protected boolean requiresRuntime(OperationContext context) {
            return context.getRunningMode() == RunningMode.NORMAL && !context.isBooting();
          }
        });
    hostRegistration.registerReadOnlyAttribute(PRODUCT_NAME, null);
    hostRegistration.registerReadOnlyAttribute(SERVER_STATE, null);
    hostRegistration.registerReadOnlyAttribute(RELEASE_VERSION, null);
    hostRegistration.registerReadOnlyAttribute(RELEASE_CODENAME, null);
    hostRegistration.registerReadOnlyAttribute(PRODUCT_VERSION, null);
    hostRegistration.registerReadOnlyAttribute(MANAGEMENT_MAJOR_VERSION, null);
    hostRegistration.registerReadOnlyAttribute(MANAGEMENT_MINOR_VERSION, null);
    hostRegistration.registerReadOnlyAttribute(MANAGEMENT_MICRO_VERSION, null);
    hostRegistration.registerReadOnlyAttribute(MASTER, IsMasterHandler.INSTANCE);
    hostRegistration.registerReadOnlyAttribute(DOMAIN_CONTROLLER, null);
    hostRegistration.registerReadOnlyAttribute(ServerRootResourceDefinition.NAMESPACES, null);
    hostRegistration.registerReadOnlyAttribute(ServerRootResourceDefinition.SCHEMA_LOCATIONS, null);
    hostRegistration.registerReadWriteAttribute(
        HostResourceDefinition.NAME,
        environment.getProcessNameReadHandler(),
        environment.getProcessNameWriteHandler());
    hostRegistration.registerReadOnlyAttribute(
        HostResourceDefinition.HOST_STATE, new ProcessStateAttributeHandler(processState));
    hostRegistration.registerReadOnlyAttribute(
        ServerRootResourceDefinition.RUNNING_MODE, new RunningModeReadHandler(runningModeControl));
    hostRegistration.registerReadOnlyAttribute(
        ServerRootResourceDefinition.SUSPEND_STATE, SuspendStateReadHandler.INSTANCE);
  }

  @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);
  }

  @Override
  public void registerChildren(ManagementResourceRegistration hostRegistration) {
    super.registerChildren(hostRegistration);

    // System Properties
    hostRegistration.registerSubModel(
        SystemPropertyResourceDefinition.createForDomainOrHost(
            SystemPropertyResourceDefinition.Location.HOST));

    /////////////////////////////////////////
    // Core Services

    // vault
    hostRegistration.registerSubModel(new VaultResourceDefinition(vaultReader));

    // Central Management
    ResourceDefinition nativeManagement =
        new NativeManagementResourceDefinition(hostControllerInfo);
    ResourceDefinition httpManagement =
        new HttpManagementResourceDefinition(hostControllerInfo, environment);

    // audit log environment reader
    final EnvironmentNameReader environmentNameReader =
        new EnvironmentNameReader() {
          public boolean isServer() {
            return false;
          }

          public String getServerName() {
            return null;
          }

          public String getHostName() {
            return environment.getHostControllerName();
          }

          public String getProductName() {
            if (environment.getProductConfig() != null
                && environment.getProductConfig().getProductName() != null) {
              return environment.getProductConfig().getProductName();
            }
            return null;
          }
        };
    hostRegistration.registerSubModel(
        CoreManagementResourceDefinition.forHost(
            authorizer,
            auditLogger,
            pathManager,
            environmentNameReader,
            bootErrorCollector,
            nativeManagement,
            httpManagement));

    // Other core services
    // TODO get a DumpServicesHandler that works on the domain
    //        ManagementResourceRegistration serviceContainer =
    // hostRegistration.registerSubModel(PathElement.pathElement(CORE_SERVICE, SERVICE_CONTAINER),
    // CommonProviders.SERVICE_CONTAINER_PROVIDER);
    //        serviceContainer.registerOperationHandler(DumpServicesHandler.OPERATION_NAME,
    // DumpServicesHandler.INSTANCE, DumpServicesHandler.INSTANCE, false);

    // host-environment
    hostRegistration.registerSubModel(HostEnvironmentResourceDefinition.of(environment));
    hostRegistration.registerSubModel(new ModuleLoadingResourceDefinition());

    // discovery options
    ManagementResourceRegistration discoveryOptions =
        hostRegistration.registerSubModel(DiscoveryOptionsResourceDefinition.INSTANCE);
    discoveryOptions.registerSubModel(new StaticDiscoveryResourceDefinition(hostControllerInfo));
    discoveryOptions.registerSubModel(new DiscoveryOptionResourceDefinition(hostControllerInfo));

    // Jvms
    final ManagementResourceRegistration jvms =
        hostRegistration.registerSubModel(JvmResourceDefinition.GLOBAL);

    // Paths
    hostRegistration.registerSubModel(
        PathResourceDefinition.createResolvableSpecified(pathManager));

    // interface
    ManagementResourceRegistration interfaces =
        hostRegistration.registerSubModel(
            new InterfaceDefinition(
                new HostSpecifiedInterfaceAddHandler(),
                new HostSpecifiedInterfaceRemoveHandler(),
                true,
                true));
    interfaces.registerOperationHandler(
        SpecifiedInterfaceResolveHandler.DEFINITION, SpecifiedInterfaceResolveHandler.INSTANCE);

    // server configurations
    hostRegistration.registerSubModel(
        new ServerConfigResourceDefinition(hostControllerInfo, serverInventory, pathManager));
    hostRegistration.registerSubModel(new StoppedServerResource(serverInventory));
  }
}