diff --git a/mongo/pom.xml b/mongo/pom.xml index c9fa16e75..8ef7a9e39 100644 --- a/mongo/pom.xml +++ b/mongo/pom.xml @@ -22,7 +22,7 @@ com.redhat.lightblue.mongo lightblue-mongo-pom - 1.28.0-SNAPSHOT + 1.29.0-SNAPSHOT com.redhat.lightblue.mongo lightblue-mongo diff --git a/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocol.java b/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocol.java index f8d456b40..56c36c6a5 100644 --- a/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocol.java +++ b/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocol.java @@ -250,7 +250,14 @@ public void retryConcurrentUpdateErrorsIfNeeded(Map results) { } else { break; } + + if (nRetries == 0) { + // retried failureRetryCount and still not able to update, the error will reach the client + LOGGER.error("Retried docs.id in {} {} times, all times failed", failedDocs, cfg.getFailureRetryCount()); + } } + + } @@ -289,10 +296,16 @@ private List retryFailedDocs(List failedDocs,Map retryFailedDocs(List failedDocs,Map initializedCollections = new CopyOnWriteArraySet<>(); + static Map sequenceInfo = new HashMap<>(); + static CopyOnWriteArraySet initializedCollections = new CopyOnWriteArraySet<>(); + + static class SequenceInfo { + final String name; + final ReentrantLock lock=new ReentrantLock(); + + long poolSize; + long nextIdInPool; + long inc; + + SequenceInfo(String name) { + this.name=name; + } + + Long nextId() { + if(poolSize>0) { + poolSize--; + long ret=nextIdInPool; + nextIdInPool+=inc; + return Long.valueOf(ret); + } else { + return null; + } + } + } public MongoSequenceGenerator(DBCollection coll) { this.coll = coll; - if (!initializedCollections.contains(coll.getFullName())) { - // Here, we also make sure we have the indexes setup properly + String name=coll.getFullName(); + if(!initializedCollections.contains(name)) { initIndex(); - initializedCollections.add(coll.getFullName()); - LOGGER.info("Initialized sequances collection {}", coll.getFullName()); + initializedCollections.add(name); + LOGGER.info("Initialized sequances collection {}", name); } } - + private void initIndex() { // Make sure we have a unique index on name BasicDBObject keys = new BasicDBObject(NAME, 1); @@ -80,48 +109,92 @@ private void initIndex() { * @param inc The increment, Could be negative or positive. If 0, it is * assumed to be 1. Used only if the sequence does not exist prior to this * call + * @param poolSize If the sequence already has a pool associated + * with it, this is ignored, and the next id is used from the + * pool. Otherwise, a new pool with this size is initialized for + * the sequence * * If the sequence already exists, the init and * inc are ignored. * * @return The value of the sequence before the call */ - public long getNextSequenceValue(String name, long init, long inc) { + public long getNextSequenceValue(String name, long init, long inc, long poolSize) { LOGGER.debug("getNextSequenceValue({})", name); - // Read the sequence document - BasicDBObject q = new BasicDBObject(NAME, name); - DBObject doc = coll.findOne(q,null,ReadPreference.primary()); - if (doc == null) { - // Sequence document does not exist. Insert a new document using the init and inc - LOGGER.debug("inserting sequence record name={}, init={}, inc={}", name, init, inc); - if (inc == 0) { - inc = 1; + // First check if there is already a pool of ids available + String fullName=coll.getFullName()+"."+name; + rwl.readLock().lock(); + SequenceInfo si=sequenceInfo.get(fullName); + rwl.readLock().unlock(); + if(si==null) { + rwl.writeLock().lock(); + si=sequenceInfo.get(fullName); + if(si==null) { + si=new SequenceInfo(fullName); + sequenceInfo.put(fullName,si); } + rwl.writeLock().unlock(); + } - BasicDBObject u = new BasicDBObject(). + si.lock.lock(); + + long ret=0; + + try { + // If there are ids in the pool, use one + Long next=si.nextId(); + if(next!=null) { + return next; + } + // No ids in the pool + + // Read the sequence document + BasicDBObject q = new BasicDBObject(NAME, name); + DBObject doc = coll.findOne(q,null,ReadPreference.primary()); + if (doc == null) { + // Sequence document does not exist. Insert a new document using the init and inc + LOGGER.debug("inserting sequence record name={}, init={}, inc={}", name, init, inc); + if (inc == 0) { + inc = 1; + } + + BasicDBObject u = new BasicDBObject(). append(NAME, name). append(INIT, init). append(INC, inc). append(VALUE, init); - try { - coll.insert(u, WriteConcern.ACKNOWLEDGED); - } catch (Exception e) { - // Someone else might have inserted already, try to re-read - LOGGER.debug("Insertion failed with {}, trying to read", e); + try { + coll.insert(u, WriteConcern.ACKNOWLEDGED); + } catch (Exception e) { + // Someone else might have inserted already, try to re-read + LOGGER.debug("Insertion failed with {}, trying to read", e); + } + doc = coll.findOne(q,null,ReadPreference.primary()); + if (doc == null) { + throw new RuntimeException("Cannot generate value for " + name); + } } - doc = coll.findOne(q,null,ReadPreference.primary()); - if (doc == null) { - throw new RuntimeException("Cannot generate value for " + name); + LOGGER.debug("Sequence doc={}", doc); + Long increment = (Long) doc.get(INC); + + if(poolSize>1) { + si.inc=increment; + increment*=poolSize; } - } - LOGGER.debug("Sequence doc={}", doc); - Long increment = (Long) doc.get(INC); - BasicDBObject u = new BasicDBObject(). + BasicDBObject u = new BasicDBObject(). append("$inc", new BasicDBObject(VALUE, increment)); - // This call returns the unmodified document - doc = coll.findAndModify(q, u); - Long l = (Long) doc.get(VALUE); - LOGGER.debug("{} -> {}", name, l); - return l; + // This call returns the unmodified document + doc = coll.findAndModify(q, u); + ret = (Long) doc.get(VALUE); + // Here, ret is the next id to return + if(poolSize>1) { + si.poolSize=poolSize-1; + si.nextIdInPool=ret+si.inc; + } + LOGGER.debug("{} -> {}", name, ret); + } finally { + si.lock.unlock(); + } + return ret; } } diff --git a/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSequenceSupport.java b/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSequenceSupport.java index 2b402b81a..968591b89 100644 --- a/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSequenceSupport.java +++ b/mongo/src/main/java/com/redhat/lightblue/mongo/crud/MongoSequenceSupport.java @@ -69,6 +69,7 @@ public class MongoSequenceSupport implements ValueGeneratorSupport { public static final String PROP_COLLECTION = "collection"; public static final String PROP_INITIAL_VALUE = "initialValue"; public static final String PROP_INCREMENT = "increment"; + public static final String PROP_POOLSIZE="poolSize"; private static final ValueGenerator.ValueGeneratorType[] TYPES = {ValueGenerator.ValueGeneratorType.IntSequence}; @@ -93,23 +94,34 @@ public Object generateValue(EntityMetadata md, ValueGenerator generator) { if (collection == null) { collection = DEFAULT_COLLECTION_NAME; } - String initialValueStr = p.getProperty(PROP_INITIAL_VALUE); + Object initialValueStr = p.get(PROP_INITIAL_VALUE); long initialValue; if (initialValueStr == null) { initialValue = 1; } else { - initialValue = Long.valueOf(initialValueStr).longValue(); + initialValue = Long.valueOf(initialValueStr.toString()).longValue(); } - String incrementStr = p.getProperty(PROP_INCREMENT); + Object incrementStr = p.get(PROP_INCREMENT); long increment; if (incrementStr == null) { increment = 1; } else { - increment = Long.valueOf(incrementStr).longValue(); + increment = Long.valueOf(incrementStr.toString()).longValue(); } + Object poolSizeStr=p.get(PROP_POOLSIZE); + long poolSize; + if(poolSizeStr==null) { + poolSize=0; + } else { + poolSize=Long.valueOf(poolSizeStr.toString()).longValue(); + // A poolsize=1 is meaningless, don't pool IDs for poolsize=1 + if(poolSize<=1) + poolSize=0; + } + DB db = controller.getDbResolver().get((MongoDataStore) md.getDataStore()); DBCollection coll = db.getCollection(collection); MongoSequenceGenerator gen = new MongoSequenceGenerator(coll); - return gen.getNextSequenceValue(name, initialValue, increment); + return gen.getNextSequenceValue(name, initialValue, increment, poolSize); } } diff --git a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/GeneratorSupportTest.java b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/GeneratorSupportTest.java index 82e7af948..d7d650d26 100644 --- a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/GeneratorSupportTest.java +++ b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/GeneratorSupportTest.java @@ -26,9 +26,14 @@ import org.junit.Ignore; import com.mongodb.DB; +import com.mongodb.DBObject; +import com.mongodb.BasicDBObject; +import com.mongodb.DBCollection; import com.redhat.lightblue.metadata.EntityMetadata; import com.redhat.lightblue.metadata.ValueGenerator; +import com.redhat.lightblue.metadata.SimpleField; +import com.redhat.lightblue.util.Path; import com.redhat.lightblue.mongo.common.DBResolver; import com.redhat.lightblue.mongo.common.MongoDataStore; import com.redhat.lightblue.mongo.config.MongoConfiguration; @@ -58,6 +63,7 @@ public MongoConfiguration getConfiguration(MongoDataStore store) { return null; } }); + factory.registerValueGenerators("mongo",controller); } @Test @@ -72,4 +78,20 @@ public void testSeq() throws Exception { value = ss.generateValue(md, vg); Assert.assertEquals("2", value.toString()); } + + @Test + public void poolTest() throws Exception { + EntityMetadata md=getMd("./testMetadata-seq.json"); + ValueGeneratorSupport ss = controller.getExtensionInstance(ValueGeneratorSupport.class); + ValueGenerator vg=((SimpleField)md.resolve(new Path("_id"))).getValueGenerator(); + Object value = ss.generateValue(md, vg); + + DBObject q=new BasicDBObject("name","testSequence"); + + DBCollection seqCollection=db.getCollection("sequences"); + DBObject obj=seqCollection.findOne(q); + Assert.assertEquals(150l, ((Long)obj.get("value")).longValue()); + + + } } diff --git a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocolTest.java b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocolTest.java index 1142861ad..1d428fc5a 100644 --- a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocolTest.java +++ b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSafeUpdateProtocolTest.java @@ -18,25 +18,20 @@ */ package com.redhat.lightblue.mongo.crud; +import java.util.ArrayList; import java.util.List; import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import java.util.UUID; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; -import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; - +import com.mongodb.WriteResult; import com.redhat.lightblue.util.Error; public class MongoSafeUpdateProtocolTest extends AbstractMongoCrudTest { @@ -51,6 +46,10 @@ public TestUpdater(DBCollection coll) { super(coll,null,null); } + public TestUpdater(DBCollection coll, DBObject query) { + super(coll,null,query,null); + } + protected DBObject reapplyChanges(int docIndex,DBObject doc) { numRetries++; System.out.println("Retrying"); @@ -70,7 +69,7 @@ public void setup() throws Exception { } private void insertDoc(String id,String value) { - coll.insert(new BasicDBObject("_id",id).append("field",value)); + coll.insert(new BasicDBObject("_id",id).append("field",value).append("a", "b")); } /** @@ -383,5 +382,84 @@ public void secondThreadUpdatesAfterFirst() throws Exception { Assert.assertEquals(MongoCrudConstants.ERR_DUPLICATE,errors.get(3).getErrorCode()); } + + @Test + public void noConcurrentUpdateErrorsWhenQueryDoesNotMatchOnRetry() { + insert50(); + + final int retryCount[] = new int[] {0}; + + // Thread1 reads first 10 docs and updates them in memory + + List criteria = new ArrayList<>(); + criteria.add(new BasicDBObject("_id",new BasicDBObject("$lte","19"))); + criteria.add(new BasicDBObject("a", "b")); + DBObject query = new BasicDBObject("$and", criteria); + + TestUpdater updater=new TestUpdater(coll, query) { + + protected DBObject reapplyChanges(int docIndex,DBObject doc) { + Assert.fail("Expecting no reapply, since origin query not matching after concurrent update"); + return null; + } + + @Override + public void retryConcurrentUpdateErrorsIfNeeded(Map results) { + retryCount[0]++; + super.retryConcurrentUpdateErrorsIfNeeded(results); + } + }; + updater.getCfg().setFailureRetryCount(100); + + DBCursor cursor=coll.find(query); + + while(cursor.hasNext()) { + DBObject doc=cursor.next(); + doc.put("field","updated1"+doc.get("_id").toString()); + updater.addDoc(doc); + } + cursor.close(); + + // Thread 2 updates first 5 docs so that thread1's query does not match anymore + + TestUpdater updater2 = new TestUpdater(coll); + + cursor=coll.find(new BasicDBObject("_id",new BasicDBObject("$lte","14"))); + + while(cursor.hasNext()) { + DBObject doc=cursor.next(); + doc.put("a", "c"); + updater2.addDoc(doc); + } + cursor.close(); + + Map result = updater2.commit(); + Assert.assertEquals(0, result.size()); + + // Thread1 persists it's updates + Map err=updater.commit(); + // https://github.com/lightblue-platform/lightblue-mongo/issues/365 + Assert.assertTrue("Expecting no ConcurrentUpdate errors sent to client, because docs do not match the original query anymore", err.isEmpty()); + + cursor=coll.find(); + while(cursor.hasNext()) { + DBObject doc=cursor.next(); + + System.out.println(doc.get("_id")+" "+doc.get("a")+" "+doc.get("field")); + + if (Integer.parseInt(doc.get("_id").toString()) < 20) { + if (doc.get("a").toString().equals("b")) { + Assert.assertTrue("a: b docs should be updated by thread1", doc.get("field").toString().startsWith("updated1")); + } + if (doc.get("a").toString().equals("c")) { + Assert.assertFalse("a: c docs should NOT be updated by thread1", doc.get("field").toString().startsWith("updated1")); + } + + } + } + cursor.close(); + + Assert.assertEquals("Thread 1 should have retried only once", 1, retryCount[0]); + } } diff --git a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSequenceGeneratorTest.java b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSequenceGeneratorTest.java index 3373418de..1d2bd6a24 100644 --- a/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSequenceGeneratorTest.java +++ b/mongo/src/test/java/com/redhat/lightblue/mongo/crud/MongoSequenceGeneratorTest.java @@ -18,7 +18,14 @@ */ package com.redhat.lightblue.mongo.crud; +import java.util.Map; +import java.util.HashMap; + import org.junit.Test; +import org.junit.Before; + +import com.mongodb.DBObject; +import com.mongodb.BasicDBObject; import com.redhat.lightblue.mongo.crud.MongoSequenceGenerator; @@ -26,16 +33,151 @@ public class MongoSequenceGeneratorTest extends AbstractMongoCrudTest { + @Before + public void init() { + coll.remove(new BasicDBObject()); + MongoSequenceGenerator.sequenceInfo.clear(); + } + + @Test + public void zeroPoolTest() throws Exception { + MongoSequenceGenerator g = new MongoSequenceGenerator(coll); + + Assert.assertEquals(1, g.getNextSequenceValue("s1", 1, 1,0)); + validateId("s1",2); + Assert.assertEquals(100, g.getNextSequenceValue("s2", 100, 1,0)); + validateId("s2",101); + Assert.assertEquals(-1000, g.getNextSequenceValue("s3", -1000, 10,0)); + validateId("s3",-990); + Assert.assertEquals(2, g.getNextSequenceValue("s1", 123, 123,0)); + validateId("s1",3); + Assert.assertEquals(3, g.getNextSequenceValue("s1", 213, 123,0)); + validateId("s1",4); + Assert.assertEquals(101, g.getNextSequenceValue("s2", 1234, 123,0)); + validateId("s2",102); + Assert.assertEquals(-990, g.getNextSequenceValue("s3", 123, 123,0)); + validateId("s3",-980); + } + @Test - public void theTest() throws Exception { + public void onePoolTest() throws Exception { MongoSequenceGenerator g = new MongoSequenceGenerator(coll); - Assert.assertEquals(1, g.getNextSequenceValue("s1", 1, 1)); - Assert.assertEquals(100, g.getNextSequenceValue("s2", 100, 1)); - Assert.assertEquals(-1000, g.getNextSequenceValue("s3", -1000, 10)); - Assert.assertEquals(2, g.getNextSequenceValue("s1", 123, 123)); - Assert.assertEquals(3, g.getNextSequenceValue("s1", 213, 123)); - Assert.assertEquals(101, g.getNextSequenceValue("s2", 1234, 123)); - Assert.assertEquals(-990, g.getNextSequenceValue("s3", 123, 123)); + Assert.assertEquals(1, g.getNextSequenceValue("s1", 1, 1,1)); + validateId("s1",2); + Assert.assertEquals(100, g.getNextSequenceValue("s2", 100, 1,1)); + validateId("s2",101); + Assert.assertEquals(-1000, g.getNextSequenceValue("s3", -1000, 10,1)); + validateId("s3",-990); + Assert.assertEquals(2, g.getNextSequenceValue("s1", 123, 123,1)); + validateId("s1",3); + Assert.assertEquals(3, g.getNextSequenceValue("s1", 213, 123,1)); + validateId("s1",4); + Assert.assertEquals(101, g.getNextSequenceValue("s2", 1234, 123,1)); + validateId("s2",102); + Assert.assertEquals(-990, g.getNextSequenceValue("s3", 123, 123,1)); + validateId("s3",-980); + } + + @Test + public void bigPoolTest() throws Exception { + MongoSequenceGenerator g = new MongoSequenceGenerator(coll); + + Assert.assertEquals(1, g.getNextSequenceValue("s1", 1, 1,2)); + validateId("s1",3); + Assert.assertEquals(2, g.getNextSequenceValue("s1", 1, 1,2)); + validateId("s1",3); + Assert.assertEquals(3, g.getNextSequenceValue("s1", 1, 1,2)); + validateId("s1",5); + Assert.assertEquals(4, g.getNextSequenceValue("s1", 1, 1,2)); + validateId("s1",5); + + + Assert.assertEquals(100, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",103); + Assert.assertEquals(101, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",103); + Assert.assertEquals(102, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",103); + Assert.assertEquals(103, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",106); + Assert.assertEquals(104, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",106); + Assert.assertEquals(105, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",106); + Assert.assertEquals(106, g.getNextSequenceValue("s2", 100, 1,3)); + validateId("s2",109); + + Assert.assertEquals(-1000, g.getNextSequenceValue("s3", -1000, 10,3)); + validateId("s3",-970); + Assert.assertEquals(-990, g.getNextSequenceValue("s3", -1000, 10,3)); + validateId("s3",-970); + Assert.assertEquals(-980, g.getNextSequenceValue("s3", -1000, 10,3)); + validateId("s3",-970); + Assert.assertEquals(-970, g.getNextSequenceValue("s3", -1000, 10,3)); + validateId("s3",-940); + } + + @Test + public void multipleGeneratorsTest() throws Exception { + // Simulate two different machines by swapping sequenceInfo + Map s1=new HashMap<>(); + Map s2=new HashMap<>(); + MongoSequenceGenerator g = new MongoSequenceGenerator(coll); + + g.sequenceInfo=s1; + Assert.assertEquals(1, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",6); + + g.sequenceInfo=s2; + Assert.assertEquals(6, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s1; + Assert.assertEquals(2, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s2; + Assert.assertEquals(7, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s1; + Assert.assertEquals(3, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s2; + Assert.assertEquals(8, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s1; + Assert.assertEquals(4, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s2; + Assert.assertEquals(9, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s1; + Assert.assertEquals(5, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s2; + Assert.assertEquals(10, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",11); + + g.sequenceInfo=s1; + Assert.assertEquals(11, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",16); + + g.sequenceInfo=s2; + Assert.assertEquals(16, g.getNextSequenceValue("s1", 1, 1,5)); + validateId("s1",21); + + } + + private void validateId(String seq,long expected) throws Exception { + DBObject obj=coll.findOne(new BasicDBObject("name",seq)); + Long l=(Long)obj.get("value"); + Assert.assertEquals(expected, l.longValue()); } } diff --git a/mongo/src/test/resources/testMetadata-seq.json b/mongo/src/test/resources/testMetadata-seq.json new file mode 100644 index 000000000..94e388513 --- /dev/null +++ b/mongo/src/test/resources/testMetadata-seq.json @@ -0,0 +1,39 @@ +{ + "entityInfo": { + "name": "test", + "datastore": { + "backend":"mongo", + "collection": "data" + } + }, + "schema": { + "name": "test", + "version": { + "value": "1.0", + "changelog": "blahblah" + }, + "status": { + "value": "active" + }, + "access" : { + "insert" : ["anyone"], + "update" : ["anyone"], + "delete" : [ "anyone" ] , + "find" : [ "anyone" ] + }, + "fields": { + "objectType": {"type": "string"}, + "_id": { + "type": "integer", + "valueGenerator": { + "configuration": { + "initialValue": "100", + "name": "testSequence", + "poolSize": 50 + }, + "type": "IntSequence" + } + } + } + } +} diff --git a/pom.xml b/pom.xml index 2a84b12b9..477744817 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.redhat.lightblue.mongo lightblue-mongo-pom pom - 1.28.0-SNAPSHOT + 1.29.0-SNAPSHOT lightblue-mongo: ${project.groupId}|${project.artifactId} Lightblue MongoDB implementation @@ -99,43 +99,43 @@ com.redhat.lightblue lightblue-core-metadata - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-crud - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-api - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-util - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-query-api - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-config - 2.9.0-SNAPSHOT + ${lightblue.core.version} com.redhat.lightblue lightblue-core-test - 2.9.0-SNAPSHOT + ${lightblue.core.version} test com.redhat.lightblue lightblue-core-extensions - 2.9.0-SNAPSHOT + ${lightblue.core.version} org.mockito @@ -215,7 +215,7 @@ lines,vars,source true - 2.0.1-SNAPSHOT + 2.10.0-SNAPSHOT diff --git a/test/pom.xml b/test/pom.xml index 6d6fd97cb..ce736aa19 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -22,7 +22,7 @@ com.redhat.lightblue.mongo lightblue-mongo-pom - 1.28.0-SNAPSHOT + 1.29.0-SNAPSHOT com.redhat.lightblue.mongo lightblue-mongo-test