blob: 528c83a7d93bbc6fb3b546b7a3e9d5070ee5bd7a [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 org.apache.atlas.catalog.query;
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.Pipe;
import org.apache.atlas.catalog.Request;
import org.apache.atlas.catalog.VertexWrapper;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.easymock.Capture;
import org.testng.annotations.Test;
import java.util.*;
import static org.easymock.EasyMock.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/**
* Unit tests for AtlasEntityQuery.
*/
@SuppressWarnings("unchecked")
public class AtlasEntityQueryTest {
//todo: add tests for instance query and getInitialPipeline()
@Test
public void testExecute_Collection() throws Exception {
AtlasGraph graph = createStrictMock(AtlasGraph.class);
QueryExpression expression = createStrictMock(QueryExpression.class);
ResourceDefinition resourceDefinition = createStrictMock(ResourceDefinition.class);
Request request = createStrictMock(Request.class);
GremlinPipeline initialPipeline = createStrictMock(GremlinPipeline.class);
Pipe queryPipe = createStrictMock(Pipe.class);
Pipe expressionPipe = createStrictMock(Pipe.class);
Pipe notDeletedPipe = createStrictMock(Pipe.class);
GremlinPipeline rootPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline queryPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline expressionPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline notDeletedPipeline = createStrictMock(GremlinPipeline.class);
Vertex vertex1 = createStrictMock(Vertex.class);
VertexWrapper vertex1Wrapper = createStrictMock(VertexWrapper.class);
List<Vertex> results = new ArrayList<>();
results.add(vertex1);
Map<String, Object> vertex1PropertyMap = new HashMap<>();
vertex1PropertyMap.put("prop1", "prop1.value1");
vertex1PropertyMap.put("prop2", "prop2.value1");
Map<String, Object> filteredVertex1PropertyMap = new HashMap<>();
filteredVertex1PropertyMap.put("prop1", "prop1.value1");
// mock expectations
expect(initialPipeline.add(queryPipe)).andReturn(queryPipeline);
expect(initialPipeline.add(notDeletedPipe)).andReturn(notDeletedPipeline);
expect(initialPipeline.as("root")).andReturn(rootPipeline);
expect(expression.asPipe()).andReturn(expressionPipe);
expect(rootPipeline.add(expressionPipe)).andReturn(expressionPipeline);
expect(expressionPipeline.back("root")).andReturn(rootPipeline);
expect(rootPipeline.toList()).andReturn(results);
graph.commit();
expect(vertex1Wrapper.getPropertyMap()).andReturn(vertex1PropertyMap);
expect(resourceDefinition.filterProperties(request, vertex1PropertyMap)).andReturn(filteredVertex1PropertyMap);
expect(resourceDefinition.resolveHref(filteredVertex1PropertyMap)).andReturn("/foo/bar");
expect(request.getCardinality()).andReturn(Request.Cardinality.COLLECTION);
replay(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
// end mock expectations
AtlasEntityQuery query = new TestAtlasEntityQuery(expression, resourceDefinition, request,
initialPipeline, queryPipe, notDeletedPipe, graph, vertex1Wrapper);
// invoke method being tested
Collection<Map<String, Object>> queryResults = query.execute();
assertEquals(queryResults.size(), 1);
Map<String, Object> queryResultMap = queryResults.iterator().next();
assertEquals(queryResultMap.size(), 2);
assertEquals(queryResultMap.get("prop1"), "prop1.value1");
assertEquals(queryResultMap.get("href"), "/foo/bar");
verify(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
}
@Test
public void testExecute_Collection_rollbackOnException() throws Exception {
AtlasGraph graph = createStrictMock(AtlasGraph.class);
QueryExpression expression = createStrictMock(QueryExpression.class);
ResourceDefinition resourceDefinition = createStrictMock(ResourceDefinition.class);
Request request = createStrictMock(Request.class);
GremlinPipeline initialPipeline = createStrictMock(GremlinPipeline.class);
Pipe queryPipe = createStrictMock(Pipe.class);
Pipe expressionPipe = createStrictMock(Pipe.class);
Pipe notDeletedPipe = createStrictMock(Pipe.class);
GremlinPipeline rootPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline queryPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline expressionPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline notDeletedPipeline = createStrictMock(GremlinPipeline.class);
// mock expectations
expect(initialPipeline.add(queryPipe)).andReturn(queryPipeline);
expect(initialPipeline.add(notDeletedPipe)).andReturn(notDeletedPipeline);
expect(initialPipeline.as("root")).andReturn(rootPipeline);
expect(expression.asPipe()).andReturn(expressionPipe);
expect(rootPipeline.add(expressionPipe)).andReturn(expressionPipeline);
expect(expressionPipeline.back("root")).andReturn(rootPipeline);
expect(rootPipeline.toList()).andThrow(new RuntimeException("something bad happened"));
graph.rollback();
replay(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline);
// end mock expectations
AtlasEntityQuery query = new TestAtlasEntityQuery(expression, resourceDefinition, request,
initialPipeline, queryPipe, notDeletedPipe, graph, null);
try {
// invoke method being tested
query.execute();
fail("expected exception");
} catch (RuntimeException e) {
assertEquals(e.getMessage(), "something bad happened");
}
verify(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline);
}
@Test
public void testExecute_Collection_update() throws Exception {
AtlasGraph graph = createStrictMock(AtlasGraph.class);
QueryExpression expression = createStrictMock(QueryExpression.class);
ResourceDefinition resourceDefinition = createStrictMock(ResourceDefinition.class);
Request request = createStrictMock(Request.class);
GremlinPipeline initialPipeline = createStrictMock(GremlinPipeline.class);
Pipe queryPipe = createStrictMock(Pipe.class);
Pipe expressionPipe = createStrictMock(Pipe.class);
Pipe notDeletedPipe = createStrictMock(Pipe.class);
GremlinPipeline rootPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline queryPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline expressionPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline notDeletedPipeline = createStrictMock(GremlinPipeline.class);
Vertex vertex1 = createStrictMock(Vertex.class);
VertexWrapper vertex1Wrapper = createStrictMock(VertexWrapper.class);
Capture<Long> modifiedTimestampCapture = newCapture();
List<Vertex> results = new ArrayList<>();
results.add(vertex1);
Map<String, Object> vertex1PropertyMap = new HashMap<>();
vertex1PropertyMap.put("prop1", "prop1.value1");
vertex1PropertyMap.put("prop2", "prop2.value1");
Map<String, Object> filteredVertex1PropertyMap = new HashMap<>();
filteredVertex1PropertyMap.put("prop1", "prop1.value1");
Map<String, Object> updateProperties = new HashMap<>();
updateProperties.put("prop3", "newValue");
// mock expectations
expect(initialPipeline.add(queryPipe)).andReturn(queryPipeline);
expect(initialPipeline.add(notDeletedPipe)).andReturn(notDeletedPipeline);
expect(initialPipeline.as("root")).andReturn(rootPipeline);
expect(expression.asPipe()).andReturn(expressionPipe);
expect(rootPipeline.add(expressionPipe)).andReturn(expressionPipeline);
expect(expressionPipeline.back("root")).andReturn(rootPipeline);
expect(rootPipeline.toList()).andReturn(results);
graph.commit();
vertex1Wrapper.setProperty("prop3", "newValue");
vertex1Wrapper.setProperty(eq(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY), capture(modifiedTimestampCapture));
expect(vertex1Wrapper.getPropertyMap()).andReturn(vertex1PropertyMap);
expect(resourceDefinition.filterProperties(request, vertex1PropertyMap)).andReturn(filteredVertex1PropertyMap);
expect(resourceDefinition.resolveHref(filteredVertex1PropertyMap)).andReturn("/foo/bar");
expect(request.getCardinality()).andReturn(Request.Cardinality.COLLECTION);
replay(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
// end mock expectations
AtlasEntityQuery query = new TestAtlasEntityQuery(expression, resourceDefinition, request,
initialPipeline, queryPipe, notDeletedPipe, graph, vertex1Wrapper);
long startTime = System.currentTimeMillis();
// invoke method being tested
Collection<Map<String, Object>> queryResults = query.execute(updateProperties);
long endTime = System.currentTimeMillis();
assertEquals(queryResults.size(), 1);
Map<String, Object> queryResultMap = queryResults.iterator().next();
assertEquals(queryResultMap.size(), 2);
assertEquals(queryResultMap.get("prop1"), "prop1.value1");
assertEquals(queryResultMap.get("href"), "/foo/bar");
long modifiedTimestamp = modifiedTimestampCapture.getValue();
assertTrue(modifiedTimestamp >= startTime && modifiedTimestamp <= endTime);
verify(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
}
private class TestAtlasEntityQuery extends AtlasEntityQuery {
private final GremlinPipeline initialPipeline;
private final Pipe queryPipe;
private final Pipe notDeletedPipe;
private final AtlasGraph graph;
private final VertexWrapper vWrapper;
public TestAtlasEntityQuery(QueryExpression queryExpression,
ResourceDefinition resourceDefinition,
Request request,
GremlinPipeline initialPipeline,
Pipe queryPipe,
Pipe notDeletedPipe,
AtlasGraph graph,
VertexWrapper vWrapper) {
super(queryExpression, resourceDefinition, request);
this.initialPipeline = initialPipeline;
this.queryPipe = queryPipe;
this.notDeletedPipe = notDeletedPipe;
this.graph = graph;
this.vWrapper = vWrapper;
}
@Override
protected GremlinPipeline getRootVertexPipeline() {
return initialPipeline;
}
@Override
protected Pipe getQueryPipe() {
return queryPipe;
}
@Override
protected Pipe getNotDeletedPipe() {
return notDeletedPipe;
}
@Override
protected AtlasGraph getGraph() {
return graph;
}
@Override
protected VertexWrapper wrapVertex(Vertex v) {
return vWrapper;
}
}
}