use of uk.gov.gchq.gaffer.operation.Operation in project Gaffer by gchq.
the class FederatedStoreUtil method updateOperationForGraph.
/**
* <p>
* Within FederatedStore an {@link Operation} is executed against a
* collection of many graphs.
* </p>
* <p>
* Problem: When an Operation contains View information about an Element
* which is not known by the Graph; It will fail validation when executed.
* </p>
* <p>
* Solution: For each operation, remove all elements from the View that is
* unknown to the graph. This method will also update AddElements operations
* to allow elements to be added to various federated graphs with different
* schemas at the same time without causing validation errors.
* </p>
*
* @param operation current operation
* @param graph current graph
* @param <OP> Operation type
* @return cloned operation with modified View for the given graph.
*/
public static <OP extends Operation> OP updateOperationForGraph(final OP operation, final Graph graph) {
OP resultOp = (OP) operation.shallowClone();
if (nonNull(resultOp.getOptions())) {
resultOp.setOptions(new HashMap<>(resultOp.getOptions()));
}
if (resultOp instanceof Operations) {
final Operations<Operation> operations = (Operations) resultOp;
final List<Operation> resultOperations = new ArrayList<>();
for (final Operation nestedOp : operations.getOperations()) {
final Operation updatedNestedOp = updateOperationForGraph(nestedOp, graph);
if (null == updatedNestedOp) {
resultOp = null;
break;
}
resultOperations.add(updatedNestedOp);
}
operations.updateOperations(resultOperations);
} else if (resultOp instanceof OperationView) {
final View view = ((OperationView) resultOp).getView();
if (null != view && view.hasGroups()) {
final View validView = createValidView(view, graph.getSchema());
if (view != validView) {
// then clone the operation and add the new view.
if (validView.hasGroups()) {
((OperationView) resultOp).setView(validView);
} else if (!graph.hasTrait(StoreTrait.DYNAMIC_SCHEMA)) {
// The view has no groups so the operation would return
// nothing, so we shouldn't execute the operation.
resultOp = null;
}
}
}
} else if (resultOp instanceof AddElements) {
final AddElements addElements = ((AddElements) resultOp);
if (null == addElements.getInput()) {
if (!addElements.isValidate() || !addElements.isSkipInvalidElements()) {
LOGGER.debug("Invalid elements will be skipped when added to {}", graph.getGraphId());
resultOp = (OP) addElements.shallowClone();
((AddElements) resultOp).setValidate(true);
((AddElements) resultOp).setSkipInvalidElements(true);
}
} else {
resultOp = (OP) addElements.shallowClone();
final Set<String> graphGroups = graph.getSchema().getGroups();
final Iterable<? extends Element> filteredInput = Iterables.filter(addElements.getInput(), element -> graphGroups.contains(null != element ? element.getGroup() : null));
((AddElements) resultOp).setInput(filteredInput);
}
}
return resultOp;
}
use of uk.gov.gchq.gaffer.operation.Operation in project Gaffer by gchq.
the class FederatedOperationHandlerTest method shouldNotThrowExceptionBecauseSkipFlagSetTrue.
@Test
public void shouldNotThrowExceptionBecauseSkipFlagSetTrue() throws Exception {
// Given
final String graphID = "1,3";
final Operation op = mock(Operation.class);
when(op.getOption(KEY_OPERATION_OPTIONS_GRAPH_IDS)).thenReturn(graphID);
when(op.getOption(KEY_SKIP_FAILED_FEDERATED_STORE_EXECUTE)).thenReturn(String.valueOf(true));
when(op.getOption(eq(KEY_SKIP_FAILED_FEDERATED_STORE_EXECUTE), any(String.class))).thenReturn(String.valueOf(true));
given(op.shallowClone()).willReturn(op);
Schema unusedSchema = new Schema.Builder().build();
StoreProperties storeProperties = new StoreProperties();
Store mockStore1 = getMockStore(unusedSchema, storeProperties);
given(mockStore1.execute(any(OperationChain.class), eq(context))).willReturn(1);
Store mockStore2 = getMockStore(unusedSchema, storeProperties);
given(mockStore2.execute(any(OperationChain.class), eq(context))).willThrow(new RuntimeException("Test Exception"));
FederatedStore mockStore = mock(FederatedStore.class);
LinkedHashSet<Graph> filteredGraphs = Sets.newLinkedHashSet();
filteredGraphs.add(getGraphWithMockStore(mockStore1));
filteredGraphs.add(getGraphWithMockStore(mockStore2));
when(mockStore.getGraphs(user, graphID, op)).thenReturn(filteredGraphs);
// When
try {
new FederatedOperationHandler().doOperation(op, context, mockStore);
} catch (Exception e) {
fail("Exception should not have been thrown: " + e.getMessage());
}
// Then
final ArgumentCaptor<Context> contextCaptor1 = ArgumentCaptor.forClass(Context.class);
verify(mockStore1, atLeastOnce()).execute(any(OperationChain.class), contextCaptor1.capture());
assertEquals(context.getUser(), contextCaptor1.getValue().getUser());
assertNotEquals(context.getJobId(), contextCaptor1.getValue().getJobId());
final ArgumentCaptor<Context> contextCaptor2 = ArgumentCaptor.forClass(Context.class);
verify(mockStore2, atLeastOnce()).execute(any(OperationChain.class), contextCaptor2.capture());
assertEquals(context.getUser(), contextCaptor2.getValue().getUser());
assertNotEquals(context.getJobId(), contextCaptor2.getValue().getJobId());
}
use of uk.gov.gchq.gaffer.operation.Operation in project Gaffer by gchq.
the class ExamplesServiceTest method shouldSerialiseAndDeserialiseOperation.
private void shouldSerialiseAndDeserialiseOperation(Operation operation) throws IOException {
//Given
// When
byte[] bytes = serialiser.serialise(operation);
final Operation deserialisedOp = serialiser.deserialise(bytes, operation.getClass());
// Then
assertNotNull(deserialisedOp);
}
use of uk.gov.gchq.gaffer.operation.Operation in project Gaffer by gchq.
the class GraphTest method shouldCallAllGraphHooksBeforeOperationExecuted.
@Test
public void shouldCallAllGraphHooksBeforeOperationExecuted() throws OperationException {
// Given
final Operation operation = mock(Operation.class);
final OperationChain opChain = mock(OperationChain.class);
given(opChain.getOperations()).willReturn(Collections.singletonList(operation));
final User user = mock(User.class);
final GraphHook hook1 = mock(GraphHook.class);
final GraphHook hook2 = mock(GraphHook.class);
final Graph graph = new Graph.Builder().storeProperties(StreamUtil.storeProps(getClass())).addSchema(new Schema.Builder().build()).addHook(hook1).addHook(hook2).build();
// When
graph.execute(opChain, user);
// Then
final ArgumentCaptor<OperationChain> captor1 = ArgumentCaptor.forClass(OperationChain.class);
final ArgumentCaptor<OperationChain> captor2 = ArgumentCaptor.forClass(OperationChain.class);
final InOrder inOrder = inOrder(hook1, hook2);
inOrder.verify(hook1).preExecute(captor1.capture(), Mockito.eq(user));
inOrder.verify(hook2).preExecute(captor2.capture(), Mockito.eq(user));
assertSame(captor1.getValue(), captor2.getValue());
final List<Operation> ops = captor1.getValue().getOperations();
assertEquals(1, ops.size());
assertSame(operation, ops.get(0));
}
use of uk.gov.gchq.gaffer.operation.Operation in project Gaffer by gchq.
the class Graph method updateOperationChainView.
private <OUTPUT> void updateOperationChainView(final OperationChain<OUTPUT> operationChain) {
for (final Operation operation : operationChain.getOperations()) {
final View opView;
if (null == operation.getView()) {
opView = view;
} else if (!operation.getView().hasGroups()) {
opView = new View.Builder().merge(view).merge(operation.getView()).build();
} else {
opView = operation.getView();
}
opView.expandGlobalDefinitions();
operation.setView(opView);
}
}
Aggregations