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 3 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,7 +39,9 @@
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.GraphConfig;
import uk.gov.gchq.gaffer.graph.GraphSerialisable;
import uk.gov.gchq.gaffer.operation.Operation;
import uk.gov.gchq.gaffer.operation.OperationChain;
Expand Down Expand Up @@ -71,6 +76,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 +88,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 +101,7 @@
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 +136,7 @@
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 +154,7 @@
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 +194,59 @@
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 accumulo table fails to be renamed
*
*/
public void changeGraphId(final String graphToUpdateId, final String newGraphId) throws OperationException {
cn337131 marked this conversation as resolved.
Show resolved Hide resolved
try {
final GraphSerialisable graphToUpdate = getGraph(graphToUpdateId);
updateTableAndCache(graphToUpdate, newGraphId);
} catch (final CacheOperationException e) {

Check warning on line 209 in store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java

View check run for this annotation

Codecov / codecov/patch

store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java#L209

Added line #L209 was not covered by tests
// Unknown issue getting graph from cache
throw new GafferRuntimeException(e.getMessage(), e);

Check warning on line 211 in store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java

View check run for this annotation

Codecov / codecov/patch

store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java#L211

Added line #L211 was not covered by tests
}
}

/**
* Remove graph from cache, update any Accumulo table names
* and then re-add graph with new id back into the cache.
*
* @param graphToUpdate The graph to have its ID updated
* @param newGraphId the new graph ID
* @throws OperationException if accumulo table fails to be renamed
*
*/
private void updateTableAndCache(final GraphSerialisable graphToUpdate, final String newGraphId) throws OperationException {
final String graphToUpdateId = graphToUpdate.getGraphId();

// Remove from cache
removeGraph(graphToUpdateId);

// Update accumulo tables with new graph ID
if (graphToUpdate.getStoreProperties().getStoreClass().startsWith(AccumuloStore.class.getPackage().getName())) {
cn337131 marked this conversation as resolved.
Show resolved Hide resolved
try {
renameTable((AccumuloProperties) graphToUpdate.getStoreProperties(), graphToUpdateId, newGraphId);
} catch (final StoreException e) {
throw new OperationException("Error trying to rename Accumulo table for graph: " + graphToUpdateId, e);

Check warning on line 235 in store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java

View check run for this annotation

Codecov / codecov/patch

store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/FederatedStore.java#L234-L235

Added lines #L234 - L235 were not covered by tests
cn337131 marked this conversation as resolved.
Show resolved Hide resolved
}
}

GraphSerialisable updatedGraphSerialisable = new GraphSerialisable.Builder(graphToUpdate)
cn337131 marked this conversation as resolved.
Show resolved Hide resolved
.config(new GraphConfig.Builder()
.json(graphToUpdate.getSerialisedConfig())
.graphId(newGraphId)
.build())
.build();

// Add graph with new id back to cache
addGraph(updatedGraphSerialisable);
}

/**
* 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;
}

Check warning on line 81 in store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/operation/ChangeGraphId.java

View check run for this annotation

Codecov / codecov/patch

store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/operation/ChangeGraphId.java#L80-L81

Added lines #L80 - L81 were not covered by tests

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

Check warning on line 89 in store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/operation/ChangeGraphId.java

View check run for this annotation

Codecov / codecov/patch

store-implementation/simple-federated-store/src/main/java/uk/gov/gchq/gaffer/federated/simple/operation/ChangeGraphId.java#L85-L89

Added lines #L85 - L89 were not covered by tests
}

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,34 @@
/*
* 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.operation.handler.OperationHandler;

public class ChangeGraphIdHandler implements OperationHandler<ChangeGraphId> {

@Override
public Object doOperation(final ChangeGraphId operation, final Context context, final Store store) throws OperationException {
((FederatedStore) store).changeGraphId(operation.getGraphId(), operation.getNewGraphId());
// Nothing to return
return null;
}
}
Loading
Loading