From 9002d7e7435feaf614c337b0d939d7f32db9e245 Mon Sep 17 00:00:00 2001 From: GCHQDev404 <45399082+GCHQDev404@users.noreply.github.com> Date: Tue, 21 Feb 2023 14:09:05 +0000 Subject: [PATCH] gh-2881: Problems with getOriginalSchema in Federated and Proxy Stores (#2884) * gh-2881-initial attempt * gh-2881 ProxyStore GetOriginalSchema. * gh-2881 FederatedStore getSchema * Checkstyle * PMD fix * Simplifying FederatedGraphStorage to pass through operations and replace getSchema method with operation * Spotless apply * Fix for op in wrong place * Rename to use compactSchema - as used by the Operation Match current behaviour by not getting this by default * Add more details to Javadoc * CompactSchema rename for Proxy methods * Add Schema tests to ProxyStoreIT * Remove deprecated methods, replace with Operation * Migrate tests from GraphStorageTest to StoreSchemaTest * Code quality fixes and Copyright * gh-2881 fetch schema inline builder change. --------- Co-authored-by: GCHQDev404 Co-authored-by: t92549 <80890692+t92549@users.noreply.github.com> Co-authored-by: GCHQDeveloper314 <94527357+GCHQDeveloper314@users.noreply.github.com> --- .../federatedstore/FederatedGraphStorage.java | 36 ---- .../gaffer/federatedstore/FederatedStore.java | 48 ++++-- .../FederatedOperationChainValidator.java | 16 +- .../handler/FederatedDelegateToHandler.java | 4 +- .../util/FederatedStoreUtil.java | 5 - .../FederatedGraphStorageTest.java | 82 +-------- .../FederatedStoreSchemaTest.java | 163 +++++++++++++++++- .../federatedstore/FederatedStoreTest.java | 16 +- .../FederatedOperationChainValidatorTest.java | 13 +- ...deratedDelegateToAggregateHandlerTest.java | 4 +- .../FederatedDelegateToFilterHandlerTest.java | 6 +- .../FederatedDelegateToTransHandlerTest.java | 6 +- ...ederatedDelegateToValidateHandlerTest.java | 4 +- .../gchq/gaffer/proxystore/ProxyStore.java | 42 ++++- .../integration/ProxyStoreBasicIT.java | 50 +++++- 15 files changed, 307 insertions(+), 188 deletions(-) diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java index 033b3b7c55f..1b6aa96e169 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorage.java @@ -27,17 +27,10 @@ import uk.gov.gchq.gaffer.commonutil.JsonUtil; import uk.gov.gchq.gaffer.commonutil.exception.OverwritingException; import uk.gov.gchq.gaffer.commonutil.pair.Pair; -import uk.gov.gchq.gaffer.core.exception.GafferRuntimeException; -import uk.gov.gchq.gaffer.data.elementdefinition.exception.SchemaException; import uk.gov.gchq.gaffer.federatedstore.exception.StorageException; -import uk.gov.gchq.gaffer.federatedstore.operation.FederatedOperation; import uk.gov.gchq.gaffer.graph.GraphConfig; import uk.gov.gchq.gaffer.graph.GraphSerialisable; -import uk.gov.gchq.gaffer.store.Context; import uk.gov.gchq.gaffer.store.library.GraphLibrary; -import uk.gov.gchq.gaffer.store.operation.GetSchema; -import uk.gov.gchq.gaffer.store.schema.Schema; -import uk.gov.gchq.gaffer.store.schema.Schema.Builder; import uk.gov.gchq.gaffer.user.User; import java.util.ArrayList; @@ -234,35 +227,6 @@ public List get(final User user, final List graphIds, return Collections.unmodifiableList(rtn); } - @Deprecated - public Schema getSchema(final FederatedOperation operation, final Context context) { - if (null == context || null == context.getUser()) { - // no user then return an empty schema - return new Schema(); - } - final List graphIds = isNull(operation) ? null : operation.getGraphIds(); - - final Stream graphs = getStream(context.getUser(), graphIds); - final Builder schemaBuilder = new Builder(); - try { - if (nonNull(operation) && operation.hasPayloadOperation() && operation.payloadInstanceOf(GetSchema.class) && ((GetSchema) operation.getPayloadOperation()).isCompact()) { - graphs.forEach(gs -> { - try { - schemaBuilder.merge(gs.getGraph().execute((GetSchema) operation.getPayloadOperation(), context)); - } catch (final Exception e) { - throw new GafferRuntimeException("Unable to fetch schema from graph " + gs.getGraphId(), e); - } - }); - } else { - graphs.forEach(g -> schemaBuilder.merge(g.getSchema(graphLibrary))); - } - } catch (final SchemaException e) { - final List resultGraphIds = getStream(context.getUser(), graphIds).map(GraphSerialisable::getGraphId).collect(Collectors.toList()); - throw new SchemaException("Unable to merge the schemas for all of your federated graphs: " + resultGraphIds + ". You can limit which graphs to query for using the FederatedOperation.graphIds option.", e); - } - return schemaBuilder.build(); - } - private void validateAllGivenGraphIdsAreVisibleForUser(final User user, final Collection graphIds, final String adminAuth) { if (null != graphIds) { final Collection visibleIds = getAllIds(user, adminAuth); diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java index c880c5ad4c8..70aa2e2d13b 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/FederatedStore.java @@ -58,6 +58,7 @@ import uk.gov.gchq.gaffer.federatedstore.util.MergeSchema; import uk.gov.gchq.gaffer.graph.GraphSerialisable; import uk.gov.gchq.gaffer.operation.Operation; +import uk.gov.gchq.gaffer.operation.OperationException; import uk.gov.gchq.gaffer.operation.impl.Validate; import uk.gov.gchq.gaffer.operation.impl.add.AddElements; import uk.gov.gchq.gaffer.operation.impl.function.Aggregate; @@ -108,7 +109,6 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.STORE_CONFIGURED_GRAPHIDS; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreProperties.STORE_CONFIGURED_MERGE_FUNCTIONS; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getCleanStrings; -import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedWrappedSchema; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.loadStoreConfiguredGraphIdsListFrom; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.loadStoreConfiguredMergeFunctionMapFrom; @@ -324,34 +324,50 @@ public List getAllGraphIds(final User user, final boolean userRequesting } /** - * Get {@link Schema} for this FederatedStore + * This method exists for compatibility only. It will + * always return a blank {@link Schema}. Either use the + * {@link FederatedStore#getSchema} method and supply a + * {@link Context}, or ideally use the {@link GetSchema} + * operation instead. * - * @return schema + * @return {@link Schema} blank schema */ @Override public Schema getSchema() { - return getSchema((Context) null); + return getSchema(new Context(), true); } /** - * Get {@link Schema} for this FederatedStore + * This method exists for compatibility only. It will + * always return a blank {@link Schema}. Either use the + * {@link FederatedStore#getSchema} method and supply a + * {@link Context}, or ideally use the {@link GetSchema} + * operation instead. * - * @param context context with User. - * @return schema + * @return {@link Schema} blank schema */ - public Schema getSchema(final Context context) { - return getSchema(getFederatedWrappedSchema(), context); + @Override + public Schema getOriginalSchema() { + return getSchema(new Context(), false); } /** - * Get {@link Schema} for this FederatedStore + * Get {@link Schema} for this FederatedStore. + *

+ * This will return a merged schema of the original schemas + * or the optimised compact schemas of the stores inside + * this FederatedStore. * - * @param operation operation with graphIds. - * @param context context with User. + * @param context context with valid User + * @param getCompactSchema if true, gets the optimised compact schemas * @return schema */ - public Schema getSchema(final FederatedOperation operation, final Context context) { - return graphStorage.getSchema(operation, context); + public Schema getSchema(final Context context, final boolean getCompactSchema) { + try { + return execute(new GetSchema.Builder().compact(getCompactSchema).build(), context); + } catch (final OperationException e) { + throw new GafferRuntimeException("Unable to execute GetSchema Operation", e); + } } /** @@ -589,8 +605,8 @@ private List getDefaultGraphs(final User user, final IFederat final List graphIds = new ArrayList<>(storeConfiguredGraphIds); final List federatedStoreSystemUser = getAllGraphIds(new User.Builder() - .userId(FEDERATED_STORE_SYSTEM_USER) - .opAuths(this.getProperties().getAdminAuth()).build(), + .userId(FEDERATED_STORE_SYSTEM_USER) + .opAuths(this.getProperties().getAdminAuth()).build(), true); graphIds.retainAll(federatedStoreSystemUser); diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidator.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidator.java index d7f8b9c8514..c1bc7dfb5bf 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidator.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,16 @@ package uk.gov.gchq.gaffer.federatedstore.operation; +import uk.gov.gchq.gaffer.core.exception.GafferRuntimeException; import uk.gov.gchq.gaffer.data.elementdefinition.view.View; import uk.gov.gchq.gaffer.federatedstore.FederatedStore; import uk.gov.gchq.gaffer.graph.GraphSerialisable; import uk.gov.gchq.gaffer.operation.Operation; +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.StoreTrait; +import uk.gov.gchq.gaffer.store.operation.GetSchema; import uk.gov.gchq.gaffer.store.operation.OperationChainValidator; import uk.gov.gchq.gaffer.store.schema.Schema; import uk.gov.gchq.gaffer.store.schema.ViewValidator; @@ -35,7 +38,6 @@ import java.util.stream.Collectors; import static java.util.Objects.nonNull; -import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedWrappedSchema; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.shallowCloneWithDeepOptions; /** @@ -51,9 +53,13 @@ public FederatedOperationChainValidator(final ViewValidator viewValidator) { @Override protected Schema getSchema(final Operation op, final User user, final Store store) { - return (op instanceof FederatedOperation) - ? ((FederatedStore) store).getSchema(getFederatedWrappedSchema().graphIds(((FederatedOperation) op).getGraphIds()), new Context(user)) - : ((FederatedStore) store).getSchema(getFederatedWrappedSchema(), new Context(user)); + try { + return (op instanceof FederatedOperation) + ? store.execute(new FederatedOperation.Builder().op(new GetSchema()).graphIds(((FederatedOperation) op).getGraphIds()).build(), new Context(user)) + : store.execute(new GetSchema(), new Context(user)); + } catch (final OperationException e) { + throw new GafferRuntimeException("Unable to execute GetSchema Operation", e); + } } @Override diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedDelegateToHandler.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedDelegateToHandler.java index 7df3243ad59..fc55f365b30 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedDelegateToHandler.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/FederatedDelegateToHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Crown Copyright + * Copyright 2022-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public Iterable doOperation(final InputOutput) ((OperationWithSchemaHandler) handler).doOperation(operation, ((FederatedStore) store).getSchema(context)); + return (Iterable) ((OperationWithSchemaHandler) handler).doOperation(operation, ((FederatedStore) store).getSchema(context, true)); } else { return handler.doOperation(operation, context, store); } diff --git a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/util/FederatedStoreUtil.java b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/util/FederatedStoreUtil.java index 5732b983b87..b36bb9101d9 100644 --- a/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/util/FederatedStoreUtil.java +++ b/store-implementation/federated-store/src/main/java/uk/gov/gchq/gaffer/federatedstore/util/FederatedStoreUtil.java @@ -280,11 +280,6 @@ public static String getDeprecatedGraphIds(final Operation operation) throws Gaf return deprecatedGraphIds; } - @Deprecated - public static FederatedOperation> getFederatedWrappedSchema() { - return new FederatedOperation.Builder().>op(new GetSchema()).build(); - } - /** * Return a clone of the given operations with a deep clone of options. *

diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java index af1054900d1..e4499db2ab9 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedGraphStorageTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,6 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static uk.gov.gchq.gaffer.federatedstore.FederatedGraphStorage.GRAPH_IDS_NOT_VISIBLE; @@ -60,9 +59,6 @@ import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ENTITIES; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.GRAPH_ID_ACCUMULO; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.STRING; -import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextAuthUser; -import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextBlankUser; -import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.contextTestUser; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.loadAccumuloStoreProperties; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.resetForFederatedTests; import static uk.gov.gchq.gaffer.store.TestTypes.DIRECTED_EITHER; @@ -295,82 +291,6 @@ public void shouldNotGetGraphForBlankUserWithIncorrectId() throws Exception { .withMessage(String.format(GRAPH_IDS_NOT_VISIBLE, singleton(X))); } - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldChangeSchemaWhenAddingGraphB() throws Exception { - //given - graphStorage.put(graphSerialisableA, auth1Access); - final Schema schemaA = graphStorage.getSchema(null, contextTestUser()); - assertEquals(1, schemaA.getTypes().size()); - assertEquals(String.class, schemaA.getType(STRING + 1).getClazz()); - assertEquals(getEntityDefinition(1), schemaA.getElement(ENTITIES + 1)); - graphStorage.put(graphSerialisableB, auth1Access); - final Schema schemaAB = graphStorage.getSchema(null, contextTestUser()); - assertNotEquals(schemaA, schemaAB); - assertEquals(2, schemaAB.getTypes().size()); - assertEquals(String.class, schemaAB.getType(STRING + 1).getClazz()); - assertEquals(String.class, schemaAB.getType(STRING + 2).getClazz()); - assertEquals(getEntityDefinition(1), schemaAB.getElement(ENTITIES + 1)); - assertEquals(getEntityDefinition(2), schemaAB.getElement(ENTITIES + 2)); - } - - - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldGetSchemaForOwningUser() throws Exception { - graphStorage.put(graphSerialisableA, auth1Access); - graphStorage.put(graphSerialisableB, new FederatedAccess(singleton(X), X)); - final Schema schema = graphStorage.getSchema(null, contextTestUser()); - assertNotEquals(2, schema.getTypes().size(), "Revealing hidden schema"); - assertEquals(1, schema.getTypes().size()); - assertEquals(String.class, schema.getType(STRING + 1).getClazz()); - assertEquals(getEntityDefinition(1), schema.getElement(ENTITIES + 1)); - } - - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldNotGetSchemaForOwningUserWhenBlockingReadAccessPredicateConfigured() throws Exception { - graphStorage.put(graphSerialisableA, blockingReadAccess); - graphStorage.put(graphSerialisableB, new FederatedAccess(singleton(X), X)); - final Schema schema = graphStorage.getSchema(null, contextTestUser()); - assertNotEquals(2, schema.getTypes().size(), "Revealing hidden schema"); - assertEquals(0, schema.getTypes().size(), "Revealing hidden schema"); - } - - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldGetSchemaForAuthUser() throws Exception { - graphStorage.put(graphSerialisableA, auth1Access); - graphStorage.put(graphSerialisableB, new FederatedAccess(singleton(X), X)); - final Schema schema = graphStorage.getSchema(null, contextAuthUser()); - assertNotEquals(2, schema.getTypes().size(), "Revealing hidden schema"); - assertEquals(1, schema.getTypes().size()); - assertEquals(String.class, schema.getType(STRING + 1).getClazz()); - assertEquals(getEntityDefinition(1), schema.getElement(ENTITIES + 1)); - } - - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldNotGetSchemaForBlankUser() throws Exception { - graphStorage.put(graphSerialisableA, auth1Access); - graphStorage.put(graphSerialisableB, new FederatedAccess(singleton(X), X)); - final Schema schema = graphStorage.getSchema(null, contextBlankUser()); - assertNotEquals(2, schema.getTypes().size(), "Revealing hidden schema"); - assertEquals(0, schema.getTypes().size(), "Revealing hidden schema"); - } - - @Test - @Deprecated // TODO FS move to FedSchema Tests, when getSchema is deleted - public void shouldGetSchemaForBlankUserWhenPermissiveReadAccessPredicateConfigured() throws Exception { - graphStorage.put(graphSerialisableA, permissiveReadAccess); - graphStorage.put(graphSerialisableB, new FederatedAccess(singleton(X), X)); - final Schema schema = graphStorage.getSchema(null, contextBlankUser()); - assertNotEquals(2, schema.getTypes().size(), "Revealing hidden schema"); - assertEquals(1, schema.getTypes().size()); - assertEquals(String.class, schema.getType(STRING + 1).getClazz()); - assertEquals(getEntityDefinition(1), schema.getElement(ENTITIES + 1)); - } - @Test public void shouldRemoveForOwningUser() throws Exception { //given diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java index 6eb7904ed9f..38957ba4c42 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreSchemaTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import uk.gov.gchq.gaffer.access.predicate.AccessPredicate; +import uk.gov.gchq.gaffer.access.predicate.NoAccessPredicate; +import uk.gov.gchq.gaffer.access.predicate.UnrestrictedAccessPredicate; import uk.gov.gchq.gaffer.accumulostore.AccumuloProperties; import uk.gov.gchq.gaffer.data.element.Edge; import uk.gov.gchq.gaffer.data.element.Element; @@ -47,8 +50,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.Set; import java.util.stream.Collectors; +import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static uk.gov.gchq.gaffer.federatedstore.FederatedStoreTestUtil.ACCUMULO_STORE_SINGLE_USE_PROPERTIES; @@ -71,6 +76,9 @@ import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getDefaultMergeFunction; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedOperation; import static uk.gov.gchq.gaffer.store.TestTypes.DIRECTED_EITHER; +import static uk.gov.gchq.gaffer.user.StoreUser.AUTH_1; +import static uk.gov.gchq.gaffer.user.StoreUser.authUser; +import static uk.gov.gchq.gaffer.user.StoreUser.blankUser; import static uk.gov.gchq.gaffer.user.StoreUser.testUser; public class FederatedStoreSchemaTest { @@ -263,6 +271,133 @@ public void shouldBeAbleToGetSchemaWithOverlappingSchemas() throws OperationExce .isTrue(); } + @Test + public void shouldGetSchemaWithOperationAndMethodWithContext() throws OperationException { + // Given + addGraphWith(GRAPH_ID_A, STRING_TYPE, PROPERTY_1); + + // When + final Schema schemaFromOperation = federatedStore.execute(new GetSchema.Builder().build(), testContext); + final Schema schemaFromStore = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaFromOperation).isEqualTo(schemaFromStore); + } + + @Test + public void shouldGetBlankSchemaWhenUsingDefaultMethod() throws OperationException { + // Given + addGraphWith(GRAPH_ID_A, STRING_TYPE, PROPERTY_1); + + // When + final Schema schemaFromStoreMethod = federatedStore.getOriginalSchema(); // No Context, results in blank schema returned + + // Then + assertThat(schemaFromStoreMethod).isEqualTo(new Schema()); + } + + @Test + public void shouldGetSchemaWhenUsingDefaultMethodWhenPermissiveReadAccessPredicateConfigured() throws OperationException { + // Given + addGraphWithContextAndAccess(GRAPH_ID_A, STRING_TYPE, GROUP_BASIC_EDGE, testContext, new UnrestrictedAccessPredicate(), PROPERTY_1); + + // When + final Schema schemaFromStoreMethod = federatedStore.getOriginalSchema(); + + // Then + assertThat(schemaFromStoreMethod.getEdge(GROUP_BASIC_EDGE).getProperties()).contains(PROPERTY_1); + } + + @Test + public void shouldChangeSchemaWhenAddingGraphB() throws OperationException { + // Given + addGraphWith(GRAPH_ID_A, STRING_TYPE, PROPERTY_1); + + // When + final Schema schemaA = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaA.getTypes().size()).isEqualTo(2); + assertThat(schemaA.getType(STRING).getClazz()).isEqualTo(String.class); + assertThat(schemaA.getEdge(GROUP_BASIC_EDGE).getProperties().size()).isEqualTo(1); + + // Given + addGraphWith(GRAPH_ID_B, STRING_REQUIRED_TYPE, PROPERTY_2); + + // When + final Schema schemaAB = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaAB).isNotEqualTo(schemaA); + assertThat(schemaAB.getEdge(GROUP_BASIC_EDGE).getProperties()).contains(PROPERTY_2); + } + + @Test + public void shouldGetSchemaForOwningUser() throws OperationException { + // Given + addGraphWith(GRAPH_ID_A, STRING_REQUIRED_TYPE, PROPERTY_1); + addGraphWithContextAndAuths(GRAPH_ID_B, STRING_TYPE, "hidden" + GROUP_BASIC_EDGE, singleton(AUTH_1), new Context(authUser()), PROPERTY_2); + + // When + final Schema schemaFromOwningUser = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaFromOwningUser.getEdge("hidden" + GROUP_BASIC_EDGE)).withFailMessage("Revealing hidden schema").isNull(); + assertThat(schemaFromOwningUser.getEdge(GROUP_BASIC_EDGE).getProperties()).contains(PROPERTY_1); + } + + @Test + public void shouldNotGetSchemaForOwningUserWhenBlockingReadAccessPredicateConfigured() throws OperationException { + // Given + addGraphWithContextAndAccess(GRAPH_ID_A, STRING_TYPE, GROUP_BASIC_EDGE, testContext, new NoAccessPredicate(), PROPERTY_1); + + // When + final Schema schemaFromOwningUser = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaFromOwningUser).withFailMessage("Revealing blocked schema, should be empty").isEqualTo(new Schema()); + } + + @Test + public void shouldGetSchemaForAuthUser() throws OperationException { + // Given + final User authUser = new User.Builder().userId("authUser2").opAuths(AUTH_1).build(); + addGraphWithContextAndAuths(GRAPH_ID_B, STRING_TYPE, GROUP_BASIC_EDGE, singleton(AUTH_1), new Context(authUser()), PROPERTY_1); + + // When + final Schema schemaFromAuthUser = federatedStore.getSchema(new Context(authUser), false); + final Schema schemaFromTestUser = federatedStore.getSchema(testContext, false); + + // Then + assertThat(schemaFromTestUser.getEdge("hidden" + GROUP_BASIC_EDGE)).withFailMessage("Revealing hidden schema").isNull(); + assertThat(schemaFromTestUser).withFailMessage("Revealing hidden schema, should be empty").isEqualTo(new Schema()); + assertThat(schemaFromAuthUser.getEdge(GROUP_BASIC_EDGE).getProperties()).contains(PROPERTY_1); + } + + @Test + public void shouldNotGetSchemaForBlankUser() throws OperationException { + // Given + addGraphWith(GRAPH_ID_A, STRING_REQUIRED_TYPE, PROPERTY_1); + + // When + final Schema schemaFromBlankUser = federatedStore.getSchema(new Context(blankUser()), false); + + // Then + assertThat(schemaFromBlankUser).withFailMessage("Revealing schema to blank user, should be empty").isEqualTo(new Schema()); + } + + @Test + public void shouldGetSchemaForBlankUserWhenPermissiveReadAccessPredicateConfigured() throws OperationException { + // Given + addGraphWithContextAndAccess(GRAPH_ID_A, STRING_TYPE, GROUP_BASIC_EDGE, testContext, new UnrestrictedAccessPredicate(), PROPERTY_1); + + // When + final Schema schemaFromBlankUser = federatedStore.getSchema(new Context(blankUser()), false); + + // Then + assertThat(schemaFromBlankUser.getEdge(GROUP_BASIC_EDGE).getProperties()).contains(PROPERTY_1); + } + @Test public void shouldValidateCorrectlyWithOverlappingSchemasUsingDefaultMergeFunction() throws OperationException { // Given @@ -788,11 +923,11 @@ private void addOverlappingPropertiesGraphs(final Schema stringSchema) throws Op addGraphWith(GRAPH_ID_B, stringSchema, PROPERTY_1, PROPERTY_2); } - private void addGraphWith(final String graphId, final Schema stringType, final String... property) throws OperationException { - federatedStore.execute(new AddGraph.Builder() + private AddGraph.Builder getAddGraphBuilder(final String graphId, final Schema stringType, final String edgeGroup, final String... property) { + return new AddGraph.Builder() .graphId(graphId) .schema(new Schema.Builder() - .edge(GROUP_BASIC_EDGE, new SchemaEdgeDefinition.Builder() + .edge(edgeGroup, new SchemaEdgeDefinition.Builder() .source(STRING) .destination(STRING) .directed(DIRECTED_EITHER) @@ -801,10 +936,28 @@ private void addGraphWith(final String graphId, final Schema stringType, final S .type(DIRECTED_EITHER, Boolean.class) .merge(stringType) .build()) - .storeProperties(STORE_PROPERTIES.clone()) + .storeProperties(STORE_PROPERTIES.clone()); + } + + private void addGraphWith(final String graphId, final Schema stringType, final String... property) throws OperationException { + federatedStore.execute(getAddGraphBuilder(graphId, stringType, GROUP_BASIC_EDGE, property) .build(), testContext); } + private void addGraphWithContextAndAuths(final String graphId, final Schema stringType, final String edgeGroup, Set graphAuths, + Context context, final String... property) throws OperationException { + federatedStore.execute(getAddGraphBuilder(graphId, stringType, edgeGroup, property) + .graphAuths(graphAuths.toArray(new String[0])) + .build(), context); + } + + private void addGraphWithContextAndAccess(final String graphId, final Schema stringType, final String edgeGroup, Context context, + AccessPredicate read, final String... property) throws OperationException { + federatedStore.execute(getAddGraphBuilder(graphId, stringType, edgeGroup, property) + .readAccessPredicate(read) + .build(), context); + } + private void addEdgeBasicWith(final String destination, final Integer... propertyValues) throws OperationException { federatedStore.execute(new AddElements.Builder() .input(edgeBasicWith(destination, propertyValues)) diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java index 5da3e90a41a..5873d7d286e 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/FederatedStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -323,9 +323,9 @@ public void shouldAlwaysReturnSupportedTraits() throws Exception { public void shouldUpdateSchemaWhenNewGraphIsAdded() throws Exception { // Given addGraphWithPaths(ACC_ID_1, propertiesAlt, blankUserContext, SCHEMA_ENTITY_BASIC_JSON); - final Schema before = store.getSchema(new Context(blankUser)); + final Schema before = store.getSchema(new Context(blankUser), true); addGraphWithPaths(ACC_ID_2, propertiesAlt, blankUserContext, SCHEMA_EDGE_BASIC_JSON); - final Schema after = store.getSchema(new Context(blankUser)); + final Schema after = store.getSchema(new Context(blankUser), true); // Then assertThat(before).isNotEqualTo(after); } @@ -335,15 +335,15 @@ public void shouldUpdateSchemaWhenNewGraphIsAdded() throws Exception { public void shouldUpdateSchemaWhenNewGraphIsRemoved() throws Exception { // Given addGraphWithPaths(ACC_ID_1, propertiesAlt, blankUserContext, SCHEMA_ENTITY_BASIC_JSON); - final Schema was = store.getSchema(new Context(blankUser)); + final Schema was = store.getSchema(new Context(blankUser), true); addGraphWithPaths(ACC_ID_2, propertiesAlt, blankUserContext, SCHEMA_EDGE_BASIC_JSON); - final Schema before = store.getSchema(new Context(blankUser)); + final Schema before = store.getSchema(new Context(blankUser), true); // When store.remove(ACC_ID_2, blankUser); - final Schema after = store.getSchema(new Context(blankUser)); + final Schema after = store.getSchema(new Context(blankUser), true); assertThat(before).isNotEqualTo(after); assertThat(was).isEqualTo(after); } @@ -1160,8 +1160,8 @@ private Set getElements(final Context context) throws OperationExceptio final Iterable elements = store .execute(new GetAllElements.Builder() .view(new View.Builder() - .edges(store.getSchema(context).getEdgeGroups()) //here - .entities(store.getSchema(context).getEntityGroups()) //here 59 -> 58 + .edges(store.getSchema(context, true).getEdgeGroups()) //here + .entities(store.getSchema(context, true).getEntityGroups()) //here 59 -> 58 .build()) .build(), context); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidatorTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidatorTest.java index 13117e8053e..fb5aa9793bd 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidatorTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/FederatedOperationChainValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 Crown Copyright + * Copyright 2017-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import uk.gov.gchq.gaffer.operation.OperationException; import uk.gov.gchq.gaffer.operation.impl.get.GetAllElements; import uk.gov.gchq.gaffer.store.Context; +import uk.gov.gchq.gaffer.store.operation.GetSchema; import uk.gov.gchq.gaffer.store.schema.Schema; import uk.gov.gchq.gaffer.store.schema.ViewValidator; import uk.gov.gchq.gaffer.user.User; @@ -37,16 +38,14 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedOperation; -import static uk.gov.gchq.gaffer.federatedstore.util.FederatedStoreUtil.getFederatedWrappedSchema; public class FederatedOperationChainValidatorTest { @Test - public void shouldGetFederatedSchema() { + public void shouldGetFederatedSchema() throws OperationException { // Given final ViewValidator viewValidator = mock(FederatedViewValidator.class); final FederatedOperationChainValidator validator = new FederatedOperationChainValidator(viewValidator); @@ -54,18 +53,18 @@ public void shouldGetFederatedSchema() { final User user = mock(User.class); final Operation op = mock(Operation.class); final Schema schema = mock(Schema.class); - given(store.getSchema(eq(getFederatedWrappedSchema()), any(Context.class))).willReturn(schema); + given(store.execute(any(GetSchema.class), any(Context.class))).willReturn(schema); // When final Schema actualSchema = validator.getSchema(op, user, store); - verify(store).getSchema(eq(getFederatedWrappedSchema()), any(Context.class)); + verify(store).execute(any(GetSchema.class), any(Context.class)); // Then assertEquals(schema, actualSchema); } @Test - public void shouldNotErrorWithInvalidViewFromMissingGraph() throws OperationException { + public void shouldNotErrorWithInvalidViewFromMissingGraph() { //given String missingGraph = "missingGraph"; final Graph graph = new Graph.Builder() diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToAggregateHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToAggregateHandlerTest.java index 598d6723550..41e38f11811 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToAggregateHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToAggregateHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,7 @@ public void shouldDelegateToHandler(@Mock final FederatedStore store, @Mock final Schema schema) throws OperationException { // Given - given(store.getSchema(context)).willReturn(schema); + given(store.getSchema(context, true)).willReturn(schema); given(handler.doOperation(op, schema)).willReturn((Iterable) expectedResult); final FederatedDelegateToHandler federatedHandler = new FederatedDelegateToHandler(handler); diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToFilterHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToFilterHandlerTest.java index f456176e8ab..41a50f0d6a5 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToFilterHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToFilterHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public void shouldDelegateToFilterHandler() throws OperationException { final Iterable expectedResult = mock(Iterable.class); final Schema schema = mock(Schema.class); - given(store.getSchema(context)).willReturn(schema); + given(store.getSchema(context, true)).willReturn(schema); given(handler.doOperation(op, schema)).willReturn(expectedResult); final FederatedDelegateToHandler federatedHandler = new FederatedDelegateToHandler(handler); @@ -53,6 +53,6 @@ public void shouldDelegateToFilterHandler() throws OperationException { // Then assertSame(expectedResult, result); verify(handler).doOperation(op, schema); - verify(store).getSchema(context); + verify(store).getSchema(context, true); } } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToTransHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToTransHandlerTest.java index a9a5eaf3f01..3f8e2a2b07c 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToTransHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToTransHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public void shouldDelegateToTransformHandler() throws OperationException { final Iterable expectedResult = mock(Iterable.class); final Schema schema = mock(Schema.class); - given(store.getSchema(context)).willReturn(schema); + given(store.getSchema(context, true)).willReturn(schema); given(handler.doOperation(op, schema)).willReturn(expectedResult); final FederatedDelegateToHandler federatedHandler = new FederatedDelegateToHandler(handler); @@ -53,6 +53,6 @@ public void shouldDelegateToTransformHandler() throws OperationException { // Then assertSame(expectedResult, result); verify(handler).doOperation(op, schema); - verify(store).getSchema(context); + verify(store).getSchema(context, true); } } diff --git a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToValidateHandlerTest.java b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToValidateHandlerTest.java index 22657ab93b7..0cc24253530 100644 --- a/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToValidateHandlerTest.java +++ b/store-implementation/federated-store/src/test/java/uk/gov/gchq/gaffer/federatedstore/operation/handler/impl/FederatedDelegateToValidateHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 Crown Copyright + * Copyright 2016-2023 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public void shouldDelegateToValidateHandler() throws OperationException { final Iterable expectedResult = mock(Iterable.class); final Schema schema = mock(Schema.class); - given(store.getSchema(context)).willReturn(schema); + given(store.getSchema(context, true)).willReturn(schema); given(handler.doOperation(op, schema)).willReturn(expectedResult); final FederatedDelegateToHandler federatedHandler = new FederatedDelegateToHandler(handler); diff --git a/store-implementation/proxy-store/src/main/java/uk/gov/gchq/gaffer/proxystore/ProxyStore.java b/store-implementation/proxy-store/src/main/java/uk/gov/gchq/gaffer/proxystore/ProxyStore.java index 81d27b2b2c3..61026697b9f 100644 --- a/store-implementation/proxy-store/src/main/java/uk/gov/gchq/gaffer/proxystore/ProxyStore.java +++ b/store-implementation/proxy-store/src/main/java/uk/gov/gchq/gaffer/proxystore/ProxyStore.java @@ -54,6 +54,7 @@ import uk.gov.gchq.gaffer.store.StoreProperties; import uk.gov.gchq.gaffer.store.StoreTrait; import uk.gov.gchq.gaffer.store.TypeReferenceStoreImpl; +import uk.gov.gchq.gaffer.store.operation.GetSchema; import uk.gov.gchq.gaffer.store.operation.GetTraits; import uk.gov.gchq.gaffer.store.operation.handler.GetTraitsHandler; import uk.gov.gchq.gaffer.store.operation.handler.OperationHandler; @@ -86,8 +87,8 @@ */ public class ProxyStore extends Store { private static final Logger LOGGER = LoggerFactory.getLogger(ProxyStore.class); + public static final String ERROR_FETCHING_SCHEMA_FROM_REMOTE_STORE = "Error fetching schema from remote store."; private Client client; - private Schema schema; public ProxyStore() { super(false); @@ -99,9 +100,8 @@ public void initialise(final String graphId, final Schema unusedSchema, final St throws StoreException { setProperties(properties); client = createClient(); - schema = fetchSchema(); - super.initialise(graphId, schema, getProperties()); + super.initialise(graphId, new Schema(), getProperties()); checkDelegateStoreStatus(); } @@ -158,10 +158,38 @@ protected Set fetchTraits() throws StoreException { return newTraits; } - protected Schema fetchSchema() throws StoreException { - final URL url = getProperties().getGafferUrl("graph/config/schema"); - final ResponseDeserialiser responseDeserialiser = getResponseDeserialiserFor(new TypeReferenceStoreImpl.Schema()); - return doGet(url, responseDeserialiser, null); + protected Schema fetchSchema(final boolean getCompactSchema) throws OperationException { + final GetSchema.Builder getSchema = new GetSchema.Builder(); + getSchema.compact(getCompactSchema); + return executeOpChainViaUrl(new OperationChain<>(getSchema.build()), new Context()); + } + + /** + * Get original {@link Schema} from the remote Store. + * + * @return original {@link Schema} + */ + @Override + public Schema getOriginalSchema() { + try { + return fetchSchema(false); + } catch (final OperationException e) { + throw new GafferRuntimeException(ERROR_FETCHING_SCHEMA_FROM_REMOTE_STORE, e); + } + } + + /** + * Get {@link Schema} from the remote Store. + * + * @return optimised compact {@link Schema} + */ + @Override + public Schema getSchema() { + try { + return fetchSchema(true); + } catch (final OperationException e) { + throw new GafferRuntimeException(ERROR_FETCHING_SCHEMA_FROM_REMOTE_STORE, e); + } } @Override diff --git a/store-implementation/proxy-store/src/test/java/uk/gov/gchq/gaffer/proxystore/integration/ProxyStoreBasicIT.java b/store-implementation/proxy-store/src/test/java/uk/gov/gchq/gaffer/proxystore/integration/ProxyStoreBasicIT.java index 65eeb756cc4..8f0455825f4 100644 --- a/store-implementation/proxy-store/src/test/java/uk/gov/gchq/gaffer/proxystore/integration/ProxyStoreBasicIT.java +++ b/store-implementation/proxy-store/src/test/java/uk/gov/gchq/gaffer/proxystore/integration/ProxyStoreBasicIT.java @@ -50,7 +50,11 @@ import uk.gov.gchq.gaffer.proxystore.SingleUseMapProxyStore; import uk.gov.gchq.gaffer.rest.RestApiTestClient; import uk.gov.gchq.gaffer.rest.service.v2.RestApiV2TestClient; +import uk.gov.gchq.gaffer.store.Store; import uk.gov.gchq.gaffer.store.StoreTrait; +import uk.gov.gchq.gaffer.store.operation.GetSchema; +import uk.gov.gchq.gaffer.store.schema.Schema; +import uk.gov.gchq.gaffer.store.schema.SchemaOptimiser; import uk.gov.gchq.gaffer.user.User; import java.io.File; @@ -98,6 +102,7 @@ public class ProxyStoreBasicIT { .build() }; + private Store store; private Graph graph; @BeforeAll @@ -116,13 +121,14 @@ public void before(@TempDir File testFolder) throws IOException { CLIENT.reinitialiseGraph(testFolder, StreamUtil.SCHEMA, "map-store.properties"); // setup ProxyStore + store = new ProxyStore.Builder() + .graphId("graph1") + .host("localhost") + .port(8080) + .contextRoot("rest/v2") + .build(); graph = new Graph.Builder() - .store(new ProxyStore.Builder() - .graphId("graph1") - .host("localhost") - .port(8080) - .contextRoot("rest/v2") - .build()) + .store(store) .build(); } @@ -237,4 +243,36 @@ public void shouldNotErrorWithNonNullOptionsMapAndNullHandlerOption() throws Exc .build(); graph.execute(add, USER); } + + @Test + public void shouldGetOriginalSchemaUsingMethodsAndOperation() throws OperationException { + // Given + Schema storeSchema = Schema.fromJson(StreamUtil.openStream(this.getClass(), StreamUtil.SCHEMA)); + + // When - Get + final Schema returnedSchemaFromGraphMethod = graph.getSchema(); // Indirectly runs getOriginalSchema + final Schema returnedSchemaFromStoreMethod = store.getOriginalSchema(); + final Schema returnedSchemaFromOperation = graph.execute(new GetSchema(), USER); + + // Then + assertThat(returnedSchemaFromGraphMethod).isEqualTo(storeSchema); + assertThat(returnedSchemaFromStoreMethod).isEqualTo(storeSchema); + assertThat(returnedSchemaFromOperation).isEqualTo(storeSchema); + } + + @Test + public void shouldGetInternalOptimisedSchemaUsingMethodAndOperation() throws OperationException { + // Given + Schema storeSchema = Schema.fromJson(StreamUtil.openStream(this.getClass(), StreamUtil.SCHEMA)); + Schema optimisedStoreSchema = new SchemaOptimiser().optimise(storeSchema, true); + + // When - Get + final Schema returnedSchemaFromMethod = store.getSchema(); + GetSchema getCompactSchema = new GetSchema.Builder().compact(true).build(); + final Schema returnedSchemaFromOperation = graph.execute(getCompactSchema, USER); + + // Then + assertThat(returnedSchemaFromMethod).isEqualTo(optimisedStoreSchema); + assertThat(returnedSchemaFromOperation).isEqualTo(optimisedStoreSchema); + } }