/** * The asynchronous version of getData. * * @see #getData(String, Watcher, Stat) */ public void getData(final String path, Watcher watcher, DataCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, wcb); }
/** * The asynchronous version of getConfig. * * @see #getConfig(Watcher, Stat) */ public void getConfig(Watcher watcher, DataCallback cb, Object ctx) { final String configZnode = ZooDefs.CONFIG_NODE; // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, configZnode); } RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(configZnode); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, configZnode, configZnode, ctx, wcb); }
/** * The Asynchronous version of getData. The request doesn't actually until * the asynchronous callback is called. * * @see #getData(String, Watcher, Stat) */ public void getData(final String path, Watcher watcher, DataCallback cb, Object ctx) { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); cnxn.queuePacket(h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, wcb); }
/** * Return the data and the stat of the node of the given path. * <p> * If the watch is non-null and the call is successful (no exception is * thrown), a watch will be left on the node with the given path. The watch * will be triggered by a successful operation that sets data on the node, or * deletes the node. * <p> * A KeeperException with error code KeeperException.NoNode will be thrown * if no node with the given path exists. * * @param path the given path * @param watcher explicit watcher * @param stat the stat of the node * @return the data of the node * @throws KeeperException If the server signals an error with a non-zero error code * @throws InterruptedException If the server transaction is interrupted. * @throws IllegalArgumentException if an invalid path is specified */ public byte[] getData(final String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException { final String clientPath = path; PathUtils.validatePath(clientPath); // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, clientPath); } final String serverPath = prependChroot(clientPath); RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(serverPath); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, wcb); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath); } if (stat != null) { DataTree.copyStat(response.getStat(), stat); } return response.getData(); }
/** * Return the last committed configuration (as known to the server to which the client is connected) * and the stat of the configuration. * <p> * If the watch is non-null and the call is successful (no exception is * thrown), a watch will be left on the configuration node (ZooDefs.CONFIG_NODE). The watch * will be triggered by a successful reconfig operation * <p> * A KeeperException with error code KeeperException.NoNode will be thrown * if the configuration node doesn't exists. * * @param watcher explicit watcher * @param stat the stat of the configuration node ZooDefs.CONFIG_NODE * @return configuration data stored in ZooDefs.CONFIG_NODE * @throws KeeperException If the server signals an error with a non-zero error code * @throws InterruptedException If the server transaction is interrupted. */ public byte[] getConfig(Watcher watcher, Stat stat) throws KeeperException, InterruptedException { final String configZnode = ZooDefs.CONFIG_NODE; // the watch contains the un-chroot path WatchRegistration wcb = null; if (watcher != null) { wcb = new DataWatchRegistration(watcher, configZnode); } RequestHeader h = new RequestHeader(); h.setType(ZooDefs.OpCode.getData); GetDataRequest request = new GetDataRequest(); request.setPath(configZnode); request.setWatch(watcher != null); GetDataResponse response = new GetDataResponse(); ReplyHeader r = cnxn.submitRequest(h, request, response, wcb); if (r.getErr() != 0) { throw KeeperException.create(KeeperException.Code.get(r.getErr()), configZnode); } if (stat != null) { DataTree.copyStat(response.getStat(), stat); } return response.getData(); }
public void sendReadRequest() throws Exception { ByteArrayOutputStream boas = new ByteArrayOutputStream(); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(boas); GetDataRequest getDataRequest = new GetDataRequest( "/session" + Long.toHexString(sessionId) + "-" + nodeId, false); getDataRequest.serialize(boa, "request"); ByteBuffer bb = ByteBuffer.wrap(boas.toByteArray()); Request req = new Request(null, sessionId, ++cxid, OpCode.getData, bb, new ArrayList<Id>()); zks.getFirstProcessor().processRequest(req); }
public Request poll() { readReqId++; try { return newRequest(new GetDataRequest("/", false), OpCode.getData, readReqId % 50, readReqId); } catch (IOException e) { e.printStackTrace(); } ; return null; }
/** * We place a read request followed by committed update request of the same * session in queuedRequests. We verify that both requests are processed, * according to the order of the session (first read, then the write). */ @Test public void committedAndUncommittedOfTheSameSessionRaceTest() throws Exception { final String path = "/testCvsUCRace"; Request readReq = newRequest(new GetDataRequest(path, false), OpCode.getData, 0x0, 0); Request writeReq = newRequest( new SetDataRequest(path, new byte[16], -1), OpCode.setData, 0x0, 1); processor.committedRequests.add(writeReq); processor.queuedRequests.add(readReq); processor.queuedRequests.add(writeReq); processor.initThreads(1); processor.stoppedMainLoop = true; processor.run(); Assert.assertTrue( "Request was not processed " + readReq + " instead " + processedRequests.peek(), processedRequests.peek() != null && processedRequests.peek().equals(readReq)); processedRequests.poll(); Assert.assertTrue( "Request was not processed " + writeReq + " instead " + processedRequests.peek(), processedRequests.peek() != null && processedRequests.peek().equals(writeReq)); }
private Request makeGetDataRequest(String path, long sessionId) throws IOException { ByteArrayOutputStream boas = new ByteArrayOutputStream(); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(boas); GetDataRequest getDataRequest = new GetDataRequest(path, false); getDataRequest.serialize(boa, "request"); ByteBuffer bb = ByteBuffer.wrap(boas.toByteArray()); return new Request(null, sessionId, 1, ZooDefs.OpCode.getData, bb, new ArrayList<Id>()); }
private EventType checkType(Record response) { if (response == null) { return EventType.other; } else if (response instanceof ConnectRequest) { return EventType.write; } else if (response instanceof CreateRequest) { return EventType.write; } else if (response instanceof DeleteRequest) { return EventType.write; } else if (response instanceof SetDataRequest) { return EventType.write; } else if (response instanceof SetACLRequest) { return EventType.write; } else if (response instanceof SetMaxChildrenRequest) { return EventType.write; } else if (response instanceof SetSASLRequest) { return EventType.write; } else if (response instanceof SetWatches) { return EventType.write; } else if (response instanceof SyncRequest) { return EventType.write; } else if (response instanceof ExistsRequest) { return EventType.read; } else if (response instanceof GetDataRequest) { return EventType.read; } else if (response instanceof GetMaxChildrenRequest) { return EventType.read; } else if (response instanceof GetACLRequest) { return EventType.read; } else if (response instanceof GetChildrenRequest) { return EventType.read; } else if (response instanceof GetChildren2Request) { return EventType.read; } else if (response instanceof GetSASLRequest) { return EventType.read; } else { return EventType.other; } }
public void sendReadRequest() throws Exception { ByteArrayOutputStream boas = new ByteArrayOutputStream(); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(boas); GetDataRequest getDataRequest = new GetDataRequest( "/session" + Long.toHexString(sessionId) + "-" + nodeId, false); getDataRequest.serialize(boa, "request"); ByteBuffer bb = ByteBuffer.wrap(boas.toByteArray()); Request req = new Request(null, sessionId, ++cxid, OpCode.getData, bb, new ArrayList<Id>()); zks.firstProcessor.processRequest(req); }
@Test public void raceTest() throws Exception { ByteArrayOutputStream boas = new ByteArrayOutputStream(); BinaryOutputArchive boa = BinaryOutputArchive.getArchive(boas); GetDataRequest getReq = new GetDataRequest("/testrace", false); getReq.serialize(boa, "request"); ByteBuffer bb = ByteBuffer.wrap(boas.toByteArray()); Request readReq = new Request(null, 0x0, 0, OpCode.getData, bb, new ArrayList<Id>()); boas.reset(); SyncRequest syncReq = new SyncRequest("/testrace"); syncReq.serialize(boa, "request"); bb = ByteBuffer.wrap(boas.toByteArray()); Request writeReq = new Request(null, 0x0, 0, OpCode.sync, bb, new ArrayList<Id>()); processor.addToCommittedRequests(writeReq); processor.addToQueuedRequests(readReq); processor.addToQueuedRequests(writeReq); processor.testStart(); processor.testProcessCommitted(); Assert.assertFalse("Next request processor executed", executedFlag); }
/** * In the following test, we add a write request followed by several read * requests of the same session, and we verify several things - 1. The write * is not processed until commit arrives. 2. Once the write is processed, * all the read requests are processed as well. 3. All read requests are * executed after the write, before any other write, along with new reads. */ @Test public void processAllFollowingUncommittedAfterFirstCommitTest() throws Exception { final String path = "/testUncommittedFollowingCommited"; Set<Request> shouldBeInPending = new HashSet<Request>(); Set<Request> shouldBeProcessedAfterPending = new HashSet<Request>(); Request writeReq = newRequest( new CreateRequest(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL.toFlag()), OpCode.create, 0x1, 1); processor.queuedRequests.add(writeReq); shouldBeInPending.add(writeReq); for (int readReqId = 2; readReqId <= 5; ++readReqId) { Request readReq = newRequest(new GetDataRequest(path, false), OpCode.getData, 0x1, readReqId); processor.queuedRequests.add(readReq); shouldBeInPending.add(readReq); shouldBeProcessedAfterPending.add(readReq); } processor.initThreads(defaultSizeOfThreadPool); processor.stoppedMainLoop = true; processor.run(); Assert.assertTrue("Processed without waiting for commit", processedRequests.isEmpty()); Assert.assertTrue("Did not handled all of queuedRequests' requests", processor.queuedRequests.isEmpty()); shouldBeInPending .removeAll(processor.pendingRequests.get(writeReq.sessionId)); for (Request r : shouldBeInPending) { LOG.error("Should be in pending " + r); } Assert.assertTrue( "Not all requests moved to pending from queuedRequests", shouldBeInPending.isEmpty()); processor.committedRequests.add(writeReq); processor.stoppedMainLoop = true; processor.run(); processor.initThreads(defaultSizeOfThreadPool); Thread.sleep(500); Assert.assertTrue("Did not process committed request", processedRequests.peek() == writeReq); Assert.assertTrue("Did not process following read request", processedRequests.containsAll(shouldBeProcessedAfterPending)); Assert.assertTrue("Did not process committed request", processor.committedRequests.isEmpty()); Assert.assertTrue("Did not process committed request", processor.pendingRequests.isEmpty()); }
/** * In the following test, we verify that we can handle the case that we got a commit * of a request we never seen since the session that we just established. This can happen * when a session is just established and there is request waiting to be committed in the * session queue but it sees a commit for a request that belongs to the previous connection. */ @Test(timeout = 5000) public void noCrashOnCommittedRequestsOfUnseenRequestTest() throws Exception { final String path = "/noCrash/OnCommittedRequests/OfUnseenRequestTest"; final int numberofReads = 10; final int sessionid = 0x123456; final int firstCXid = 0x100; int readReqId = firstCXid; processor.stoppedMainLoop = true; HashSet<Request> localRequests = new HashSet<Request>(); // queue the blocking write request to queuedRequests Request firstCommittedReq = newRequest( new CreateRequest(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL.toFlag()), OpCode.create, sessionid, readReqId++); processor.queuedRequests.add(firstCommittedReq); localRequests.add(firstCommittedReq); // queue read requests to queuedRequests for (; readReqId <= numberofReads+firstCXid; ++readReqId) { Request readReq = newRequest(new GetDataRequest(path, false), OpCode.getData, sessionid, readReqId); processor.queuedRequests.add(readReq); localRequests.add(readReq); } //run once Assert.assertTrue(processor.queuedRequests.containsAll(localRequests)); processor.initThreads(defaultSizeOfThreadPool); processor.run(); Thread.sleep(1000); //We verify that the processor is waiting for the commit Assert.assertTrue(processedRequests.isEmpty()); // We add a commit that belongs to the same session but with smaller cxid, // i.e., commit of an update from previous connection of this session. Request preSessionCommittedReq = newRequest( new CreateRequest(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL.toFlag()), OpCode.create, sessionid, firstCXid - 2); processor.committedRequests.add(preSessionCommittedReq); processor.committedRequests.add(firstCommittedReq); processor.run(); Thread.sleep(1000); //We verify that the commit processor processed the old commit prior to the newer messages Assert.assertTrue(processedRequests.peek() == preSessionCommittedReq); processor.run(); Thread.sleep(1000); //We verify that the commit processor handle all messages. Assert.assertTrue(processedRequests.containsAll(localRequests)); }
/** * In the following test, we verify if we handle the case in which we get a commit * for a request that has higher Cxid than the one we are waiting. This can happen * when a session connection is lost but there is a request waiting to be committed in the * session queue. However, since the session has moved, new requests can get to * the leader out of order. Hence, the commits can also arrive "out of order" w.r.t. cxid. * We should commit the requests according to the order we receive from the leader, i.e., wait for the relevant commit. */ @Test(timeout = 5000) public void noCrashOnOutofOrderCommittedRequestTest() throws Exception { final String path = "/noCrash/OnCommittedRequests/OfUnSeenRequestTest"; final int sessionid = 0x123456; final int lastCXid = 0x100; final int numberofReads = 10; int readReqId = lastCXid; processor.stoppedMainLoop = true; HashSet<Request> localRequests = new HashSet<Request>(); // queue the blocking write request to queuedRequests Request orphanCommittedReq = newRequest( new CreateRequest(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL.toFlag()), OpCode.create, sessionid, lastCXid); processor.queuedRequests.add(orphanCommittedReq); localRequests.add(orphanCommittedReq); // queue read requests to queuedRequests for (; readReqId <= numberofReads+lastCXid; ++readReqId) { Request readReq = newRequest(new GetDataRequest(path, false), OpCode.getData, sessionid, readReqId); processor.queuedRequests.add(readReq); localRequests.add(readReq); } //run once processor.initThreads(defaultSizeOfThreadPool); processor.run(); Thread.sleep(1000); //We verify that the processor is waiting for the commit Assert.assertTrue(processedRequests.isEmpty()); // We add a commit that belongs to the same session but with larger cxid, // i.e., commit of an update from the next connection of this session. Request otherSessionCommittedReq = newRequest( new CreateRequest(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL.toFlag()), OpCode.create, sessionid, lastCXid+10); processor.committedRequests.add(otherSessionCommittedReq); processor.committedRequests.add(orphanCommittedReq); processor.run(); Thread.sleep(1000); //We verify that the commit processor processed the old commit prior to the newer messages Assert.assertTrue(processedRequests.size() == 1); Assert.assertTrue(processedRequests.contains(otherSessionCommittedReq)); processor.run(); Thread.sleep(1000); //We verify that the commit processor handle all messages. Assert.assertTrue(processedRequests.containsAll(localRequests)); }
public IGetDataRequest() { this(new GetDataRequest()); }
public IGetDataRequest(String path, boolean watch) { this(new GetDataRequest(path, watch)); }
public IGetDataRequest(GetDataRequest record) { super(record); }