/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.as.server.mgmt.domain; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.as.repository.ContentFilter; import org.jboss.as.repository.ContentReference; import org.jboss.as.repository.ContentRepository; import org.jboss.as.repository.ContentRepositoryElement; import org.jboss.as.repository.DeploymentFileRepository; import org.jboss.as.repository.ExplodedContent; import org.jboss.as.repository.ExplodedContentException; import org.jboss.as.repository.LocalDeploymentFileRepository; import org.jboss.as.repository.TypedInputStream; import org.jboss.as.server.logging.ServerLogger; import org.jboss.msc.service.Service; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StartException; import org.jboss.msc.service.StopContext; import org.jboss.msc.value.InjectedValue; import org.jboss.vfs.VirtualFile; /** * @author Emanuel Muckenhuber */ public class RemoteFileRepositoryService implements CompositeContentRepository, Service<CompositeContentRepository> { private final InjectedValue<HostControllerClient> clientInjectedValue = new InjectedValue<HostControllerClient>(); private final File localDeploymentFolder; private final DeploymentFileRepository localRepository; private final ContentRepository contentRepository; private volatile RemoteFileRepositoryExecutor remoteFileRepositoryExecutor; public static void addService(final ServiceTarget target, final File localDeploymentContentsFolder, final File localTmpFolder) { final RemoteFileRepositoryService service = new RemoteFileRepositoryService(localDeploymentContentsFolder, localTmpFolder); target.addService(ContentRepository.SERVICE_NAME, service) .addDependency(HostControllerConnectionService.SERVICE_NAME, HostControllerClient.class, service.clientInjectedValue) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); } RemoteFileRepositoryService(final File localDeploymentFolder, final File localTmpFolder) { this.localDeploymentFolder = localDeploymentFolder; this.contentRepository = ContentRepository.Factory.create(localDeploymentFolder, localTmpFolder); this.localRepository = new LocalDeploymentFileRepository(localDeploymentFolder); } @Override public void start(final StartContext context) throws StartException { final HostControllerClient client = clientInjectedValue.getValue(); this.remoteFileRepositoryExecutor = client.getRemoteFileRepository(); } @Override public void stop(StopContext context) { remoteFileRepositoryExecutor = null; } @Override public CompositeContentRepository getValue() throws IllegalStateException, IllegalArgumentException { final RemoteFileRepositoryExecutor executor = this.remoteFileRepositoryExecutor; if (executor == null) { throw ServerLogger.ROOT_LOGGER.couldNotFindHcFileRepositoryConnection(); } return this; } @Override public byte[] addContent(InputStream stream) throws IOException { return contentRepository.addContent(stream); } @Override public VirtualFile getContent(byte[] hash) { return contentRepository.getContent(hash); } @Override public boolean syncContent(ContentReference reference) { if (!contentRepository.hasContent(reference.getHash())) { getDeploymentFiles(reference); // Make sure it's in sync } return contentRepository.hasContent(reference.getHash()); } @Override public boolean hasContent(byte[] hash) { return contentRepository.hasContent(hash); } @Override public void removeContent(ContentReference reference) { contentRepository.removeContent(reference); } @Override public final File[] getDeploymentFiles(ContentReference reference) { final File root = getDeploymentRoot(reference); return root.listFiles(); } @Override public File getDeploymentRoot(ContentReference reference) { final File file = localRepository.getDeploymentRoot(reference); if (!file.exists()) { return getFile(reference, DomainServerProtocol.PARAM_ROOT_ID_DEPLOYMENT); } return file; } private File getFile(final ContentReference reference, final byte repoId) { final RemoteFileRepositoryExecutor executor = this.remoteFileRepositoryExecutor; if (executor == null) { throw ServerLogger.ROOT_LOGGER.couldNotFindHcFileRepositoryConnection(); } File file = remoteFileRepositoryExecutor.getFile(reference.getHexHash(), repoId, localDeploymentFolder); addContentReference(reference); return file; } @Override public void deleteDeployment(ContentReference reference) { if (hasContent(reference.getHash())) {//Don't delete referenced content in the back removeContent(reference); } else { localRepository.deleteDeployment(reference); removeContent(reference); } } @Override public void addContentReference(ContentReference reference) { contentRepository.addContentReference(reference); } @Override public Map<String, Set<String>> cleanObsoleteContent() { return contentRepository.cleanObsoleteContent(); } @Override public byte[] removeContentFromExploded(byte[] deploymentHash, List<String> paths) throws ExplodedContentException { return contentRepository.removeContentFromExploded(deploymentHash, paths); } @Override public byte[] addContentToExploded(byte[] deploymentHash, List<ExplodedContent> addFiles, boolean overwrite) throws ExplodedContentException { return contentRepository.addContentToExploded(deploymentHash, addFiles, overwrite); } @Override public void copyExplodedContent(byte[] hash, Path target) throws ExplodedContentException { contentRepository.copyExplodedContent(hash, target); } @Override public void copyExplodedContentFiles(byte[] deploymentHash, List<String> relativePaths, Path target) throws ExplodedContentException { contentRepository.copyExplodedContentFiles(deploymentHash, relativePaths, target); } @Override public byte[] explodeContent(byte[] hash) throws ExplodedContentException { return contentRepository.explodeContent(hash); } @Override public TypedInputStream readContent(byte[] deploymentHash, String path) throws ExplodedContentException { return contentRepository.readContent(deploymentHash, path); } @Override public byte[] explodeSubContent(byte[] deploymentHash, String relativePath) throws ExplodedContentException { return contentRepository.explodeSubContent(deploymentHash, relativePath); } @Override public List<ContentRepositoryElement> listContent(byte[] deploymentHash, String path, ContentFilter filter) throws ExplodedContentException { return contentRepository.listContent(deploymentHash, path, filter); } }