/*
* Copyright 2016 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.integration.impl;
import com.google.common.collect.Lists;
import org.hamcrest.core.IsCollectionContaining;
import org.junit.Before;
import org.junit.Test;
import uk.gov.gchq.gaffer.commonutil.TestGroups;
import uk.gov.gchq.gaffer.commonutil.TestPropertyNames;
import uk.gov.gchq.gaffer.commonutil.iterable.CloseableIterable;
import uk.gov.gchq.gaffer.data.element.Edge;
import uk.gov.gchq.gaffer.data.element.Element;
import uk.gov.gchq.gaffer.data.element.Entity;
import uk.gov.gchq.gaffer.data.element.IdentifierType;
import uk.gov.gchq.gaffer.data.element.function.ElementFilter;
import uk.gov.gchq.gaffer.data.element.function.ElementTransformer;
import uk.gov.gchq.gaffer.data.element.id.ElementId;
import uk.gov.gchq.gaffer.data.elementdefinition.view.View;
import uk.gov.gchq.gaffer.data.elementdefinition.view.ViewElementDefinition;
import uk.gov.gchq.gaffer.integration.AbstractStoreIT;
import uk.gov.gchq.gaffer.integration.TraitRequirement;
import uk.gov.gchq.gaffer.operation.data.EdgeSeed;
import uk.gov.gchq.gaffer.operation.data.ElementSeed;
import uk.gov.gchq.gaffer.operation.impl.add.AddElements;
import uk.gov.gchq.gaffer.operation.impl.get.GetAllElements;
import uk.gov.gchq.gaffer.store.StoreTrait;
import uk.gov.gchq.koryphe.impl.function.Concat;
import uk.gov.gchq.koryphe.impl.predicate.IsEqual;
import uk.gov.gchq.koryphe.impl.predicate.IsIn;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static uk.gov.gchq.gaffer.operation.graph.GraphFilters.DirectedType;
public class GetAllElementsIT extends AbstractStoreIT {
@Override
@Before
public void setup() throws Exception {
super.setup();
addDefaultElements();
}
@TraitRequirement(StoreTrait.INGEST_AGGREGATION)
@Test
public void shouldGetAllElements() throws Exception {
for (final boolean includeEntities : Arrays.asList(true, false)) {
for (final boolean includeEdges : Arrays.asList(true, false)) {
if (!includeEntities && !includeEdges) {
// Cannot query for nothing!
continue;
}
for (final DirectedType directedType : DirectedType.values()) {
try {
shouldGetAllElements(includeEntities, includeEdges, directedType);
} catch (final AssertionError e) {
throw new AssertionError("GetAllElements failed with parameters: includeEntities=" + includeEntities
+ ", includeEdges=" + includeEdges + ", directedType=" + directedType.name(), e);
}
}
}
}
}
@TraitRequirement(StoreTrait.PRE_AGGREGATION_FILTERING)
@Test
public void shouldGetAllElementsWithFilterWithoutSummarisation() throws
Exception {
final Edge edge1 = getEdges().get(new EdgeSeed(SOURCE_1, DEST_1, false)).emptyClone();
edge1.putProperty(TestPropertyNames.INT, 100);
edge1.putProperty(TestPropertyNames.COUNT, 1L);
final Edge edge2 = edge1.emptyClone();
edge2.putProperty(TestPropertyNames.INT, 101);
edge2.putProperty(TestPropertyNames.COUNT, 1L);
graph.execute(new AddElements.Builder()
.input(edge1, edge2)
.build(),
getUser());
final GetAllElements op = new GetAllElements.Builder()
.view(new View.Builder()
.edge(TestGroups.EDGE, new ViewElementDefinition.Builder()
.preAggregationFilter(new ElementFilter.Builder()
.select(TestPropertyNames.INT)
.execute(new IsIn(Arrays.asList((Object) 100, 101)))
.build())
.build())
.build())
.build();
// When
final CloseableIterable<? extends Element> results = graph.execute(op, getUser());
// Then
final List<Element> resultList = Lists.newArrayList(results);
assertEquals(2, resultList.size());
assertThat(resultList, IsCollectionContaining.hasItems(
(Element) edge1, edge2));
}
@TraitRequirement({StoreTrait.PRE_AGGREGATION_FILTERING, StoreTrait.INGEST_AGGREGATION})
@Test
public void shouldGetAllElementsFilteredOnGroup() throws Exception {
final GetAllElements op = new GetAllElements.Builder()
.view(new View.Builder()
.entity(TestGroups.ENTITY)
.build())
.build();
// When
final CloseableIterable<? extends Element> results = graph.execute(op, getUser());
// Then
final List<Element> resultList = Lists.newArrayList(results);
assertEquals(getEntities().size(), resultList.size());
for (final Element element : resultList) {
assertEquals(TestGroups.ENTITY, element.getGroup());
}
}
@TraitRequirement(StoreTrait.PRE_AGGREGATION_FILTERING)
@Test
public void shouldGetAllFilteredElements() throws Exception {
final GetAllElements op = new GetAllElements.Builder()
.view(new View.Builder()
.entity(TestGroups.ENTITY, new ViewElementDefinition.Builder()
.preAggregationFilter(new ElementFilter.Builder()
.select(IdentifierType.VERTEX.name())
.execute(new IsEqual("A1"))
.build())
.build())
.build())
.build();
// When
final CloseableIterable<? extends Element> results = graph.execute(op, getUser());
// Then
final List<Element> resultList = Lists.newArrayList(results);
assertEquals(1, resultList.size());
assertEquals("A1", ((Entity) resultList.get(0)).getVertex());
}
@TraitRequirement({StoreTrait.TRANSFORMATION, StoreTrait.PRE_AGGREGATION_FILTERING})
@Test
public void shouldGetAllTransformedFilteredElements() throws Exception {
final GetAllElements op = new GetAllElements.Builder()
.view(new View.Builder()
.entity(TestGroups.ENTITY, new ViewElementDefinition.Builder()
.preAggregationFilter(new ElementFilter.Builder()
.select(IdentifierType.VERTEX.name())
.execute(new IsEqual("A1"))
.build())
.transientProperty(TestPropertyNames.TRANSIENT_1, String.class)
.transformer(new ElementTransformer.Builder()
.select(IdentifierType.VERTEX.name(),
TestPropertyNames.STRING)
.execute(new Concat())
.project(TestPropertyNames.TRANSIENT_1)
.build())
.build())
.build())
.build();
// When
final CloseableIterable<? extends Element> results = graph.execute(op, getUser());
// Then
final List<Element> resultList = Lists.newArrayList(results);
assertEquals(1, resultList.size());
assertEquals("A1,3", resultList.get(0).getProperties().get(TestPropertyNames.TRANSIENT_1));
}
protected void shouldGetAllElements(final boolean includeEntities, final boolean includeEdges, final DirectedType directedType) throws Exception {
// Given
final List<Element> expectedElements = new ArrayList<>();
if (includeEntities) {
expectedElements.addAll(getEntities().values());
}
if (includeEdges) {
for (final Edge edge : getEdges().values()) {
if (DirectedType.BOTH == directedType
|| (edge.isDirected() && DirectedType.DIRECTED == directedType)
|| (!edge.isDirected() && DirectedType.UNDIRECTED == directedType)) {
expectedElements.add(edge);
}
}
}
final View.Builder viewBuilder = new View.Builder();
if (includeEntities) {
viewBuilder.entity(TestGroups.ENTITY);
}
if (includeEdges) {
viewBuilder.edge(TestGroups.EDGE);
}
final GetAllElements op = new GetAllElements.Builder()
.directedType(directedType)
.view(viewBuilder.build())
.build();
// When
final CloseableIterable<? extends Element> results = graph.execute(op, getUser());
// Then
final List<Element> expectedElementsCopy = Lists.newArrayList(expectedElements);
for (final Element result : results) {
final ElementId seed = ElementSeed.createSeed(result);
if (result instanceof Entity) {
Entity entity = (Entity) result;
assertTrue("Entity was not expected: " + entity, expectedElements.contains(entity));
} else {
Edge edge = (Edge) result;
if (edge.isDirected()) {
assertTrue("Edge was not expected: " + edge, expectedElements.contains(edge));
} else {
final Edge edgeReversed = new Edge(TestGroups.EDGE, edge.getDestination(), edge.getSource(), edge.isDirected());
expectedElementsCopy.remove(edgeReversed);
assertTrue("Edge was not expected: " + seed, expectedElements.contains(result) || expectedElements.contains(edgeReversed));
}
}
expectedElementsCopy.remove(result);
}
assertEquals("The number of elements returned was not as expected. Missing elements: " + expectedElementsCopy, expectedElements.size(),
Lists.newArrayList(results).size());
}
}