Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gh-3299: Add ChangeGraphId operation to POC simple federated store #3301

Merged
merged 9 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions store-implementation/simple-federated-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,16 @@
<artifactId>graph</artifactId>
<version>${project.parent.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>uk.gov.gchq.gaffer</groupId>
<artifactId>map-store</artifactId>
<artifactId>accumulo-store</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>uk.gov.gchq.gaffer</groupId>
<artifactId>accumulo-store</artifactId>
<artifactId>map-store</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties;
import uk.gov.gchq.gaffer.accumulostore.AccumuloStore;
import uk.gov.gchq.gaffer.cache.Cache;
import uk.gov.gchq.gaffer.cache.CacheServiceLoader;
import uk.gov.gchq.gaffer.cache.exception.CacheOperationException;
Expand All @@ -27,6 +29,7 @@
import uk.gov.gchq.gaffer.data.element.Element;
import uk.gov.gchq.gaffer.data.element.id.EntityId;
import uk.gov.gchq.gaffer.federated.simple.operation.AddGraph;
import uk.gov.gchq.gaffer.federated.simple.operation.ChangeGraphId;
import uk.gov.gchq.gaffer.federated.simple.operation.GetAllGraphIds;
import uk.gov.gchq.gaffer.federated.simple.operation.GetAllGraphInfo;
import uk.gov.gchq.gaffer.federated.simple.operation.RemoveGraph;
Expand All @@ -36,6 +39,7 @@
import uk.gov.gchq.gaffer.federated.simple.operation.handler.get.GetAllGraphIdsHandler;
import uk.gov.gchq.gaffer.federated.simple.operation.handler.get.GetAllGraphInfoHandler;
import uk.gov.gchq.gaffer.federated.simple.operation.handler.get.GetSchemaHandler;
import uk.gov.gchq.gaffer.federated.simple.operation.handler.misc.ChangeGraphIdHandler;
import uk.gov.gchq.gaffer.federated.simple.operation.handler.misc.RemoveGraphHandler;
import uk.gov.gchq.gaffer.graph.GraphSerialisable;
import uk.gov.gchq.gaffer.operation.Operation;
Expand Down Expand Up @@ -71,6 +75,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static uk.gov.gchq.gaffer.accumulostore.utils.TableUtils.renameTable;
import static uk.gov.gchq.gaffer.cache.CacheServiceLoader.DEFAULT_SERVICE_NAME;
import static uk.gov.gchq.gaffer.federated.simple.FederatedStoreProperties.PROP_DEFAULT_GRAPH_IDS;

Expand All @@ -82,6 +87,7 @@
public class FederatedStore extends Store {
private static final Logger LOGGER = LoggerFactory.getLogger(FederatedStore.class);
private static final String DEFAULT_CACHE_CLASS_FALLBACK = "uk.gov.gchq.gaffer.cache.impl.HashMapCacheService";
private static final String GRAPH_ID_ERROR = "Graph with Graph ID: %s is not available to this federated store";

// Default graph IDs to execute on
private List<String> defaultGraphIds = new LinkedList<>();
Expand All @@ -94,6 +100,7 @@ public class FederatedStore extends Store {
new SimpleEntry<>(AddGraph.class, new AddGraphHandler()),
new SimpleEntry<>(GetAllGraphIds.class, new GetAllGraphIdsHandler()),
new SimpleEntry<>(GetSchema.class, new GetSchemaHandler()),
new SimpleEntry<>(ChangeGraphId.class, new ChangeGraphIdHandler()),
new SimpleEntry<>(GetAllGraphInfo.class, new GetAllGraphInfoHandler()),
new SimpleEntry<>(RemoveGraph.class, new RemoveGraphHandler()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Expand Down Expand Up @@ -128,7 +135,7 @@ public void addGraph(final GraphSerialisable graph) {
public void removeGraph(final String graphId) {
if (!graphCache.contains(graphId)) {
throw new IllegalArgumentException(
"Graph with Graph ID: '" + graphId + "' is not available to this federated store");
String.format(GRAPH_ID_ERROR, graphId));
}
graphCache.deleteFromCache(graphId);
}
Expand All @@ -146,7 +153,7 @@ public GraphSerialisable getGraph(final String graphId) throws CacheOperationExc
GraphSerialisable graph = graphCache.getFromCache(graphId);
if (graph == null) {
throw new IllegalArgumentException(
"Graph with Graph ID: '" + graphId + "' is not available to this federated store");
String.format(GRAPH_ID_ERROR, graphId));
}
return graph;
}
Expand Down Expand Up @@ -186,6 +193,44 @@ public void setDefaultGraphIds(final List<String> defaultGraphIds) {
this.defaultGraphIds = defaultGraphIds;
}

/**
* Change the graph's ID for the specified graph.
*
* @param graphToUpdateId the graph that is to have its ID updated
* @param newGraphId the new graph ID
* @throws OperationException if the operation fails
* @throws StoreException if the accumulo tables cannot be renamed
*
*/
public void changeGraphId(final String graphToUpdateId, final String newGraphId) throws OperationException, StoreException {
cn337131 marked this conversation as resolved.
Show resolved Hide resolved
try {
final GraphSerialisable graphToUpdate = getGraph(graphToUpdateId);

// Remove from cache
removeGraph(graphToUpdateId);

if (graphToUpdate.getStoreProperties().getStoreClass().startsWith(AccumuloStore.class.getPackage().getName())) {
// Update accumulo tables with new graph ID
renameTable((AccumuloProperties) graphToUpdate.getStoreProperties(), graphToUpdateId, newGraphId);
// Update id in the original graph
graphToUpdate.getConfig().setGraphId(newGraphId);
GraphSerialisable updatedGraphSerialisable = new GraphSerialisable.Builder(graphToUpdate)
.config(graphToUpdate.getConfig())
.build();
// Add graph with new id back to cache
addGraph(updatedGraphSerialisable);
} else {
// For other stores just re-add with new graph ID
graphToUpdate.getConfig().setGraphId(newGraphId);
addGraph(graphToUpdate);
}

} catch (final CacheOperationException e) {
// Unknown issue getting graph from cache
throw new GafferRuntimeException(e.getMessage(), e);
}
}

/**
* Gets a merged schema based on the graphs specified.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright 2024 Crown Copyright
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.gchq.gaffer.federated.simple.operation;

import org.apache.commons.lang3.exception.CloneFailedException;

import uk.gov.gchq.gaffer.operation.Operation;
import uk.gov.gchq.koryphe.Since;
import uk.gov.gchq.koryphe.Summary;

import java.util.Map;

@Since("2.4.0")
@Summary("Changes Graph ID")
public class ChangeGraphId implements Operation {

private String graphId;
private String newGraphId;
private Map<String, String> options;

// Getters
/**
* Get the graph ID that will be changed.
*
* @return the graph ID
*/
public String getGraphId() {
return graphId;
}

/**
* Get the new ID for the graph.
*
* @return the new graph ID
*/
public String getNewGraphId() {
return newGraphId;
}

// Setters
/**
* Set the graph ID of the current graph.
*
* @param graphId the graph ID
*/
public void setGraphId(final String graphId) {
this.graphId = graphId;
}

/**
* Set the new graph ID of the current graph.
*
* @param newGraphId the new Graph ID
*/
public void setNewGraphId(final String newGraphId) {
this.newGraphId = newGraphId;
}

@Override
public Map<String, String> getOptions() {
return options;
}

@Override
public void setOptions(final Map<String, String> options) {
this.options = options;
}

@Override
public Operation shallowClone() throws CloneFailedException {
return new ChangeGraphId.Builder()
.graphId(graphId)
.newGraphId(newGraphId)
.options(options)
.build();
}

public static class Builder extends Operation.BaseBuilder<ChangeGraphId, Builder> {
public Builder() {
super(new ChangeGraphId());
}

/**
* Set the current graph ID
*
* @param graphId the graph ID to be changed
* @return the builder
*/
public Builder graphId(final String graphId) {
_getOp().setGraphId(graphId);
return _self();
}

/**
* Set the new graph ID
*
* @param newGraphId the new graph ID
* @return the builder
*/
public Builder newGraphId(final String newGraphId) {
_getOp().setNewGraphId(newGraphId);
return _self();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 Crown Copyright
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.gchq.gaffer.federated.simple.operation.handler.misc;

import uk.gov.gchq.gaffer.federated.simple.FederatedStore;
import uk.gov.gchq.gaffer.federated.simple.operation.ChangeGraphId;
import uk.gov.gchq.gaffer.operation.OperationException;
import uk.gov.gchq.gaffer.store.Context;
import uk.gov.gchq.gaffer.store.Store;
import uk.gov.gchq.gaffer.store.StoreException;
import uk.gov.gchq.gaffer.store.operation.handler.OperationHandler;

public class ChangeGraphIdHandler implements OperationHandler<ChangeGraphId> {

@Override
public Object doOperation(final ChangeGraphId operation, final Context context, final Store store) throws OperationException {
try {
((FederatedStore) store).changeGraphId(operation.getGraphId(), operation.getNewGraphId());
} catch (OperationException | StoreException e) {
throw new OperationException("Error changing graph ID", e);
}

// Nothing to return
return null;
}
}
Loading
Loading