/** * Scan each required path in each of the workspaces. * * @param operation the scanning operation that is to be called for each workspace & path * combination; may not be null */ public void onEachPathInWorkspace(ScanOperation operation) { for (Map.Entry<String, PathToScan> entry : pathsToScanByWorkspace.entries()) { String workspaceName = entry.getKey(); PathToScan pathToScan = entry.getValue(); try { for (IndexingCallback callback : pathToScan) { try { callback.beforeIndexing(); } catch (RuntimeException e) { Logger.getLogger(getClass()) .error( e, JcrI18n.errorIndexing, pathToScan.path(), workspaceName, e.getMessage()); } } operation.scan(workspaceName, pathToScan.path()); } catch (RuntimeException e) { Logger.getLogger(getClass()) .error(e, JcrI18n.errorIndexing, pathToScan.path(), workspaceName, e.getMessage()); } finally { for (IndexingCallback callback : pathToScan) { try { callback.afterIndexing(); } catch (RuntimeException e) { Logger.getLogger(getClass()) .error( e, JcrI18n.errorIndexing, pathToScan.path(), workspaceName, e.getMessage()); } } } } }
protected final void logReceivedOperation(ChangeSet changeSet) { if (LOGGER.isTraceEnabled()) { LOGGER.trace( "Received on cluster '{0}' {1} changes on workspace {2} made by {3} from process '{4}' at {5}", clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp()); } }
/** @param resp */ private void doUserAgentWorkaround(HttpServletResponse resp) { if (isOSXFinder()) { LOG.trace("DoPut.execute() : do workaround for user agent '" + userAgent + "'"); resp.setStatus(WebdavStatus.SC_CREATED); } else if (userAgent != null && userAgent.contains("Transmit")) { // Transmit also uses WEBDAVFS 1.x.x but crashes // with SC_CREATED response LOG.trace("DoPut.execute() : do workaround for user agent '" + userAgent + "'"); resp.setStatus(WebdavStatus.SC_NO_CONTENT); } else { resp.setStatus(WebdavStatus.SC_CREATED); } }
@Override public void addRecords(JournalRecord... records) { if (stopped) { return; } RW_LOCK.writeLock().lock(); try { LOGGER.debug("Adding {0} records", records.length); for (JournalRecord record : records) { if (record.getTimeBasedKey() < 0) { // generate a unique timestamp only if there isn't one. In some scenarios (i.e. running in // a cluster) we // always want to keep the original TS because otherwise it would be impossible to have a // correct order // and therefore search long createTimeMillisUTC = TIME_BASED_KEYS.nextKey(); record.withTimeBasedKey(createTimeMillisUTC); } this.records.put(record.getTimeBasedKey(), record); } this.journalDB.commit(); } finally { RW_LOCK.writeLock().unlock(); } }
@Override public BinaryValue storeValue(InputStream stream, String hint) throws BinaryStoreException { BinaryStore binaryStore = selectBinaryStore(hint); BinaryValue bv = binaryStore.storeValue(stream); logger.debug("Stored binary " + bv.getKey() + " into binary store " + binaryStore); return bv; }
@Override public String getText(BinaryValue binary) throws BinaryStoreException { if (binary instanceof InMemoryBinaryValue) { if (extractors == null || !extractors.extractionEnabled()) { return null; } // The extracted text will never be stored, so try directly using the text extractors ... return extractors.extract((InMemoryBinaryValue) binary, new TextExtractorContext(detector)); } Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator(); while (it.hasNext()) { Map.Entry<String, BinaryStore> entry = it.next(); final String binaryStoreKey = entry.getKey(); BinaryStore bs = entry.getValue(); try { if (bs.hasBinary(binary.getKey())) { return bs.getText(binary); } } catch (BinaryStoreException e) { logger.debug(e, "The named store " + binaryStoreKey + " raised exception"); if (!it.hasNext()) { throw e; } } } throw new BinaryStoreException(JcrI18n.unableToFindBinaryValue.text(binary.getKey(), this)); }
@Override public String getMimeType(BinaryValue binary, String name) throws IOException, RepositoryException { if (detector == null) { return null; } String detectedMimeType = detector.mimeTypeOf(name, binary); if (binary instanceof InMemoryBinaryValue) { return detectedMimeType; } Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator(); while (it.hasNext()) { Map.Entry<String, BinaryStore> entry = it.next(); final String binaryStoreKey = entry.getKey(); BinaryStore bs = entry.getValue(); try { if (bs.hasBinary(binary.getKey())) { return bs.getMimeType(binary, name); } } catch (BinaryStoreException e) { logger.debug(e, "The named store " + binaryStoreKey + " raised exception"); if (!it.hasNext()) { throw e; } } } throw new BinaryStoreException(JcrI18n.unableToFindBinaryValue.text(binary.getKey(), this)); }
@Override public NodeTypeIterator registerNodeTypes(URL url, boolean allowUpdate) throws IOException, RepositoryException { String content = IoUtil.read(url.openStream()); if (content.startsWith("<?xml")) { // This is Jackrabbit XML format ... return registerNodeTypes( importFromXml(new InputSource(new StringReader(content))), allowUpdate); } // Assume this is CND format ... CndImporter importer = new CndImporter(context(), true); Problems problems = new SimpleProblems(); importer.importFrom(content, problems, url.toExternalForm()); // Check for (and report) any problems ... if (problems.hasProblems()) { // There are errors and/or warnings, so report them ... String summary = messageFrom(problems); if (problems.hasErrors()) { String msg = JcrI18n.errorsParsingNodeTypeDefinitions.text(url.toExternalForm(), summary); throw new RepositoryException(msg); } // Otherwise, there are warnings, so log them ... I18n msg = JcrI18n.warningsParsingNodeTypeDefinitions; Logger.getLogger(getClass()).warn(msg, url.toExternalForm(), summary); } // Register the node types ... return registerNodeTypes(importer.getNodeTypeDefinitions(), allowUpdate); }
/** * Create a cache container using the supplied configurations. * * @param globalConfiguration the global configuration * @param configuration the default cache configuration * @return the cache container * @deprecated use {@link #createContainer(GlobalConfigurationBuilder, ConfigurationBuilder)} * instead */ @Deprecated protected CacheContainer createContainer( GlobalConfiguration globalConfiguration, Configuration configuration) { logger.debug( "Starting cache manager with global configuration \n{0}\nand default configuration:\n{1}", globalConfiguration, configuration); return new DefaultCacheManager(globalConfiguration, configuration); }
/** * Select a named binary store for the given hint * * @param hint a hint to a binary store; possibly null * @return a named BinaryStore from the hint, or the default store */ private BinaryStore selectBinaryStore(String hint) { BinaryStore namedBinaryStore = null; if (hint != null) { logger.trace("Selecting named binary store for hint: " + hint); namedBinaryStore = namedStores.get(hint); } if (namedBinaryStore == null) { namedBinaryStore = getDefaultBinaryStore(); } logger.trace("Selected binary store: " + namedBinaryStore.toString()); return namedBinaryStore; }
@Override public Connection createConnection(DriverInfo info) throws SQLException { logger.debug("Creating connection for RepositoryDelegte"); if (this.repository == null) { retrieveRepository(); } return new JcrConnection(this, info); }
@Override public void start() { cluster = Cluster.builder().addContactPoint(address).build(); Metadata metadata = cluster.getMetadata(); LOGGER.debug("Connected to cluster: {0}", metadata.getClusterName()); for (Host host : metadata.getAllHosts()) { LOGGER.debug( "Datacenter: {0}; Host: {1}; Rack: {2}", host.getDatacenter(), host.getAddress(), host.getRack()); } session = cluster.connect(); try { session.execute( "CREATE KEYSPACE modeshape WITH replication " + "= {'class':'SimpleStrategy', 'replication_factor':3};"); } catch (AlreadyExistsException e) { } session.execute("USE modeshape;"); try { session.execute( "CREATE TABLE modeshape.binary(" + "cid text PRIMARY KEY," + "mime_type text," + "ext_text text," + "usage int," + "usage_time timestamp," + "payload blob)"); } catch (AlreadyExistsException e) { } try { session.execute("CREATE INDEX USAGE_IDX ON modeshape.binary (usage);"); } catch (InvalidQueryException e) { // exists } try { session.execute("CREATE INDEX EXPIRE_IDX ON modeshape.binary (usage_time);"); } catch (InvalidQueryException e) { // exists } }
protected Indexes( ExecutionContext context, Collection<IndexDefinition> defns, NodeTypes nodeTypes) { // Identify the subtypes for each node type, and do this before we build any views ... if (!defns.isEmpty()) { Map<Name, Collection<String>> subtypesByName = new HashMap<>(); for (JcrNodeType nodeType : nodeTypes.getAllNodeTypes()) { // For each of the supertypes ... for (JcrNodeType supertype : nodeType.getTypeAndSupertypes()) { Collection<String> types = subtypesByName.get(supertype.getInternalName()); if (types == null) { types = new LinkedList<>(); subtypesByName.put(supertype.getInternalName(), types); } types.add(nodeType.getName()); } } // Now process all of the indexes ... NameFactory names = context.getValueFactories().getNameFactory(); Set<Name> nodeTypeNames = new HashSet<>(); for (IndexDefinition defn : defns) { // Determine all of the node types that are subtypes of any columns nodeTypeNames.clear(); Name nodeTypeName = names.create(defn.getNodeTypeName()); if (!subtypesByName.containsKey(nodeTypeName)) { Logger.getLogger(getClass()) .warn( JcrI18n.errorIndexing, "not creating index " + defn.getName() + " because of unknown nodeType " + nodeTypeName.getString()); continue; } indexByName.put(defn.getName(), defn); // Now find out all of the node types that are or subtype the named node types ... for (String typeAndSubtype : subtypesByName.get(nodeTypeName)) { Map<String, Collection<IndexDefinition>> byProvider = indexesByProviderByNodeTypeName.get(typeAndSubtype); if (byProvider == null) { byProvider = new HashMap<>(); indexesByProviderByNodeTypeName.put(typeAndSubtype, byProvider); } Collection<IndexDefinition> indexes = byProvider.get(defn.getProviderName()); if (indexes == null) { indexes = new LinkedList<>(); byProvider.put(typeAndSubtype, indexes); } indexes.add(defn); } } } }
/** * Create a cache container using the supplied configurations. * * @param globalConfigurationBuilder the global configuration builder * @param configurationBuilder the default cache configuration builder * @return the cache container */ protected CacheContainer createContainer( GlobalConfigurationBuilder globalConfigurationBuilder, ConfigurationBuilder configurationBuilder) { GlobalConfiguration globalConfiguration = globalConfigurationBuilder.build(); Configuration configuration = configurationBuilder.build(); logger.debug( "Starting cache manager with global configuration \n{0}\nand default configuration:\n{1}", globalConfiguration, configuration); return new DefaultCacheManager(globalConfiguration, configuration); }
/** * Initialize the supplied provider. * * @param provider the provider; may not be null * @throws RepositoryException if there is a problem initializing the provider */ protected void doInitialize(IndexProvider provider) throws RepositoryException { // Set the execution context instance ... Reflection.setValue(provider, "context", repository.context()); // Set the environment Reflection.setValue(provider, "environment", repository.environment()); provider.initialize(); // If successful, call the 'postInitialize' method reflectively (due to inability to call // directly) ... Method postInitialize = Reflection.findMethod(IndexProvider.class, "postInitialize"); Reflection.invokeAccessibly(provider, postInitialize, new Object[] {}); if (logger.isDebugEnabled()) { logger.debug( "Successfully initialized index provider '{0}' in repository '{1}'", provider.getName(), repository.name()); } }
@Override public InputStream getInputStream(BinaryKey key) throws BinaryStoreException { Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator(); while (it.hasNext()) { final Map.Entry<String, BinaryStore> entry = it.next(); final String binaryStoreKey = entry.getKey(); BinaryStore binaryStore = entry.getValue(); logger.trace("Checking binary store " + binaryStoreKey + " for key " + key); try { return binaryStore.getInputStream(key); } catch (BinaryStoreException e) { // this exception is "normal", and is thrown logger.trace(e, "The named store " + binaryStoreKey + " raised exception"); } } throw new BinaryStoreException(JcrI18n.unableToFindBinaryValue.text(key, this.toString())); }
/** * Check if the named node type is in use in any workspace in the repository * * @param nodeTypeName the name of the node type to check * @return true if at least one node is using that type; false otherwise * @throws InvalidQueryException if there is an error searching for uses of the named node type */ boolean isNodeTypeInUse(Name nodeTypeName) throws InvalidQueryException { String nodeTypeString = nodeTypeName.getString(context.getNamespaceRegistry()); String expression = "SELECT * from [" + nodeTypeString + "] LIMIT 1"; TypeSystem typeSystem = context.getValueFactories().getTypeSystem(); // Parsing must be done now ... QueryCommand command = queryParser.parseQuery(expression, typeSystem); assert command != null : "Could not parse " + expression; Schemata schemata = getRepositorySchemata(); // Now query the entire repository for any nodes that use this node type ... RepositoryCache repoCache = repository.repositoryCache(); RepositoryQueryManager queryManager = repository.queryManager(); Set<String> workspaceNames = repoCache.getWorkspaceNames(); Map<String, NodeCache> overridden = null; NodeTypes nodeTypes = repository.nodeTypeManager().getNodeTypes(); RepositoryIndexes indexDefns = repository.queryManager().getIndexes(); CancellableQuery query = queryManager.query( context, repoCache, workspaceNames, overridden, command, schemata, indexDefns, nodeTypes, null, null); try { QueryResults result = query.execute(); if (result.isEmpty()) return false; if (result.getRowCount() < 0) { // Try to get the first row ... NodeSequence seq = result.getRows(); Batch batch = seq.nextBatch(); while (batch != null) { if (batch.hasNext()) return true; // It's not common for the first batch may be empty, but it's possible. So try the next // batch ... batch = seq.nextBatch(); } return false; } return result.getRowCount() > 0; } catch (RepositoryException e) { logger.error(e, JcrI18n.errorCheckingNodeTypeUsage, nodeTypeName, e.getLocalizedMessage()); return true; } }
private void initializeModeShapeEngine( final OperationContext context, final ModelNode operation, ModelNode model, final List<ServiceController<?>> newControllers) { ServiceTarget target = context.getServiceTarget(); final JBossLifeCycleListener shutdownListener = new JBossLifeCycleListener(); engine = buildModeShapeEngine(model); // Engine service ServiceBuilder<JcrEngine> engineBuilder = target.addService(ModeShapeServiceNames.ENGINE, engine); engineBuilder.setInitialMode(ServiceController.Mode.ACTIVE); ServiceController<JcrEngine> controller = engineBuilder.install(); controller.getServiceContainer().addTerminateListener(shutdownListener); newControllers.add(controller); // JNDI Binding final ReferenceFactoryService<JcrEngine> referenceFactoryService = new ReferenceFactoryService<JcrEngine>(); final ServiceName referenceFactoryServiceName = ModeShapeServiceNames.ENGINE.append("reference-factory"); // $NON-NLS-1$ final ServiceBuilder<?> referenceBuilder = target.addService(referenceFactoryServiceName, referenceFactoryService); referenceBuilder.addDependency( ModeShapeServiceNames.ENGINE, JcrEngine.class, referenceFactoryService.getInjector()); referenceBuilder.setInitialMode(ServiceController.Mode.ACTIVE); final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(ModeShapeJndiNames.JNDI_BASE_NAME); final BinderService binderService = new BinderService(bindInfo.getBindName()); final ServiceBuilder<?> binderBuilder = target.addService(bindInfo.getBinderServiceName(), binderService); binderBuilder.addDependency( ModeShapeServiceNames.ENGINE, JcrEngine.class, new ManagedReferenceInjector<JcrEngine>(binderService.getManagedObjectInjector())); binderBuilder.addDependency( bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector()); binderBuilder.setInitialMode(ServiceController.Mode.ACTIVE); Logger.getLogger(getClass()) .debug("Binding ModeShape to JNDI name '{0}'", bindInfo.getAbsoluteJndiName()); newControllers.add(referenceBuilder.install()); newControllers.add(binderBuilder.install()); }
void shutdown() { for (IndexProvider provider : providers.values()) { try { provider.shutdown(); } catch (RepositoryException e) { logger.error( e, JcrI18n.errorShuttingDownIndexProvider, repository.name(), provider.getName(), e.getMessage()); } } }
@Override public void notify(ChangeSet changeSet) { if (changeSet == null) { return; // do nothing } if (!isOpen.get()) { // The channel is not open ... return; } if (!multipleAddressesInCluster.get()) { // We are in clustered mode, but there is only one participant in the cluster (us). // So short-circuit the cluster and just notify the local observers ... if (hasObservers()) { delegate.notify(changeSet); logReceivedOperation(changeSet); } return; } // There are multiple participants in the cluster, so send all changes out to JGroups, // letting JGroups do the ordering of messages... try { logSendOperation(changeSet); byte[] data = serialize(changeSet); Message message = new Message(null, null, data); channel.send(message); } catch (IllegalStateException e) { LOGGER.warn( BusI18n.unableToNotifyChanges, clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp()); } catch (Exception e) { // Something went wrong here (this should not happen) ... String msg = BusI18n.errorSerializingChanges.text( clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp(), changeSet); throw new SystemFailureException(msg, e); } }
protected synchronized void removeRecordsOlderThan(long millisInUtc) { RW_LOCK.writeLock().lock(); try { if (millisInUtc <= 0 || stopped) { return; } long searchBound = TIME_BASED_KEYS.getCounterEndingAt(millisInUtc); LOGGER.debug("Removing records older than " + searchBound); NavigableMap<Long, JournalRecord> toRemove = this.records.headMap(searchBound); toRemove.clear(); journalDB.commit(); journalDB.compact(); } finally { RW_LOCK.writeLock().unlock(); } }
@Override public void shutdown() { if (this.stopped) { return; } RW_LOCK.writeLock().lock(); this.stopped = true; try { this.journalDB.commit(); this.journalDB.close(); } catch (Exception e) { LOGGER.error(e, JcrI18n.cannotStopJournal); } finally { RW_LOCK.writeLock().unlock(); } }
/** * Refresh the node types from the stored representation. * * @return true if there was at least one node type found, or false if there were none */ protected boolean refreshFromSystem() { this.nodeTypesLock.writeLock().lock(); try { // Re-read and re-register all of the node types ... SessionCache systemCache = repository.createSystemSession(context, true); SystemContent system = new SystemContent(systemCache); Collection<NodeTypeDefinition> nodeTypes = system.readAllNodeTypes(); if (nodeTypes.isEmpty()) return false; registerNodeTypes(nodeTypes, false, false, false); return true; } catch (Throwable e) { logger.error(e, JcrI18n.errorRefreshingNodeTypes, repository.name()); return false; } finally { this.nodeTypesLock.writeLock().unlock(); } }
private BinaryStore getDefaultBinaryStore() { if (defaultBinaryStore == null) { if (namedStores.containsKey(DEFAULT_STRATEGY_HINT)) { defaultBinaryStore = namedStores.get(DEFAULT_STRATEGY_HINT); } else { logger.trace( "Did not find a named binary store with the key 'default', picking the first binary store in the list"); final Iterator<BinaryStore> iterator = namedStores.values().iterator(); if (iterator.hasNext()) { defaultBinaryStore = iterator.next(); } } } return defaultBinaryStore; }
protected RepositoryIndexes readIndexDefinitions() { // There were at least some changes ... NodeTypes nodeTypes = repository.nodeTypeManager().getNodeTypes(); try { // Read the affected index definitions ... SessionCache systemCache = repository.createSystemSession(context, false); SystemContent system = new SystemContent(systemCache); Collection<IndexDefinition> indexDefns = system.readAllIndexDefinitions(providers.keySet()); this.indexes = new Indexes(context, indexDefns, nodeTypes); return this.indexes; } catch (WorkspaceNotFoundException e) { // This happens occasionally when shutting down ... } catch (Throwable e) { logger.error(e, JcrI18n.errorRefreshingIndexDefinitions, repository.name()); } return indexes; }
@SuppressWarnings("unused") @Override public void markAsUnused(Iterable<BinaryKey> keys) throws BinaryStoreException { Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator(); while (it.hasNext()) { Map.Entry<String, BinaryStore> entry = it.next(); final String binaryStoreKey = entry.getKey(); BinaryStore bs = entry.getValue(); try { bs.markAsUnused(keys); } catch (BinaryStoreException e) { logger.debug(e, "The named store " + binaryStoreKey + " raised exception"); } } }
/** * Obtain a new temporary directory that can be used by a transient binary store. Note that none * of the directories are actually created at this time, but are instead created (if needed) * during {@link #initializeStorage(File)}. * * @return the new directory; never null */ private static File newTempDirectory() { String tempDirName = System.getProperty(JAVA_IO_TMPDIR); if (tempDirName == null) { throw new SystemFailureException( JcrI18n.tempDirectorySystemPropertyMustBeSet.text(JAVA_IO_TMPDIR)); } File tempDir = new File(tempDirName); if (System.getProperty(JBOSS_SERVER_DATA_DIR) == null) { // We're not running in JBoss AS (where we always specify the directory where the binaries are // stored), // so log where the temporary directory is ... Logger.getLogger(TransientBinaryStore.class) .info(JcrI18n.tempDirectoryLocation, tempDir.getAbsolutePath()); } // Create a temporary directory in the "java.io.tmpdir" directory ... return new File(tempDir, "modeshape-binary-store"); }
@SuppressWarnings("unused") @Override public void removeValuesUnusedLongerThan(long minimumAge, TimeUnit unit) throws BinaryStoreException { Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator(); while (it.hasNext()) { Map.Entry<String, BinaryStore> entry = it.next(); final String binaryStoreKey = entry.getKey(); BinaryStore bs = entry.getValue(); try { bs.removeValuesUnusedLongerThan(minimumAge, unit); } catch (BinaryStoreException e) { logger.debug(e, "The named store " + binaryStoreKey + " raised exception"); } } }
/** * Ensures that the directory used by this binary store exists and can be both read and written * to. * * @throws BinaryStoreException if the directory cannot be written to, read, or (if needed) * created */ @Override protected void initializeStorage(File directory) throws BinaryStoreException { if (!directory.exists()) { Logger.getLogger(getClass()) .debug( "Creating temporary directory for transient binary store: {0}", directory.getAbsolutePath()); directory.mkdirs(); } if (!directory.canRead()) { throw new BinaryStoreException( JcrI18n.unableToReadTemporaryDirectory.text(directory.getAbsolutePath(), JAVA_IO_TMPDIR)); } if (!directory.canWrite()) { throw new BinaryStoreException( JcrI18n.unableToWriteTemporaryDirectory.text( directory.getAbsolutePath(), JAVA_IO_TMPDIR)); } }
/** * @param xmiUuid the UUID of the model object whose node has not been created (cannot be <code> * null</code>) * @return the unresolved reference (never <code>null</code>) * @throws Exception if a node for the specified UUID does exist */ public UnresolvedReference addUnresolvedReference(String xmiUuid) throws Exception { CheckArg.isNotEmpty(xmiUuid, "xmiUuid"); xmiUuid = resolveInternalReference(xmiUuid); if (this.uuidToNode.containsKey(xmiUuid)) { throw new Exception(TeiidI18n.illegalUnresolvedReference.text(xmiUuid)); } // see if already unresolved UnresolvedReference unresolved = this.unresolved.get(xmiUuid); // create unresolved if necessary if (unresolved == null) { unresolved = new UnresolvedReference(xmiUuid); this.unresolved.put(xmiUuid, unresolved); LOGGER.debug("added '{0}' to the list of unresolved references", xmiUuid); } return unresolved; }