/** * Copyright (c) Codice Foundation * <p/> * 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 3 of the * License, or any later version. * <p/> * This program 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. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package ddf.catalog.impl.operations; import java.nio.file.Path; import java.util.List; import java.util.Map; import java.util.function.Supplier; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.catalog.Constants; import ddf.catalog.content.StorageException; import ddf.catalog.content.StorageProvider; import ddf.catalog.content.data.ContentItem; import ddf.catalog.content.operation.StorageRequest; import ddf.catalog.history.Historian; import ddf.catalog.source.IngestException; import ddf.catalog.source.SourceUnavailableException; import ddf.catalog.util.impl.Requests; /** * Support class for working with {@code StorageRequest}s for the {@code CatalogFrameworkImpl}. * <p> * This class contains methods for management/manipulation for storage requests for the CFI and its * support classes. No operations/support methods should be added to this class except in support * of CFI, specific to storage requests. */ public class OperationsStorageSupport { private static final Logger LOGGER = LoggerFactory.getLogger(OperationsStorageSupport.class); private static final Logger INGEST_LOGGER = LoggerFactory.getLogger(Constants.INGEST_LOGGER_NAME); // // Injected propertiers // private final SourceOperations sourceOperations; private final QueryOperations queryOperations; private Historian historian; public OperationsStorageSupport(SourceOperations sourceOperations, QueryOperations queryOperations) { this.sourceOperations = sourceOperations; this.queryOperations = queryOperations; } public void setHistorian(Historian historian) { this.historian = historian; } <T extends StorageRequest> T prepareStorageRequest(T storageRequest, Supplier<List<ContentItem>> getContentItems) throws IngestException, SourceUnavailableException { validateStorageRequest(storageRequest, getContentItems); queryOperations.setFlagsOnRequest(storageRequest); if (Requests.isLocal(storageRequest) && (!sourceOperations.isSourceAvailable( sourceOperations.getCatalog()) || !isStorageAvailable(sourceOperations.getStorage()))) { String message = "Local provider is not available, cannot perform storage operation."; SourceUnavailableException sourceUnavailableException = new SourceUnavailableException( message); if (INGEST_LOGGER.isWarnEnabled()) { INGEST_LOGGER.warn(message, sourceUnavailableException); } throw sourceUnavailableException; } return storageRequest; } public void commitAndCleanup(StorageRequest storageRequest, Map<String, Map<String, Path>> tmpContentPaths) { if (storageRequest != null) { try { sourceOperations.getStorage() .commit(storageRequest); } catch (StorageException e) { LOGGER.info("Unable to commit content changes for id: {}", storageRequest.getId(), e); rollbackStorage(storageRequest); } } tmpContentPaths.values() .stream() .flatMap(id -> id.values() .stream()) .forEach(path -> FileUtils.deleteQuietly(path.toFile())); tmpContentPaths.clear(); } private void rollbackStorage(StorageRequest storageRequest) { try { sourceOperations.getStorage() .rollback(storageRequest); } catch (StorageException e1) { LOGGER.info("Unable to remove temporary content for id: {}", storageRequest.getId(), e1); } } /** * Validates that the {@link StorageRequest} is non-null and has a non-empty list of * {@link ContentItem}s in it. * * @param request the {@link StorageRequest} * @throws IngestException if the {@link StorageRequest} is null, or request has a null or empty list of * {@link ContentItem}s */ private void validateStorageRequest(StorageRequest request, Supplier<List<ContentItem>> getContentItems) throws IngestException { if (request == null) { throw new IngestException("StorageRequest was null."); } List<ContentItem> contentItems = getContentItems.get(); if (CollectionUtils.isEmpty(contentItems)) { throw new IngestException("Cannot perform ingest or update with null/empty entry list."); } } private boolean isStorageAvailable(StorageProvider storageProvider) { if (storageProvider == null) { LOGGER.warn("storageProvider is null, therefore not available"); return false; } return true; } }