/* * JBoss, Home of Professional Open Source. * Copyright 2009, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.system.server.profileservice.repository.clustered.local; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.jboss.system.server.profileservice.repository.clustered.ClusteredDeploymentRepository; import org.jboss.system.server.profileservice.repository.clustered.metadata.RepositoryContentMetadata; import org.jboss.system.server.profileservice.repository.clustered.metadata.RepositoryItemMetadata; import org.jboss.system.server.profileservice.repository.clustered.metadata.RepositoryRootMetadata; import org.jboss.system.server.profileservice.repository.clustered.sync.AbstractContentModificationGenerator; import org.jboss.system.server.profileservice.repository.clustered.sync.ContentModification; import org.jboss.system.server.profileservice.repository.clustered.sync.SynchronizationAction; import org.jboss.system.server.profileservice.repository.clustered.sync.SynchronizationActionContext; import org.jboss.system.server.profileservice.repository.clustered.sync.SynchronizationId; import org.jboss.virtual.VirtualFile; /** * Object responsible for the local persistence operations associated with a * {@link ClusteredDeploymentRepository}. * * @author Brian Stansberry * * @version $Revision: $ */ public interface LocalContentManager<T extends SynchronizationActionContext> { /** * Gets the "official" record of the contents of the persistent store. * This is the version persisted to disk following synchronization * of changes with the cluster. * * @return the content metadata */ RepositoryContentMetadata getOfficialContentMetadata(); /** * Scan the persistent store for the current content metadata. This * is not the "official" metadata that has been persisted, as any * changes between it and the {@link #getOfficialContentMetadata() official version} * have not been synchronized with the cluster. * * @return the content metadata */ RepositoryContentMetadata getCurrentContentMetadata() throws IOException; /** * Initiate a process of synchronizing this node's persistent store with * the rest of the cluster * * @param id a unique id for this cluster synchronization process * @param modifications the overall list of modifications that will occur during * this process * @param toInstall TODO * @param localLed <code>true</code> if this node is driving the synchronization, * <code>false</code> if another node is * @return list of {@link SynchronizationAction}s each of which * can be executed by the caller to fulfill a portion of this node's role in * the overall cluster synchronization * * @throws IllegalStateException if another synchronization process has * been initiated and not yet completed */ List<? extends SynchronizationAction<T>> initiateSynchronization(SynchronizationId<?> id, List<ContentModification> modifications, RepositoryContentMetadata toInstall, boolean localLed); /** * Execute the prepare phase of the two phase commit process for the cluster * synchronization that has been * {@link #initiateSynchronization(SynchronizationId, List, RepsitoryContentMetadata, boolean) initialized}. * * @param id id of the synchronization. Cannot be <code>null</code> * * @return <code>true</code> if the prepare phase was successful; * <code>false</code> if not and the synchronization needs to be * rolled back * * @throws IllegalStateException if <code>id</code> is not equal to the * id of an uncompleted synchronization started via * {@link #initiateSynchronization(SynchronizationId, List, RepsitoryContentMetadata, boolean)} */ boolean prepareSynchronization(SynchronizationId<?> id); /** * Complete the two-phase commit process for the cluster synchronization that has been * {@link #prepareSynchronization(SynchronizationId) prepared}. * * @param id id of the synchronization. Cannot be <code>null</code> * * @throws IllegalStateException if <code>id</code> is not equal to the * id of an uncompleted synchronization started via * {@link #initiateSynchronization(SynchronizationId, List, RepsitoryContentMetadata, boolean)} */ void commitSynchronization(SynchronizationId<?> id); /** * Roll back the cluster synchronization. * * @param id id of the synchronization. Cannot be <code>null</code> * * @throws IllegalStateException if <code>id</code> is not equal to the * id of an uncompleted synchronization started via * {@link #initiateSynchronization(SynchronizationId, List, RepsitoryContentMetadata, boolean)} */ void rollbackSynchronization(SynchronizationId<?> id); /** * Creates a new {@link RepositoryContentMetadata} with a child * {@link RepositoryRootMetadata} for each of this persister's URIs, * but no {@link RepositoryItemMetadata}s under those roots. When a node that * is starting for the first time does not have a persisted set of * content metadata, this method should be used to create an object that can * be used as a base to * {@link AbstractContentModificationGenerator#getModificationList(RepositoryContentMetadata, RepositoryContentMetadata) generate a set of modifications} * needed to synchronize the node with the cluster. * * @return a {@link RepositoryContentMetadata} with no grandchildren. */ RepositoryContentMetadata createEmptyContentMetadata(); /** * Install the result from the latest call to {@link #getCurrentContentMetadata()} * as the "official" content metadata. Intended for use during node startup * when the node discovers it is the only member of the cluster, and thus * that it's "current" content metadata is "official". * * @throws IllegalStateException if no "current" content metadata is available, either * because {@link #getCurrentContentMetadata()} * hasn't been called, or because a cluster * synchronization has been executed to completion * since that call. * */ void installCurrentContentMetadata(); /** * Gets a {@link RepositoryItemMetadata} that will describe an item that * may be added. * * @param vfsPath path relative to one of this repository's root URIs * * @return the item metadata * * @throws IOException */ RepositoryItemMetadata getItemForAddition(String vfsPath) throws IOException; /** * Generate content metadata that would reflect what the metadata would * look like if an item with path vfsPath were added. * * @param vfsPath * @param contentIS * @return */ RepositoryContentMetadata getContentMetadataForAdd(RepositoryItemMetadata toAdd, InputStream contentIS) throws IOException; /** * Get a {@link VirtualFile} for the content indicated by <code>item</code>. * * @param item metadata describing the content * @return the virtual file * * @throws IOException */ VirtualFile getVirtualFileForItem(RepositoryItemMetadata item) throws IOException; /** * Generate content metadata that would reflect what the metadata would * look like if an item with path vfsPath were removed. * * @param vfsPath path relative to one of this repository's root URIs * * @return the content metadata * * @throws IOException */ RepositoryContentMetadata getContentMetadataForRemove(VirtualFile vf) throws IOException; }