DeprecatedAttribute(
     String name, org.jboss.as.clustering.controller.Attribute[]... attributeSets) {
   int size = 0;
   for (org.jboss.as.clustering.controller.Attribute[] attributes : attributeSets) {
     size += attributes.length;
   }
   List<AttributeDefinition> definitions = new ArrayList<>(size);
   for (org.jboss.as.clustering.controller.Attribute[] attributes : attributeSets) {
     for (org.jboss.as.clustering.controller.Attribute attribute : attributes) {
       definitions.add(attribute.getDefinition());
     }
   }
   this.definition =
       ObjectTypeAttributeDefinition.Builder.of(
               name, definitions.toArray(new AttributeDefinition[size]))
           .setAllowNull(true)
           .setDeprecated(InfinispanModel.VERSION_4_0_0.getVersion())
           .setSuffix("table")
           .build();
 }
/**
 * Resource description for the addressable resource
 * /subsystem=infinispan/cache-container=X/cache=Y/remote-store=REMOTE_STORE
 *
 * @author Richard Achmatowicz (c) 2011 Red Hat Inc.
 */
public class RemoteStoreResourceDefinition extends StoreResourceDefinition {

  static final PathElement PATH =
      PathElement.pathElement(ModelKeys.REMOTE_STORE, ModelKeys.REMOTE_STORE_NAME);

  // attributes
  static final SimpleAttributeDefinition CACHE =
      new SimpleAttributeDefinitionBuilder(ModelKeys.CACHE, ModelType.STRING, true)
          .setXmlName(Attribute.CACHE.getLocalName())
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .setDefaultValue(new ModelNode(BasicCacheContainer.DEFAULT_CACHE_NAME))
          .build();

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

  static final SimpleAttributeDefinition SOCKET_TIMEOUT =
      new SimpleAttributeDefinitionBuilder(ModelKeys.SOCKET_TIMEOUT, ModelType.LONG, true)
          .setXmlName(Attribute.SOCKET_TIMEOUT.getLocalName())
          .setMeasurementUnit(MeasurementUnit.MILLISECONDS)
          .setAllowExpression(true)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .setDefaultValue(new ModelNode().set(60000L))
          .build();

  // the remote servers parameter is required (not null), and the list of remote-server objects must
  // have size >= 1
  static final SimpleAttributeDefinition OUTBOUND_SOCKET_BINDING =
      new SimpleAttributeDefinitionBuilder(ModelKeys.OUTBOUND_SOCKET_BINDING, ModelType.STRING)
          .setAllowNull(false)
          .setXmlName(Attribute.OUTBOUND_SOCKET_BINDING.getLocalName())
          .build();

  static final ObjectTypeAttributeDefinition REMOTE_SERVER =
      ObjectTypeAttributeDefinition.Builder.of(ModelKeys.REMOTE_SERVER, OUTBOUND_SOCKET_BINDING)
          .setAllowNull(false)
          .setSuffix("remote-server")
          .build();

  static final ObjectListAttributeDefinition REMOTE_SERVERS =
      ObjectListAttributeDefinition.Builder.of(ModelKeys.REMOTE_SERVERS, REMOTE_SERVER)
          .setAllowNull(false)
          .setMinSize(1)
          .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES)
          .build();

  static final AttributeDefinition[] ATTRIBUTES =
      new AttributeDefinition[] {CACHE, TCP_NO_DELAY, SOCKET_TIMEOUT, REMOTE_SERVERS};

  // operations
  private static final OperationDefinition ADD_DEFINITION =
      new SimpleOperationDefinitionBuilder(
              ADD, InfinispanExtension.getResourceDescriptionResolver(ModelKeys.REMOTE_STORE))
          .setParameters(PARAMETERS)
          .addParameter(CACHE)
          .addParameter(TCP_NO_DELAY)
          .addParameter(SOCKET_TIMEOUT)
          .addParameter(REMOTE_SERVERS)
          .setAttributeResolver(
              InfinispanExtension.getResourceDescriptionResolver(ModelKeys.REMOTE_STORE))
          .build();

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

    if (InfinispanModel.VERSION_1_4_0.requiresTransformation(version)) {
      builder
          .getAttributeBuilder()
          .addRejectCheck(
              RejectAttributeChecker.SIMPLE_EXPRESSIONS, CACHE, SOCKET_TIMEOUT, TCP_NO_DELAY);
    }

    StoreResourceDefinition.buildTransformation(version, builder);
  }

  RemoteStoreResourceDefinition(boolean allowRuntimeOnlyRegistration) {
    super(StoreType.REMOTE, allowRuntimeOnlyRegistration);
  }

  @Override
  public void registerAttributes(ManagementResourceRegistration registration) {
    super.registerAttributes(registration);
    // check that we don't need a special handler here?
    final OperationStepHandler writeHandler = new ReloadRequiredWriteAttributeHandler(ATTRIBUTES);
    for (AttributeDefinition attr : ATTRIBUTES) {
      registration.registerReadWriteAttribute(attr, null, writeHandler);
    }
  }

  // override the add operation to provide a custom definition (for the optional PROPERTIES
  // parameter to add())
  @Override
  protected void registerAddOperation(
      final ManagementResourceRegistration registration,
      final OperationStepHandler handler,
      OperationEntry.Flag... flags) {
    registration.registerOperationHandler(ADD_DEFINITION, handler);
  }
}