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 Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.UUID;

Expand All @@ -27,6 +28,8 @@
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.util.CloseableIterator;
import org.geoserver.config.GeoServer;
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);
}
}

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 Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*/
package org.geogig.geoserver.wms;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
Expand All @@ -14,8 +16,9 @@
import java.util.logging.Logger;
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.CatalogException;
import org.geoserver.catalog.CatalogVisitor;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
Expand All @@ -36,6 +39,7 @@
import org.locationtech.geogig.geotools.data.GeoGigDataStore;
import org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory;
import org.locationtech.geogig.model.ObjectId;
import org.locationtech.geogig.repository.Repository;

import com.google.common.base.Optional;

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

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

@Override
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
FUTURE_SERVICE.submit(new Runnable() {
@Override
public void run() {
final String layerName = geogigLayer.getName();
try {
Optional<ObjectId> objId = indexId.get();
if (!objId.isPresent()) {
Expand All @@ -138,35 +151,37 @@ public void run() {
public void visit(LayerInfo layer) {
// get the Resource for this layer
final ResourceInfo resource = layer.getResource();
if (resource != null) {
if (RepositoryManager.get().isGeogigLayer(layer)) {
// get the Store to see if it's a GeoGig store
final StoreInfo store = resource.getStore();
if (GeoGigDataStoreFactory.DISPLAY_NAME.equals(store.getType())) {
// it's a GeoGig dataStore
GeoGigDataStore geogigDataStore = null;
try {
geogigDataStore = GeoGigDataStore.class.cast(
((DataStoreInfo) store).getDataStore(null));
} catch (Exception ex) {
throw new CatalogException("Error accessing GeoGig DataStore", ex);
}
if (!geogigDataStore.getAutoIndexing()) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine(String.format(
"GeoGig DataStore is not configured for automatic indexing."));
}
// skip it
return;
// it's a GeoGig dataStore
Map<String, Serializable> connectionParams = store.getConnectionParameters();
Serializable autoIndexingParam = connectionParams
.get(GeoGigDataStoreFactory.AUTO_INDEXING.key);

final boolean autoIndexing = Boolean.TRUE.equals(autoIndexingParam);

if (!autoIndexing) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine(String.format(
"GeoGig DataStore is not configured for automatic indexing."));
}
// 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(geogigDataStore, resource.getName(), dimensions);
// skip it
return;
}
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 Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.geoserver.catalog.LayerIdentifierInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.event.CatalogAddEvent;
import org.geoserver.catalog.event.CatalogListener;
Expand All @@ -53,26 +52,25 @@
* <p>
* The identifier is made of the following parts:
* <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
* {@link RepositoryManager} and are the way this plugin supports configuring several datastores
* against the same repository without duplication of information.
* <li> {@code <nativeName>}: the layer's resource {@link ResourceInfo#getNativeName() native name}
* <li> {@code <branch/head>}: the geogig datastore's configured
* {@link GeoGigDataStoreFactory#BRANCH branch} or {@link GeoGigDataStoreFactory#HEAD}, whichever is
* present, or absent if no branch or head is configured (and hence the datastore operates on
* whatever the current HEAD is)
* <li>{@code <nativeName>}: the layer's resource {@link ResourceInfo#getNativeName() native name}
* <li>{@code <branch/head>}: the geogig datastore's configured {@link GeoGigDataStoreFactory#BRANCH
* branch} or {@link GeoGigDataStoreFactory#HEAD}, whichever is present, or absent if no branch or
* head is configured (and hence the datastore operates on whatever the current HEAD is)
* </ul>
* <p>
* Handles the following events:
* <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
* <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
* <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
* <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
* </ul>
*/
Expand All @@ -87,6 +85,7 @@ public class GeogigLayerIntegrationListener implements CatalogListener {
private final GeoServer geoserver;

private final GeoGigCatalogVisitor visitor = new GeoGigCatalogVisitor();

/**
*/
public GeogigLayerIntegrationListener(GeoServer geoserver) {
Expand All @@ -101,7 +100,7 @@ public void handleAddEvent(CatalogAddEvent event) throws CatalogException {
return;
}
LayerInfo layer = (LayerInfo) event.getSource();
if (!isGeogigLayer(layer)) {
if (!RepositoryManager.get().isGeogigLayer(layer)) {
return;
}
event.getSource().accept(visitor);
Expand All @@ -117,13 +116,14 @@ public void handleAddEvent(CatalogAddEvent event) throws CatalogException {
@Override
public void handleModifyEvent(CatalogModifyEvent event) throws CatalogException {
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;
}
event.getSource().accept(visitor);

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

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

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);
updateIdentifier(layer, layerIdentifier);
}
Expand Down Expand Up @@ -267,7 +268,7 @@ private void updateIdentifier(LayerInfo geogigLayer, final String newIdentifier)
Catalog catalog = geoserver.getCatalog();
catalog.save(geogigLayer);
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) {
Expand All @@ -284,27 +285,12 @@ private String buildLayerIdentifier(LayerInfo geogigLayer) {
refSpec = connectionParameters.get(HEAD.key);
}

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

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 Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.junit.Rule;
import org.junit.Test;
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.impl.GeoGIG;
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
DataStoreInfo dataStore = catalog.getDataStoreByName(GeoGigTestData.CatalogBuilder.WORKSPACE,
GeoGigTestData.CatalogBuilder.STORE);
final GeoGigDataStore geogigDataStore = GeoGigDataStore.class.cast(
((DataStoreInfo) dataStore).getDataStore(null));
geogigDataStore.setAutoIndexing(true);
dataStore.getConnectionParameters().put(GeoGigDataStoreFactory.AUTO_INDEXING.key, true);
catalog.save(dataStore);
}
}

0 comments on commit 4b540fe

Please sign in to comment.