@Test public void shouldStoreDocumentAndFetchAndModifyAndRefetch() throws Exception { // Store the document ... Document doc = Schematic.newDocument("k1", "value1", "k2", 2); Document metadata = Schematic.newDocument("mimeType", "text/plain"); String key = "can be anything"; SchematicEntry prior = db.put(key, doc, metadata); assert prior == null : "Should not have found a prior entry"; // Read back from the database ... SchematicEntry entry = db.get(key); assert entry != null : "Should have found the entry"; // Verify the content ... Document read = entry.getContentAsDocument(); assert read != null; assert "value1".equals(read.getString("k1")); assert 2 == read.getInteger("k2"); assert entry.getContentAsBinary() == null : "Should not have a Binary value for the entry's content"; assert read.containsAll(doc); assert read.equals(doc); // Modify using an editor ... try { // tm.begin(); EditableDocument editable = entry.editDocumentContent(); editable.setBoolean("k3", true); editable.setNumber("k4", 3.5d); } finally { // tm.commit(); } // Now re-read ... SchematicEntry entry2 = db.get(key); Document read2 = entry2.getContentAsDocument(); assert read2 != null; assert "value1".equals(read2.getString("k1")); assert 2 == read2.getInteger("k2"); assert true == read2.getBoolean("k3"); assert 3.4d < read2.getDouble("k4"); }
private void parseJournaling( RepositoryService repositoryService, OperationContext context, ModelNode model, EditableDocument configDoc) throws OperationFailedException { if (model.hasDefined(ModelKeys.JOURNALING)) { EditableDocument journaling = configDoc.getOrCreateDocument(FieldName.JOURNALING); // set it temporarily on the repository service because the final location needs to be // resolved later if (model.hasDefined(ModelKeys.JOURNAL_RELATIVE_TO)) { String relativeTo = attribute(context, model, ModelAttributes.JOURNAL_RELATIVE_TO).asString(); repositoryService.setJournalRelativeTo(relativeTo); } // set it temporarily on the repository service because the final location needs to be // resolved later if (model.hasDefined(ModelKeys.JOURNAL_PATH)) { String path = attribute(context, model, ModelAttributes.JOURNAL_PATH).asString(); repositoryService.setJournalPath(path); } int maxDaysToKeepRecords = attribute(context, model, ModelAttributes.MAX_DAYS_TO_KEEP_RECORDS).asInt(); journaling.setNumber(FieldName.MAX_DAYS_TO_KEEP_RECORDS, maxDaysToKeepRecords); boolean asyncWrites = attribute(context, model, ModelAttributes.ASYNC_WRITES).asBoolean(); journaling.setBoolean(FieldName.ASYNC_WRITES_ENABLED, asyncWrites); String gcThreadPool = attribute(context, model, ModelAttributes.JOURNAL_GC_THREAD_POOL).asString(); journaling.setString(FieldName.THREAD_POOL, gcThreadPool); String gcInitialTime = attribute(context, model, ModelAttributes.JOURNAL_GC_INITIAL_TIME).asString(); journaling.setString(FieldName.INITIAL_TIME, gcInitialTime); } }
@Override protected void performRuntime( final OperationContext context, final ModelNode operation, final ModelNode model, final ServiceVerificationHandler verificationHandler, final List<ServiceController<?>> newControllers) throws OperationFailedException { final ServiceTarget target = context.getServiceTarget(); final AddressContext addressContext = AddressContext.forOperation(operation); final String repositoryName = addressContext.repositoryName(); final String cacheName = attribute(context, model, ModelAttributes.CACHE_NAME, repositoryName); String infinispanConfig = attribute(context, model, ModelAttributes.CACHE_CONFIG, null); String configRelativeTo = attribute(context, model, ModelAttributes.CONFIG_RELATIVE_TO).asString(); final boolean enableMonitoring = attribute(context, model, ModelAttributes.ENABLE_MONITORING).asBoolean(); final String gcThreadPool = attribute(context, model, ModelAttributes.GARBAGE_COLLECTION_THREAD_POOL, null); final String gcInitialTime = attribute(context, model, ModelAttributes.GARBAGE_COLLECTION_INITIAL_TIME, null); final int gcIntervalInHours = attribute(context, model, ModelAttributes.GARBAGE_COLLECTION_INTERVAL).asInt(); final String optThreadPool = attribute(context, model, ModelAttributes.DOCUMENT_OPTIMIZATION_THREAD_POOL, null); final String optInitialTime = attribute(context, model, ModelAttributes.DOCUMENT_OPTIMIZATION_INITIAL_TIME, null); final int optIntervalInHours = attribute(context, model, ModelAttributes.DOCUMENT_OPTIMIZATION_INTERVAL).asInt(); final Integer optTarget = intAttribute( context, model, ModelAttributes.DOCUMENT_OPTIMIZATION_CHILD_COUNT_TARGET, null); final Integer eventBusSize = intAttribute(context, model, ModelAttributes.EVENT_BUS_SIZE, null); final Integer optTolerance = intAttribute( context, model, ModelAttributes.DOCUMENT_OPTIMIZATION_CHILD_COUNT_TOLERANCE, null); // Create a document for the repository configuration ... EditableDocument configDoc = Schematic.newDocument(); configDoc.set(FieldName.NAME, repositoryName); // Determine the JNDI name ... configDoc.set( FieldName.JNDI_NAME, ""); // always set to empty string, since we'll register in JNDI here ... final String jndiName = ModeShapeJndiNames.JNDI_BASE_NAME + repositoryName; String jndiAlias = ModeShapeJndiNames.jndiNameFrom(model, repositoryName); if (jndiName.equals(jndiAlias)) { jndiAlias = null; } if (eventBusSize != null) { configDoc.setNumber(FieldName.EVENT_BUS_SIZE, eventBusSize); } // Parse the cache configuration if (StringUtil.isBlank(infinispanConfig)) { infinispanConfig = "modeshape/" + repositoryName + "-cache-config.xml"; } else { // check if it's a system property String infinispanConfigSystemProperty = System.getProperty(infinispanConfig); if (!StringUtil.isBlank(infinispanConfigSystemProperty)) { infinispanConfig = infinispanConfigSystemProperty; } } // Set the storage information (that was set on the repository ModelNode) ... setRepositoryStorageConfiguration(infinispanConfig, cacheName, configDoc); // Always set whether monitoring is enabled ... enableMonitoring(enableMonitoring, configDoc); // Initial node-types if configured parseCustomNodeTypes(model, configDoc); // Workspace information is on the repository model node (unlike the XML) ... EditableDocument workspacesDoc = parseWorkspaces(context, model, configDoc); // security parseSecurity(context, model, configDoc); // Now create the repository service that manages the lifecycle of the JcrRepository instance // ... RepositoryConfiguration repositoryConfig = new RepositoryConfiguration(configDoc, repositoryName); String configRelativeToSystemProperty = System.getProperty(configRelativeTo); if (!StringUtil.isBlank(configRelativeToSystemProperty)) { configRelativeTo = configRelativeToSystemProperty; } if (!configRelativeTo.endsWith("/")) { configRelativeTo = configRelativeTo + "/"; } RepositoryService repositoryService = new RepositoryService(repositoryConfig, infinispanConfig, configRelativeTo); ServiceName repositoryServiceName = ModeShapeServiceNames.repositoryServiceName(repositoryName); // Sequencing parseSequencing(model, configDoc); // Text Extraction parseTextExtraction(model, configDoc); // Reindexing parseReindexing(model, configDoc); // Journaling parseJournaling(repositoryService, context, model, configDoc); // Add the EngineService's dependencies ... ServiceBuilder<JcrRepository> repositoryServiceBuilder = target.addService(repositoryServiceName, repositoryService); // Add dependency to the ModeShape engine service ... repositoryServiceBuilder.addDependency( ModeShapeServiceNames.ENGINE, ModeShapeEngine.class, repositoryService.getEngineInjector()); repositoryServiceBuilder.setInitialMode(ServiceController.Mode.ACTIVE); // Add garbage collection information ... if (gcThreadPool != null) { configDoc .getOrCreateDocument(FieldName.GARBAGE_COLLECTION) .setString(FieldName.THREAD_POOL, gcThreadPool); } if (gcInitialTime != null) { configDoc .getOrCreateDocument(FieldName.GARBAGE_COLLECTION) .setString(FieldName.INITIAL_TIME, gcInitialTime); } configDoc .getOrCreateDocument(FieldName.GARBAGE_COLLECTION) .setNumber(FieldName.INTERVAL_IN_HOURS, gcIntervalInHours); // Add document optimization information ... if (optTarget != null) { EditableDocument docOpt = configDoc .getOrCreateDocument(FieldName.STORAGE) .getOrCreateDocument(FieldName.DOCUMENT_OPTIMIZATION); if (optThreadPool != null) { docOpt.setString(FieldName.THREAD_POOL, optThreadPool); } if (optInitialTime != null) { docOpt.setString(FieldName.INITIAL_TIME, optInitialTime); } docOpt.setNumber(FieldName.INTERVAL_IN_HOURS, optIntervalInHours); docOpt.setNumber(FieldName.OPTIMIZATION_CHILD_COUNT_TARGET, optTarget.intValue()); if (optTolerance != null) { docOpt.setNumber(FieldName.OPTIMIZATION_CHILD_COUNT_TOLERANCE, optTolerance.intValue()); } } // Add the dependency to the Security Manager repositoryServiceBuilder.addDependency( SecurityManagementService.SERVICE_NAME, ISecurityManagement.class, repositoryService.getSecurityManagementServiceInjector()); // Add dependency, if necessary, to the workspaces cache container String workspacesInfinispanConfig = attribute(context, model, ModelAttributes.WORKSPACES_CACHE_CONTAINER, null); if (workspacesInfinispanConfig != null && !workspacesInfinispanConfig.toLowerCase().equalsIgnoreCase(infinispanConfig)) { workspacesDoc.set(FieldName.WORKSPACE_CACHE_CONFIGURATION, workspacesInfinispanConfig); } repositoryServiceBuilder.addDependency( Services.JBOSS_SERVICE_MODULE_LOADER, ModuleLoader.class, repositoryService.getModuleLoaderInjector()); // Set up the JNDI binder service ... final ReferenceFactoryService<JcrRepository> referenceFactoryService = new ReferenceFactoryService<JcrRepository>(); ServiceName referenceFactoryServiceName = ModeShapeServiceNames.referenceFactoryServiceName(repositoryName); final ServiceBuilder<?> referenceBuilder = target.addService(referenceFactoryServiceName, referenceFactoryService); referenceBuilder.addDependency( repositoryServiceName, JcrRepository.class, referenceFactoryService.getInjector()); referenceBuilder.setInitialMode(ServiceController.Mode.ACTIVE); ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(jndiName); BinderService binder = new BinderService(bindInfo.getBindName()); ServiceBuilder<?> binderBuilder = target.addService(bindInfo.getBinderServiceName(), binder); if (jndiAlias != null) { ContextNames.BindInfo aliasInfo = ContextNames.bindInfoFor(jndiAlias); ServiceName alias = aliasInfo.getBinderServiceName(); binderBuilder.addAliases(alias); LOG.debugv( "Binding repository {0} to JNDI name {1} and {2}", repositoryName, bindInfo.getAbsoluteJndiName(), aliasInfo.getAbsoluteJndiName()); } else { LOG.debugv( "Binding repository {0} to JNDI name {1}", repositoryName, bindInfo.getAbsoluteJndiName()); } binderBuilder.addDependency( referenceFactoryServiceName, ManagedReferenceFactory.class, binder.getManagedObjectInjector()); binderBuilder.addDependency( bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binder.getNamingStoreInjector()); binderBuilder.setInitialMode(ServiceController.Mode.ACTIVE); // Add dependency to the data directory ... ServiceName dataDirServiceName = ModeShapeServiceNames.dataDirectoryServiceName(repositoryName); ServiceController<String> dataDirServiceController = RelativePathService.addService( dataDirServiceName, "modeshape/" + repositoryName, ModeShapeExtension.JBOSS_DATA_DIR_VARIABLE, target); newControllers.add(dataDirServiceController); repositoryServiceBuilder.addDependency( dataDirServiceName, String.class, repositoryService.getDataDirectoryPathInjector()); // Add the default binary storage service which will provide the binary configuration BinaryStorageService defaultBinaryService = BinaryStorageService.createDefault(); ServiceName defaultBinaryStorageServiceName = ModeShapeServiceNames.binaryStorageDefaultServiceName(repositoryName); ServiceBuilder<BinaryStorage> binaryStorageBuilder = target.addService(defaultBinaryStorageServiceName, defaultBinaryService); binaryStorageBuilder.setInitialMode(ServiceController.Mode.ACTIVE); // Add dependency to the binaries storage service, which captures the properties for the // binaries storage repositoryServiceBuilder.addDependency( defaultBinaryStorageServiceName, BinaryStorage.class, repositoryService.getBinaryStorageInjector()); // Add monitor service final MonitorService monitorService = new MonitorService(); final ServiceBuilder<RepositoryMonitor> monitorBuilder = target.addService(ModeShapeServiceNames.monitorServiceName(repositoryName), monitorService); monitorBuilder.addDependency( ModeShapeServiceNames.repositoryServiceName(repositoryName), JcrRepository.class, monitorService.getJcrRepositoryInjector()); monitorBuilder.setInitialMode(ServiceController.Mode.ACTIVE); // Now add the controller for the RepositoryService ... newControllers.add(repositoryServiceBuilder.install()); newControllers.add(referenceBuilder.install()); newControllers.add(binderBuilder.install()); newControllers.add(binaryStorageBuilder.install()); newControllers.add(monitorBuilder.install()); }