/** * * @param payload Can be <code>null</code>. * @param statusCode * @param packetId */ public static Collection<ResponsePacket> create(DataPacket payload, StatusCode statusCode, UniqueId packetId) { if (payload instanceof Splittable && payload.isTooBig()) { Collection<? extends DataPacket> dataPackets = ((Splittable)payload).split(); ArrayList<ResponsePacket> responsePackets = new ArrayList<ResponsePacket>(); for (DataPacket dataPacket: dataPackets) responsePackets.add(new ResponsePacket(dataPacket, statusCode, packetId)); return responsePackets; } else return Collections.singleton(new ResponsePacket(payload, statusCode, packetId)); }
/** * Sends a Response Packet to a {@link Destination}. * @param packet Can be <code>null</code> for a response that only contains a status code. * @param destination * @param statusCode * @param requestPacketId The packet id of the packet we're responding to */ public void sendResponse(DataPacket packet, Destination destination, StatusCode statusCode, UniqueId requestPacketId) { send(ResponsePacket.create(packet, statusCode, requestPacketId), destination); }
@Override public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) { // synchronize access to lastSentPacket (which can be null, so synchronize on "this") synchronized(this) { if (lastSentPacket!=null && packet instanceof ResponsePacket) { ResponsePacket responsePacket = (ResponsePacket)packet; boolean packetIdMatches = lastSentPacket.getPacketId().equals(responsePacket.getPacketId()); boolean statusOk = StatusCode.OK == responsePacket.getStatusCode(); if (packetIdMatches && statusOk) confirmationReceived.countDown(); } } } }
@Override public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) { if (packet instanceof ResponsePacket) { ResponsePacket responsePacket = (ResponsePacket)packet; synchronized(pendingRequests) { FindClosePeersPacket request = getPacketById(pendingRequests.values(), responsePacket.getPacketId()); // find the request the node list is in response to // if the packet is in response to a pending request, update responses + notQueriedYet + pendingRequests if (request != null) { log.debug("Response to FindCloseNodesPacket received from " + Util.toShortenedBase32(sender)); responses.add(sender); DataPacket payload = responsePacket.getPayload(); if (payload instanceof PeerList) updatePeers((PeerList)payload, sender, receiveTime); pendingRequests.remove(sender); } } } else if (packet instanceof MalformedCommunicationPacket) pendingRequests.remove(sender); // since it is not generally possible to tell if an invalid comm packet is in response to a certain request, always remove invalid packets from the pending list }
@Test public void toByteArrayAndBack() throws Exception { byte[] arrayA = responsePacket.toByteArray(); byte[] arrayB = new ResponsePacket(arrayA).toByteArray(); assertArrayEquals("The two arrays differ!", arrayA, arrayB); } }
@Override public byte[] toByteArray() { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); DataOutputStream dataStream = new DataOutputStream(byteStream); try { writeHeader(dataStream); dataStream.write(statusCode.ordinal()); if (payload == null) dataStream.writeShort(0); else { byte[] payloadBytes = payload.toByteArray(); dataStream.writeShort(payloadBytes.length); dataStream.write(payloadBytes); } } catch (IOException e) { log.error("Can't write to ByteArrayOutputStream.", e); } return byteStream.toByteArray(); }
@Override public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) { if (packet instanceof ResponsePacket) { UniqueId packetId = packet.getPacketId(); for (PacketBatch batch: runningBatches) if (batch.contains(packetId)) { DataPacket payload = ((ResponsePacket)packet).getPayload(); if (payload != null) batch.addResponse(sender, payload); else batch.addResponse(sender, new EmptyResponse()); } } }
@Before public void setUp() throws Exception { byte[] packetIdBytes = new byte[] {120, 120, -8, -88, 21, 126, 46, -61, 18, -101, 15, 53, 20, -44, -112, 42, 86, -117, 30, -96, -66, 33, 71, -55, -102, -78, 78, -82, -105, 66, -116, 43}; UniqueId packetId = new UniqueId(packetIdBytes, 0); Collection<ResponsePacket> responsePackets = ResponsePacket.create(createDataPacket(), StatusCode.OK, packetId); assertEquals(1, responsePackets.size()); responsePacket = responsePackets.iterator().next(); }
DhtStorablePacket storedPacket = storageHandler.retrieve(retrieveRequest.getKey()); Collection<ResponsePacket> response = ResponsePacket.create(storedPacket, StatusCode.OK, retrieveRequest.getPacketId()); if (storedPacket != null) log.debug("Packet found for retrieve request: [" + retrieveRequest + "], replying to sender: [" + Util.toBase32(sender) + "]"); DeletionInfoPacket delInfo = new DeletionInfoPacket(); delInfo.put(dhtKey, delAuthorization); Collection<ResponsePacket> response = ResponsePacket.create(delInfo, StatusCode.OK, packet.getPacketId()); sendQueue.send(response, sender);