protected AbstractAddSecurityRealmSubElement(Builder builder) {
    this.securityRealmName = builder.securityRealmName;
    this.replaceExisting = builder.replaceExisting;

    securityRealmAddress =
        Address.coreService("management").and("security-realm", securityRealmName);
  }
  private void performRestartOperation(RestartOperation restartOperation)
      throws IOException, InterruptedException, TimeoutException {
    boolean needsToReconnect = false;
    try {
      restartOperation.perform(ops, Address.root());
    } catch (Throwable e) {
      // server went down before we received the response, this can happen
      needsToReconnect = true;
    }

    waitUntilServerIsRunning(needsToReconnect);
  }
 private boolean isRestartOperationRequired(RestartOperation restartOperation) throws IOException {
   return restartOperation.isRequired(
       ops.readAttribute(Address.root(), Constants.SERVER_STATE), false);
 }
 private boolean isServerRunning() throws IOException {
   ModelNodeResult result = ops.readAttribute(Address.root(), Constants.SERVER_STATE);
   result.assertDefinedValue();
   return ServerState.isRunning(result.stringValue());
 }
@RunWith(Arquillian.class)
public class AddDataSourceOnlineTest {
  private OnlineManagementClient client;
  private Operations ops;
  private Administration administration;

  private static final String TEST_DATASOURCE_NAME = "creaper-ds";
  private static final Address TEST_DATASOURCE_ADDRESS =
      Address.subsystem("datasources").and("data-source", TEST_DATASOURCE_NAME);
  private static final String VALID_DS_URL = "jdbc:h2:mem:test-creaper;DB_CLOSE_DELAY=-1;";

  @Before
  public void connect() throws IOException {
    client = ManagementClient.online(OnlineOptions.standalone().localDefault().build());
    ops = new Operations(client);
    administration = new Administration(client);
  }

  @After
  public void cleanup()
      throws IOException, CliException, OperationException, TimeoutException, InterruptedException {
    try {
      ops.removeIfExists(TEST_DATASOURCE_ADDRESS);
      administration.reloadIfRequired();
    } finally {
      client.close();
    }
  }

  @Test
  public void addDataSource_commandSuccessful() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .connectionUrl(VALID_DS_URL)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .connectable(false)
            .jta(false)
            .usernameAndPassword("creaper", "creaper")
            .useJavaContext(true)
            .maxPoolSize(666)
            .minPoolSize(0)
            .statisticsEnabled(false)
            .build();
    client.apply(addDataSource);

    assertTrue("The data source should be created", ops.exists(TEST_DATASOURCE_ADDRESS));
  }

  @Test
  public void addDataSource_replaceExisting() throws Exception {
    client.apply(
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .connectionUrl(VALID_DS_URL)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .usernameAndPassword("creaper", "creaper")
            .build());
    assertTrue("The datasource should be created", ops.exists(TEST_DATASOURCE_ADDRESS));

    client.apply(
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .connectionUrl(VALID_DS_URL)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .usernameAndPassword("creaper2", "creaper2")
            .replaceExisting()
            .build());
    assertTrue("The datasource should be created", ops.exists(TEST_DATASOURCE_ADDRESS));
    assertEquals(
        "The datasource should be replaced with the new one with different username",
        "creaper2",
        ops.readAttribute(TEST_DATASOURCE_ADDRESS, "user-name").stringValue());
  }

  @Test(expected = CommandFailedException.class)
  public void addDataSource_commandFails() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .jndiName("invalid-jndi-name")
            .driverName("h2")
            .connectionUrl("invalid-url")
            .build();
    client.apply(addDataSource);
  }

  @Test
  public void addDataSourceAndEnable_commandSuccessful() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .connectionUrl(VALID_DS_URL)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .enableAfterCreate()
            .connectable(false)
            .jta(false)
            .usernameAndPassword("creaper", "creaper")
            .useJavaContext(true)
            .build();
    client.apply(addDataSource);

    assertTrue("The data source should be created", ops.exists(TEST_DATASOURCE_ADDRESS));
    assertTrue(
        "The data source should be enabled",
        ops.readAttribute(TEST_DATASOURCE_ADDRESS, "enabled").booleanValue());
  }

  @Test
  public void addDataSourceAndEnable_commandFailed_incorrectPoolSize() throws Exception {
    try {
      AddDataSource addDataSource =
          new AddDataSource.Builder(TEST_DATASOURCE_NAME)
              .connectionUrl(VALID_DS_URL)
              .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
              .driverName("h2")
              .maxPoolSize(-1) // improper value which causes enable to fail
              .enableAfterCreate()
              .build();
      client.apply(addDataSource);
      fail("Command should fail");
    } catch (IllegalArgumentException expected) {
      assertFalse(
          "The datasource shouldn't be created as the command should be composite and enable should fail",
          ops.exists(TEST_DATASOURCE_ADDRESS));
    }
  }

  @Test(expected = IllegalArgumentException.class)
  public void addDataSource_commandFailed_urlNotDefined() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .maxPoolSize(1)
            .usernameAndPassword("creaper", "creaper")
            .securityDomain("other")
            .build();
    client.apply(addDataSource);
  }

  @Test(expected = IllegalArgumentException.class)
  public void addDataSource_commandFailed_usernameAndSecurityDomainDefined() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .build();
    client.apply(addDataSource);
  }

  @Test
  public void addDataSource_commandSuccessful_fullLoad() throws Exception {
    AddDataSource addDataSource =
        new AddDataSource.Builder(TEST_DATASOURCE_NAME)
            .connectionUrl(VALID_DS_URL)
            .jndiName("java:/jboss/datasources/" + TEST_DATASOURCE_NAME)
            .driverName("h2")
            .usernameAndPassword("creaper", "creaper")
            .allocationRetry(3)
            .allocationRetryWaitMillis(1000)
            .allowMultipleUsers(true)
            .backgroundValidation(true)
            .backgroundValidationMillis(1000)
            .blockingTimeoutWaitMillis(1000)
            .checkValidConnectionSql("SELECT 1")
            .connectable(true)
            .addConnectionProperty("other-user-name", "right-its-other-username")
            .datasourceClass("org.h2.jdbcx.JdbcDataSource")
            .driverClass("org.h2.Driver")
            .exceptionSorterClass(
                "org.jboss.jca.adapters.jdbc.extensions.novendor.NullExceptionSorter")
            .addExceptionSorterProperty("exception-sorter-prop", "ok")
            .idleTimeoutMinutes(10)
            .jta(true)
            .managedConnectionPool(
                "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool")
            .maxPoolSize(1)
            .minPoolSize(1)
            .newConnectionSql("SELECT 1")
            .flushStrategy(PoolFlushStrategy.ENTIRE_POOL)
            .prefill(true)
            .preparedStatementsCacheSize(3)
            .queryTimeout(20)
            // .reauthPluginClass() - no null reauth plugin exists
            // .securityDomain("other") - can't be used as interferes with usage of username
            .setTxQueryTimeout(true)
            .sharePreparedStatements(true)
            .spy(true)
            .staleConnectionCheckerClass(
                "org.jboss.jca.adapters.jdbc.extensions.novendor.NullStaleConnectionChecker")
            .addStaleConnectionCheckerProperty("stale-checker-prop", "ok")
            .statisticsEnabled(true)
            .trackPreparedStatements(TrackStatementType.TRUE)
            .transactionIsolation(TransactionIsolation.TRANSACTION_REPEATABLE_READ)
            .urlDelimiter(";")
            // .urlSelectorStrategyClass() - can't find any implementation of SPI
            .useCcm(true)
            .useFastFailAllocation(false)
            .useJavaContext(true)
            .useStrictMinPoolSize(true)
            .useTryLock(60)
            .validateOnMatch(true)
            .validConnectionCheckerClass(
                "org.jboss.jca.adapters.jdbc.extensions.novendor.NullValidConnectionChecker")
            .addValidConnectionCheckerProperty("valid-checker-prop", "ok")
            .build();

    client.apply(addDataSource);

    assertTrue("The datasource should be created", ops.exists(TEST_DATASOURCE_ADDRESS));
  }
}
@RunWith(Arquillian.class)
public class AddSecurityRealmOnlineTest {

  private OnlineManagementClient client;
  private Operations ops;
  private Administration administration;

  private static final String TEST_SECURITY_REALM_NAME = "creaperSecRealm";
  private static final Address TEST_SECURITY_REALM_ADDRESS =
      Address.coreService("management").and("security-realm", TEST_SECURITY_REALM_NAME);

  @Before
  public void connect() throws IOException {
    client = ManagementClient.online(OnlineOptions.standalone().localDefault().build());
    ops = new Operations(client);
    administration = new Administration(client);
  }

  @After
  public void cleanup()
      throws IOException, CliException, OperationException, TimeoutException, InterruptedException {
    try {
      ops.removeIfExists(TEST_SECURITY_REALM_ADDRESS);
      administration.reloadIfRequired();
    } finally {
      client.close();
    }
  }

  @Test
  public void addSimple() throws Exception {
    AddSecurityRealm addSecurityRealm =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME).build();

    assertFalse("The security realm should not exist", ops.exists(TEST_SECURITY_REALM_ADDRESS));
    client.apply(addSecurityRealm);
    assertTrue("The security realm should be created", ops.exists(TEST_SECURITY_REALM_ADDRESS));
  }

  @Test
  public void addFull() throws Exception {
    AddSecurityRealm addSecurityRealm =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME).mapGroupsToRoles(true).build();
    client.apply(addSecurityRealm);

    assertTrue("The security realm should be created", ops.exists(TEST_SECURITY_REALM_ADDRESS));

    ModelNodeResult readAttribute =
        ops.readAttribute(TEST_SECURITY_REALM_ADDRESS, "map-groups-to-roles");
    readAttribute.assertSuccess("Read operation for map-groups-to-roles failed");
    Assert.assertEquals(
        "Read operation for map-groups-to-roles return wrong value",
        "true",
        readAttribute.stringValue());
  }

  @Test(expected = CommandFailedException.class)
  public void existing() throws Exception {
    AddSecurityRealm addSecurityRealm =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME).build();
    AddSecurityRealm addSecurityRealm2 =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME).mapGroupsToRoles(true).build();

    client.apply(addSecurityRealm);
    client.apply(addSecurityRealm2);

    fail(
        "Security realm creaperSecRealm already exists in configuration, exception should be thrown");
  }

  @Test
  public void overrideExisting() throws Exception {
    AddSecurityRealm addSecurityRealm =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME).build();
    AddSecurityRealm addSecurityRealm2 =
        new AddSecurityRealm.Builder(TEST_SECURITY_REALM_NAME)
            .mapGroupsToRoles(true)
            .replaceExisting()
            .build();

    client.apply(addSecurityRealm);
    assertTrue("The security realm should be created", ops.exists(TEST_SECURITY_REALM_ADDRESS));
    client.apply(addSecurityRealm2);
    assertTrue("The security realm should be created", ops.exists(TEST_SECURITY_REALM_ADDRESS));

    ModelNodeResult readAttribute =
        ops.readAttribute(TEST_SECURITY_REALM_ADDRESS, "map-groups-to-roles");
    readAttribute.assertSuccess("Read operation for map-groups-to-roles failed");
    Assert.assertEquals(
        "Read operation for map-groups-to-roles return wrong value",
        "true",
        readAttribute.stringValue());
  }

  @Test(expected = IllegalArgumentException.class)
  public void addSecurityRealm_nullName() throws Exception {
    new AddSecurityRealm.Builder(null).build();
    fail("Creating command with null security realm name should throw exception");
  }

  @Test(expected = IllegalArgumentException.class)
  public void addSecurityRealm_emptyName() throws Exception {
    new AddSecurityRealm.Builder("").build();
    fail("Creating command with empty security realm name should throw exception");
  }
}