/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.backuprestore.processor;
import java.util.logging.Logger;
import org.geoserver.backuprestore.Backup;
import org.geoserver.backuprestore.BackupRestoreItem;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.ValidationResult;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.config.util.XStreamPersisterFactory;
import org.geoserver.ows.util.OwsUtils;
import org.geotools.util.logging.Logging;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ItemProcessor;
/**
* Concrete Spring Batch {@link ItemProcessor}.
*
* Processes {@link Catalog} resource items while reading.
*
* @author Alessio Fabiani, GeoSolutions
*
*/
public class CatalogItemProcessor<T> extends BackupRestoreItem<T> implements ItemProcessor<T, T> {
/**
* logger
*/
private static final Logger LOGGER = Logging.getLogger(CatalogItemProcessor.class);
Class<T> clazz;
@Override
protected void initialize(StepExecution stepExecution) {
}
/**
* Default Constructor.
*
* @param clazz
* @param backupFacade
*/
public CatalogItemProcessor(Class<T> clazz, Backup backupFacade,
XStreamPersisterFactory xStreamPersisterFactory) {
super(backupFacade, xStreamPersisterFactory);
this.clazz = clazz;
}
/**
* @return the clazz
*/
public Class<T> getClazz() {
return clazz;
}
@Override
public T process(T resource) throws Exception {
if (resource != null) {
if (isNew()) {
// Disabling additional validators
((CatalogImpl) getCatalog()).setExtendedValidation(false);
// Resolving Collections
OwsUtils.resolveCollections(resource);
}
LOGGER.info("Processing resource: " + resource + " - Progress: ["
+ getCurrentJobExecution().getProgress() + "]");
if (resource instanceof WorkspaceInfo) {
WorkspaceInfo ws = ((WorkspaceInfo) resource);
if (filteredResource(resource, ws, true)) {
return null;
}
if (!validateWorkspace((WorkspaceInfo) resource, isNew())) {
LOGGER.warning("Skipped invalid resource: " + resource);
logValidationExceptions(resource, null);
return null;
}
} else if (resource instanceof DataStoreInfo) {
WorkspaceInfo ws = ((DataStoreInfo) resource).getWorkspace() != null ? getCatalog()
.getWorkspaceByName(((DataStoreInfo) resource).getWorkspace().getName())
: null;
if (filteredResource(resource, ws, true)) {
return null;
}
if (!validateDataStore((DataStoreInfo) resource, isNew())) {
LOGGER.warning("Skipped invalid resource: " + resource);
logValidationExceptions(resource, null);
return null;
}
if (getCatalog().getDefaultDataStore(ws) == null) {
getCatalog().setDefaultDataStore(ws, (DataStoreInfo) resource);
}
} else if (resource instanceof CoverageStoreInfo) {
WorkspaceInfo ws = ((CoverageStoreInfo) resource).getWorkspace() != null
? getCatalog().getWorkspaceByName(
((CoverageStoreInfo) resource).getWorkspace().getName())
: null;
if (filteredResource(resource, ws, true)) {
return null;
}
if (!validateCoverageStore((CoverageStoreInfo) resource, isNew())) {
LOGGER.warning("Skipped invalid resource: " + resource);
logValidationExceptions(resource, null);
return null;
}
} else if (resource instanceof ResourceInfo) {
WorkspaceInfo ws = ((ResourceInfo) resource).getStore() != null
&& ((ResourceInfo) resource).getStore().getWorkspace() != null
? getCatalog().getWorkspaceByName(((ResourceInfo) resource)
.getStore().getWorkspace().getName())
: null;
if (filteredResource(resource, ws, true)) {
return null;
}
if (!validateResource((ResourceInfo) resource, isNew())) {
LOGGER.warning("Skipped invalid resource: " + resource);
logValidationExceptions(resource, null);
return null;
}
} else if (resource instanceof LayerInfo) {
ValidationResult result = null;
try {
WorkspaceInfo ws = ((LayerInfo) resource).getResource() != null
&& ((LayerInfo) resource).getResource().getStore() != null
&& ((LayerInfo) resource).getResource().getStore()
.getWorkspace() != null
? getCatalog().getWorkspaceByName(
((LayerInfo) resource).getResource().getStore()
.getWorkspace().getName())
: null;
if (filteredResource(resource, ws, true)) {
return null;
}
result = getCatalog().validate((LayerInfo) resource, isNew());
if (!result.isValid()) {
logValidationExceptions(resource, null);
return null;
}
} catch (Exception e) {
LOGGER.warning("Could not validate the resource " + resource
+ " due to the following issue: " + e.getLocalizedMessage());
logValidationExceptions(result, e);
return null;
}
} else if (resource instanceof StyleInfo) {
ValidationResult result = null;
try {
WorkspaceInfo ws = ((StyleInfo) resource).getWorkspace() != null ? getCatalog()
.getWorkspaceByName(((StyleInfo) resource).getWorkspace().getName())
: null;
if (filteredResource(resource, ws, false)) {
return null;
}
result = this.getCatalog().validate((StyleInfo) resource, isNew());
if (!result.isValid()) {
logValidationExceptions(resource, null);
return null;
}
} catch (Exception e) {
logValidationExceptions(result, e);
return null;
}
} else if (resource instanceof LayerGroupInfo) {
ValidationResult result = null;
try {
WorkspaceInfo ws = ((LayerGroupInfo) resource).getWorkspace() != null
? getCatalog().getWorkspaceByName(
((LayerGroupInfo) resource).getWorkspace().getName())
: null;
if (filteredResource(resource, ws, false)) {
return null;
}
result = this.getCatalog().validate((LayerGroupInfo) resource, isNew());
if (!result.isValid()) {
logValidationExceptions(resource, null);
return null;
}
} catch (Exception e) {
logValidationExceptions(result, e);
return null;
}
}
return resource;
}
return null;
}
/**
* Being sure the associated {@link NamespaceInfo} exists and is available on the GeoServer Catalog.
*
* @param isNew
*
* @param {@link WorkspaceInfo} resource
*
* @return boolean indicating whether the resource is valid or not.
* @throws Exception
*/
private boolean validateWorkspace(WorkspaceInfo resource, boolean isNew) throws Exception {
final NamespaceInfo ns = this.getCatalog().getNamespaceByPrefix(resource.getName());
if (ns == null) {
return false;
}
ValidationResult result = null;
try {
result = this.getCatalog().validate(resource, isNew);
} catch (Exception e) {
LOGGER.warning("Could not validate the resource " + resource
+ " due to the following issue: " + e.getLocalizedMessage());
logValidationExceptions(result, e);
return false;
}
return true;
}
/**
* Being sure the associated {@link WorkspaceInfo} exists and is available on the GeoServer Catalog.
*
* Also if a default {@link DataStoreInfo} has not been defined for the current {@link WorkspaceInfo}, set this one as default.
*
* @param isNew
*
* @param {@link DataStoreInfo} resource
*
* @return boolean indicating whether the resource is valid or not.
* @throws Exception
*/
private boolean validateDataStore(DataStoreInfo resource, boolean isNew) throws Exception {
final WorkspaceInfo ws = this.getCatalog()
.getWorkspaceByName(resource.getWorkspace().getName());
if (ws == null) {
return false;
}
ValidationResult result = null;
try {
result = this.getCatalog().validate(resource, isNew);
} catch (Exception e) {
LOGGER.warning("Could not validate the resource " + resource
+ " due to the following issue: " + e.getLocalizedMessage());
logValidationExceptions(result, e);
return false;
}
resource.setWorkspace(ws);
return true;
}
/**
* Being sure the associated {@link WorkspaceInfo} exists and is available on the GeoServer Catalog.
*
* @param isNew
*
* @param {@link CoverageStoreInfo} resource
*
* @return boolean indicating whether the resource is valid or not.
* @throws Exception
*/
private boolean validateCoverageStore(CoverageStoreInfo resource, boolean isNew)
throws Exception {
final WorkspaceInfo ws = this.getCatalog()
.getWorkspaceByName(resource.getWorkspace().getName());
if (ws == null) {
return false;
}
ValidationResult result = null;
try {
result = this.getCatalog().validate(resource, isNew);
} catch (Exception e) {
LOGGER.warning("Could not validate the resource " + resource
+ " due to the following issue: " + e.getLocalizedMessage());
return logValidationExceptions(result, e);
}
resource.setWorkspace(ws);
return true;
}
/**
* Being sure the associated {@link StoreInfo} exists and is available on the GeoServer Catalog.
*
* @param isNew2
*
* @param {@link ResourceInfo} resource
* @return
*
* @return boolean indicating whether the resource is valid or not.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private boolean validateResource(ResourceInfo resource, boolean isNew) {
try {
final StoreInfo store = resource.getStore();
final NamespaceInfo namespace = resource.getNamespace();
if (store == null) {
return logValidationExceptions((T) resource, null);
}
final Class storeClazz = (store instanceof DataStoreInfo ? DataStoreInfo.class
: CoverageStoreInfo.class);
final StoreInfo ds = this.getCatalog().getStoreByName(store.getName(), storeClazz);
if (ds != null) {
resource.setStore(ds);
} else {
return logValidationExceptions((T) resource, null);
}
ResourceInfo existing = getCatalog().getResourceByStore(store, resource.getName(),
ResourceInfo.class);
if (existing != null && !existing.getId().equals(resource.getId())) {
final String msg = "Resource named '" + resource.getName()
+ "' already exists in store: '" + store.getName() + "'";
return logValidationExceptions((T) resource, new RuntimeException(msg));
}
existing = getCatalog().getResourceByName(namespace, resource.getName(),
ResourceInfo.class);
if (existing != null && !existing.getId().equals(resource.getId())) {
final String msg = "Resource named '" + resource.getName()
+ "' already exists in namespace: '" + namespace.getPrefix() + "'";
return logValidationExceptions((T) resource, new RuntimeException(msg));
}
return true;
} catch (Exception e) {
LOGGER.warning("Could not validate the resource " + resource
+ " due to the following issue: " + e.getLocalizedMessage());
return logValidationExceptions((T) resource, e);
}
}
}