/******************************************************************************* * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019) * * contact.vitam@culture.gouv.fr * * This software is a computer program whose purpose is to implement a digital archiving back-office system managing * high volumetry securely and efficiently. * * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as * circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the * successive licensors have only limited liability. * * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or * developing or reproducing the software by the user in light of its specific status of free software, that may mean * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data * to be ensured and, more generally, to use and operate it in the same conditions as regards security. * * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you * accept its terms. *******************************************************************************/ package fr.gouv.vitam.common.database.translators.mongodb; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.bson.conversions.Bson; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.fasterxml.jackson.databind.JsonNode; import fr.gouv.vitam.common.database.parser.request.multiple.DeleteParserMultiple; import fr.gouv.vitam.common.database.parser.request.multiple.InsertParserMultiple; import fr.gouv.vitam.common.database.parser.request.multiple.SelectParserMultiple; import fr.gouv.vitam.common.database.parser.request.multiple.UpdateParserMultiple; import fr.gouv.vitam.common.exception.InvalidParseOperationException; import fr.gouv.vitam.common.json.JsonHandler; @SuppressWarnings("javadoc") public class RequestToMongodbTest { private static JsonNode exampleSelectMd; private static JsonNode exampleDeleteMd; private static JsonNode data; private static JsonNode exampleInsertMd; private static JsonNode updateAction; private static JsonNode exampleUpdateMd; @BeforeClass public static void setUpBeforeClass() throws Exception { exampleSelectMd = JsonHandler.getFromString("{ $roots : [ 'id0' ], $query : [ " + "{ $path : [ 'id1', 'id2'] }," + "{ $and : [ {$exists : 'mavar1'}, {$missing : 'mavar2'}, {$isNull : 'mavar3'}, { $or : [ {$in : { 'mavar4' : [1, 2, 'maval1'] }}, { $nin : { 'mavar5' : ['maval2', true] } } ] } ] }," + "{ $not : [ { $size : { 'mavar5' : 5 } }, { $gt : { 'mavar6' : 7 } }, { $lte : { 'mavar7' : 8 } } ] , $exactdepth : 4}," + "{ $not : [ { $eq : { 'mavar8' : 5 } }, { $ne : { 'mavar9' : 'ab' } }, { $range : { 'mavar10' : { $gte : 12, $lte : 20} } } ], $depth : 1}, " + "{ $and : [ { $term : { 'mavar14' : 'motMajuscule', 'mavar15' : 'simplemot' } } ] }, " + "{ $regex : { 'mavar14' : '^start?aa.*' }, $depth : -1 } " + "], " + "$filter : {$offset : 100, $limit : 1000, $hint : ['cache'], " + "$orderby : { maclef1 : 1 , maclef2 : -1, maclef3 : 1 } }," + "$projection : {$fields : {#dua : 1, #all : 1}, $usage : 'abcdef1234' } }"); data = JsonHandler .getFromString("{ " + "\"address\": { \"streetAddress\": \"21 2nd Street\", \"city\": \"New York\" }, " + "\"phoneNumber\": [ { \"location\": \"home\", \"code\": 44 } ] }"); exampleDeleteMd = JsonHandler.getFromString("{ $roots : [ 'id0' ], $query : [ " + "{ $path : [ 'id1', 'id2'] }," + "{ $and : [ {$exists : 'mavar1'}, {$missing : 'mavar2'}, {$isNull : 'mavar3'}, { $or : [ {$in : { 'mavar4' : [1, 2, 'maval1'] }}, { $nin : { 'mavar5' : ['maval2', true] } } ] } ] }," + "{ $not : [ { $size : { 'mavar5' : 5 } }, { $gt : { 'mavar6' : 7 } }, { $lte : { 'mavar7' : 8 } } ] , $exactdepth : 4}," + "{ $not : [ { $eq : { 'mavar8' : 5 } }, { $ne : { 'mavar9' : 'ab' } }, { $range : { 'mavar10' : { $gte : 12, $lte : 20} } } ], $depth : 1}, " + "{ $and : [ { $term : { 'mavar14' : 'motMajuscule', 'mavar15' : 'simplemot' } } ] }, " + "{ $regex : { 'mavar14' : '^start?aa.*' }, $depth : -1 } " + "], " + "$filter : {$mult : false } }"); exampleInsertMd = JsonHandler.getFromString("{ $roots : [ 'id0' ], $query : [ " + "{ $path : [ 'id1', 'id2'] }," + "{ $and : [ {$exists : 'mavar1'}, {$missing : 'mavar2'}, {$isNull : 'mavar3'}, { $or : [ {$in : { 'mavar4' : [1, 2, 'maval1'] }}, { $nin : { 'mavar5' : ['maval2', true] } } ] } ] }," + "{ $not : [ { $size : { 'mavar5' : 5 } }, { $gt : { 'mavar6' : 7 } }, { $lte : { 'mavar7' : 8 } } ] , $exactdepth : 4}," + "{ $not : [ { $eq : { 'mavar8' : 5 } }, { $ne : { 'mavar9' : 'ab' } }, { $range : { 'mavar10' : { $gte : 12, $lte : 20} } } ], $depth : 1}, " + "{ $and : [ { $term : { 'mavar14' : 'motMajuscule', 'mavar15' : 'simplemot' } } ] }, " + "{ $regex : { 'mavar14' : '^start?aa.*' }, $depth : -1 } " + "], " + "$filter : {$mult : false }," + "$data : " + data + " }"); updateAction = JsonHandler .getFromString("[ " + "{ $set : { mavar1 : 1, mavar2 : 1.2, mavar3 : true, mavar4 : 'ma chaine' } }," + "{ $unset : [ 'mavar5', 'mavar6' ] }," + "{ $inc : { mavar7 : 2 } }," + "{ $min : { mavar8 : 3 } }," + "{ $min : { mavar16 : 12 } }," + "{ $max : { mavar9 : 3 } }," + "{ $rename : { mavar10 : 'mavar11' } }," + "{ $push : { mavar12 : { $each : [ 1, 2 ] } } }," + "{ $add : { mavar13 : { $each : [ 1, 2 ] } } }," + "{ $pop : { mavar14 : -1 } }," + "{ $pull : { mavar15 : { $each : [ 1, 2 ] } } } ]"); exampleUpdateMd = JsonHandler.getFromString("{ $roots : [ 'id0' ], $query : [ " + "{ $path : [ 'id1', 'id2'] }," + "{ $and : [ {$exists : 'mavar1'}, {$missing : 'mavar2'}, {$isNull : 'mavar3'}, { $or : [ {$in : { 'mavar4' : [1, 2, 'maval1'] }}, { $nin : { 'mavar5' : ['maval2', true] } } ] } ] }," + "{ $not : [ { $size : { 'mavar5' : 5 } }, { $gt : { 'mavar6' : 7 } }, { $lte : { 'mavar7' : 8 } } ] , $exactdepth : 4}," + "{ $not : [ { $eq : { 'mavar8' : 5 } }, { $ne : { 'mavar9' : 'ab' } }, { $range : { 'mavar10' : { $gte : 12, $lte : 20} } } ], $depth : 1}, " + "{ $and : [ { $term : { 'mavar14' : 'motMajuscule', 'mavar15' : 'simplemot' } } ] }, " + "{ $regex : { 'mavar14' : '^start?aa.*' }, $depth : -1 } " + "], " + "$filter : {$mult : false }," + "$action : " + updateAction + " }"); } @AfterClass public static void tearDownAfterClass() throws Exception {} private SelectToMongodb createSelect() { try { final SelectParserMultiple request1 = new SelectParserMultiple(); request1.parse(exampleSelectMd); assertNotNull(request1); return new SelectToMongodb(request1); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); return null; } } private InsertToMongodb createInsert() { try { final InsertParserMultiple request1 = new InsertParserMultiple(); request1.parse(exampleInsertMd); assertNotNull(request1); return new InsertToMongodb(request1); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); return null; } } private UpdateToMongodb createUpdate() { try { final UpdateParserMultiple request1 = new UpdateParserMultiple(); request1.parse(exampleUpdateMd); assertNotNull(request1); return new UpdateToMongodb(request1); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); return null; } } private DeleteToMongodb createDelete() { try { final DeleteParserMultiple request1 = new DeleteParserMultiple(); request1.parse(exampleDeleteMd); assertNotNull(request1); return new DeleteToMongodb(request1); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); return null; } } @Test public void testGetRequestToMongoDb() { try { final SelectParserMultiple request1 = new SelectParserMultiple(); request1.parse(exampleSelectMd); assertNotNull(request1); assertTrue(RequestToMongodb.getRequestToMongoDb(request1) instanceof SelectToMongodb); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final InsertParserMultiple request1 = new InsertParserMultiple(); request1.parse(exampleInsertMd); assertNotNull(request1); assertTrue(RequestToMongodb.getRequestToMongoDb(request1) instanceof InsertToMongodb); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final UpdateParserMultiple request1 = new UpdateParserMultiple(); request1.parse(exampleUpdateMd); assertNotNull(request1); assertTrue(RequestToMongodb.getRequestToMongoDb(request1) instanceof UpdateToMongodb); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final DeleteParserMultiple request1 = new DeleteParserMultiple(); request1.parse(exampleDeleteMd); assertNotNull(request1); assertTrue(RequestToMongodb.getRequestToMongoDb(request1) instanceof DeleteToMongodb); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } } @Test public void testGetCommands() { try { final SelectToMongodb rtm = createSelect(); final Bson bsonRoot = rtm.getInitialRoots("_up"); final int size = rtm.getNbQueries(); for (int i = 0; i < size; i++) { final Bson bsonQuery = rtm.getNthQueries(i); final Bson pseudoRequest = rtm.getRequest(bsonRoot, bsonQuery); System.out.println(i + " = " + MongoDbHelper.bsonToString(pseudoRequest, false)); } try { rtm.getNthQueries(size); fail("Should failed"); } catch (final IllegalAccessError e) { } assertNotNull(rtm.getRequest()); assertNotNull(rtm.getNthQuery(0)); assertNotNull(rtm.getRequestParser()); assertNotNull(rtm.model()); System.out.println("OrderBy = " + MongoDbHelper.bsonToString(rtm.getFinalOrderBy(), false)); System.out.println("Projection = " + MongoDbHelper.bsonToString(rtm.getFinalProjection(), false)); System.out.println("Select Context = " + rtm.getLastDepth() + ":" + rtm.getFinalLimit() + ":" + rtm.getFinalOffset() + ":" + rtm.getUsage() + ":" + rtm.getHints()); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final InsertToMongodb rtm = createInsert(); final Bson bsonRoot = rtm.getInitialRoots("_up"); final int size = rtm.getNbQueries(); for (int i = 0; i < size; i++) { final Bson bsonQuery = rtm.getNthQueries(i); final Bson pseudoRequest = rtm.getRequest(bsonRoot, bsonQuery); System.out.println(i + " = " + MongoDbHelper.bsonToString(pseudoRequest, false)); } System.out.println("Data = " + MongoDbHelper.bsonToString(rtm.getFinalData(), false)); System.out.println("Insert Context = " + rtm.getLastDepth() + ":" + rtm.isMultiple()); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final UpdateToMongodb rtm = createUpdate(); final Bson bsonRoot = rtm.getInitialRoots("_up"); final int size = rtm.getNbQueries(); for (int i = 0; i < size; i++) { final Bson bsonQuery = rtm.getNthQueries(i); final Bson pseudoRequest = rtm.getRequest(bsonRoot, bsonQuery); System.out.println(i + " = " + MongoDbHelper.bsonToString(pseudoRequest, false)); } System.out.println("Update Actons = " + MongoDbHelper.bsonToString(rtm.getFinalUpdate(), false)); System.out.println("Update Context = " + rtm.getLastDepth() + ":" + rtm.isMultiple()); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } try { final DeleteToMongodb rtm = createDelete(); final Bson bsonRoot = rtm.getInitialRoots("_up"); final int size = rtm.getNbQueries(); for (int i = 0; i < size; i++) { final Bson bsonQuery = rtm.getNthQueries(i); final Bson pseudoRequest = rtm.getRequest(bsonRoot, bsonQuery); System.out.println(i + " = " + MongoDbHelper.bsonToString(pseudoRequest, false)); } System.out.println("Delete Context = " + rtm.getLastDepth() + ":" + rtm.isMultiple()); } catch (final Exception e) { e.printStackTrace(); fail(e.getMessage()); } } @Test public void testSelectGetFinalOrderby() throws InvalidParseOperationException { final String example1 = "{ $roots : [], $query : [], $filter : {$orderby : {}}, $projection : {} }"; final SelectParserMultiple request1 = new SelectParserMultiple(); request1.parse(JsonHandler.getFromString(example1)); final SelectToMongodb rtm1 = new SelectToMongodb(request1); assertEquals("", MongoDbHelper.bsonToString(rtm1.getFinalOrderBy(), false)); final String example2 = "{ $roots : [], $query : [], $filter : {$orderby : {maclef : 1}}, $projection : {} }"; final SelectParserMultiple request2 = new SelectParserMultiple(); request2.parse(JsonHandler.getFromString(example2)); final SelectToMongodb rtm2 = new SelectToMongodb(request2); assertEquals("{ \"maclef\" : 1 }", MongoDbHelper.bsonToString(rtm2.getFinalOrderBy(), false)); final String example3 = "{ $roots : [], $query : [], $filter : {$orderby : {maclef : -1}}, $projection : {} }"; final SelectParserMultiple request3 = new SelectParserMultiple(); request3.parse(JsonHandler.getFromString(example3)); final SelectToMongodb rtm3 = new SelectToMongodb(request3); assertEquals("{ \"maclef\" : -1 }", MongoDbHelper.bsonToString(rtm3.getFinalOrderBy(), false)); } @Test public void testSelectGetFinalProjection() throws InvalidParseOperationException { final String example1 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : 1, #all : -1}} }"; final SelectParserMultiple request1 = new SelectParserMultiple(); request1.parse(JsonHandler.getFromString(example1)); final SelectToMongodb rtm1 = new SelectToMongodb(request1); assertEquals("{ \"#dua\" : 1, \"#all\" : 0 }", MongoDbHelper.bsonToString(rtm1.getFinalProjection(), false)); final String example2 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : 1}} }"; final SelectParserMultiple request2 = new SelectParserMultiple(); request2.parse(JsonHandler.getFromString(example2)); final SelectToMongodb rtm2 = new SelectToMongodb(request2); assertEquals("{ \"#dua\" : 1 }", MongoDbHelper.bsonToString(rtm2.getFinalProjection(), false)); final String example3 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1}} }"; final SelectParserMultiple request3 = new SelectParserMultiple(); request3.parse(JsonHandler.getFromString(example3)); final SelectToMongodb rtm3 = new SelectToMongodb(request3); assertEquals("{ \"#dua\" : 0 }", MongoDbHelper.bsonToString(rtm3.getFinalProjection(), false)); final String example4 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"$slice\" : 1}}} }"; final SelectParserMultiple request4 = new SelectParserMultiple(); request4.parse(JsonHandler.getFromString(example4)); final SelectToMongodb rtm4 = new SelectToMongodb(request4); assertEquals("{ \"#dua\" : 0, \"test1\" : { \"$slice\" : 1 } }", MongoDbHelper.bsonToString(rtm4 .getFinalProjection(), false)); final String example5 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"$slice\" : [0,1]}}} }"; final SelectParserMultiple request5 = new SelectParserMultiple(); request5.parse(JsonHandler.getFromString(example5)); final SelectToMongodb rtm5 = new SelectToMongodb(request5); assertEquals("{ \"#dua\" : 0, \"test1\" : { \"$slice\" : [0, 1] } }", MongoDbHelper.bsonToString(rtm5 .getFinalProjection(), false)); final String exampleEmptyProjection = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields:{}} }"; final SelectParserMultiple requestEmptyProjection = new SelectParserMultiple(); requestEmptyProjection.parse(JsonHandler.getFromString(exampleEmptyProjection)); final SelectToMongodb rtmEmptyProjection = new SelectToMongodb(requestEmptyProjection); assertNull(rtmEmptyProjection.getFinalProjection()); try { // Test invalid slice projection final String example6 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"$slice\" : [0,0,1]}}} }"; final SelectParserMultiple request6 = new SelectParserMultiple(); request6.parse(JsonHandler.getFromString(example6)); final SelectToMongodb rtm6 = new SelectToMongodb(request6); rtm6.getFinalProjection(); fail("Invalid projection should, an exception should have been raised"); } catch (final InvalidParseOperationException exc) { // DO NOTHING } try { // Test invalid slice projection final String example7 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"$slice\" : {\"field\":\"value\"}}}} }"; final SelectParserMultiple request7 = new SelectParserMultiple(); request7.parse(JsonHandler.getFromString(example7)); final SelectToMongodb rtm7 = new SelectToMongodb(request7); rtm7.getFinalProjection(); fail("Invalid projection should, an exception should have been raised"); } catch (final InvalidParseOperationException exc) { // DO NOTHING } try { // Test invalid slice projection final String example7 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"$slice\" : [\"test\", \"s\"]}}} }"; final SelectParserMultiple request7 = new SelectParserMultiple(); request7.parse(JsonHandler.getFromString(example7)); final SelectToMongodb rtm7 = new SelectToMongodb(request7); rtm7.getFinalProjection(); fail("Invalid projection should, an exception should have been raised"); } catch (final InvalidParseOperationException exc) { // DO NOTHING } try { // Test unsupported projection final String example8 = "{ $roots : [], $query : [], $filter : {}, $projection : {$fields : {#dua : -1, " + "\"test1\" : {\"field\":\"value\"}}} }"; final SelectParserMultiple request8 = new SelectParserMultiple(); request8.parse(JsonHandler.getFromString(example8)); final SelectToMongodb rtm8 = new SelectToMongodb(request8); rtm8.getFinalProjection(); fail("Invalid projection should, an exception should have been raised"); } catch (final InvalidParseOperationException exc) { // DO NOTHING } } @Test public void testRequestToAbstract() throws Exception { final InsertToMongodb rtm = createInsert(); assertEquals(null, rtm.getHints()); assertEquals(false, rtm.hasFullTextQuery()); assertEquals(false, rtm.hintCache()); assertEquals(false, rtm.hintNoTimeout()); } }