NamedOperationResolver implements GraphHook { @Override public void preExecute(final OperationChain<?> opChain, final Context context) { resolveNamedOperations(opChain, context.getUser()); } NamedOperationResolver();  NamedOperationResolver(final NamedOperationCache cache); @Override void preExecute(final OperationChain<?> opChain, final Context context); @Override T postExecute(final T result, final OperationChain<?> opChain, final Context context); @Override T onFailure(final T result, final OperationChain<?> opChain, final Context context, final Exception e);  }
@Test public void shouldResolveNamedOperation() throws CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); final NamedOperationDetail extendedNamedOperation = mock(NamedOperationDetail.class); final GetAdjacentIds op1 = mock(GetAdjacentIds.class); final GetElements op2 = mock(GetElements.class); final OperationChain namedOperationOpChain = new OperationChain(Arrays.asList(op1, op2)); final Iterable<?> input = mock(CloseableIterable.class); final Map<String, Object> params = null; given(op1.getInput()).willReturn(null); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); given(extendedNamedOperation.getOperationChain(params)).willReturn(namedOperationOpChain); final OperationChain<Object> opChain = new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .input(input) .build()) .build(); resolver.preExecute(opChain, new Context(user)); assertEquals(namedOperationOpChain.getOperations(), opChain.getOperations()); verify(op1).setInput((Iterable) input); verify(op2, never()).setInput((Iterable) input); }
@Test public void shouldResolveNestedNamedOperation() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); final NamedOperationDetail extendedNamedOperation = mock(NamedOperationDetail.class); final GetAdjacentIds op1 = mock(GetAdjacentIds.class); final GetElements op2 = mock(GetElements.class); final OperationChain namedOperationOpChain = new OperationChain(Arrays.asList(op1, op2)); final Iterable<?> input = mock(CloseableIterable.class); final Map<String, Object> params = null; given(op1.getInput()).willReturn(null); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); given(extendedNamedOperation.getOperationChain(params)).willReturn(namedOperationOpChain); final OperationChain<Object> opChain = new OperationChain.Builder() .first(new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .input(input) .build()) .build()) .build(); resolver.preExecute(opChain, new Context(user)); assertEquals(1, opChain.getOperations().size()); final OperationChain<?> nestedOpChain = (OperationChain<?>) opChain.getOperations().get(0); assertEquals(namedOperationOpChain.getOperations(), nestedOpChain.getOperations()); verify(op1).setInput((Iterable) input); verify(op2, never()).setInput((Iterable) input); }
@Test public void shouldExecuteNamedOperationWithoutOverridingInput() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); final NamedOperationDetail extendedNamedOperation = mock(NamedOperationDetail.class); final GetAdjacentIds op1 = mock(GetAdjacentIds.class); final GetElements op2 = mock(GetElements.class); final OperationChain namedOpChain = new OperationChain(Arrays.asList(op1, op2)); final Iterable<?> input = mock(CloseableIterable.class); final Map<String, Object> params = null; given(op1.getInput()).willReturn(mock(CloseableIterable.class)); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); given(extendedNamedOperation.getOperationChain(params)).willReturn(namedOpChain); final OperationChain<Object> opChain = new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .input(input) .build()) .build(); resolver.preExecute(opChain, new Context(user)); assertSame(op1, opChain.getOperations().get(0)); verify(op1, never()).setInput((Iterable) input); assertSame(op2, opChain.getOperations().get(1)); verify(op2, never()).setInput((Iterable) input); }
@Test public void shouldResolveNamedOperationWithParameter() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); Map<String, Object> paramMap = Maps.newHashMap(); paramMap.put("param1", 1L); ParameterDetail param = new ParameterDetail.Builder() .defaultValue(1L) .description("Limit param") .valueClass(Long.class) .build(); Map<String, ParameterDetail> paramDetailMap = Maps.newHashMap(); paramDetailMap.put("param1", param); final NamedOperationDetail extendedNamedOperation = new NamedOperationDetail.Builder() .operationName(opName) .description("standard operation") .operationChain("{ \"operations\": [ { \"class\":\"uk.gov.gchq.gaffer.operation.impl.get.GetAllElements\" }, { \"class\":\"uk.gov.gchq.gaffer.operation.impl.Limit\", \"resultLimit\": \"${param1}\" } ] }") .parameters(paramDetailMap) .build(); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); final OperationChain<Object> opChain = new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .parameters(paramMap) .build()) .build(); resolver.preExecute(opChain, new Context(user)); assertEquals(opChain.getOperations().get(0).getClass(), GetAllElements.class); assertEquals(opChain.getOperations().get(1).getClass(), Limit.class); assertEquals((long) ((Limit) opChain.getOperations().get(1)).getResultLimit(), 1L); }
@Test public void shouldNotExecuteNamedOperationWithParameterOfWrongType() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); Map<String, Object> paramMap = Maps.newHashMap(); paramMap.put("param1", new ArrayList()); ParameterDetail param = new ParameterDetail.Builder() .defaultValue(1L) .description("Limit param") .valueClass(Long.class) .build(); Map<String, ParameterDetail> paramDetailMap = Maps.newHashMap(); paramDetailMap.put("param1", param); final NamedOperationDetail extendedNamedOperation = new NamedOperationDetail.Builder() .operationName(opName) .description("standard operation") .operationChain("{ \"operations\": [ { \"class\":\"uk.gov.gchq.gaffer.operation.impl.get.GetAllElements\" }, { \"class\":\"uk.gov.gchq.gaffer.operation.impl.Limit\", \"resultLimit\": \"${param1}\" } ] }") .parameters(paramDetailMap) .build(); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); assertThrows(IllegalArgumentException.class, () -> resolver.preExecute(new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .parameters(paramMap) .build()) .build(), new Context(user))); }
@Test public void shouldNotExecuteNamedOperationWithWrongParameterName() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); Map<String, Object> paramMap = Maps.newHashMap(); paramMap.put("param2", 1L); ParameterDetail param = new ParameterDetail.Builder() .defaultValue(1L) .description("Limit param") .valueClass(Long.class) .build(); Map<String, ParameterDetail> paramDetailMap = Maps.newHashMap(); paramDetailMap.put("param1", param); final NamedOperationDetail extendedNamedOperation = new NamedOperationDetail.Builder() .operationName(opName) .description("standard operation") .operationChain("{ \"operations\": [ { \"class\":\"uk.gov.gchq.gaffer.operation.impl.get.GetAllElements\" }, { \"class\":\"uk.gov.gchq.gaffer.operation.impl.Limit\", \"resultLimit\": \"${param1}\" } ] }") .parameters(paramDetailMap) .build(); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); assertThrows(IllegalArgumentException.class, () -> resolver.preExecute(new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .parameters(paramMap) .build()) .build(), new Context(user))); }
@Test public void shouldNotExecuteNamedOperationWithMissingRequiredArg() throws OperationException, CacheOperationFailedException { final String opName = "opName"; final NamedOperationCache cache = mock(NamedOperationCache.class); final NamedOperationResolver resolver = new NamedOperationResolver(cache); final User user = mock(User.class); Map<String, Object> paramMap = Maps.newHashMap(); ParameterDetail param = new ParameterDetail.Builder() .description("Limit param") .valueClass(Long.class) .required(true) .build(); Map<String, ParameterDetail> paramDetailMap = Maps.newHashMap(); paramDetailMap.put("param1", param); final NamedOperationDetail extendedNamedOperation = new NamedOperationDetail.Builder() .operationName(opName) .description("standard operation") .operationChain("{ \"operations\": [ { \"class\":\"uk.gov.gchq.gaffer.operation.impl.get.GetAllElements\" }, { \"class\":\"uk.gov.gchq.gaffer.operation.impl.Limit\", \"resultLimit\": \"${param1}\" } ] }") .parameters(paramDetailMap) .build(); given(cache.getNamedOperation(opName, user)).willReturn(extendedNamedOperation); assertThrows(IllegalArgumentException.class, () -> resolver.preExecute(new OperationChain.Builder() .first(new NamedOperation.Builder<>() .name(opName) .parameters(paramMap) .build()) .build(), new Context(user))); }