示例#1
0
  /**
   * Get the number of connections currently in use
   *
   * @param connectorName
   * @return boolean
   */
  @ManagementOperation(
      description = "Get the number of connections currently in use",
      impact = Impact.ReadOnly)
  public long getInUseConnections(String connectorName) {
    if (!isRunning()) return 0;

    // Get engine to use for the rest of the method (this is synchronized)
    final JcrEngine engine = getEngine();
    assert engine != null;

    long totalConnectionsInUse = 0;
    try {
      totalConnectionsInUse =
          engine
              .getRepositoryService()
              .getRepositoryLibrary()
              .getConnectionPool(connectorName)
              .getInUseCount();
    } catch (Exception e) {
      Logger.getLogger(getClass())
          .error(e, JBossManagedI18n.errorDeterminingTotalInUseConnections, connectorName);
    }

    return totalConnectionsInUse;
  }
示例#2
0
  /**
   * Pings a connector by name.
   *
   * @param connectorName
   * @return RepositorySource - may be <code>null</code>)
   */
  @ManagementOperation(description = "Pings a connector by name", impact = Impact.ReadOnly)
  public boolean pingConnector(String connectorName) {
    if (!isRunning()) return false;

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    boolean success = false;
    String pingDuration = null;
    try {
      RepositoryConnectionPool pool =
          engine.getRepositoryService().getRepositoryLibrary().getConnectionPool(connectorName);
      if (pool != null) {
        Stopwatch sw = new Stopwatch();
        sw.start();
        success = pool.ping();
        sw.stop();
        pingDuration = sw.getTotalDuration().toString();
      }
    } catch (Exception e) {
      Logger.getLogger(getClass())
          .error(e, JBossManagedI18n.errorDeterminingIfConnectionIsAlive, connectorName);
    }
    if (pingDuration == null) pingDuration = new Duration(0L).toString();
    return success;
  }
示例#3
0
  /**
   * Obtains the properties for the passed in object. This is a JBoss managed operation.
   *
   * @param objectName
   * @param objectType
   * @return an collection of managed properties (may be <code>null</code>)
   */
  @ManagementOperation(
      description = "Obtains the properties for an object",
      impact = Impact.ReadOnly)
  public List<ManagedProperty> getProperties(String objectName, Component objectType) {
    if (!isRunning()) return Collections.emptyList();

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    List<ManagedProperty> managedProps = new ArrayList<ManagedProperty>();
    if (objectType.equals(Component.CONNECTOR)) {
      RepositorySource repositorySource = engine.getRepositorySource(objectName);
      assert repositorySource != null : "Connection '" + objectName + "' does not exist";
      managedProps = ManagedUtils.getProperties(objectType, repositorySource);
    } else if (objectType.equals(Component.CONNECTIONPOOL)) {
      RepositoryConnectionPool connectionPool =
          engine.getRepositoryService().getRepositoryLibrary().getConnectionPool(objectName);
      assert connectionPool != null
          : "Repository Connection Pool for repository '" + objectName + "' does not exist";
      managedProps = ManagedUtils.getProperties(objectType, connectionPool);
    }

    return managedProps;
  }
示例#4
0
  /**
   * First {@link #shutdown() shutdowns} the engine and then {@link #start() starts} it back up
   * again. This is a JBoss managed operation.
   *
   * @see #shutdown()
   * @see #start()
   * @throws Exception if there is a problem restarting the engine (usually reading the
   *     configuration file)
   */
  @ManagementOperation(description = "Restarts this engine", impact = Impact.Lifecycle)
  public synchronized void restart() throws Exception {
    // Grab a reference to the existing engine first ...
    JcrEngine oldEngine = this.engine;
    try {
      // Before we shutdown the existing engine, start up a new one ...
      loadConfigurationAndCreateEngine();
      start();
    } catch (Throwable e) {
      // There was a problem starting the new engine, so keep the old
      // engine (which is still running) ...
      this.engine = oldEngine;
      if (e instanceof RuntimeException) throw (RuntimeException) e;
      throw (Exception) e;
    }

    // At this point, we know that the new engine was started correctly and
    // is ready to be used.
    // So now we can shutdown the old engine (preventing new sessions from
    // being created), waiting up to 10 seconds
    // for any previously-created sessions to be closed gracefully, and then
    // forcing termination of all
    // remaining, longer-running sessions.
    oldEngine.shutdownAndAwaitTermination(10, TimeUnit.SECONDS);
  }
  @Test
  public void shouldAllowSettingUpConfigurationRepositoryWithAuthenticationProviders()
      throws Exception {
    InMemoryRepositorySource configSource = new InMemoryRepositorySource();
    configSource.setName("config2");
    configSource.setRetryLimit(5);
    configuration.loadFrom(configSource, "workspaceXYZ");
    configuration
        .repositorySource("Source2")
        .usingClass(InMemoryRepositorySource.class.getName())
        .loadedFromClasspath()
        .setDescription("description")
        .and()
        .repository("JCR Repository")
        .setSource("Source2")
        .setOption(Option.JAAS_LOGIN_CONFIG_NAME, "test")
        .authenticator("customAuth")
        .usingClass("org.modeshape.jcr.security.SecurityContextProvider")
        .loadedFromClasspath()
        .setDescription("customAuth Desc");
    configuration.save();
    // Save the configuration and start the engine ...
    engine = configuration.build();
    engine.start();

    ConfigurationDefinition configDefn = configuration.getConfigurationDefinition();
    assertThat(configDefn.getWorkspace(), is("workspaceXYZ"));
    assertThat(configDefn.getPath(), is(path("/")));

    // Get a graph to the configuration source ...
    RepositorySource configReposSource =
        engine.getRepositoryService().getRepositoryLibrary().getSource("config2");
    assertThat(configReposSource, is(notNullValue()));
    assertThat(configReposSource, is(instanceOf(InMemoryRepositorySource.class)));
    assertThat(configReposSource.getName(), is("config2"));
    InMemoryRepositorySource configSource2 = (InMemoryRepositorySource) configReposSource;
    assertThat(configSource2.getDefaultWorkspaceName(), is("")); // didn't change this

    Graph graph = engine.getGraph("config2");
    assertThat(graph, is(notNullValue()));
    assertThat(graph.getNodeAt("/"), is(notNullValue()));
    assertThat(graph.getNodeAt("/mode:sources"), is(notNullValue()));
    assertThat(
        graph.getNodeAt("/mode:sources/Source2"),
        hasProperty(ModeShapeLexicon.DESCRIPTION, "description"));
    assertThat(
        graph.getNodeAt("/mode:repositories/JCR Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Source2"));
    assertThat(
        graph.getNodeAt("/mode:repositories/JCR Repository/mode:authenticationProviders"),
        is(notNullValue()));

    // Get the repository ...
    JcrRepository repository = engine.getRepository("JCR Repository");
    assertThat(repository, is(notNullValue()));
  }
示例#6
0
  /**
   * Obtains a connector by name.
   *
   * @param connectorName
   * @return RepositorySource - may be <code>null</code>)
   */
  public RepositorySource getConnector(String connectorName) {
    if (!isRunning()) return null;

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    RepositorySource repositorySource = engine.getRepositorySource(connectorName);
    assert (repositorySource != null) : "Connector '" + connectorName + "' does not exist";
    return repositorySource;
  }
 @After
 public void afterEach() throws Exception {
   if (engine != null) {
     try {
       engine.shutdown();
       engine.awaitTermination(3, TimeUnit.SECONDS);
     } finally {
       engine = null;
     }
   }
   JaasTestUtil.releaseJaas();
 }
示例#8
0
  /**
   * Obtains the specified managed repository of this engine. This is called by the
   * JNDIManagedRepositories when a JNDI lookup is performed to find a repository.
   *
   * @param repositoryName for the repository to be returned
   * @return a repository or <code>null</code> if repository doesn't exist
   */
  public JcrRepository getRepository(String repositoryName) {
    if (!isRunning()) return null;

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    try {
      return engine.getRepository(repositoryName);
    } catch (RepositoryException e) {
      Logger.getLogger(getClass())
          .error(e, JBossManagedI18n.errorGettingRepositoryFromEngine, repositoryName);
      return null;
    }
  }
示例#9
0
  /**
   * Obtains the managed repositories of this engine. This is a JBoss managed operation.
   *
   * @return an unmodifiable collection of repositories (never <code>null</code>)
   */
  @ManagementOperation(
      description = "Obtains the managed repositories of this engine",
      impact = Impact.ReadOnly)
  public Collection<ManagedRepository> getRepositories() {
    if (!isRunning()) return Collections.emptyList();

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    Collection<ManagedRepository> repositories = new ArrayList<ManagedRepository>();
    for (String repositoryName : engine.getRepositoryNames()) {
      repositories.add(new ManagedRepository(repositoryName));
    }

    return repositories;
  }
  @Test
  public void shouldAllowSettingUpConfigurationRepositoryWithDifferentConfigurationSourceName()
      throws Exception {
    configuration
        .repositorySource("Source2")
        .usingClass(InMemoryRepositorySource.class.getName())
        .loadedFromClasspath()
        .setDescription("description")
        .and()
        .repository("JCR Repository")
        .setSource("Source2")
        .setOption(Option.JAAS_LOGIN_CONFIG_NAME, "test")
        .and()
        .save();

    // Start the engine ...
    engine = configuration.build();
    engine.start();
    // Get a graph to the configuration source ...
    RepositorySource configReposSource =
        engine
            .getRepositoryService()
            .getRepositoryLibrary()
            .getSource(JcrConfiguration.DEFAULT_CONFIGURATION_SOURCE_NAME);
    assertThat(configReposSource, is(notNullValue()));
    assertThat(configReposSource, is(instanceOf(InMemoryRepositorySource.class)));
    assertThat(configReposSource.getName(), is(JcrConfiguration.DEFAULT_CONFIGURATION_SOURCE_NAME));
    InMemoryRepositorySource configSource = (InMemoryRepositorySource) configReposSource;
    assertThat(configSource.getDefaultWorkspaceName(), is(JcrConfiguration.DEFAULT_WORKSPACE_NAME));
    Graph graph = engine.getGraph(JcrConfiguration.DEFAULT_CONFIGURATION_SOURCE_NAME);
    assertThat(graph, is(notNullValue()));
    assertThat(graph.getNodeAt("/"), is(notNullValue()));
    assertThat(graph.getNodeAt("/mode:sources"), is(notNullValue()));
    assertThat(
        graph.getNodeAt("/mode:sources/Source2"),
        hasProperty(ModeShapeLexicon.DESCRIPTION, "description"));
    assertThat(
        graph.getNodeAt("/mode:repositories/JCR Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Source2"));

    // Get the repository ...
    JcrRepository repository = engine.getRepository("JCR Repository");
    assertThat(repository, is(notNullValue()));
  }
示例#11
0
  /**
   * Obtains the managed connectors of this engine. This is a JBoss managed operation.
   *
   * @return an unmodifiable collection of managed connectors (never <code>null</code>)
   */
  @ManagementOperation(
      description = "Obtains the managed connectors of this engine",
      impact = Impact.ReadOnly)
  public Collection<ManagedConnector> getConnectors() {
    if (!isRunning()) return Collections.emptyList();

    // Get engine to use for the rest of the method (this is synchronized)
    // ...
    final JcrEngine engine = getEngine();
    assert engine != null;

    Collection<ManagedConnector> connectors = new ArrayList<ManagedConnector>();
    for (RepositorySource repositorySource :
        engine.getRepositoryService().getRepositoryLibrary().getSources()) {
      assert repositorySource != null;
      connectors.add(new ManagedConnector(repositorySource));
    }

    return Collections.unmodifiableCollection(connectors);
  }
示例#12
0
  @Override
  public void start(StartContext arg0) throws StartException {
    JcrEngine jcr = getEngine();
    try {
      final String repositoryName = repositoryConfiguration.getName();

      // Get the index storage configuration ...
      IndexStorage indexStorageConfig = indexStorageConfigInjector.getValue();
      Document queryConfig = null;
      if (indexStorageConfig != null) {
        queryConfig = indexStorageConfig.getQueryConfiguration();
      } else {
        // We'll use the default index storage, but this will be overwritten by the *IndexStorageAdd
        // operation
        // (that we're dependent upon). The default for non-AS7 ModeShape repositories is to use
        // RAM index storage, but in AS7 we want to by default store the indexes on the filesystem
        // in the
        // AS7 data directory.
        // We'll do this by setting a path relative to the data directory, and then injecting
        // the "${jboss.server.data.dir}/modeshape" path into the repository service
        // (which will then update the configuration prior to deployment) ...
        EditableDocument query = Schematic.newDocument();
        EditableDocument indexing = query.getOrCreateDocument(FieldName.INDEXING);
        EditableDocument indexStorage = query.getOrCreateDocument(FieldName.INDEX_STORAGE);
        EditableDocument backend = indexing.getOrCreateDocument(FieldName.INDEXING_BACKEND);
        query.set(FieldName.REBUILD_UPON_STARTUP, "if_needed");
        backend.set(FieldName.TYPE, FieldValue.INDEXING_BACKEND_TYPE_LUCENE);
        indexStorage.set(FieldName.TYPE, FieldValue.INDEX_STORAGE_FILESYSTEM);
        String dataDirPath = dataDirectoryPathInjector.getValue();
        indexStorage.set(
            FieldName.INDEX_STORAGE_LOCATION, dataDirPath + "/" + repositoryName + "/indexes");
        queryConfig = query;
      }
      assert queryConfig != null;

      // Get the binary storage configuration ...
      Document binaryConfig = null;
      BinaryStorage binaryStorageConfig = binaryStorageInjector.getValue();
      if (binaryStorageConfig != null) {
        binaryConfig = binaryStorageConfig.getBinaryConfiguration();
      } else {
        // By default, store the binaries in the data directory ...
        EditableDocument binaries = Schematic.newDocument();
        binaries.set(FieldName.TYPE, FieldValue.BINARY_STORAGE_TYPE_FILE);
        String dataDirPath = dataDirectoryPathInjector.getValue();
        binaries.set(FieldName.DIRECTORY, dataDirPath + "/" + repositoryName + "/binaries");
        binaryConfig = binaries;
      }

      // Now update the configuration ...
      Editor editor = repositoryConfiguration.edit();
      editor.setDocument(FieldName.QUERY, queryConfig);
      editor
          .getOrCreateDocument(FieldName.STORAGE)
          .setDocument(FieldName.BINARY_STORAGE, binaryConfig);

      // Apply the changes to the configuration ...
      editor.apply(editor.getChanges());

      // Deploy the repository and use this as the environment ...
      jcr.deploy(repositoryConfiguration.with(this));
    } catch (ConfigurationException e) {
      throw new StartException(e);
    } catch (RepositoryException e) {
      throw new StartException(e);
    }
  }
  @Test
  public void shouldLoadConfigurationWithCustomAuthenticators() throws Exception {
    File file = new File("src/test/resources/config/configRepositoryWithAuthenticators.xml");
    assertThat(file.exists(), is(true));
    assertThat(file.canRead(), is(true));
    assertThat(file.isFile(), is(true));

    configuration.loadFrom("src/test/resources/config/configRepositoryWithAuthenticators.xml");

    assertThat(configuration.getProblems().isEmpty(), is(true));

    // Verify that the graph has been updated correctly ...
    ModeShapeConfiguration.ConfigurationDefinition content =
        configuration.getConfigurationDefinition();
    Subgraph subgraph = content.graph().getSubgraphOfDepth(6).at("/");

    assertThat(subgraph.getNode("/mode:sources"), is(notNullValue()));
    assertThat(subgraph.getNode("/mode:sources/Stuff"), is(notNullValue()));

    assertThat(
        subgraph.getNode("/mode:repositories").getChildren(), hasChild(segment("My Repository")));
    assertThat(subgraph.getNode("/mode:repositories/My Repository"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Stuff"));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository").getChildren(),
        hasChildren(segment("mode:options"), segment("mode:authenticationProviders")));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository/mode:options"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository/mode:options").getChildren(),
        hasChild(segment("jaasLoginConfigName")));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository/mode:options/jaasLoginConfigName"),
        is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/My Repository/mode:authenticationProviders"),
        is(notNullValue()));
    assertThat(
        subgraph.getNode(
            "/mode:repositories/My Repository/mode:authenticationProviders/CustomProviderA"),
        is(notNullValue()));

    // Initialize PicketBox ...
    JaasTestUtil.initJaas("security/jaas.conf.xml");

    // Create and start the engine ...
    engine = configuration.build();
    engine.start();
    Repository repository = engine.getRepository("My Repository");
    assertThat(repository, is(notNullValue()));

    // Create a session, authenticating using one of the usernames defined by our JAAS policy
    // file(s) ...
    Session session = null;
    try {
      session = repository.login(new SimpleCredentials("superuser", "superuser".toCharArray()));
    } finally {
      if (session != null) session.logout();
    }

    // Create a session, authenticating using a SecurityContextCredentials
    try {
      SecurityContext mockSecurityContext =
          new MockSecurityContext("testuser", Collections.singleton(ModeShapeRoles.READWRITE));
      session = repository.login(new TestSecurityContextCredentials(mockSecurityContext));
    } finally {
      if (session != null) session.logout();
    }
  }
  @Test
  public void shouldAddNodeTypesAndNamespaces() throws Exception {
    File file = new File("src/test/resources/config/configRepository.xml");
    assertThat(file.exists(), is(true));
    assertThat(file.canRead(), is(true));
    assertThat(file.isFile(), is(true));

    configuration.loadFrom("src/test/resources/config/configRepository.xml");
    // Verify that the configration was loaded correctly ...
    assertThat(configuration.repository("Car Repository").getSource(), is("Cars"));
    // ModeShapeConfiguration.ConfigurationDefinition content1 =
    // configuration.getConfigurationDefinition();
    // Subgraph subgraph1 = content1.graph().getSubgraphOfDepth(6).at("/");

    // Load the node types from the CND file, and save the configuration ...
    InputStream nodeTypes = getClass().getResourceAsStream("/tck/tck_test_types.cnd");
    configuration.repository("Car Repository").addNodeTypes(nodeTypes);
    configuration.save();
    // ModeShapeConfiguration.ConfigurationDefinition content2 =
    // configuration.getConfigurationDefinition();
    // Subgraph subgraph2 = content2.graph().getSubgraphOfDepth(6).at("/");

    // Verify there were no problems loading the CND file ...
    assertThat(configuration.getProblems().isEmpty(), is(true));
    assertThat(
        configuration
            .getConfigurationDefinition()
            .getContext()
            .getNamespaceRegistry()
            .isRegisteredNamespaceUri("http://www.modeshape.org/test/1.0"),
        is(true));

    // Verify that the graph has been updated correctly ...
    ModeShapeConfiguration.ConfigurationDefinition content =
        configuration.getConfigurationDefinition();
    Subgraph subgraph = content.graph().getSubgraphOfDepth(6).at("/");

    assertThat(
        subgraph.getNode("/mode:repositories").getChildren(), hasChild(segment("Car Repository")));
    assertThat(subgraph.getNode("/mode:repositories/Car Repository"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Cars"));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository").getChildren(),
        hasChild(segment("mode:options")));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/jcr:nodeTypes"), is(notNullValue()));
    // for (Location child : subgraph.getNode("/mode:repositories/Car
    // Repository/mode:nodeTypes").getChildren()) {
    // System.out.println(child.getPath().getLastSegment().getString(context().getNamespaceRegistry()));
    // }
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/jcr:nodeTypes").getChildren(),
        hasChildren(
            segment("modetest:noSameNameSibs"),
            segment("modetest:referenceableUnstructured"),
            segment("modetest:nodeWithMandatoryProperty"),
            segment("modetest:nodeWithMandatoryChild"),
            segment("modetest:unorderableUnstructured")));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:namespaces"), is(notNullValue()));

    // Check that the namespace in the CND file was persisted correctly ...
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:namespaces").getChildren(),
        hasChild(segment("modetest")));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:namespaces/modetest"),
        hasProperty(ModeShapeLexicon.URI, "http://www.modeshape.org/test/1.0"));

    // Initialize IDTrust and a policy file (which defines the "modeshape-jcr" login config name)
    JaasTestUtil.initJaas("security/jaas.conf.xml");

    // Create and start the engine ...
    engine = configuration.build();
    engine.start();
    Repository repository = engine.getRepository("Car Repository");
    assertThat(repository, is(notNullValue()));

    // Create a session, authenticating using one of the usernames defined by our JAAS policy
    // file(s) ...
    Session session = null;
    try {
      session = repository.login(new SimpleCredentials("superuser", "superuser".toCharArray()));

      // Check that the namespace showed up ...
      assertThat(session.getNamespacePrefix("http://www.modeshape.org/test/1.0"), is("modetest"));

      // Check that some of the node types showed up ...
      NodeTypeManager ntm = session.getWorkspace().getNodeTypeManager();
      assertThat(
          ntm.getNodeType("modetest:noSameNameSibs"), is(notNullValue())); // throws exception
      assertThat(
          ntm.getNodeType("modetest:referenceableUnstructured"),
          is(notNullValue())); // throws exception
      assertThat(
          ntm.getNodeType("modetest:nodeWithMandatoryProperty"),
          is(notNullValue())); // throws exception
      assertThat(
          ntm.getNodeType("modetest:nodeWithMandatoryChild"),
          is(notNullValue())); // throws exception
      assertThat(
          ntm.getNodeType("modetest:unorderableUnstructured"),
          is(notNullValue())); // throws exception
    } finally {
      if (session != null) session.logout();
    }
  }
  @Test
  public void shouldLoadConfigurationFromFilePath() throws Exception {
    File file = new File("src/test/resources/config/configRepository.xml");
    assertThat(file.exists(), is(true));
    assertThat(file.canRead(), is(true));
    assertThat(file.isFile(), is(true));

    configuration.loadFrom("src/test/resources/config/configRepository.xml");

    assertThat(configuration.getProblems().isEmpty(), is(true));

    // Verify that the graph has been updated correctly ...
    ModeShapeConfiguration.ConfigurationDefinition content =
        configuration.getConfigurationDefinition();
    Subgraph subgraph = content.graph().getSubgraphOfDepth(6).at("/");

    assertThat(subgraph.getNode("/mode:sources"), is(notNullValue()));
    assertThat(subgraph.getNode("/mode:sources/Cars"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:sources/Cars"), hasProperty(ModeShapeLexicon.RETRY_LIMIT, "3"));
    assertThat(
        subgraph.getNode("/mode:sources/Cars"),
        hasProperty(ModeShapeLexicon.CLASSNAME, InMemoryRepositorySource.class.getName()));
    assertThat(subgraph.getNode("/mode:sources/Aircraft"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:sources/Aircraft"), hasProperty("defaultWorkspaceName", "default"));
    assertThat(
        subgraph.getNode("/mode:sources/Aircraft"),
        hasProperty(ModeShapeLexicon.CLASSNAME, InMemoryRepositorySource.class.getName()));
    assertThat(subgraph.getNode("/mode:sources/Cache"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:sources/Cache"),
        hasProperty(ModeShapeLexicon.CLASSNAME, InMemoryRepositorySource.class.getName()));

    assertThat(
        subgraph.getNode("/mode:mimeTypeDetectors").getChildren(), hasChild(segment("Detector")));
    assertThat(subgraph.getNode("/mode:mimeTypeDetectors/Detector"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:mimeTypeDetectors/Detector"),
        hasProperty(ModeShapeLexicon.DESCRIPTION, "Standard extension-based MIME type detector"));
    assertThat(
        subgraph.getNode("/mode:mimeTypeDetectors/Detector"),
        hasProperty(ModeShapeLexicon.CLASSNAME, ExtensionBasedMimeTypeDetector.class.getName()));

    assertThat(
        subgraph.getNode("/mode:repositories").getChildren(), hasChild(segment("Car Repository")));
    assertThat(subgraph.getNode("/mode:repositories/Car Repository"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Cars"));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository").getChildren(),
        hasChild(segment("mode:options")));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:options"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:options").getChildren(),
        hasChild(segment("jaasLoginConfigName")));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:options/jaasLoginConfigName"),
        is(notNullValue()));
    assertThat(
        subgraph.getNode(
            "/mode:repositories/Car Repository/mode:descriptors/query.xpath.doc.order"),
        is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/Car Repository/mode:descriptors/myDescriptor"),
        is(notNullValue()));

    // Initialize PicketBox ...
    JaasTestUtil.initJaas("security/jaas.conf.xml");

    // Create and start the engine ...
    engine = configuration.build();
    engine.start();
    Repository repository = engine.getRepository("Car Repository");
    assertThat(repository, is(notNullValue()));
    assertThat(repository.getDescriptor("query.xpath.doc.order"), is("false"));
    assertThat(repository.getDescriptor("myDescriptor"), is("foo"));

    // Create a session, authenticating using one of the usernames defined by our JAAS policy
    // file(s) ...
    Session session = null;
    try {
      session = repository.login(new SimpleCredentials("superuser", "superuser".toCharArray()));
    } finally {
      if (session != null) session.logout();
    }
  }
  @SuppressWarnings("deprecation")
  @Test
  public void shouldAllowSpecifyingOptions() throws Exception {
    configuration
        .repositorySource("Source2")
        .usingClass(InMemoryRepositorySource.class.getName())
        .loadedFromClasspath()
        .setDescription("description")
        .and()
        .repository("JCR Repository")
        .setSource("Source2")
        .setOption(Option.JAAS_LOGIN_CONFIG_NAME, "test");

    engine = configuration.build();
    engine.start();

    // Verify that the graph has been updated correctly ...
    Graph config = engine.getGraph(JcrConfiguration.DEFAULT_CONFIGURATION_SOURCE_NAME);
    Subgraph subgraph = config.getSubgraphOfDepth(6).at("/");
    assertThat(subgraph.getNode("/mode:sources"), is(notNullValue()));
    assertThat(subgraph.getNode("/mode:sources/Source2"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:sources/Source2"),
        hasProperty(ModeShapeLexicon.CLASSNAME, InMemoryRepositorySource.class.getName()));
    assertThat(subgraph.getNode("/mode:repositories"), is(notNullValue()));
    assertThat(subgraph.getNode("/mode:repositories/JCR Repository"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/JCR Repository"),
        hasProperty(ModeShapeLexicon.SOURCE_NAME, "Source2"));
    assertThat(
        subgraph.getNode("/mode:repositories/JCR Repository/mode:options"), is(notNullValue()));
    assertThat(
        subgraph.getNode("/mode:repositories/JCR Repository/mode:options/JAAS_LOGIN_CONFIG_NAME"),
        hasProperty(ModeShapeLexicon.VALUE, "test"));

    JcrRepository repository = engine.getRepository("JCR Repository");

    Map<Option, String> options = new HashMap<Option, String>();
    options.put(Option.JAAS_LOGIN_CONFIG_NAME, "test");
    options.put(Option.PROJECT_NODE_TYPES, DefaultOption.PROJECT_NODE_TYPES);
    options.put(Option.READ_DEPTH, DefaultOption.READ_DEPTH);
    options.put(Option.INDEX_READ_DEPTH, DefaultOption.INDEX_READ_DEPTH);
    options.put(Option.ANONYMOUS_USER_ROLES, DefaultOption.ANONYMOUS_USER_ROLES);
    options.put(
        Option.TABLES_INCLUDE_COLUMNS_FOR_INHERITED_PROPERTIES,
        DefaultOption.TABLES_INCLUDE_COLUMNS_FOR_INHERITED_PROPERTIES);
    options.put(Option.QUERY_EXECUTION_ENABLED, DefaultOption.QUERY_EXECUTION_ENABLED);
    options.put(Option.QUERY_INDEX_DIRECTORY, DefaultOption.QUERY_INDEX_DIRECTORY);
    options.put(
        Option.QUERY_INDEXES_UPDATED_SYNCHRONOUSLY,
        DefaultOption.QUERY_INDEXES_UPDATED_SYNCHRONOUSLY);
    options.put(
        Option.PERFORM_REFERENTIAL_INTEGRITY_CHECKS,
        DefaultOption.PERFORM_REFERENTIAL_INTEGRITY_CHECKS);
    options.put(
        Option.EXPOSE_WORKSPACE_NAMES_IN_DESCRIPTOR,
        DefaultOption.EXPOSE_WORKSPACE_NAMES_IN_DESCRIPTOR);
    options.put(Option.VERSION_HISTORY_STRUCTURE, DefaultOption.VERSION_HISTORY_STRUCTURE);
    options.put(Option.REPOSITORY_JNDI_LOCATION, DefaultOption.REPOSITORY_JNDI_LOCATION);
    options.put(
        Option.USE_ANONYMOUS_ACCESS_ON_FAILED_LOGIN,
        DefaultOption.USE_ANONYMOUS_ACCESS_ON_FAILED_LOGIN);
    options.put(
        Option.REBUILD_QUERY_INDEX_ON_STARTUP, DefaultOption.REBUILD_QUERY_INDEX_ON_STARTUP);
    options.put(
        Option.QUERY_INDEXES_REBUILT_SYNCHRONOUSLY,
        DefaultOption.QUERY_INDEXES_REBUILT_SYNCHRONOUSLY);
    String defaultRemoveDerivedValue = DefaultOption.REMOVE_DERIVED_CONTENT_WITH_ORIGINAL;
    if (engine.getSequencingService().getSequencers().isEmpty()) {
      defaultRemoveDerivedValue = Boolean.FALSE.toString();
    }
    options.put(Option.REMOVE_DERIVED_CONTENT_WITH_ORIGINAL, defaultRemoveDerivedValue);
    options.put(
        Option.USE_SECURITY_CONTEXT_CREDENTIALS, DefaultOption.USE_SECURITY_CONTEXT_CREDENTIALS);
    assertThat(repository.getOptions(), is(options));
  }