@Test public void testBasicLocalSync() throws Exception { waitForFullMesh(2000); ArrayList<IStoreClient<String, String>> clients = new ArrayList<IStoreClient<String, String>>(syncManagers.length); // write one value to each node's local interface for (int i = 0; i < syncManagers.length; i++) { IStoreClient<String, String> client = syncManagers[i].getStoreClient("local", String.class, String.class); clients.add(client); client.put("key" + i, "" + i); } // verify that we see all the values from each local group at all the // nodes of that local group for (int j = 0; j < clients.size(); j++) { IStoreClient<String, String> client = clients.get(j); for (int i = 0; i < syncManagers.length; i++) { if (i % 2 == j % 2) waitForValue(client, "key" + i, "" + i, 2000, "client" + j); else { Versioned<String> v = client.get("key" + i); if (v.getValue() != null) { fail("Node " + j + " reading key" + i + ": " + v.getValue()); } } } } }
@Test public void testBasicOneNode() throws Exception { AbstractSyncManager sync = syncManagers[0]; IStoreClient<Key, TBean> testClient = sync.getStoreClient("global", Key.class, TBean.class); Key k = new Key("com.bigswitch.bigsync.internal", "test"); TBean tb = new TBean("hello", 42); TBean tb2 = new TBean("hello", 84); TBean tb3 = new TBean("hello", 126); assertNotNull(testClient.get(k)); assertNull(testClient.get(k).getValue()); testClient.put(k, tb); Versioned<TBean> result = testClient.get(k); assertEquals(result.getValue(), tb); result.setValue(tb2); testClient.put(k, result); try { result.setValue(tb3); testClient.put(k, result); fail("Should get ObsoleteVersionException"); } catch (ObsoleteVersionException e) { // happy town } result = testClient.get(k); assertEquals(tb2, result.getValue()); }
@Override public void put(ByteArray key, Versioned<byte[]> value) throws SyncException { StoreUtils.assertValidKey(key); try (Connection dbConnection = getConnection()) { dbConnection.setAutoCommit(false); try (PreparedStatement stmt = dbConnection.prepareStatement(getSql(SELECT_KEY))) { String keyStr = getKeyAsString(key); List<Versioned<byte[]>> values = doSelect(stmt, keyStr); int vindex; int kindex; String sql; if (values.size() > 0) { sql = getSql(UPDATE_KEY); kindex = 2; vindex = 1; } else { sql = getSql(INSERT_KEY); kindex = 1; vindex = 2; } try (PreparedStatement update = dbConnection.prepareStatement(sql)) { update.setString(kindex, keyStr); List<Versioned<byte[]>> itemsToRemove = new ArrayList<Versioned<byte[]>>(values.size()); for (Versioned<byte[]> versioned : values) { Occurred occurred = value.getVersion().compare(versioned.getVersion()); if (occurred == Occurred.BEFORE) { throw new ObsoleteVersionException( "Obsolete version for key '" + key + "': " + value.getVersion()); } else if (occurred == Occurred.AFTER) { itemsToRemove.add(versioned); } } values.removeAll(itemsToRemove); values.add(value); ByteArrayInputStream is = new ByteArrayInputStream(mapper.writeValueAsBytes(values)); update.setBinaryStream(vindex, is); update.execute(); } } catch (SyncException e) { dbConnection.rollback(); throw e; } catch (Exception e) { dbConnection.rollback(); throw new PersistException("Could not retrieve key from database", e); } dbConnection.commit(); dbConnection.setAutoCommit(true); } catch (SQLException e) { throw new PersistException("Could not clean up", e); } }
@Test public void testNotify() throws Exception { IStoreClient<String, String> client0 = syncManagers[0].getStoreClient("local", String.class, String.class); IStoreClient<String, String> client2 = syncManagers[2].getStoreClient( "local", new TypeReference<String>() {}, new TypeReference<String>() {}); TestListener t0 = new TestListener(); TestListener t2 = new TestListener(); client0.addStoreListener(t0); client2.addStoreListener(t2); client0.put("test0", "value"); client2.put("test2", "value"); HashSet<Update> c0 = new HashSet<Update>(); c0.add(new Update("test0", UpdateType.LOCAL)); c0.add(new Update("test2", UpdateType.REMOTE)); HashSet<Update> c2 = new HashSet<Update>(); c2.add(new Update("test0", UpdateType.REMOTE)); c2.add(new Update("test2", UpdateType.LOCAL)); waitForNotify(t0, c0, 2000); waitForNotify(t2, c2, 2000); assertEquals(2, t0.notified.size()); assertEquals(2, t2.notified.size()); t0.notified.clear(); t2.notified.clear(); Versioned<String> v0 = client0.get("test0"); v0.setValue("newvalue"); client0.put("test0", v0); Versioned<String> v2 = client0.get("test2"); v2.setValue("newvalue"); client2.put("test2", v2); waitForNotify(t0, c0, 2000); waitForNotify(t2, c2, 2000); assertEquals(2, t0.notified.size()); assertEquals(2, t2.notified.size()); t0.notified.clear(); t2.notified.clear(); client0.delete("test0"); client2.delete("test2"); waitForNotify(t0, c0, 2000); waitForNotify(t2, c2, 2000); assertEquals(2, t0.notified.size()); assertEquals(2, t2.notified.size()); }
protected static <K, V> Versioned<V> waitForValue( IStoreClient<K, V> client, K key, V value, int maxTime, String clientName) throws Exception { Versioned<V> v = null; long then = System.currentTimeMillis(); while (true) { v = client.get(key); if (value != null) { if (v.getValue() != null && v.getValue().equals(value)) break; } else { if (v.getValue() != null) break; } if (v.getValue() != null) logger.info( "{}: Value for key {} not yet right: " + "expected: {}; actual: {}", new Object[] {clientName, key, value, v.getValue()}); else logger.info( "{}: Value for key {} is null: expected {}", new Object[] {clientName, key, value}); Thread.sleep(100); assertTrue(then + maxTime > System.currentTimeMillis()); } return v; }