1
0
Fork 0

Bug fix 3.3/issue 3811 (#4983)

* now checking existence of _from and _to vertices during edge creation
This commit is contained in:
Heiko 2018-04-25 15:07:54 +02:00 committed by Michael Hackstein
parent bd3aa401a4
commit 40a46d1aab
9 changed files with 224 additions and 20 deletions

View File

@ -1,3 +1,9 @@
v3.3.9 (XXXX-XX-XX)
-------------------
* fixed issue #3811: gharial api is now checking existence of _from and _to vertices
during edge creation
v3.3.8 (2018-04-24)
-------------------

View File

@ -26,6 +26,7 @@
const _ = require('lodash');
const joi = require('joi');
const db = require('@arangodb').db;
const dd = require('dedent');
const statuses = require('statuses');
const httperr = require('http-errors');
@ -738,6 +739,41 @@ router.post('/:graph/edge/:collection', function (req, res) {
{errorNum: errors.ERROR_GRAPH_INVALID_EDGE.code}
);
}
// check existence of _from and _to vertices
// _from vertex
try {
db._document(req.body._from);
} catch (e) {
if (e.errorNum === errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code) {
throw Object.assign(
new httperr.Gone('_from: ' + e.errorMessage),
{errorNum: errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code, cause: e}
);
} else {
throw Object.assign(
new httperr.Gone('_from: ' + e.errorMessage),
{errorNum: errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, cause: e}
);
}
}
// _to vertex
try {
db._document(req.body._to);
} catch (e) {
if (e.errorNum === errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code) {
throw Object.assign(
new httperr.Gone('_to: ' + e.errorMessage),
{errorNum: errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code, cause: e}
);
} else {
throw Object.assign(
new httperr.Gone('_to: ' + e.errorMessage),
{errorNum: errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, cause: e}
);
}
}
const g = loadGraph(name);
checkCollection(g, collection);
let meta;

View File

@ -64,6 +64,18 @@ describe('_api/gharial', () => {
db._graphs.remove(graphName);
} catch (e) {
}
try {
db._graphs.remove('knows_graph');
} catch (e) {
}
try {
db._drop('persons');
} catch (e) {
}
try {
db._drop('knows');
} catch (e) {
}
};
beforeEach(cleanup);
@ -126,7 +138,7 @@ describe('_api/gharial', () => {
// This is all async give it some time
do {
wait(0.1);
req = request.get(url + "/" + graphName);
req = request.get(url + "/" + graphName);
} while (req.statusCode !== 200);
expect(db._collection(eColName)).to.not.be.null;
@ -135,5 +147,171 @@ describe('_api/gharial', () => {
expect(db._collection(oColName2)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should create', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'persons/bob',
_to: 'persons/charlie'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(202);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing from document', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'persons/notavailable',
_to: 'persons/charlie'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing to document', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'persons/bob',
_to: 'persons/notavailable'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing both from and to documents', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'persons/notavailable',
_to: 'persons/notavailable'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing from collection', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'xxx/peter',
_to: 'persons/charlie'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_COLLECTION_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing to collection', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'persons/bob',
_to: 'xxx/charlie'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_COLLECTION_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
it('should check if edges can only be created if their _from and _to vertices are existent - should NOT create - missing from and to collection', () => {
const examples = require('@arangodb/graph-examples/example-graph');
const exampleGraphName = 'knows_graph';
const vName = 'persons';
const eName = 'knows';
expect(db._collection(eName)).to.be.null; // edgec
expect(db._collection(vName)).to.be.null; // vertexc
const g = examples.loadGraph(exampleGraphName);
expect(g).to.not.be.null;
const edgeDef = {
_from: 'xxx/peter',
_to: 'xxx/charlie'
};
let req = request.post(url + '/' + exampleGraphName + '/edge/knows', {
body: JSON.stringify(edgeDef)
});
expect(req.statusCode).to.equal(410);
expect(req.json.errorNum).to.equal(ERRORS.ERROR_ARANGO_COLLECTION_NOT_FOUND.code);
expect(db._collection(eName)).to.not.be.null;
expect(db._collection(vName)).to.not.be.null;
});
});

View File

@ -272,7 +272,6 @@
"ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION" : { "code" : 1928, "message" : "not in orphan collection" },
"ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF" : { "code" : 1929, "message" : "collection already used in edge def" },
"ERROR_GRAPH_EDGE_COLLECTION_NOT_USED" : { "code" : 1930, "message" : "edge collection not used in graph" },
"ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION" : { "code" : 1931, "message" : " is not an ArangoCollection" },
"ERROR_GRAPH_NO_GRAPH_COLLECTION" : { "code" : 1932, "message" : "collection _graphs does not exist" },
"ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT_STRING" : { "code" : 1933, "message" : "Invalid example type. Has to be String, Array or Object" },
"ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT" : { "code" : 1934, "message" : "Invalid example type. Has to be Array or Object" },

View File

@ -96,8 +96,8 @@ var findOrCreateCollectionByName = function (name, type, noCreate, options) {
res = true;
} else if (!(col instanceof ArangoCollection)) {
var err = new ArangoError();
err.errorNum = arangodb.errors.ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION.code;
err.errorMessage = name + arangodb.errors.ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION.message;
err.errorNum = arangodb.errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code;
err.errorMessage = name + arangodb.errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.message;
throw err;
} else if (type === ArangoCollection.TYPE_EDGE && col.type() !== type) {
var err2 = new ArangoError();

View File

@ -359,7 +359,6 @@ ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX,1927,"not a vertex collection","the col
ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION,1928,"not in orphan collection","Vertex collection not in orphan collection of the graph.",
ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF,1929,"collection already used in edge def","The collection is already used in an edge definition of the graph.",
ERROR_GRAPH_EDGE_COLLECTION_NOT_USED,1930,"edge collection not used in graph","The edge collection is not used in any edge definition of the graph.",
ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION,1931," is not an ArangoCollection","The collection is not an ArangoCollection.",
ERROR_GRAPH_NO_GRAPH_COLLECTION,1932,"collection _graphs does not exist","collection _graphs does not exist.",
ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT_STRING,1933,"Invalid example type. Has to be String, Array or Object","Invalid example type. Has to be String, Array or Object.",
ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT,1934,"Invalid example type. Has to be Array or Object","Invalid example type. Has to be Array or Object.",

View File

@ -268,7 +268,6 @@ void TRI_InitializeErrorMessages () {
REG_ERROR(ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION, "not in orphan collection");
REG_ERROR(ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF, "collection already used in edge def");
REG_ERROR(ERROR_GRAPH_EDGE_COLLECTION_NOT_USED, "edge collection not used in graph");
REG_ERROR(ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION, " is not an ArangoCollection");
REG_ERROR(ERROR_GRAPH_NO_GRAPH_COLLECTION, "collection _graphs does not exist");
REG_ERROR(ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT_STRING, "Invalid example type. Has to be String, Array or Object");
REG_ERROR(ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT, "Invalid example type. Has to be Array or Object");

View File

@ -652,8 +652,6 @@
/// The collection is already used in an edge definition of the graph.
/// - 1930: @LIT{edge collection not used in graph}
/// The edge collection is not used in any edge definition of the graph.
/// - 1931: @LIT{ is not an ArangoCollection}
/// The collection is not an ArangoCollection.
/// - 1932: @LIT{collection _graphs does not exist}
/// collection _graphs does not exist.
/// - 1933: @LIT{Invalid example type. Has to be String, Array or Object}
@ -3515,16 +3513,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_GRAPH_EDGE_COLLECTION_NOT_USED (1930)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1931: ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION
///
/// is not an ArangoCollection
///
/// The collection is not an ArangoCollection.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION (1931)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1932: ERROR_GRAPH_NO_GRAPH_COLLECTION
///

View File

@ -349,7 +349,6 @@ rest::ResponseCode GeneralResponse::responseCode(int code) {
case TRI_ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION:
case TRI_ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF:
case TRI_ERROR_GRAPH_EDGE_COLLECTION_NOT_USED:
case TRI_ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION:
case TRI_ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT_STRING:
case TRI_ERROR_GRAPH_INVALID_EXAMPLE_ARRAY_OBJECT:
case TRI_ERROR_GRAPH_INVALID_NUMBER_OF_ARGUMENTS:
@ -366,10 +365,10 @@ rest::ResponseCode GeneralResponse::responseCode(int code) {
return ResponseCode::FORBIDDEN;
case TRI_ERROR_ARANGO_DATABASE_NOT_FOUND:
case TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND:
case TRI_ERROR_ARANGO_VIEW_NOT_FOUND:
case TRI_ERROR_ARANGO_COLLECTION_NOT_LOADED:
case TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND:
case TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND:
case TRI_ERROR_ARANGO_ENDPOINT_NOT_FOUND:
case TRI_ERROR_ARANGO_INDEX_NOT_FOUND:
case TRI_ERROR_CURSOR_NOT_FOUND: