Skip to content

Commit

Permalink
Make autoindexing not require a cast to GeoGigDataStore
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Roldan authored and Erik Merkle committed Jun 7, 2017
1 parent d89e44d commit 4b540fe
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 65 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.UUID; import java.util.UUID;


Expand All @@ -27,6 +28,8 @@
import org.geoserver.catalog.DataStoreInfo; import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.util.CloseableIterator; import org.geoserver.catalog.util.CloseableIterator;
import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerInitializer; import org.geoserver.config.GeoServerInitializer;
Expand Down Expand Up @@ -419,4 +422,45 @@ private static Ref pingRemote(Remote remote) throws Exception {
throw new IllegalArgumentException("Unable to connect: " + e.getMessage(), e); throw new IllegalArgumentException("Unable to connect: " + e.getMessage(), e);
} }
} }

public boolean isGeogigLayer(LayerInfo layer) {
ResourceInfo resource = layer.getResource();
if (resource == null) {
return false;
}
StoreInfo store = resource.getStore();
if (store == null) {
return false;
}
return isGeogigStore(store);
}

public boolean isGeogigStore(CatalogInfo store) {
if (!(store instanceof DataStoreInfo)) {
return false;
}
final String storeType = ((DataStoreInfo) store).getType();
boolean isGeogigStore = GeoGigDataStoreFactory.DISPLAY_NAME.equals(storeType);
return isGeogigStore;
}

public Repository findRepository(LayerInfo geogigLayer) {
Preconditions.checkArgument(isGeogigLayer(geogigLayer));

Map<String, Serializable> params = geogigLayer.getResource().getStore()
.getConnectionParameters();
String repoUriStr = String.valueOf(params.get(GeoGigDataStoreFactory.REPOSITORY.key));
URI repoURI = URI.create(repoUriStr);
RepositoryResolver resolver = RepositoryResolver.lookup(repoURI);
String repoName = resolver.getName(repoURI);
RepositoryInfo repoInfo = getByRepoName(repoName);
String repoId = repoInfo.getId();
try {
Repository repository = getRepository(repoId);
Preconditions.checkState(repository != null);
return repository;
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*/ */
package org.geogig.geoserver.wms; package org.geogig.geoserver.wms;


import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
Expand All @@ -14,8 +16,9 @@
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Stream; import java.util.stream.Stream;


import org.eclipse.jdt.annotation.Nullable;
import org.geogig.geoserver.config.RepositoryManager;
import org.geoserver.catalog.Catalog; import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogException;
import org.geoserver.catalog.CatalogVisitor; import org.geoserver.catalog.CatalogVisitor;
import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo; import org.geoserver.catalog.CoverageStoreInfo;
Expand All @@ -36,6 +39,7 @@
import org.locationtech.geogig.geotools.data.GeoGigDataStore; import org.locationtech.geogig.geotools.data.GeoGigDataStore;
import org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory; import org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory;
import org.locationtech.geogig.model.ObjectId; import org.locationtech.geogig.model.ObjectId;
import org.locationtech.geogig.repository.Repository;


import com.google.common.base.Optional; import com.google.common.base.Optional;


Expand Down Expand Up @@ -100,21 +104,30 @@ public void visit(CoverageInfo coverage) {
// do nothing // do nothing
} }


private void createOrUpdateIndex(final GeoGigDataStore dataStore, final String layerName, private void createOrUpdateIndex(final LayerInfo geogigLayer, final @Nullable String head,
final String[] extraAttribues) { final String[] extraAttributes) {
// schedule the index creation // schedule the index creation
final Future<Optional<ObjectId>> indexId = INDEX_SERVICE.submit( final Future<Optional<ObjectId>> indexId = INDEX_SERVICE.submit(
new Callable<Optional<ObjectId>>() { new Callable<Optional<ObjectId>>() {


@Override @Override
public Optional<ObjectId> call() throws Exception { public Optional<ObjectId> call() throws Exception {
return dataStore.createOrUpdateIndex(layerName, extraAttribues); RepositoryManager manager = RepositoryManager.get();
Repository findRepository = manager.findRepository(geogigLayer);

String featureTreePath=geogigLayer.getResource().getNativeName();

Optional<ObjectId> index = GeoGigDataStore.createOrUpdateIndex(findRepository, head,
featureTreePath, extraAttributes);

return index;
} }
}); });
// handle the Future and generate an error log if the index create/update fails // handle the Future and generate an error log if the index create/update fails
FUTURE_SERVICE.submit(new Runnable() { FUTURE_SERVICE.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
final String layerName = geogigLayer.getName();
try { try {
Optional<ObjectId> objId = indexId.get(); Optional<ObjectId> objId = indexId.get();
if (!objId.isPresent()) { if (!objId.isPresent()) {
Expand All @@ -138,35 +151,37 @@ public void run() {
public void visit(LayerInfo layer) { public void visit(LayerInfo layer) {
// get the Resource for this layer // get the Resource for this layer
final ResourceInfo resource = layer.getResource(); final ResourceInfo resource = layer.getResource();
if (resource != null) { if (RepositoryManager.get().isGeogigLayer(layer)) {
// get the Store to see if it's a GeoGig store // get the Store to see if it's a GeoGig store
final StoreInfo store = resource.getStore(); final StoreInfo store = resource.getStore();
if (GeoGigDataStoreFactory.DISPLAY_NAME.equals(store.getType())) { // it's a GeoGig dataStore
// it's a GeoGig dataStore Map<String, Serializable> connectionParams = store.getConnectionParameters();
GeoGigDataStore geogigDataStore = null; Serializable autoIndexingParam = connectionParams
try { .get(GeoGigDataStoreFactory.AUTO_INDEXING.key);
geogigDataStore = GeoGigDataStore.class.cast(
((DataStoreInfo) store).getDataStore(null)); final boolean autoIndexing = Boolean.TRUE.equals(autoIndexingParam);
} catch (Exception ex) {
throw new CatalogException("Error accessing GeoGig DataStore", ex); if (!autoIndexing) {
} if (LOGGER.isLoggable(Level.FINE)) {
if (!geogigDataStore.getAutoIndexing()) { LOGGER.fine(String.format(
if (LOGGER.isLoggable(Level.FINE)) { "GeoGig DataStore is not configured for automatic indexing."));
LOGGER.fine(String.format(
"GeoGig DataStore is not configured for automatic indexing."));
}
// skip it
return;
} }
// get the metadata for the layer resource // skip it
final MetadataMap metadata = resource.getMetadata(); return;
final String[] timeAttr = getAttribute(metadata, "time");
final String[] elevationAttr = getAttribute(metadata, "elevation");
String[] dimensions = Stream.concat(Arrays.stream(timeAttr),
Arrays.stream(elevationAttr)).toArray(String[]::new);
// create the indexes
createOrUpdateIndex(geogigDataStore, resource.getName(), dimensions);
} }
String head = (String) connectionParams.get(GeoGigDataStoreFactory.HEAD.key);
String branch = (String) connectionParams.get(GeoGigDataStoreFactory.BRANCH.key);

String effectiveHead = head == null? branch:head;

// get the metadata for the layer resource
final MetadataMap metadata = resource.getMetadata();
final String[] timeAttr = getAttribute(metadata, "time");
final String[] elevationAttr = getAttribute(metadata, "elevation");
String[] dimensions = Stream.concat(Arrays.stream(timeAttr),
Arrays.stream(elevationAttr)).toArray(String[]::new);
// create the indexes
createOrUpdateIndex(layer, effectiveHead, dimensions);
} }
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.geoserver.catalog.LayerIdentifierInfo; import org.geoserver.catalog.LayerIdentifierInfo;
import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.event.CatalogAddEvent; import org.geoserver.catalog.event.CatalogAddEvent;
import org.geoserver.catalog.event.CatalogListener; import org.geoserver.catalog.event.CatalogListener;
Expand All @@ -53,26 +52,25 @@
* <p> * <p>
* The identifier is made of the following parts: * The identifier is made of the following parts:
* <ul> * <ul>
* <li> {@code <repositoryId>}: {@link RepositoryInfo#getId() RepositoryInfo ID} that identifies the * <li>{@code <repositoryId>}: {@link RepositoryInfo#getId() RepositoryInfo ID} that identifies the
* repository referred by the layer's {@link DataStore}. {@link RepositoryInfo}s are managed by * repository referred by the layer's {@link DataStore}. {@link RepositoryInfo}s are managed by
* {@link RepositoryManager} and are the way this plugin supports configuring several datastores * {@link RepositoryManager} and are the way this plugin supports configuring several datastores
* against the same repository without duplication of information. * against the same repository without duplication of information.
* <li> {@code <nativeName>}: the layer's resource {@link ResourceInfo#getNativeName() native name} * <li>{@code <nativeName>}: the layer's resource {@link ResourceInfo#getNativeName() native name}
* <li> {@code <branch/head>}: the geogig datastore's configured * <li>{@code <branch/head>}: the geogig datastore's configured {@link GeoGigDataStoreFactory#BRANCH
* {@link GeoGigDataStoreFactory#BRANCH branch} or {@link GeoGigDataStoreFactory#HEAD}, whichever is * branch} or {@link GeoGigDataStoreFactory#HEAD}, whichever is present, or absent if no branch or
* present, or absent if no branch or head is configured (and hence the datastore operates on * head is configured (and hence the datastore operates on whatever the current HEAD is)
* whatever the current HEAD is)
* </ul> * </ul>
* <p> * <p>
* Handles the following events: * Handles the following events:
* <ul> * <ul>
* <li> {@link WorkspaceInfo} renamed: all geogig layers of stores in that workspace get their * <li>{@link WorkspaceInfo} renamed: all geogig layers of stores in that workspace get their
* authority URL identifiers updated * authority URL identifiers updated
* <li> {@link DataStoreInfo} renamed: all geogig layers of stores in that workspace get their * <li>{@link DataStoreInfo} renamed: all geogig layers of stores in that workspace get their
* authority URL identifiers updated * authority URL identifiers updated
* <li> {@link DataStoreInfo} workspace changed: all geogig layers of stores in that workspace get * <li>{@link DataStoreInfo} workspace changed: all geogig layers of stores in that workspace get
* their authority URL identifiers updated * their authority URL identifiers updated
* <li> {@link LayerInfo} added: if its a geogig layer, creates its geogig authority URL identifier * <li>{@link LayerInfo} added: if its a geogig layer, creates its geogig authority URL identifier
* and saves the layer info * and saves the layer info
* </ul> * </ul>
*/ */
Expand All @@ -87,6 +85,7 @@ public class GeogigLayerIntegrationListener implements CatalogListener {
private final GeoServer geoserver; private final GeoServer geoserver;


private final GeoGigCatalogVisitor visitor = new GeoGigCatalogVisitor(); private final GeoGigCatalogVisitor visitor = new GeoGigCatalogVisitor();

/** /**
*/ */
public GeogigLayerIntegrationListener(GeoServer geoserver) { public GeogigLayerIntegrationListener(GeoServer geoserver) {
Expand All @@ -101,7 +100,7 @@ public void handleAddEvent(CatalogAddEvent event) throws CatalogException {
return; return;
} }
LayerInfo layer = (LayerInfo) event.getSource(); LayerInfo layer = (LayerInfo) event.getSource();
if (!isGeogigLayer(layer)) { if (!RepositoryManager.get().isGeogigLayer(layer)) {
return; return;
} }
event.getSource().accept(visitor); event.getSource().accept(visitor);
Expand All @@ -117,13 +116,14 @@ public void handleAddEvent(CatalogAddEvent event) throws CatalogException {
@Override @Override
public void handleModifyEvent(CatalogModifyEvent event) throws CatalogException { public void handleModifyEvent(CatalogModifyEvent event) throws CatalogException {
if (PRE_MOFIFY_EVENT.get() != null) { if (PRE_MOFIFY_EVENT.get() != null) {
LOGGER.log(Level.FINE, "pre-modify event exists, ignoring handleModifyEvent ({0})", PRE_MOFIFY_EVENT.get()); LOGGER.log(Level.FINE, "pre-modify event exists, ignoring handleModifyEvent ({0})",
PRE_MOFIFY_EVENT.get());
return; return;
} }
event.getSource().accept(visitor); event.getSource().accept(visitor);


final CatalogInfo source = event.getSource(); final CatalogInfo source = event.getSource();
final boolean isGeogigStore = isGeogigStore(source); final boolean isGeogigStore = RepositoryManager.get().isGeogigStore(source);


boolean tryPostUpdate = (source instanceof WorkspaceInfo) || isGeogigStore; boolean tryPostUpdate = (source instanceof WorkspaceInfo) || isGeogigStore;
final List<String> propertyNames = event.getPropertyNames(); final List<String> propertyNames = event.getPropertyNames();
Expand Down Expand Up @@ -236,7 +236,8 @@ public void reloaded() {
} }


private void setIdentifier(LayerInfo layer) { private void setIdentifier(LayerInfo layer) {
LOGGER.log(Level.FINE, "Updating geogig auth identifier for layer {0}", layer.prefixedName()); LOGGER.log(Level.FINE, "Updating geogig auth identifier for layer {0}",
layer.prefixedName());
final String layerIdentifier = buildLayerIdentifier(layer); final String layerIdentifier = buildLayerIdentifier(layer);
updateIdentifier(layer, layerIdentifier); updateIdentifier(layer, layerIdentifier);
} }
Expand Down Expand Up @@ -267,7 +268,7 @@ private void updateIdentifier(LayerInfo geogigLayer, final String newIdentifier)
Catalog catalog = geoserver.getCatalog(); Catalog catalog = geoserver.getCatalog();
catalog.save(geogigLayer); catalog.save(geogigLayer);
LOGGER.log(Level.INFO, "Updated geogig auth identifier for layer {0} as {1}", LOGGER.log(Level.INFO, "Updated geogig auth identifier for layer {0} as {1}",
new Object[]{geogigLayer.prefixedName(), newIdentifier}); new Object[] { geogigLayer.prefixedName(), newIdentifier });
} }


private String buildLayerIdentifier(LayerInfo geogigLayer) { private String buildLayerIdentifier(LayerInfo geogigLayer) {
Expand All @@ -284,27 +285,12 @@ private String buildLayerIdentifier(LayerInfo geogigLayer) {
refSpec = connectionParameters.get(HEAD.key); refSpec = connectionParameters.get(HEAD.key);
} }


StringBuilder identifier = new StringBuilder(repositoryId).append(':').append( StringBuilder identifier = new StringBuilder(repositoryId).append(':')
resource.getNativeName()); .append(resource.getNativeName());
if (refSpec != null) { if (refSpec != null) {
identifier.append(':').append(refSpec); identifier.append(':').append(refSpec);
} }


return identifier.toString(); return identifier.toString();
} }

private boolean isGeogigLayer(LayerInfo layer) {
ResourceInfo resource = layer.getResource();
StoreInfo store = resource.getStore();
return isGeogigStore(store);
}

private boolean isGeogigStore(CatalogInfo store) {
if (!(store instanceof DataStoreInfo)) {
return false;
}
final String storeType = ((DataStoreInfo) store).getType();
boolean isGeogigLayer = DISPLAY_NAME.equals(storeType);
return isGeogigLayer;
}
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.locationtech.geogig.geotools.data.GeoGigDataStore; import org.locationtech.geogig.geotools.data.GeoGigDataStore;
import org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory;
import org.locationtech.geogig.repository.IndexInfo; import org.locationtech.geogig.repository.IndexInfo;
import org.locationtech.geogig.repository.impl.GeoGIG; import org.locationtech.geogig.repository.impl.GeoGIG;
import org.locationtech.geogig.storage.IndexDatabase; import org.locationtech.geogig.storage.IndexDatabase;
Expand Down Expand Up @@ -141,8 +142,7 @@ private void addAvailableGeogigLayers() throws IOException {
// set the DataStore to auto-index // set the DataStore to auto-index
DataStoreInfo dataStore = catalog.getDataStoreByName(GeoGigTestData.CatalogBuilder.WORKSPACE, DataStoreInfo dataStore = catalog.getDataStoreByName(GeoGigTestData.CatalogBuilder.WORKSPACE,
GeoGigTestData.CatalogBuilder.STORE); GeoGigTestData.CatalogBuilder.STORE);
final GeoGigDataStore geogigDataStore = GeoGigDataStore.class.cast( dataStore.getConnectionParameters().put(GeoGigDataStoreFactory.AUTO_INDEXING.key, true);
((DataStoreInfo) dataStore).getDataStore(null)); catalog.save(dataStore);
geogigDataStore.setAutoIndexing(true);
} }
} }

0 comments on commit 4b540fe

Please sign in to comment.