/**
 * Resource definition for /subsystem=jgroups/stack=X/relay=RELAY
 *
 * @author Paul Ferraro
 */
public class RelayResourceDefinition extends SimpleResourceDefinition {

  static final PathElement PATH = PathElement.pathElement(ModelKeys.RELAY, ModelKeys.RELAY_NAME);

  static final SimpleAttributeDefinition SITE =
      new SimpleAttributeDefinitionBuilder(ModelKeys.SITE, ModelType.STRING, false)
          .setXmlName(Attribute.SITE.getLocalName())
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
          .build();

  static final AttributeDefinition[] ATTRIBUTES =
      new AttributeDefinition[] {SITE, ProtocolResourceDefinition.PROPERTIES};

  static void buildTransformation(
      ModelVersion version, ResourceTransformationDescriptionBuilder parent) {
    ResourceTransformationDescriptionBuilder builder = parent.addChildResource(PATH);

    RemoteSiteResourceDefinition.buildTransformation(version, builder);
    PropertyResourceDefinition.buildTransformation(version, builder);
  }

  RelayResourceDefinition() {
    super(
        PATH,
        new JGroupsResourceDescriptionResolver(ModelKeys.RELAY),
        new ReloadRequiredAddStepHandler(ATTRIBUTES),
        ReloadRequiredRemoveStepHandler.INSTANCE);
  }

  @Override
  public void registerAttributes(ManagementResourceRegistration registration) {
    final OperationStepHandler writeHandler = new ReloadRequiredWriteAttributeHandler(ATTRIBUTES);
    for (AttributeDefinition attribute : ATTRIBUTES) {
      registration.registerReadWriteAttribute(attribute, null, writeHandler);
    }
  }

  @Override
  public void registerChildren(ManagementResourceRegistration registration) {
    registration.registerSubModel(new RemoteSiteResourceDefinition());
    registration.registerSubModel(new PropertyResourceDefinition());
  }
}
예제 #2
0
/** @author Richard Achmatowicz (c) 2011 Red Hat Inc. */
public interface CommonAttributes {

  SimpleAttributeDefinition DEFAULT_STACK =
      new SimpleAttributeDefinitionBuilder(ModelKeys.DEFAULT_STACK, ModelType.STRING, false)
          .setXmlName(Attribute.DEFAULT_STACK.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition NAME =
      new SimpleAttributeDefinitionBuilder(ModelKeys.NAME, ModelType.STRING, false)
          .setXmlName(Attribute.NAME.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition TYPE =
      new SimpleAttributeDefinitionBuilder(ModelKeys.TYPE, ModelType.STRING, false)
          .setXmlName(Attribute.TYPE.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          //                    .setValidator(new ProtocolTypeValidator(false))
          .build();

  SimpleAttributeDefinition SHARED =
      new SimpleAttributeDefinitionBuilder(ModelKeys.SHARED, ModelType.BOOLEAN, true)
          .setXmlName(Attribute.SHARED.getLocalName())
          .setAllowExpression(false)
          .setDefaultValue(new ModelNode().set(true))
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition SOCKET_BINDING =
      new SimpleAttributeDefinitionBuilder(ModelKeys.SOCKET_BINDING, ModelType.STRING, true)
          .setXmlName(Attribute.SOCKET_BINDING.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition DIAGNOSTICS_SOCKET_BINDING =
      new SimpleAttributeDefinitionBuilder(
              ModelKeys.DIAGNOSTICS_SOCKET_BINDING, ModelType.STRING, true)
          .setXmlName(Attribute.DIAGNOSTICS_SOCKET_BINDING.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition DEFAULT_EXECUTOR =
      new SimpleAttributeDefinitionBuilder(ModelKeys.DEFAULT_EXECUTOR, ModelType.STRING, true)
          .setXmlName(Attribute.DEFAULT_EXECUTOR.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition OOB_EXECUTOR =
      new SimpleAttributeDefinitionBuilder(ModelKeys.OOB_EXECUTOR, ModelType.STRING, true)
          .setXmlName(Attribute.OOB_EXECUTOR.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition TIMER_EXECUTOR =
      new SimpleAttributeDefinitionBuilder(ModelKeys.TIMER_EXECUTOR, ModelType.STRING, true)
          .setXmlName(Attribute.TIMER_EXECUTOR.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition THREAD_FACTORY =
      new SimpleAttributeDefinitionBuilder(ModelKeys.THREAD_FACTORY, ModelType.STRING, true)
          .setXmlName(Attribute.THREAD_FACTORY.getLocalName())
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition SITE =
      new SimpleAttributeDefinitionBuilder(ModelKeys.SITE, ModelType.STRING, true)
          .setXmlName(Attribute.SITE.getLocalName())
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition RACK =
      new SimpleAttributeDefinitionBuilder(ModelKeys.RACK, ModelType.STRING, true)
          .setXmlName(Attribute.RACK.getLocalName())
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition MACHINE =
      new SimpleAttributeDefinitionBuilder(ModelKeys.MACHINE, ModelType.STRING, true)
          .setXmlName(Attribute.MACHINE.getLocalName())
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  SimpleAttributeDefinition PROPERTY =
      new SimpleAttributeDefinition(ModelKeys.PROPERTY, ModelType.PROPERTY, true);

  SimpleListAttributeDefinition PROPERTIES =
      SimpleListAttributeDefinition.Builder.of(ModelKeys.PROPERTIES, PROPERTY)
          .setAllowNull(true)
          .build();

  SimpleAttributeDefinition VALUE =
      new SimpleAttributeDefinitionBuilder("value", ModelType.STRING, false)
          .setXmlName("value")
          .setAllowExpression(false)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  AttributeDefinition[] TRANSPORT_ATTRIBUTES = {
    TYPE,
    SHARED,
    SOCKET_BINDING,
    DIAGNOSTICS_SOCKET_BINDING,
    DEFAULT_EXECUTOR,
    OOB_EXECUTOR,
    TIMER_EXECUTOR,
    THREAD_FACTORY,
    SITE,
    RACK,
    MACHINE,
    PROPERTIES
  };

  AttributeDefinition[] PROTOCOL_ATTRIBUTES = {TYPE, SOCKET_BINDING, PROPERTIES};

  ObjectTypeAttributeDefinition PROTOCOL =
      ObjectTypeAttributeDefinition.Builder.of(ModelKeys.PROTOCOL, PROTOCOL_ATTRIBUTES)
          .setAllowNull(true)
          .setSuffix("protocol")
          .build();

  ObjectTypeAttributeDefinition TRANSPORT =
      ObjectTypeAttributeDefinition.Builder.of(ModelKeys.TRANSPORT, TRANSPORT_ATTRIBUTES)
          .setAllowNull(true)
          .setSuffix("transport")
          .build();

  ObjectListAttributeDefinition PROTOCOLS =
      ObjectListAttributeDefinition.Builder.of(ModelKeys.PROTOCOLS, PROTOCOL)
          .setAllowNull(true)
          .build();

  AttributeDefinition[] STACK_ATTRIBUTES = {TRANSPORT, PROTOCOLS};

  ObjectTypeAttributeDefinition STACK =
      ObjectTypeAttributeDefinition.Builder.of(ModelKeys.STACK, STACK_ATTRIBUTES)
          .setAllowNull(true)
          .setSuffix("stack")
          .build();
}
  private void processCommonCacheAttributesElements(XMLExtendedStreamWriter writer, ModelNode cache)
      throws XMLStreamException {

    this.writeOptional(writer, Attribute.START, cache, ModelKeys.START);
    this.writeOptional(writer, Attribute.BATCHING, cache, ModelKeys.BATCHING);
    this.writeOptional(writer, Attribute.JNDI_NAME, cache, ModelKeys.JNDI_NAME);
    this.writeOptional(writer, Attribute.MODULE, cache, ModelKeys.MODULE);
    this.writeOptional(writer, Attribute.STATISTICS, cache, ModelKeys.STATISTICS);

    if (cache.get(ModelKeys.LOCKING, ModelKeys.LOCKING_NAME).isDefined()) {
      writer.writeStartElement(Element.LOCKING.getLocalName());
      ModelNode locking = cache.get(ModelKeys.LOCKING, ModelKeys.LOCKING_NAME);
      this.writeOptional(writer, Attribute.ISOLATION, locking, ModelKeys.ISOLATION);
      this.writeOptional(writer, Attribute.STRIPING, locking, ModelKeys.STRIPING);
      this.writeOptional(writer, Attribute.ACQUIRE_TIMEOUT, locking, ModelKeys.ACQUIRE_TIMEOUT);
      this.writeOptional(writer, Attribute.CONCURRENCY_LEVEL, locking, ModelKeys.CONCURRENCY_LEVEL);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.TRANSACTION, ModelKeys.TRANSACTION_NAME).isDefined()) {
      writer.writeStartElement(Element.TRANSACTION.getLocalName());
      ModelNode transaction = cache.get(ModelKeys.TRANSACTION, ModelKeys.TRANSACTION_NAME);
      this.writeOptional(writer, Attribute.STOP_TIMEOUT, transaction, ModelKeys.STOP_TIMEOUT);
      this.writeOptional(writer, Attribute.MODE, transaction, ModelKeys.MODE);
      this.writeOptional(writer, Attribute.LOCKING, transaction, ModelKeys.LOCKING);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.EVICTION, ModelKeys.EVICTION_NAME).isDefined()) {
      writer.writeStartElement(Element.EVICTION.getLocalName());
      ModelNode eviction = cache.get(ModelKeys.EVICTION, ModelKeys.EVICTION_NAME);
      this.writeOptional(writer, Attribute.STRATEGY, eviction, ModelKeys.STRATEGY);
      this.writeOptional(writer, Attribute.MAX_ENTRIES, eviction, ModelKeys.MAX_ENTRIES);
      this.writeOptional(writer, Attribute.TYPE, eviction, ModelKeys.TYPE);
      this.writeOptional(writer, Attribute.SIZE, eviction, ModelKeys.SIZE);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.EXPIRATION, ModelKeys.EXPIRATION_NAME).isDefined()) {
      writer.writeStartElement(Element.EXPIRATION.getLocalName());
      ModelNode expiration = cache.get(ModelKeys.EXPIRATION, ModelKeys.EXPIRATION_NAME);
      this.writeOptional(writer, Attribute.MAX_IDLE, expiration, ModelKeys.MAX_IDLE);
      this.writeOptional(writer, Attribute.LIFESPAN, expiration, ModelKeys.LIFESPAN);
      this.writeOptional(writer, Attribute.INTERVAL, expiration, ModelKeys.INTERVAL);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.STATE_TRANSFER, ModelKeys.STATE_TRANSFER_NAME).isDefined()) {
      ModelNode stateTransfer = cache.get(ModelKeys.STATE_TRANSFER, ModelKeys.STATE_TRANSFER_NAME);
      writer.writeStartElement(Element.STATE_TRANSFER.getLocalName());
      this.writeOptional(
          writer,
          Attribute.AWAIT_INITIAL_TRANSFER,
          stateTransfer,
          ModelKeys.AWAIT_INITIAL_TRANSFER);
      this.writeOptional(writer, Attribute.ENABLED, stateTransfer, ModelKeys.ENABLED);
      this.writeOptional(writer, Attribute.TIMEOUT, stateTransfer, ModelKeys.TIMEOUT);
      this.writeOptional(writer, Attribute.CHUNK_SIZE, stateTransfer, ModelKeys.CHUNK_SIZE);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.PARTITION_HANDLING, ModelKeys.PARTITION_HANDLING_NAME).isDefined()) {
      ModelNode partitionHandling =
          cache.get(ModelKeys.PARTITION_HANDLING, ModelKeys.PARTITION_HANDLING_NAME);
      writer.writeStartElement(Element.PARTITION_HANDLING.getLocalName());
      this.writeOptional(writer, Attribute.ENABLED, partitionHandling, ModelKeys.ENABLED);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.COMPATIBILITY).isDefined()) {
      ModelNode compatibility = cache.get(ModelKeys.COMPATIBILITY, ModelKeys.COMPATIBILITY_NAME);
      writer.writeStartElement(Element.COMPATIBILITY.getLocalName());
      CompatibilityResource.ENABLED.marshallAsAttribute(compatibility, writer);
      CompatibilityResource.MARSHALLER.marshallAsAttribute(compatibility, writer);
      writer.writeEndElement();
    }

    if (cache.hasDefined(ModelKeys.SECURITY)) {
      writer.writeStartElement(Element.SECURITY.getLocalName());
      ModelNode security = cache.get(ModelKeys.SECURITY, ModelKeys.SECURITY_NAME);
      if (security.hasDefined(ModelKeys.AUTHORIZATION)) {
        writer.writeStartElement(Element.AUTHORIZATION.getLocalName());
        ModelNode authorization =
            security.get(ModelKeys.AUTHORIZATION, ModelKeys.AUTHORIZATION_NAME);
        CacheAuthorizationResource.ENABLED.marshallAsAttribute(authorization, writer);
        this.writeListAsAttribute(writer, Attribute.ROLES, authorization, ModelKeys.ROLES);
        writer.writeEndElement();
      }

      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.LOADER).isDefined()) {
      for (Property clusterLoaderEntry : cache.get(ModelKeys.LOADER).asPropertyList()) {
        ModelNode loader = clusterLoaderEntry.getValue();
        writer.writeStartElement(Element.LOADER.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(clusterLoaderEntry.getName());
        LoaderResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeRequired(writer, Attribute.CLASS, loader, ModelKeys.CLASS);
        this.writeLoaderAttributes(writer, loader);
        this.writeStoreProperties(writer, loader);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.CLUSTER_LOADER).isDefined()) {
      for (Property clusterLoaderEntry : cache.get(ModelKeys.CLUSTER_LOADER).asPropertyList()) {
        ModelNode loader = clusterLoaderEntry.getValue();
        writer.writeStartElement(Element.CLUSTER_LOADER.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(clusterLoaderEntry.getName());
        ClusterLoaderResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeOptional(writer, Attribute.REMOTE_TIMEOUT, loader, ModelKeys.REMOTE_TIMEOUT);
        this.writeLoaderAttributes(writer, loader);
        this.writeStoreProperties(writer, loader);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.STORE).isDefined()) {
      for (Property storeEntry : cache.get(ModelKeys.STORE).asPropertyList()) {
        ModelNode store = storeEntry.getValue();
        writer.writeStartElement(Element.STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(storeEntry.getName());
        StoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeRequired(writer, Attribute.CLASS, store, ModelKeys.CLASS);
        this.writeStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.FILE_STORE).isDefined()) {
      for (Property fileStoreEntry : cache.get(ModelKeys.FILE_STORE).asPropertyList()) {
        ModelNode store = fileStoreEntry.getValue();
        writer.writeStartElement(Element.FILE_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(fileStoreEntry.getName());
        FileStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeOptional(writer, Attribute.MAX_ENTRIES, store, ModelKeys.MAX_ENTRIES);
        this.writeOptional(writer, Attribute.RELATIVE_TO, store, ModelKeys.RELATIVE_TO);
        this.writeOptional(writer, Attribute.PATH, store, ModelKeys.PATH);
        this.writeStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.STRING_KEYED_JDBC_STORE).isDefined()) {
      for (Property stringKeyedJDBCStoreEntry :
          cache.get(ModelKeys.STRING_KEYED_JDBC_STORE).asPropertyList()) {
        ModelNode store = stringKeyedJDBCStoreEntry.getValue();
        writer.writeStartElement(Element.STRING_KEYED_JDBC_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(stringKeyedJDBCStoreEntry.getName());
        StringKeyedJDBCStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeJdbcStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        this.writeJDBCStoreTable(
            writer, Element.STRING_KEYED_TABLE, store, ModelKeys.STRING_KEYED_TABLE);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.BINARY_KEYED_JDBC_STORE).isDefined()) {
      for (Property binaryKeyedJDBCStoreEntry :
          cache.get(ModelKeys.BINARY_KEYED_JDBC_STORE).asPropertyList()) {
        ModelNode store = binaryKeyedJDBCStoreEntry.getValue();
        writer.writeStartElement(Element.BINARY_KEYED_JDBC_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(binaryKeyedJDBCStoreEntry.getName());
        BinaryKeyedJDBCStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeJdbcStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        this.writeJDBCStoreTable(
            writer, Element.BINARY_KEYED_TABLE, store, ModelKeys.BINARY_KEYED_TABLE);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.MIXED_KEYED_JDBC_STORE).isDefined()) {
      for (Property mixedKeyedJDBCStoreEntry :
          cache.get(ModelKeys.MIXED_KEYED_JDBC_STORE).asPropertyList()) {
        ModelNode store = mixedKeyedJDBCStoreEntry.getValue();
        writer.writeStartElement(Element.MIXED_KEYED_JDBC_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(mixedKeyedJDBCStoreEntry.getName());
        MixedKeyedJDBCStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeJdbcStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        this.writeJDBCStoreTable(
            writer, Element.STRING_KEYED_TABLE, store, ModelKeys.STRING_KEYED_TABLE);
        this.writeJDBCStoreTable(
            writer, Element.BINARY_KEYED_TABLE, store, ModelKeys.BINARY_KEYED_TABLE);
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.REMOTE_STORE).isDefined()) {
      for (Property remoteStoreEntry : cache.get(ModelKeys.REMOTE_STORE).asPropertyList()) {
        ModelNode store = remoteStoreEntry.getValue();
        writer.writeStartElement(Element.REMOTE_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(remoteStoreEntry.getName());
        RemoteStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeOptional(writer, Attribute.CACHE, store, ModelKeys.CACHE);
        this.writeOptional(writer, Attribute.HOTROD_WRAPPING, store, ModelKeys.HOTROD_WRAPPING);
        this.writeOptional(writer, Attribute.RAW_VALUES, store, ModelKeys.RAW_VALUES);
        this.writeOptional(writer, Attribute.SOCKET_TIMEOUT, store, ModelKeys.SOCKET_TIMEOUT);
        this.writeOptional(writer, Attribute.TCP_NO_DELAY, store, ModelKeys.TCP_NO_DELAY);
        this.writeStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);
        for (ModelNode remoteServer : store.require(ModelKeys.REMOTE_SERVERS).asList()) {
          writer.writeStartElement(Element.REMOTE_SERVER.getLocalName());
          writer.writeAttribute(
              Attribute.OUTBOUND_SOCKET_BINDING.getLocalName(),
              remoteServer.get(ModelKeys.OUTBOUND_SOCKET_BINDING).asString());
          writer.writeEndElement();
        }
        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.REST_STORE).isDefined()) {
      for (Property restStoreEntry : cache.get(ModelKeys.REST_STORE).asPropertyList()) {
        ModelNode store = restStoreEntry.getValue();
        writer.writeStartElement(Element.REST_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(restStoreEntry.getName());
        RestStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeOptional(
            writer,
            Attribute.APPEND_CACHE_NAME_TO_PATH,
            store,
            ModelKeys.APPEND_CACHE_NAME_TO_PATH);
        this.writeOptional(writer, Attribute.PATH, store, ModelKeys.PATH);

        this.writeStoreAttributes(writer, store);
        this.writeStoreWriteBehind(writer, store);
        this.writeStoreProperties(writer, store);

        if (store.hasDefined(ModelKeys.CONNECTION_POOL)) {
          ModelNode pool = store.get(ModelKeys.CONNECTION_POOL);
          writer.writeStartElement(Element.CONNECTION_POOL.getLocalName());
          this.writeOptional(
              writer, Attribute.CONNECTION_TIMEOUT, pool, ModelKeys.CONNECTION_TIMEOUT);
          this.writeOptional(
              writer, Attribute.MAX_CONNECTIONS_PER_HOST, pool, ModelKeys.MAX_CONNECTIONS_PER_HOST);
          this.writeOptional(
              writer, Attribute.MAX_TOTAL_CONNECTIONS, pool, ModelKeys.MAX_TOTAL_CONNECTIONS);
          this.writeOptional(writer, Attribute.BUFFER_SIZE, pool, ModelKeys.BUFFER_SIZE);
          this.writeOptional(writer, Attribute.SOCKET_TIMEOUT, pool, ModelKeys.SOCKET_TIMEOUT);
          this.writeOptional(writer, Attribute.TCP_NO_DELAY, pool, ModelKeys.TCP_NO_DELAY);
          writer.writeEndElement();
        }

        for (ModelNode remoteServer : store.require(ModelKeys.REMOTE_SERVERS).asList()) {
          writer.writeStartElement(Element.REMOTE_SERVER.getLocalName());
          writer.writeAttribute(
              Attribute.OUTBOUND_SOCKET_BINDING.getLocalName(),
              remoteServer.get(ModelKeys.OUTBOUND_SOCKET_BINDING).asString());
          writer.writeEndElement();
        }

        writer.writeEndElement();
      }
    }

    if (cache.get(ModelKeys.INDEXING).isDefined()
        || cache.get(ModelKeys.INDEXING_PROPERTIES).isDefined()) {
      writer.writeStartElement(Element.INDEXING.getLocalName());
      CacheResource.INDEXING.marshallAsAttribute(cache, writer);
      CacheResource.INDEXING_AUTO_CONFIG.marshallAsAttribute(cache, writer);
      CacheResource.INDEXING_PROPERTIES.marshallAsElement(cache, writer);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.BACKUP).isDefined()) {
      writer.writeStartElement(Element.BACKUPS.getLocalName());
      for (Property property : cache.get(ModelKeys.BACKUP).asPropertyList()) {
        writer.writeStartElement(Element.BACKUP.getLocalName());
        writer.writeAttribute(Attribute.SITE.getLocalName(), property.getName());
        ModelNode backup = property.getValue();
        BackupSiteResource.FAILURE_POLICY.marshallAsAttribute(backup, writer);
        BackupSiteResource.STRATEGY.marshallAsAttribute(backup, writer);
        BackupSiteResource.REPLICATION_TIMEOUT.marshallAsAttribute(backup, writer);
        BackupSiteResource.ENABLED.marshallAsAttribute(backup, writer);
        if (backup.hasDefined(ModelKeys.TAKE_BACKUP_OFFLINE_AFTER_FAILURES)
            || backup.hasDefined(ModelKeys.TAKE_BACKUP_OFFLINE_MIN_WAIT)) {
          writer.writeStartElement(Element.TAKE_OFFLINE.getLocalName());
          BackupSiteResource.TAKE_OFFLINE_AFTER_FAILURES.marshallAsAttribute(backup, writer);
          BackupSiteResource.TAKE_OFFLINE_MIN_WAIT.marshallAsAttribute(backup, writer);
          writer.writeEndElement();
        }
        if (backup.get(ModelKeys.STATE_TRANSFER, ModelKeys.STATE_TRANSFER_NAME).isDefined()) {
          ModelNode stateTransfer =
              backup.get(ModelKeys.STATE_TRANSFER, ModelKeys.STATE_TRANSFER_NAME);
          if (stateTransfer.hasDefined(ModelKeys.CHUNK_SIZE)
              || stateTransfer.hasDefined(ModelKeys.TIMEOUT)
              || stateTransfer.hasDefined(ModelKeys.MAX_RETRIES)
              || stateTransfer.hasDefined(ModelKeys.WAIT_TIME)) {
            writer.writeStartElement(Element.STATE_TRANSFER.getLocalName());
            BackupSiteStateTransferResource.STATE_TRANSFER_CHUNK_SIZE.marshallAsAttribute(
                stateTransfer, writer);
            BackupSiteStateTransferResource.STATE_TRANSFER_TIMEOUT.marshallAsAttribute(
                stateTransfer, writer);
            BackupSiteStateTransferResource.STATE_TRANSFER_MAX_RETRIES.marshallAsAttribute(
                stateTransfer, writer);
            BackupSiteStateTransferResource.STATE_TRANSFER_WAIT_TIME.marshallAsAttribute(
                stateTransfer, writer);
            writer.writeEndElement();
          }
        }
        writer.writeEndElement();
      }
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.REMOTE_CACHE).isDefined()
        || cache.get(ModelKeys.REMOTE_SITE).isDefined()) {
      writer.writeStartElement(Element.BACKUP_FOR.getLocalName());
      CacheResource.REMOTE_CACHE.marshallAsAttribute(cache, writer);
      CacheResource.REMOTE_SITE.marshallAsAttribute(cache, writer);
      writer.writeEndElement();
    }

    if (cache.get(ModelKeys.LEVELDB_STORE).isDefined()) {
      for (Property levelDbStoreEntry : cache.get(ModelKeys.LEVELDB_STORE).asPropertyList()) {
        ModelNode store = levelDbStoreEntry.getValue();
        writer.writeStartElement(Element.LEVELDB_STORE.getLocalName());
        // write identifier before other attributes
        ModelNode name = new ModelNode();
        name.get(ModelKeys.NAME).set(levelDbStoreEntry.getName());
        LevelDBStoreResource.NAME.marshallAsAttribute(name, false, writer);
        this.writeOptional(writer, Attribute.RELATIVE_TO, store, ModelKeys.RELATIVE_TO);
        this.writeOptional(writer, Attribute.PATH, store, ModelKeys.PATH);
        this.writeOptional(writer, Attribute.BLOCK_SIZE, store, ModelKeys.BLOCK_SIZE);
        this.writeOptional(writer, Attribute.CACHE_SIZE, store, ModelKeys.CACHE_SIZE);
        this.writeOptional(writer, Attribute.CLEAR_THRESHOLD, store, ModelKeys.CLEAR_THRESHOLD);
        this.writeStoreAttributes(writer, store);
        this.writeStoreExpiration(writer, store);
        this.writeStoreCompression(writer, store);
        this.writeStoreImplementation(writer, store);
        this.writeStoreProperties(writer, store);
        writer.writeEndElement();
      }
    }
  }