From e1eb9a17f3c0f77c5eb373114d0e0648237d6114 Mon Sep 17 00:00:00 2001 From: Daniel Andres Pelaez Lopez Date: Fri, 5 Oct 2018 13:43:28 -0500 Subject: [PATCH] Handling file transfer progress (#39) * Modifying how the sockets connections is processed * Adding factory changes * Excluding communication api dependency * Removing unnecesary files * Updating dhash layer * Adding dhash changes * Adding new transfer communication methods * Adding receive method * Integration tests worked * Defining MessageStream and resources classes * Changing resources approach, removing checksum * New classes and serialization is working, integration tests passes * Async operations. Integrations tests passed * Refactoring * Refactoring * Refactoring * Refactoring * Message refactoring * Changing log api * Refactoring. Integration tests working * Adding close to Resource interface * Adding unit tests * Adding unit tests * Using LocalFileResource * Defining versions and publishing * Updating readme --- README.md | 2 +- communication/communication-api/build.gradle | 4 +- ...equenceGenerator.java => IdGenerator.java} | 4 +- .../utils/communication/message/Message.java | 43 +-- .../communication/message/MessageStream.java | 21 ++ ...eGeneratorImpl.java => UUIDGenerator.java} | 27 +- .../transfer/CommunicationManager.java | 75 +++- .../transfer/ConnectionHandler.java | 7 + .../transfer/MessageStreamProcessor.java | 30 +- .../transfer/ProgressStatusTransfer.java | 5 + .../communication/transfer/StreamManager.java | 10 + .../data-structure-communication/build.gradle | 6 +- .../structure/CommunicationDataStructure.java | 118 +++++- .../CommunicationDataStructureFactory.java | 10 +- .../main/resources/schema/communication.xsd | 53 --- .../src/main/resources/schema/message.xsd | 91 ----- .../src/main/resources/schema/utils.xsd | 34 -- .../socket-communication/build.gradle | 8 +- .../communication/transfer/Communicator.java | 12 +- .../transfer/ConnectionListener.java | 8 + .../transfer/StreamCommunicator.java | 9 + .../network/CommunicationManagerTCP.java | 145 +++++--- .../CommunicationManagerTCPFactory.java | 39 +- .../ConnectionHandlerAsynchronous.java | 21 ++ .../transfer/network/ConnectionReceiver.java | 57 +++ .../transfer/network/MulticastManagerUDP.java | 163 +++----- .../transfer/network/UnicastManagerTCP.java | 242 +++++++----- .../network/jackson/AddressMixIn.java | 2 +- .../network/jackson/MessageTypeMixIn.java | 2 +- .../ConnectionMessageProcessorGateway.java | 59 +++ ...ay.java => MessageProcessorExecution.java} | 9 +- .../response/MessageResponseProcessor.java | 7 +- .../MessageStreamProcessorExecution.java | 38 ++ .../MessageStreamProcessorOutput.java | 9 + .../transfer/response/MessagesReceiver.java | 2 +- .../transfer/response/ReturnsManager.java | 12 +- .../response/ReturnsManagerCommunication.java | 28 +- .../transfer/response/WaitingResult.java | 57 ++- .../main/resources/schema/communication.xsd | 53 --- .../src/main/resources/schema/message.xsd | 91 ----- .../src/main/resources/schema/utils.xsd | 34 -- gradle.properties | 8 +- it/data-structure-it/build.gradle | 8 +- .../gets/GetsDefinitionStep.java | 9 +- .../datastructure/put/PutsDefinitionStep.java | 13 +- .../ring/RingDefinitionStep.java | 2 +- .../src/main/resources/log4j.xml | 102 ----- it/socket-it/Dockerfile | 2 +- it/socket-it/build.gradle | 12 +- .../socket/test/gets/GetsDefinitionStep.java | 12 +- .../socket/test/put/PutsDefinitionStep.java | 8 +- .../socket/test/ring/RingDefinitionStep.java | 8 +- .../resources/features/new-node.feature | 2 +- .../uniquindio/dht/it/socket/Protocol.java | 18 +- .../dht/it/socket/node/MessageServer.java | 10 +- .../dht/it/socket/node/NodeMain.java | 13 +- .../it/socket/node/NodeMessageProcessor.java | 54 +-- .../uniquindio/dht/it/socket/test/ITMain.java | 9 +- .../dht/it/socket/test/MessageClient.java | 7 +- .../src/main/resources/application.yml | 15 +- it/socket-it/src/main/resources/log4j.xml | 102 ----- main/desktop-network-gui/build.gradle | 11 +- .../co/edu/uniquindio/dht/gui/PanelDhash.java | 9 +- .../dht/gui/network/NetworkWindow.java | 11 +- .../network/task/storageservice/GetTask.java | 18 +- .../network/task/storageservice/PutTask.java | 16 +- .../src/main/resources/application.yml | 15 +- .../src/main/resources/log4j.xml | 102 ----- main/desktop-structure-gui/build.gradle | 11 +- .../co/edu/uniquindio/dht/gui/PanelDhash.java | 41 +-- .../task/controller/NewNodeTask.java | 4 - .../task/storageservice/GetTask.java | 18 +- .../task/storageservice/PutTask.java | 15 +- .../src/main/resources/log4j.xml | 102 ----- main/standalone-network/build.gradle | 8 +- .../src/main/resources/application.yml | 15 +- .../src/main/resources/log4j.xml | 102 ----- .../chord-spring-boot-starter/build.gradle | 5 +- .../chord/starter/ChordAutoConfiguration.java | 10 +- .../build.gradle | 4 +- .../dhash-spring-boot-starter/build.gradle | 4 +- .../dhash/starter/DHashAutoConfiguration.java | 25 +- .../dhash/starter/DHashProperties.java | 1 + .../build.gradle | 5 +- p2p/chord/build.gradle | 5 +- .../edu/uniquindio/chord/node/BootStrap.java | 32 +- .../edu/uniquindio/chord/node/ChordNode.java | 71 ++-- .../chord/node/ChordNodeFactory.java | 25 +- .../uniquindio/chord/node/FingersTable.java | 347 +++++++++--------- .../chord/node/NodeEnvironment.java | 37 +- .../edu/uniquindio/chord/node/StableRing.java | 12 +- .../uniquindio/chord/node/SuccessorList.java | 31 +- .../uniquindio/chord/node/BootStrapTest.java | 11 +- .../chord/node/ChordNodeFactoryTest.java | 5 +- .../uniquindio/chord/node/ChordNodeTest.java | 68 ++-- .../chord/node/NodeEnvironmentTest.java | 4 +- .../chord/node/SuccessorListTest.java | 24 +- storage/dhash/build.gradle | 11 +- .../dhash/node/DHashEnvironment.java | 233 ------------ .../edu/uniquindio/dhash/node/DHashNode.java | 252 +++++++------ .../dhash/node/DHashNodeFactory.java | 48 +-- .../dhash/node/ReAssignObserver.java | 18 +- .../node/processor/ContainProcessor.java | 51 +++ .../processor/MessageProcessorGateway.java | 77 ++++ .../stream/GetMessageStreamProcessor.java | 51 +++ .../stream/MessageStreamProcessorGateway.java | 47 +++ .../stream/PutMessageStreamProcessor.java | 55 +++ .../uniquindio/dhash/protocol/Protocol.java | 72 +--- .../dhash/resource/BasicResource.java | 28 ++ .../dhash/resource/FileResource.java | 45 +++ .../dhash/resource/LocalFileResource.java | 44 +++ ...ava => ChecksumInputStreamCalculator.java} | 23 +- .../resource/manager/FileResourceManager.java | 38 +- .../manager/FileResourceManagerFactory.java | 6 +- .../resource/manager/ResourceManager.java | 1 + .../ObjectMapperSerializationHandler.java | 51 +++ .../ObjectSerializationHandler.java | 49 --- .../serialization/SerializationHandler.java | 8 +- .../jackson/FileResourceBuilderMixIn.java | 15 + .../jackson/FileResourceMixIn.java | 21 ++ .../dhash/node/DHashEnvironmentTest.java | 227 ------------ .../dhash/node/DHashNodeFactoryTest.java | 31 +- .../uniquindio/dhash/node/DHashNodeTest.java | 243 ++++++------ .../dhash/node/ReAssignObserverTest.java | 5 +- .../node/processor/ContainProcessorTest.java | 86 +++++ .../MessageProcessorGatewayTest.java | 67 ++++ .../stream/GetMessageStreamProcessorTest.java | 75 ++++ .../MessageStreamProcessorGatewayTest.java | 75 ++++ .../stream/PutMessageStreamProcessorTest.java | 105 ++++++ ...=> ChecksumInputStreamCalculatorTest.java} | 15 +- .../ObjectMapperSerializationHandlerTest.java | 71 ++++ .../ObjectSerializationHandlerTest.java | 54 --- storage/storage-service/build.gradle | 2 +- .../edu/uniquindio/storage/StorageNode.java | 11 +- .../storage/StorageNodeFactory.java | 4 +- .../storage/resource/ProgressStatus.java | 5 + .../uniquindio/storage/resource/Resource.java | 19 +- 137 files changed, 2781 insertions(+), 2843 deletions(-) rename communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/{SequenceGenerator.java => IdGenerator.java} (93%) create mode 100644 communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/MessageStream.java rename communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/{SequenceGeneratorImpl.java => UUIDGenerator.java} (71%) create mode 100644 communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionHandler.java rename storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BytesResource.java => communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/MessageStreamProcessor.java (58%) create mode 100644 communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ProgressStatusTransfer.java create mode 100644 communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamManager.java delete mode 100644 communication/data-structure-communication/src/main/resources/schema/communication.xsd delete mode 100644 communication/data-structure-communication/src/main/resources/schema/message.xsd delete mode 100644 communication/data-structure-communication/src/main/resources/schema/utils.xsd create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionListener.java create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamCommunicator.java create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionHandlerAsynchronous.java create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionReceiver.java create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ConnectionMessageProcessorGateway.java rename communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/{MessageProcessorGateway.java => MessageProcessorExecution.java} (78%) create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorExecution.java create mode 100644 communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorOutput.java delete mode 100644 communication/socket-communication/src/main/resources/schema/communication.xsd delete mode 100644 communication/socket-communication/src/main/resources/schema/message.xsd delete mode 100644 communication/socket-communication/src/main/resources/schema/utils.xsd delete mode 100644 it/data-structure-it/src/main/resources/log4j.xml delete mode 100644 it/socket-it/src/main/resources/log4j.xml delete mode 100644 main/desktop-network-gui/src/main/resources/log4j.xml delete mode 100644 main/desktop-structure-gui/src/main/resources/log4j.xml delete mode 100644 main/standalone-network/src/main/resources/log4j.xml delete mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashEnvironment.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/ContainProcessor.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGateway.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessor.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGateway.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessor.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BasicResource.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/FileResource.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/LocalFileResource.java rename storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/{BytesChecksumCalculator.java => ChecksumInputStreamCalculator.java} (68%) create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandler.java delete mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandler.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceBuilderMixIn.java create mode 100644 storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceMixIn.java delete mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashEnvironmentTest.java create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/ContainProcessorTest.java create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGatewayTest.java create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessorTest.java create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGatewayTest.java create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessorTest.java rename storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/{BytesChecksumCalculatorTest.java => ChecksumInputStreamCalculatorTest.java} (70%) create mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandlerTest.java delete mode 100644 storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandlerTest.java create mode 100644 storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/ProgressStatus.java diff --git a/README.md b/README.md index 78e7cb3..a1b0daf 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ jDHTUQ is a peer-to-peer DHT system based on Chord algorithm, but built to gener ## Download last versions -[![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/latest/desktop-structure-gui-2.0.2.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/v2.0.4/desktop-structure-gui-2.0.2.jar) [![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/latest/desktop-network-gui-2.0.4.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/v2.0.4/desktop-network-gui-2.0.4.jar) [![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/latest/standalone-network-2.0.4.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/standalone-network-v2.0.4/standalone-network-2.0.4.jar) +[![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/desktop-structure-gui-v2.0.3/desktop-structure-gui-2.0.3.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/desktop-structure-gui-v2.0.3/desktop-structure-gui-2.0.3.jar) [![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/desktop-network-gui-v2.0.5/desktop-network-gui-2.0.5.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/desktop-network-gui-v2.0.5/desktop-network-gui-2.0.5.jar) [![Github Releases (by Asset)](https://img.shields.io/github/downloads/estigma88/jdhtuq/standalone-network-v2.0.5/standalone-network-2.0.5.jar.svg)](https://github.com/estigma88/jdhtuq/releases/download/standalone-network-v2.0.5/standalone-network-2.0.5.jar) Data structure and network applications. - Execute with double click or diff --git a/communication/communication-api/build.gradle b/communication/communication-api/build.gradle index 38ff170..cf2813b 100644 --- a/communication/communication-api/build.gradle +++ b/communication/communication-api/build.gradle @@ -9,13 +9,11 @@ repositories { } group = 'com.github.estigma88' -version = '2.0.0' +version = '3.0.0' dependencies { compileOnly 'org.projectlombok:lombok:1.16.20' - - compile group: 'log4j', name: 'log4j', version: '1.2.16' } task sourcesJar(type: Jar) { diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGenerator.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/IdGenerator.java similarity index 93% rename from communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGenerator.java rename to communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/IdGenerator.java index 5a0ad5c..c881999 100644 --- a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGenerator.java +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/IdGenerator.java @@ -21,11 +21,11 @@ /** * Sequence generator */ -public interface SequenceGenerator { +public interface IdGenerator { /** * Get the next sequence value * * @return next sequence value */ - long getSequenceNumber(); + String newId(); } diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/Message.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/Message.java index 9111fea..98fbb39 100644 --- a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/Message.java +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/Message.java @@ -64,17 +64,19 @@ public enum SendType { @Singular private final Map params; - /** - * Hash map of names with datas - */ - @Singular - private final Map datas; - /** * Sequence number */ - private final long sequenceNumber; - + private final String id; + + public static Message.MessageBuilder with(Message message){ + return Message.builder() + .id(message.id) + .sendType(message.sendType) + .messageType(message.messageType) + .address(message.address) + .params(message.params); + } /** * This method is used for getting a specific data from the message @@ -82,30 +84,7 @@ public enum SendType { * @return Returns the data that is stored in the given position */ public String getParam(String name) { - if (!params.containsKey(name)) { - throw new IllegalArgumentException("The message type " - + messageType.getName() + " not contains param '" + name - + "'"); - } else { - return params.get(name); - } - } - - - /** - * Gets data by name - * - * @param name Data name - * @return Data - */ - public byte[] getData(String name) { - if (!datas.containsKey(name)) { - throw new IllegalArgumentException("The big message type " - + messageType.getName() + " not contains param '" + name - + "'"); - } else { - return datas.get(name); - } + return params.get(name); } /** diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/MessageStream.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/MessageStream.java new file mode 100644 index 0000000..151a7d7 --- /dev/null +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/MessageStream.java @@ -0,0 +1,21 @@ +package co.edu.uniquindio.utils.communication.message; + +import lombok.Builder; +import lombok.Data; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; + +@Builder +@Data +public class MessageStream implements Closeable{ + private final Message message; + private transient final InputStream inputStream; + private final Long size; + + @Override + public void close() throws IOException { + this.inputStream.close(); + } +} diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGeneratorImpl.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/UUIDGenerator.java similarity index 71% rename from communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGeneratorImpl.java rename to communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/UUIDGenerator.java index c2dd132..91f6637 100644 --- a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/SequenceGeneratorImpl.java +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/message/UUIDGenerator.java @@ -18,12 +18,14 @@ package co.edu.uniquindio.utils.communication.message; +import java.util.UUID; + /** - * The {@code SequenceGenerator} class is responsible for generating the sequence + * The {@code IdGenerator} class is responsible for generating the sequence * numbers for the messages. This create a sequence number between 1 and Long.MAX_VALUE. * When the sequence number is bigger than Long.MAX_VALUE the sequence number starts at 0 * again. The sequence number increments in one every time that {@code - * SequenceGenerator.getSequenceNumber()} is called + * IdGenerator.newId()} is called * * * @author Daniel Pelaez @@ -33,27 +35,14 @@ * @since 1.0 * */ -public class SequenceGeneratorImpl implements SequenceGenerator{ - /** - * The next sequence number, star at 0 - */ - private static long number = 0; - - /** - * The max number that SequenceGenerator can generate, its value is Long.MAX_VALUE - */ - private static long maxNumber = Long.MAX_VALUE; - +public class UUIDGenerator implements IdGenerator { /** * This method return the next sequence number * * @return Returns the next sequence number */ - public synchronized long getSequenceNumber() { - if (number > maxNumber) { - number = 0; - } - - return ++number; + @Override + public String newId() { + return UUID.randomUUID().toString(); } } diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/CommunicationManager.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/CommunicationManager.java index 83bd345..e5c2588 100644 --- a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/CommunicationManager.java +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/CommunicationManager.java @@ -20,6 +20,11 @@ import co.edu.uniquindio.utils.communication.Observer; import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; /** * The {@code CommunicationManager} interface is used to send messages @@ -31,7 +36,7 @@ * @version 1.0.2, 17/06/2010 * @since 1.0.2 */ -public interface CommunicationManager { +public interface CommunicationManager extends StreamManager{ /** * Creates and sends a message specifying its type, the type of the response @@ -41,7 +46,7 @@ public interface CommunicationManager { * @param typeReturn The type of the response * @return An object of the specified type. */ - T sendMessageUnicast(Message message, Class typeReturn); + T send(Message message, Class typeReturn); /** * Creates and sends a message specifying its type, the type of the response @@ -52,8 +57,9 @@ public interface CommunicationManager { * @param paramNameResult Param name of result * @return An object of the specified type. */ - T sendMessageUnicast(Message message, Class typeReturn, - String paramNameResult); + T send(Message message, Class typeReturn, + String paramNameResult); + /** * Sends a message specifying its type, the type of the response and the @@ -61,24 +67,24 @@ T sendMessageUnicast(Message message, Class typeReturn, * * @param message Messages to send */ - void sendMessageUnicast(Message message); + void send(Message message); /** * Creates and sends a multicast message specifying its type, the type of * the response and the data. Used - * sendMessageMultiCast(message) to send message + * sendMultiCast(message) to send message * * @param Type return * @param message Message * @param typeReturn Type return * @return Response */ - T sendMessageMultiCast(Message message, Class typeReturn); + T sendMultiCast(Message message, Class typeReturn); /** * Creates and sends a multicast message specifying its type, the type of * the response and the data. Used - * sendMessageMultiCast(message) to send message + * sendMultiCast(message) to send message * * @param Type return * @param message Message @@ -86,8 +92,8 @@ T sendMessageUnicast(Message message, Class typeReturn, * @param paramNameResult Param name of result * @return Response */ - T sendMessageMultiCast(Message message, Class typeReturn, - String paramNameResult); + T sendMultiCast(Message message, Class typeReturn, + String paramNameResult); /** * Sends a multicast message specifying its type, the type of the response @@ -96,12 +102,7 @@ T sendMessageMultiCast(Message message, Class typeReturn, * * @param message Messages to send */ - void sendMessageMultiCast(Message message); - - /** - * Stop all process - */ - void stopAll(); + void sendMultiCast(Message message); /** * Adds observer to communication @@ -124,6 +125,28 @@ T sendMessageMultiCast(Message message, Class typeReturn, */ void removeObserver(String name); + + /** + * Adds observer to communication + * + * @param observer Observer to add + */ + void addStreamObserver(Observer observer); + + /** + * Remove observer to communication + * + * @param observer Observer to remove + */ + void removeStreamObserver(Observer observer); + + /** + * Remove observer by name + * + * @param name Observer name + */ + void removeStreamObserver(String name); + /** * Add a message processor to handle any kind of message * @@ -132,6 +155,13 @@ T sendMessageMultiCast(Message message, Class typeReturn, */ void addMessageProcessor(String name, MessageProcessor messageProcessor); + /** + * Add a message processor to handle any kind of message with additional input stream + * + * @param name of the message processor + */ + void addMessageStreamProcessor(String name, MessageStreamProcessor messageStreamProcessor); + /** * Remove a message processor * @@ -139,8 +169,21 @@ T sendMessageMultiCast(Message message, Class typeReturn, */ void removeMessageProcessor(String name); + /** + * Remove a message processor + * + * @param name of the message processor + */ + void removeMessageStreamProcessor(String name); + /** * Initialize communication manager. */ void init(); + + /** + * Stop all process + */ + void stopAll(); + } diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionHandler.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionHandler.java new file mode 100644 index 0000000..6574601 --- /dev/null +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionHandler.java @@ -0,0 +1,7 @@ +package co.edu.uniquindio.utils.communication.transfer; + +import java.net.Socket; + +public interface ConnectionHandler { + void handle(Socket socket); +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BytesResource.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/MessageStreamProcessor.java similarity index 58% rename from storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BytesResource.java rename to communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/MessageStreamProcessor.java index dd68ff7..f8b39e8 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BytesResource.java +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/MessageStreamProcessor.java @@ -1,5 +1,5 @@ /* - * DHash project implement a storage management + * Communication project implement communication point to point and multicast * Copyright (C) 2010 - 2018 Daniel Pelaez * * This program is free software: you can redistribute it and/or modify @@ -16,28 +16,14 @@ * along with this program. If not, see . */ -package co.edu.uniquindio.dhash.resource; +package co.edu.uniquindio.utils.communication.transfer; -import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; -import java.io.Serializable; +import java.io.InputStream; +import java.io.OutputStream; -public class BytesResource implements Resource, Serializable { - - private final String id; - private final byte[] bytes; - - public BytesResource(String id, byte[] bytes) { - this.id = id; - this.bytes = bytes; - } - - @Override - public String getId() { - return id; - } - - public byte[] getBytes() { - return bytes; - } +public interface MessageStreamProcessor { + MessageStream process(MessageStream messageStream); } diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ProgressStatusTransfer.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ProgressStatusTransfer.java new file mode 100644 index 0000000..cdc6a42 --- /dev/null +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/ProgressStatusTransfer.java @@ -0,0 +1,5 @@ +package co.edu.uniquindio.utils.communication.transfer; + +public interface ProgressStatusTransfer { + void status(String name, Long current, Long size); +} diff --git a/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamManager.java b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamManager.java new file mode 100644 index 0000000..4c76633 --- /dev/null +++ b/communication/communication-api/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamManager.java @@ -0,0 +1,10 @@ +package co.edu.uniquindio.utils.communication.transfer; + +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; + +public interface StreamManager { + MessageStream receive(Message message, ProgressStatusTransfer progressStatusTransfer); + + void send(MessageStream messageStream, ProgressStatusTransfer progressStatusTransfer); +} diff --git a/communication/data-structure-communication/build.gradle b/communication/data-structure-communication/build.gradle index 61f9eab..f9c0f89 100644 --- a/communication/data-structure-communication/build.gradle +++ b/communication/data-structure-communication/build.gradle @@ -9,12 +9,10 @@ repositories { } group = 'com.github.estigma88' -version = '2.0.0' +version = '3.0.0' dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '2.0.0' - - compile group: 'log4j', name: 'log4j', version: '1.2.16' + compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '3.0.0' } task sourcesJar(type: Jar) { diff --git a/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructure.java b/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructure.java index 50c7941..8b02214 100644 --- a/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructure.java +++ b/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructure.java @@ -19,10 +19,15 @@ package co.edu.uniquindio.utils.communication.transfer.structure; import co.edu.uniquindio.utils.communication.Observable; +import co.edu.uniquindio.utils.communication.Observer; import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import co.edu.uniquindio.utils.communication.transfer.ProgressStatusTransfer; +import java.io.OutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.*; @@ -35,17 +40,27 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ -public class CommunicationDataStructure extends Observable implements CommunicationManager { +public class CommunicationDataStructure implements CommunicationManager { /** * Data struture map */ - private Map dataStructure; + private final Map dataStructure; + private final Map dataStructureStream; + private final Observable observable; + private final Observable observableStream; /** * Builds a CommunicationDataStructure + * @param dataStructure + * @param dataStructureStream + * @param observable + * @param observableStream */ - public CommunicationDataStructure() { - dataStructure = new HashMap(); + public CommunicationDataStructure(Map dataStructure, Map dataStructureStream, Observable observable, Observable observableStream) { + this.dataStructure = dataStructure; + this.dataStructureStream = dataStructureStream; + this.observable = observable; + this.observableStream = observableStream; } public Message notifyUnicast(Message message) { @@ -53,13 +68,13 @@ public Message notifyUnicast(Message message) { MessageProcessor messageProcessor = dataStructure.get(message.getAddress().getDestination()); - super.notifyMessage(message); + observable.notifyMessage(message); if (messageProcessor != null) { response = messageProcessor.process(message); } - super.notifyMessage(response); + observable.notifyMessage(response); return response; } @@ -86,56 +101,90 @@ public Message notifyMulticast(Message message) { MessageProcessor messageProcessor = dataStructure.get(nameDestination); - super.notifyMessage(message); + observable.notifyMessage(message); if (messageProcessor != null) { response = messageProcessor.process(message); } - super.notifyMessage(response); + observable.notifyMessage(response); } return response; } @Override - public T sendMessageUnicast(Message message, Class typeReturn) { + public T send(Message message, Class typeReturn) { Message response = notifyUnicast(message); return processResponse(response, typeReturn, null); } @Override - public T sendMessageUnicast(Message message, Class typeReturn, String paramNameResult) { + public T send(Message message, Class typeReturn, String paramNameResult) { Message response = notifyUnicast(message); return processResponse(response, typeReturn, paramNameResult); } @Override - public void sendMessageUnicast(Message message) { + public void send(Message message) { notifyUnicast(message); } @Override - public T sendMessageMultiCast(Message message, Class typeReturn) { + public T sendMultiCast(Message message, Class typeReturn) { Message response = notifyMulticast(message); return processResponse(response, typeReturn, null); } @Override - public T sendMessageMultiCast(Message message, Class typeReturn, String paramNameResult) { + public T sendMultiCast(Message message, Class typeReturn, String paramNameResult) { Message response = notifyMulticast(message); return processResponse(response, typeReturn, paramNameResult); } @Override - public void sendMessageMultiCast(Message message) { + public void sendMultiCast(Message message) { notifyMulticast(message); } + @Override + public MessageStream receive(Message message, ProgressStatusTransfer progressStatusTransfer) { + MessageStream response = null; + + MessageStreamProcessor messageProcessor = dataStructureStream.get(message.getAddress().getDestination()); + + observable.notifyMessage(message); + + if (messageProcessor != null) { + response = messageProcessor.process(MessageStream.builder() + .message(message) + .build()); + } + + observableStream.notifyMessage(response); + + return response; + } + + @Override + public void send(MessageStream messageStream, ProgressStatusTransfer progressStatusTransfer) { + MessageStream response = null; + + MessageStreamProcessor messageProcessor = dataStructureStream.get(messageStream.getMessage().getAddress().getDestination()); + + observableStream.notifyMessage(messageStream); + + if (messageProcessor != null) { + response = messageProcessor.process(messageStream); + } + + observableStream.notifyMessage(response); + } + @Override public void stopAll() { @@ -146,11 +195,52 @@ public void addMessageProcessor(String name, MessageProcessor messageProcessor) dataStructure.put(name, messageProcessor); } + @Override + public void addMessageStreamProcessor(String name, MessageStreamProcessor messageStreamProcessor) { + dataStructureStream.put(name, messageStreamProcessor); + } + @Override public void removeMessageProcessor(String name) { dataStructure.remove(name); } + @Override + public void removeMessageStreamProcessor(String name) { + dataStructureStream.remove(name); + } + + + @Override + public void addObserver(Observer observer) { + observable.addObserver(observer); + } + + @Override + public void removeObserver(Observer observer) { + observable.removeObserver(observer); + } + + @Override + public void removeObserver(String name) { + observable.removeObserver(name); + } + + @Override + public void addStreamObserver(Observer observer) { + observableStream.addObserver(observer); + } + + @Override + public void removeStreamObserver(Observer observer) { + observableStream.removeObserver(observer); + } + + @Override + public void removeStreamObserver(String name) { + observableStream.removeObserver(name); + } + @Override public void init() { diff --git a/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructureFactory.java b/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructureFactory.java index afdf98f..47c3840 100644 --- a/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructureFactory.java +++ b/communication/data-structure-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/structure/CommunicationDataStructureFactory.java @@ -1,11 +1,19 @@ package co.edu.uniquindio.utils.communication.transfer.structure; +import co.edu.uniquindio.utils.communication.Observable; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.CommunicationManagerFactory; +import java.util.HashMap; + public class CommunicationDataStructureFactory implements CommunicationManagerFactory { @Override public CommunicationManager newCommunicationManager(String name) { - return new CommunicationDataStructure(); + Observable observable = new Observable<>(); + Observable observableStream = new Observable<>(); + + return new CommunicationDataStructure(new HashMap<>(), new HashMap<>(), observable, observableStream); } } diff --git a/communication/data-structure-communication/src/main/resources/schema/communication.xsd b/communication/data-structure-communication/src/main/resources/schema/communication.xsd deleted file mode 100644 index b63312e..0000000 --- a/communication/data-structure-communication/src/main/resources/schema/communication.xsd +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/communication/data-structure-communication/src/main/resources/schema/message.xsd b/communication/data-structure-communication/src/main/resources/schema/message.xsd deleted file mode 100644 index d294ccd..0000000 --- a/communication/data-structure-communication/src/main/resources/schema/message.xsd +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/communication/data-structure-communication/src/main/resources/schema/utils.xsd b/communication/data-structure-communication/src/main/resources/schema/utils.xsd deleted file mode 100644 index 4593bb9..0000000 --- a/communication/data-structure-communication/src/main/resources/schema/utils.xsd +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/communication/socket-communication/build.gradle b/communication/socket-communication/build.gradle index 47f6e1e..ea270c9 100644 --- a/communication/socket-communication/build.gradle +++ b/communication/socket-communication/build.gradle @@ -9,15 +9,15 @@ repositories { } group = 'com.github.estigma88' -version = '2.1.0' +version = '3.0.0' dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '3.0.0' - // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind + compileOnly 'org.projectlombok:lombok:1.16.20' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4' - compile group: 'log4j', name: 'log4j', version: '1.2.16' + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' } task sourcesJar(type: Jar) { diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/Communicator.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/Communicator.java index 68812b6..12657cf 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/Communicator.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/Communicator.java @@ -19,13 +19,17 @@ package co.edu.uniquindio.utils.communication.transfer; import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Map; /** - * The Communicator interface hava all services for to send and to - * receiver messages + * The Communicator interface hava all services for to transfer and to + * receive messages * * @author Daniel Pelaez * @version 1.0, 17/06/2010 @@ -36,7 +40,7 @@ public interface Communicator extends Closeable { /** * Send message * - * @param message Message to send + * @param message Message to transfer */ void send(Message message); @@ -45,7 +49,7 @@ public interface Communicator extends Closeable { * * @return Message */ - Message receiver(); + Message receive(); void start(Map properties); } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionListener.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionListener.java new file mode 100644 index 0000000..fb417dc --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/ConnectionListener.java @@ -0,0 +1,8 @@ +package co.edu.uniquindio.utils.communication.transfer; + +import java.io.IOException; +import java.net.Socket; + +public interface ConnectionListener { + Socket listen() throws IOException; +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamCommunicator.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamCommunicator.java new file mode 100644 index 0000000..3c88fa9 --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/StreamCommunicator.java @@ -0,0 +1,9 @@ +package co.edu.uniquindio.utils.communication.transfer; + +import co.edu.uniquindio.utils.communication.message.MessageStream; + +import java.io.OutputStream; + +public interface StreamCommunicator extends Communicator, ConnectionListener, StreamManager { + void send(MessageStream messageStream, OutputStream destination, ProgressStatusTransfer progressStatusTransfer); +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCP.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCP.java index 7e19ccd..4c38cd3 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCP.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCP.java @@ -21,16 +21,16 @@ import co.edu.uniquindio.utils.communication.Observable; import co.edu.uniquindio.utils.communication.Observer; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import co.edu.uniquindio.utils.communication.transfer.Communicator; -import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.*; import co.edu.uniquindio.utils.communication.transfer.response.MessageResponseProcessor; import co.edu.uniquindio.utils.communication.transfer.response.MessagesReceiver; import co.edu.uniquindio.utils.communication.transfer.response.ReturnsManager; import co.edu.uniquindio.utils.communication.transfer.response.WaitingResult; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.io.IOException; +import java.io.OutputStream; import java.util.Map; import java.util.concurrent.ExecutorService; @@ -46,33 +46,33 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ + +@Slf4j public class CommunicationManagerTCP implements CommunicationManager { + private static final String RESPONSE_TIME = "response_time"; - - private static final Logger logger = Logger - .getLogger(CommunicationManagerTCP.class); - - private static final String RESPONSE_TIME = "RESPONSE_TIME"; - - private final Communicator unicastManager; - private final MessagesReceiver unicastMessagesReciever; + private final StreamCommunicator unicastManager; + private final ConnectionReceiver unicastConnectionReceiver; private final Communicator multicastManager; private final MessagesReceiver multicastMessagesReciever; private final MessageResponseProcessor messageResponseProcessor; private final Observable observableCommunication; + private final Observable messageStreamObservable; private final ReturnsManager returnsManager; private final ExecutorService messagesReceiverExecutor; private MessageProcessor messageProcessor; + private MessageStreamProcessor messageStreamProcessor; private Map communicationProperties; - public CommunicationManagerTCP(Communicator unicastManager, MessagesReceiver unicastMessagesReciever, Communicator multicastManager, MessagesReceiver multicastMessagesReciever, MessageResponseProcessor messageResponseProcessor, Observable observableCommunication, ReturnsManager returnsManager, ExecutorService messagesReceiverExecutor) { + public CommunicationManagerTCP(StreamCommunicator unicastManager, ConnectionReceiver unicastConnectionReceiver, Communicator multicastManager, MessagesReceiver multicastMessagesReciever, MessageResponseProcessor messageResponseProcessor, Observable observableCommunication, Observable messageStreamObservable, ReturnsManager returnsManager, ExecutorService messagesReceiverExecutor) { this.unicastManager = unicastManager; - this.unicastMessagesReciever = unicastMessagesReciever; + this.unicastConnectionReceiver = unicastConnectionReceiver; this.multicastManager = multicastManager; this.multicastMessagesReciever = multicastMessagesReciever; this.messageResponseProcessor = messageResponseProcessor; this.observableCommunication = observableCommunication; + this.messageStreamObservable = messageStreamObservable; this.returnsManager = returnsManager; this.messagesReceiverExecutor = messagesReceiverExecutor; } @@ -80,7 +80,7 @@ public CommunicationManagerTCP(Communicator unicastManager, MessagesReceiver uni /** * Creates and sends a message specifying its type, the type of the response - * and the data. Used sendMessage(message) to send message. The + * and the data. Used sendMessage(message) to transfer message. The * typeReturn must to have a method by signed T valueOf(String) * and class must to have constructor without parameters, or an constructor * T(String) . If typeReturn is a Message class, the return is @@ -91,16 +91,17 @@ public CommunicationManagerTCP(Communicator unicastManager, MessagesReceiver uni * @param typeReturn The type of the response * @return An object of the specified type. */ - public T sendMessageUnicast(Message message, Class typeReturn) { + @Override + public T send(Message message, Class typeReturn) { /* - * Created WaitingResult for message sequence number to send + * Created WaitingResult for message sequence number to transfer */ WaitingResult waitingResult = returnsManager - .createWaitingResult(message.getSequenceNumber(), Long + .createWaitingResult(message.getId(), Long .parseLong(communicationProperties.get(RESPONSE_TIME))); - sendMessageUnicast(message); + send(message); /* * Waiting for response @@ -115,7 +116,7 @@ public T sendMessageUnicast(Message message, Class typeReturn) { /** * Creates and sends a message specifying its type, the type of the response - * and the data. Used sendMessage(message) to send message. The + * and the data. Used sendMessage(message) to transfer message. The * typeReturn must to have a method by signed T valueOf(String) * and class must to have constructor without parameters, or an constructor * T(String) . If typeReturn is a Message class, the return is @@ -127,17 +128,18 @@ public T sendMessageUnicast(Message message, Class typeReturn) { * @param paramNameResult Param name of result * @return An object of the specified type. */ - public T sendMessageUnicast(Message message, Class typeReturn, - String paramNameResult) { + @Override + public T send(Message message, Class typeReturn, + String paramNameResult) { /* - * Created WaitingResult for message sequence number to send + * Created WaitingResult for message sequence number to transfer */ WaitingResult waitingResult = returnsManager - .createWaitingResult(message.getSequenceNumber(), Long + .createWaitingResult(message.getId(), Long .parseLong(communicationProperties.get(RESPONSE_TIME))); - sendMessageUnicast(message); + send(message); /* * Waiting for response @@ -152,18 +154,19 @@ public T sendMessageUnicast(Message message, Class typeReturn, /** * Sends a message specifying its type, the type of the response and the - * data. Used Communicator instance called unicastManager to send message + * data. Used Communicator instance called unicastManager to transfer message * - * @param message Messages to send + * @param message Messages to transfer */ - public void sendMessageUnicast(Message message) { + @Override + public void send(Message message) { unicastManager.send(message); } /** * Creates and sends a multicast message specifying its type, the type of * the response and the data. Used - * sendMessageMultiCast(message) to send message. The + * sendMultiCast(message) to transfer message. The * typeReturn must to have a method by signed T valueOf(String) * and class must to have constructor without parameters, or an constructor * T(String) . If typeReturn is a Message class, the return is @@ -175,16 +178,17 @@ public void sendMessageUnicast(Message message) { * @param typeReturn Type return * @return Response */ - public T sendMessageMultiCast(Message message, Class typeReturn) { + @Override + public T sendMultiCast(Message message, Class typeReturn) { /* - * Created WaitingResult for message sequence number to send + * Created WaitingResult for message sequence number to transfer */ WaitingResult waitingResult = returnsManager - .createWaitingResult(message.getSequenceNumber(), Long + .createWaitingResult(message.getId(), Long .parseLong(communicationProperties.get(RESPONSE_TIME))); - sendMessageMultiCast(message); + sendMultiCast(message); /* * Waiting for response @@ -200,7 +204,7 @@ public T sendMessageMultiCast(Message message, Class typeReturn) { /** * Creates and sends a multicast message specifying its type, the type of * the response and the data. Used - * sendMessageMultiCast(message) to send message. The + * sendMultiCast(message) to transfer message. The * typeReturn must to have a method by signed T valueOf(String) * and class must to have constructor without parameters, or an constructor * T(String) . If typeReturn is a Message class, the return is @@ -213,17 +217,18 @@ public T sendMessageMultiCast(Message message, Class typeReturn) { * @param paramNameResult Param name of result * @return Response */ - public T sendMessageMultiCast(Message message, Class typeReturn, - String paramNameResult) { + @Override + public T sendMultiCast(Message message, Class typeReturn, + String paramNameResult) { /* - * Created WaitingResult for message sequence number to send + * Created WaitingResult for message sequence number to transfer */ WaitingResult waitingResult = returnsManager - .createWaitingResult(message.getSequenceNumber(), Long + .createWaitingResult(message.getId(), Long .parseLong(communicationProperties.get(RESPONSE_TIME))); - sendMessageMultiCast(message); + sendMultiCast(message); /* * Waiting for response @@ -238,15 +243,37 @@ public T sendMessageMultiCast(Message message, Class typeReturn, /** * Sends a multicast message specifying its type, the type of the response - * and the data. Used Communicator instance called multicastManager to send + * and the data. Used Communicator instance called multicastManager to transfer * message * - * @param message Messages to send + * @param message Messages to transfer */ - public void sendMessageMultiCast(Message message) { + @Override + public void sendMultiCast(Message message) { multicastManager.send(message); } + /** + * Sends a message specifying its type, the type of the response and the + * data. Used Communicator instance called unicastManager to transfer message. + * Besides, it sends an input stream + * + * @param message Messages to transfer + */ + @Override + public void send(MessageStream message, ProgressStatusTransfer progressStatusTransfer) { + unicastManager.send(message, progressStatusTransfer); + } + + @Override + public MessageStream receive(Message resourceTransferMessage, ProgressStatusTransfer progressStatusTransfer) { + return unicastManager.receive(resourceTransferMessage, progressStatusTransfer); + } + + public void send(MessageStream message, OutputStream destination, ProgressStatusTransfer progressStatusTransfer) { + unicastManager.send(message, destination, progressStatusTransfer); + } + /** * Stop all process */ @@ -255,7 +282,7 @@ public void stopAll() { multicastManager.close(); multicastMessagesReciever.close(); unicastManager.close(); - unicastMessagesReciever.close(); + unicastConnectionReceiver.close(); messagesReceiverExecutor.shutdown(); } catch (IOException e) { throw new IllegalStateException("Problem stopping communication", e); @@ -289,20 +316,48 @@ public void removeObserver(String name) { observableCommunication.removeObserver(name); } + @Override + public void addStreamObserver(Observer observer) { + messageStreamObservable.addObserver(observer); + } + + @Override + public void removeStreamObserver(Observer observer) { + messageStreamObservable.removeObserver(observer); + } + + @Override + public void removeStreamObserver(String name) { + messageStreamObservable.removeObserver(name); + } + @Override public void addMessageProcessor(String name, MessageProcessor messageProcessor) { this.messageProcessor = messageProcessor; } + @Override + public void addMessageStreamProcessor(String name, MessageStreamProcessor messageStreamProcessor) { + this.messageStreamProcessor = messageStreamProcessor; + } + @Override public void removeMessageProcessor(String name) { this.messageProcessor = null; } + @Override + public void removeMessageStreamProcessor(String name) { + this.messageStreamProcessor = null; + } + public MessageProcessor getMessageProcessor() { return messageProcessor; } + public MessageStreamProcessor getMessageStreamProcessor() { + return messageStreamProcessor; + } /* * (non-Javadoc) @@ -314,11 +369,11 @@ public void init() { this.unicastManager.start(communicationProperties); this.multicastManager.start(communicationProperties); - messagesReceiverExecutor.execute(unicastMessagesReciever); + messagesReceiverExecutor.execute(unicastConnectionReceiver); messagesReceiverExecutor.execute(multicastMessagesReciever); } - public void init(Map communicationProperties){ + public void init(Map communicationProperties) { this.communicationProperties = communicationProperties; init(); } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCPFactory.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCPFactory.java index 32e99e8..79818e7 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCPFactory.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/CommunicationManagerTCPFactory.java @@ -2,10 +2,10 @@ import co.edu.uniquindio.utils.communication.Observable; import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.CommunicationManagerFactory; -import co.edu.uniquindio.utils.communication.transfer.Communicator; -import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import co.edu.uniquindio.utils.communication.transfer.ConnectionHandler; import co.edu.uniquindio.utils.communication.transfer.response.*; import java.util.HashMap; @@ -26,14 +26,13 @@ public CommunicationManagerTCPFactory(MessageSerialization messageSerialization, this.instancesProperties = instancesProperties; this.defaultProperties = new HashMap<>(); - this.defaultProperties.put("RESPONSE_TIME", "2000"); - this.defaultProperties.put("BUFFER_SIZE_MULTICAST", "1024"); - this.defaultProperties.put("IP_MULTICAST", "224.0.0.2"); - this.defaultProperties.put("PORT_MULTICAST", "2000"); - this.defaultProperties.put("TIMEOUT_TCP_CONNECTION", "2000"); - this.defaultProperties.put("PORT_TCP", "2005"); - this.defaultProperties.put("PORT_UDP", "2006"); - this.defaultProperties.put("BUFFER_SIZE_UDP", "1024"); + this.defaultProperties.put("response_time", "2000"); + this.defaultProperties.put("buffer_size_multicast", "1024"); + this.defaultProperties.put("ip_multicast", "224.0.0.2"); + this.defaultProperties.put("port_multicast", "2000"); + this.defaultProperties.put("timeout_tcp_connection", "2000"); + this.defaultProperties.put("port_tcp", "2005"); + this.defaultProperties.put("size_tcp_buffer", "1024"); } @Override @@ -45,18 +44,24 @@ public CommunicationManager newCommunicationManager(String name) { ReturnsManager returnsManager = new ReturnsManagerCommunication<>(); Observable observable = new Observable<>(); + Observable streamObservable = new Observable<>(); - MessageProcessorGateway messageProcessorGateway = new MessageProcessorGateway(returnsManager, observable); - MessageProcessor messageProcessorGatewayAsynchronous = new MessageProcessorGatewayAsynchronous(messageProcessorGateway, messageProcessorExecutor); + MessageProcessorExecution messageProcessorExecution = new MessageProcessorExecution(returnsManager, observable); - Communicator multicastManager = new MulticastManagerUDP(messageSerialization); - Communicator unicastManager = new UnicastManagerTCP(messageSerialization); - MessagesReceiver unicastMessagesReceiver = new MessagesReceiver(unicastManager, messageProcessorGatewayAsynchronous); + MulticastManagerUDP multicastManager = new MulticastManagerUDP(messageSerialization); + MessageProcessorGatewayAsynchronous messageProcessorGatewayAsynchronous = new MessageProcessorGatewayAsynchronous(messageProcessorExecution, messageProcessorExecutor); MessagesReceiver multicastMessagesReceiver = new MessagesReceiver(multicastManager, messageProcessorGatewayAsynchronous); - CommunicationManagerTCP communication = new CommunicationManagerTCP(unicastManager, unicastMessagesReceiver, multicastManager, multicastMessagesReceiver, messageResponseProcessor, observable, returnsManager, messagesReceiverExecutor); + UnicastManagerTCP unicastManager = new UnicastManagerTCP(messageSerialization); + MessageStreamProcessorExecution messageInputStreamProcessorExecution = new MessageStreamProcessorExecution(streamObservable); + ConnectionHandler connectionHandler = new ConnectionMessageProcessorGateway(messageInputStreamProcessorExecution, messageProcessorExecution, messageSerialization); + ConnectionHandler connectionHandlerAsynchronous = new ConnectionHandlerAsynchronous(connectionHandler, messageProcessorExecutor); + ConnectionReceiver connectionReceiver = new ConnectionReceiver(unicastManager, connectionHandlerAsynchronous); - messageProcessorGateway.setCommunicationManager(communication); + CommunicationManagerTCP communication = new CommunicationManagerTCP(unicastManager, connectionReceiver, multicastManager, multicastMessagesReceiver, messageResponseProcessor, observable, streamObservable, returnsManager, messagesReceiverExecutor); + + messageInputStreamProcessorExecution.setCommunicationManager(communication); + messageProcessorExecution.setCommunicationManager(communication); communication.init(communicationProperties); diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionHandlerAsynchronous.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionHandlerAsynchronous.java new file mode 100644 index 0000000..aae7c1e --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionHandlerAsynchronous.java @@ -0,0 +1,21 @@ +package co.edu.uniquindio.utils.communication.transfer.network; + +import co.edu.uniquindio.utils.communication.transfer.ConnectionHandler; + +import java.net.Socket; +import java.util.concurrent.ExecutorService; + +public class ConnectionHandlerAsynchronous implements ConnectionHandler { + private final ConnectionHandler connectionHandler; + private final ExecutorService executorService; + + public ConnectionHandlerAsynchronous(ConnectionHandler connectionHandler, ExecutorService executorService) { + this.connectionHandler = connectionHandler; + this.executorService = executorService; + } + + @Override + public void handle(Socket socket) { + executorService.execute(() -> connectionHandler.handle(socket)); + } +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionReceiver.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionReceiver.java new file mode 100644 index 0000000..b6e7bce --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/ConnectionReceiver.java @@ -0,0 +1,57 @@ +/* + * Communication project implement communication point to point and multicast + * Copyright (C) 2010 Daniel Pelaez, Daniel Lopez, Hector Hurtado + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package co.edu.uniquindio.utils.communication.transfer.network; + +import co.edu.uniquindio.utils.communication.transfer.ConnectionHandler; +import co.edu.uniquindio.utils.communication.transfer.ConnectionListener; +import lombok.extern.slf4j.Slf4j; + +import java.io.Closeable; +import java.io.IOException; +import java.net.Socket; + +@Slf4j +public class ConnectionReceiver implements Closeable, Runnable { + private boolean run; + private final ConnectionListener connectionListener; + private final ConnectionHandler connectionHandler; + + public ConnectionReceiver(ConnectionListener connectionListener, ConnectionHandler connectionHandler) { + this.connectionHandler = connectionHandler; + this.run = true; + this.connectionListener = connectionListener; + } + + public void close() { + run = false; + } + + public void run() { + while (run) { + try { + Socket socket = connectionListener.listen(); + + connectionHandler.handle(socket); + } catch (IOException e) { + log.error("Error processing connection", e); + } + } + } + +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/MulticastManagerUDP.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/MulticastManagerUDP.java index 82c2963..a7be5db 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/MulticastManagerUDP.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/MulticastManagerUDP.java @@ -20,13 +20,15 @@ import co.edu.uniquindio.utils.communication.message.Message; import co.edu.uniquindio.utils.communication.transfer.Communicator; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; +import java.net.UnknownHostException; import java.util.Map; +import java.util.Optional; /** * The MulticastManagerUDP class implemented the transfer @@ -36,59 +38,26 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ + +@Slf4j public class MulticastManagerUDP implements Communicator { public enum MulticastManagerUDPProperties { BUFFER_SIZE_MULTICAST, IP_MULTICAST, PORT_MULTICAST } - private static final Logger logger = Logger - .getLogger(MulticastManagerUDP.class); - - /** - * Is the size of the buffer used for receiving messages. - */ - private long bufferSize = 1024; - - /** - * Is the {@code MulticastSocket} used for sending and receiving messages. - */ private MulticastSocket multicastSocket; - - /** - * Is the group that will be communicating by multicast. - */ private InetAddress group; - - /** - * Is the buffer used for a DatagramPacket when reading a message. - */ private byte[] buffer; - - /** - * Stores the value of the port used for the UDP Multicast communication. - */ private int portMulticast; - - private final MessageSerialization messageSerialization; - /** - * Builds a MulticastManagerUDP and started multicast socket - * - * @param messageSerialization - */ - public MulticastManagerUDP(MessageSerialization messageSerialization) { + MulticastManagerUDP(MessageSerialization messageSerialization) { this.messageSerialization = messageSerialization; } - /* - * (non-Javadoc) - * - * @see - * co.edu.uniquindio.utils.communication.transfer.Communicator#receiver() - */ - public Message receiver() { + @Override + public Message receive() { DatagramPacket datagramPacket; String string; Message message = null; @@ -103,87 +72,13 @@ public Message receiver() { message = messageSerialization.decode(string); } catch (IOException e) { - logger.error("Error reading multicast socket", e); + log.error("Error reading multicast socket", e); } return message; } @Override - public void start(Map properties) { - try { - if (properties - .containsKey(MulticastManagerUDPProperties.PORT_MULTICAST - .name())) { - portMulticast = Integer - .parseInt(properties - .get(MulticastManagerUDPProperties.PORT_MULTICAST - .name())); - } else { - IllegalArgumentException illegalArgumentException = new IllegalArgumentException( - "Property PORT_MULTICAST not found"); - - logger.error("Property PORT_MULTICAST no found", - illegalArgumentException); - - throw illegalArgumentException; - } - - if (properties - .containsKey(MulticastManagerUDPProperties.IP_MULTICAST - .name())) { - group = InetAddress.getByName(properties - .get(MulticastManagerUDPProperties.IP_MULTICAST - .name())); - } else { - IllegalArgumentException illegalArgumentException = new IllegalArgumentException( - "Property IP_MULTICAST not found"); - - logger.error("Property IP_MULTICAST no found", - illegalArgumentException); - - throw illegalArgumentException; - } - - if (properties - .containsKey(MulticastManagerUDPProperties.BUFFER_SIZE_MULTICAST - .name())) { - bufferSize = Long - .parseLong(properties - .get(MulticastManagerUDPProperties.BUFFER_SIZE_MULTICAST - .name())); - } else { - IllegalArgumentException illegalArgumentException = new IllegalArgumentException( - "Property BUFFER_SIZE_MULTICAST not found"); - - logger.error("Property BUFFER_SIZE_MULTICAST no found", - illegalArgumentException); - - throw illegalArgumentException; - } - - this.portMulticast = portMulticast; - - this.multicastSocket = new MulticastSocket(portMulticast); - - this.group = group; - - this.multicastSocket.joinGroup(group); - - this.buffer = new byte[(int) bufferSize]; - } catch (IOException e) { - logger.error("Error creating multicast socket", e); - throw new IllegalStateException("Error creating multicast socket", e); - } - } - - /* - * (non-Javadoc) - * - * @see - * co.edu.uniquindio.utils.communication.transfer.Communicator#send(co.edu - * .uniquindio.utils.communication.message.Message) - */ public void send(Message message) { DatagramPacket datagramPacket; String string = messageSerialization.encode(message); @@ -194,15 +89,43 @@ public void send(Message message) { try { multicastSocket.send(datagramPacket); } catch (IOException e) { - logger.error("Error writing multicast socket", e); + log.error("Error writing multicast socket", e); + } + } + + @Override + public void start(Map properties) { + try { + portMulticast = Optional.ofNullable(properties.get(MulticastManagerUDPProperties.PORT_MULTICAST.name().toLowerCase())) + .map(Integer::parseInt) + .orElseThrow(() -> new IllegalArgumentException("Property port_multicast not found")); + + group = Optional.ofNullable(properties.get(MulticastManagerUDPProperties.IP_MULTICAST.name().toLowerCase())) + .map(ip -> { + try { + return InetAddress.getByName(ip); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Problem wih ip_multicast property", e); + } + }) + .orElseThrow(() -> new IllegalArgumentException("Property ip_multicast not found")); + + Integer bufferSize = Optional.ofNullable(properties.get(MulticastManagerUDPProperties.BUFFER_SIZE_MULTICAST.name().toLowerCase())) + .map(Integer::parseInt) + .orElseThrow(() -> new IllegalArgumentException("Property buffer_size_multicast not found")); + + this.multicastSocket = new MulticastSocket(portMulticast); + + this.multicastSocket.joinGroup(group); + + this.buffer = new byte[bufferSize]; + } catch (IOException e) { + log.error("Error creating multicast socket", e); + throw new IllegalStateException("Error creating multicast socket", e); } } - /* - * (non-Javadoc) - * - * @see co.edu.uniquindio.utils.communication.transfer.Stoppable#close() - */ + @Override public void close() { multicastSocket.close(); } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/UnicastManagerTCP.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/UnicastManagerTCP.java index 740367c..bbc3db9 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/UnicastManagerTCP.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/UnicastManagerTCP.java @@ -19,16 +19,19 @@ package co.edu.uniquindio.utils.communication.transfer.network; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.transfer.Communicator; -import org.apache.log4j.Logger; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.ProgressStatusTransfer; +import co.edu.uniquindio.utils.communication.transfer.StreamCommunicator; +import lombok.extern.slf4j.Slf4j; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.*; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; +import java.util.Optional; + +import static co.edu.uniquindio.utils.communication.transfer.response.ConnectionMessageProcessorGateway.HANDLE_STREAMS; /** * The UnicastManagerTCP class implemented transfer message based @@ -38,138 +41,183 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ -public class UnicastManagerTCP implements Communicator { - - /** - * The UnicastManagerTCPProperties enum contains params - * required for communication - * - * @author dpelaez - */ +@Slf4j +public class UnicastManagerTCP implements StreamCommunicator { public enum UnicastManagerTCPProperties { - TIMEOUT_TCP_CONNECTION, PORT_TCP + TIMEOUT_TCP_CONNECTION, PORT_TCP, SIZE_TCP_BUFFER } - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(UnicastManagerTCP.class); - - /** - * The server socket that will be waiting for connection. - */ private ServerSocket serverSocket; - - /** - * The value of the port used to create the socket. - */ private int portTcp; private int timeoutTcpConnection; + private int sizeBuffer; private final MessageSerialization messageSerialization; - /** - * Builds a UnicastManagerTCP - * - * @param messageSerialization - */ - public UnicastManagerTCP(MessageSerialization messageSerialization) { + UnicastManagerTCP(MessageSerialization messageSerialization) { this.messageSerialization = messageSerialization; } - /* - * (non-Javadoc) - * - * @see - * co.edu.uniquindio.utils.communication.transfer.Communicator#receiver() - */ - public Message receiver() { - String stringMessage; - Message message = null; + @Override + public Message receive() { + try (Socket socket = listen()) { + return readMessage(socket.getInputStream()); + } catch (IOException | ClassNotFoundException e) { + log.error("Error reading socket", e); + } + + return null; + } + + @Override + public MessageStream receive(Message message, ProgressStatusTransfer progressStatusTransfer) { + try { + Socket socket = new Socket(); + + message = Message.with(message) + .param(HANDLE_STREAMS, String.valueOf(true)) + .build(); + + progressStatusTransfer.status("message-starter", 0L, 1L); + + send(message, socket); - try (Socket socket = serverSocket.accept(); - ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) { + progressStatusTransfer.status("message-starter", 1L, 1L); + progressStatusTransfer.status("message-ack", 0L, 1L); - stringMessage = (String) objectInputStream.readObject(); + Message messageResponse = readMessage(socket.getInputStream()); - message = messageSerialization.decode(stringMessage); + progressStatusTransfer.status("message-ack", 1L, 1L); + + return MessageStream.builder() + .message(messageResponse) + .inputStream(socket.getInputStream()) + .build(); } catch (IOException | ClassNotFoundException e) { - logger.error("Error reading socket", e); + log.error("Error writing socket " + message.getAddress(), e); + return null; } + } - return message; + @Override + public Socket listen() throws IOException { + return serverSocket.accept(); } @Override - public void start(Map properties) { - if (properties - .containsKey(UnicastManagerTCPProperties.PORT_TCP.name())) { - portTcp = Integer.parseInt(properties - .get(UnicastManagerTCPProperties.PORT_TCP.name())); - } else { - IllegalArgumentException illegalArgumentException = new IllegalArgumentException( - "Property PORT_TCP not found"); - - logger.error("Property PORT_TCP not found", - illegalArgumentException); - - throw illegalArgumentException; + public void send(Message message) { + try (Socket socket = new Socket()) { + send(message, socket); + } catch (IOException e) { + log.error("Error writing socket " + message.getAddress(), e); } - if (properties - .containsKey(UnicastManagerTCPProperties.TIMEOUT_TCP_CONNECTION.name())) { - timeoutTcpConnection = Integer.parseInt(properties - .get(UnicastManagerTCPProperties.TIMEOUT_TCP_CONNECTION.name())); - } else { - IllegalArgumentException illegalArgumentException = new IllegalArgumentException( - "Property TIMEOUT_TCP_CONNECTION not found"); - - logger.error("Property TIMEOUT_TCP_CONNECTION not found", - illegalArgumentException); - - throw illegalArgumentException; + + } + + @Override + public void send(MessageStream messageStream, ProgressStatusTransfer progressStatusTransfer) { + try (Socket socket = new Socket()) { + Message message = Message.with(messageStream.getMessage()) + .param(HANDLE_STREAMS, String.valueOf(true)) + .build(); + + progressStatusTransfer.status("message-starter", 0L, 1L); + + send(message, socket); + + progressStatusTransfer.status("message-starter", 1L, 1L); + + send(socket.getOutputStream(), messageStream.getInputStream(), messageStream.getSize(), progressStatusTransfer); + } catch (IOException e) { + log.error("Error writing socket", e); } + } + + @Override + public void send(MessageStream messageStream, OutputStream destination, ProgressStatusTransfer progressStatusTransfer) { + progressStatusTransfer.status("message-starter", 0L, 1L); + + sendTo(messageStream.getMessage(), destination); + + progressStatusTransfer.status("message-starter", 1L, 1L); + try { - this.serverSocket = new ServerSocket(portTcp); + send(destination, messageStream.getInputStream(), messageStream.getSize(), progressStatusTransfer); } catch (IOException e) { - logger.error("Error creating server socket", e); - throw new IllegalStateException("Error creating server socket", e); + log.error("Error writing socket", e); } - } - /* - * (non-Javadoc) - * - * @see - * co.edu.uniquindio.utils.communication.transfer.Communicator#send(co.edu - * .uniquindio.utils.communication.message.Message) - */ - public void send(Message message) { - try (Socket socket = new Socket()) { - socket.connect(new InetSocketAddress(message.getAddress().getDestination(), portTcp), timeoutTcpConnection); + @Override + public void start(Map properties) { + portTcp = Optional.ofNullable(properties.get(UnicastManagerTCPProperties.PORT_TCP.name().toLowerCase())) + .map(Integer::parseInt) + .orElseThrow(() -> new IllegalArgumentException("Property port_tcp not found")); - ObjectOutputStream objectOutputStream = new ObjectOutputStream( - socket.getOutputStream()); - objectOutputStream.writeObject(messageSerialization.encode(message)); + timeoutTcpConnection = Optional.ofNullable(properties.get(UnicastManagerTCPProperties.TIMEOUT_TCP_CONNECTION.name().toLowerCase())) + .map(Integer::parseInt) + .orElseThrow(() -> new IllegalArgumentException("Property timeout_tcp_connection not found")); + + sizeBuffer = Optional.ofNullable(properties.get(UnicastManagerTCPProperties.SIZE_TCP_BUFFER.name().toLowerCase())) + .map(Integer::parseInt) + .orElseThrow(() -> new IllegalArgumentException("Property size_tcp_buffer not found")); + try { + this.serverSocket = new ServerSocket(portTcp); } catch (IOException e) { - logger.error("Error writing socket " + message.getAddress(), e); + log.error("Error creating server socket", e); + throw new IllegalStateException("Error creating server socket", e); } } - /* - * (non-Javadoc) - * - * @see co.edu.uniquindio.utils.communication.transfer.Stoppable#close() - */ + @Override public void close() { try { serverSocket.close(); } catch (IOException e) { - logger.error("Error closing server socket", e); + log.error("Error closing server socket", e); throw new IllegalStateException("Error closing server socket", e); } } + private Message readMessage(InputStream inputStream) throws IOException, ClassNotFoundException { + ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); + + String stringMessage = (String) objectInputStream.readObject(); + + return messageSerialization.decode(stringMessage); + } + + private void send(Message message, Socket socket) throws IOException { + socket.connect(new InetSocketAddress(message.getAddress().getDestination(), portTcp), timeoutTcpConnection); + + sendTo(message, socket.getOutputStream()); + } + + private void send(OutputStream destination, InputStream source, Long size, ProgressStatusTransfer progressStatusTransfer) throws IOException { + int count; + long sent = 0L; + byte[] buffer = new byte[sizeBuffer]; + + progressStatusTransfer.status("stream-transfer", sent, size); + + while ((count = source.read(buffer)) > 0) { + destination.write(buffer, 0, count); + + sent += count; + + progressStatusTransfer.status("stream-transfer", sent, size); + } + } + + + private void sendTo(Message message, OutputStream destination) { + try { + ObjectOutputStream objectOutputStream = new ObjectOutputStream( + destination); + objectOutputStream.writeObject(messageSerialization.encode(message)); + } catch (IOException e) { + log.error("Error writing socket " + message.getAddress(), e); + } + } } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/AddressMixIn.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/AddressMixIn.java index c7c92d0..1f40b14 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/AddressMixIn.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/AddressMixIn.java @@ -6,5 +6,5 @@ @JsonDeserialize(builder = Address.AddressBuilder.class) @JsonIgnoreProperties({"messageFromMySelf"}) -class AddressMixIn { +interface AddressMixIn { } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/MessageTypeMixIn.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/MessageTypeMixIn.java index 7b99ba7..9e5b027 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/MessageTypeMixIn.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/network/jackson/MessageTypeMixIn.java @@ -4,5 +4,5 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(builder = MessageType.MessageTypeBuilder.class) -class MessageTypeMixIn { +interface MessageTypeMixIn { } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ConnectionMessageProcessorGateway.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ConnectionMessageProcessorGateway.java new file mode 100644 index 0000000..a12528c --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ConnectionMessageProcessorGateway.java @@ -0,0 +1,59 @@ +package co.edu.uniquindio.utils.communication.transfer.response; + +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.ConnectionHandler; +import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import co.edu.uniquindio.utils.communication.transfer.network.MessageSerialization; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.net.Socket; +import java.util.Optional; + +@Slf4j +public class ConnectionMessageProcessorGateway implements ConnectionHandler { + public static final String HANDLE_STREAMS = ConnectionMessageProcessorGateway.class.getName() + ".handle_streams"; + + private final MessageStreamProcessorOutput messageStreamProcessorOutput; + private final MessageProcessor messageProcessor; + private final MessageSerialization messageSerialization; + + public ConnectionMessageProcessorGateway(MessageStreamProcessorOutput messageStreamProcessorOutput, MessageProcessor messageProcessor, MessageSerialization messageSerialization) { + this.messageStreamProcessorOutput = messageStreamProcessorOutput; + this.messageProcessor = messageProcessor; + this.messageSerialization = messageSerialization; + } + + @Override + public void handle(Socket connection) { + try (Socket socket = connection){ + Message message = readMessage(socket); + + Boolean sendingInputStream = Optional.ofNullable(message.getParam(HANDLE_STREAMS)) + .map(Boolean::new) + .orElse(false); + + if (sendingInputStream) { + messageStreamProcessorOutput.process(MessageStream.builder() + .message(message) + .inputStream(socket.getInputStream()) + .build(), socket.getOutputStream()); + } else { + messageProcessor.process(message); + } + } catch (IOException | ClassNotFoundException e) { + log.error("Error processing connection", e); + } + } + + Message readMessage(Socket socket) throws IOException, ClassNotFoundException { + ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); + + String stringMessage = (String) objectInputStream.readObject(); + + return messageSerialization.decode(stringMessage); + } +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorGateway.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorExecution.java similarity index 78% rename from communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorGateway.java rename to communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorExecution.java index 8d1f9a6..dbb3170 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorGateway.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageProcessorExecution.java @@ -2,16 +2,15 @@ import co.edu.uniquindio.utils.communication.Observable; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; import co.edu.uniquindio.utils.communication.transfer.network.CommunicationManagerTCP; -public class MessageProcessorGateway implements MessageProcessor { +public class MessageProcessorExecution implements MessageProcessor { private final ReturnsManager responseReleaser; private CommunicationManagerTCP communicationManager; private final Observable observable; - public MessageProcessorGateway(ReturnsManager responseReleaser, Observable observable) { + public MessageProcessorExecution(ReturnsManager responseReleaser, Observable observable) { this.responseReleaser = responseReleaser; this.observable = observable; } @@ -24,7 +23,7 @@ public Message process(Message message) { response = communicationManager.getMessageProcessor().process(message); } if (response != null) { - communicationManager.sendMessageUnicast(response); + communicationManager.send(response); observable.notifyMessage(message); } } @@ -33,7 +32,7 @@ public Message process(Message message) { public boolean release(Message message) { if (message.getSendType().equals(Message.SendType.RESPONSE)) { - responseReleaser.releaseWaitingResult(message.getSequenceNumber(), + responseReleaser.releaseWaitingResult(message.getId(), message); return true; diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageResponseProcessor.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageResponseProcessor.java index 1998745..8c6390e 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageResponseProcessor.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageResponseProcessor.java @@ -1,6 +1,7 @@ package co.edu.uniquindio.utils.communication.transfer.response; import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -11,7 +12,7 @@ public T process(Message message, Class type, String paramNameResult) { T typeInstance; - if (message == null/* || message.getMessageType().equals(EMPTY_MESSAGE_TYPE)*/) { + if (message == null) { return null; } @@ -19,6 +20,10 @@ public T process(Message message, Class type, return type.cast(message); } + if (type.equals(MessageStream.class)) { + return type.cast(message); + } + if (type.isInterface() || type.isAnnotation() || type.isArray()) { throw new IllegalArgumentException("The type must a class (" + type.getName() + ")"); diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorExecution.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorExecution.java new file mode 100644 index 0000000..3a27cd7 --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorExecution.java @@ -0,0 +1,38 @@ +package co.edu.uniquindio.utils.communication.transfer.response; + +import co.edu.uniquindio.utils.communication.Observable; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import co.edu.uniquindio.utils.communication.transfer.network.CommunicationManagerTCP; + +import java.io.InputStream; +import java.io.OutputStream; + +public class MessageStreamProcessorExecution implements MessageStreamProcessorOutput { + private CommunicationManagerTCP communicationManager; + private final Observable observable; + + public MessageStreamProcessorExecution(Observable observable) { + this.observable = observable; + } + + @Override + public MessageStream process(MessageStream messageStream, OutputStream outputStream) { + MessageStream response = null; + if (communicationManager.getMessageStreamProcessor() != null) { + response = communicationManager.getMessageStreamProcessor().process(messageStream); + } + + if(response != null){ + communicationManager.send(response, outputStream, (name, current, size) -> {}); + observable.notifyMessage(response); + } + + return null; + } + + public void setCommunicationManager(CommunicationManagerTCP communicationManager) { + this.communicationManager = communicationManager; + } +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorOutput.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorOutput.java new file mode 100644 index 0000000..34e284c --- /dev/null +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessageStreamProcessorOutput.java @@ -0,0 +1,9 @@ +package co.edu.uniquindio.utils.communication.transfer.response; + +import co.edu.uniquindio.utils.communication.message.MessageStream; + +import java.io.OutputStream; + +public interface MessageStreamProcessorOutput { + MessageStream process(MessageStream messageStream, OutputStream outputStream); +} diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessagesReceiver.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessagesReceiver.java index 01dfd0f..bfadcd5 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessagesReceiver.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/MessagesReceiver.java @@ -41,7 +41,7 @@ public void close() { public void run() { while (run) { - messageProcessor.process(communicator.receiver()); + messageProcessor.process(communicator.receive()); } } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManager.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManager.java index 9bdd88e..278f75f 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManager.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManager.java @@ -32,21 +32,21 @@ public interface ReturnsManager { /** * Creates a waiting result for sequence number and time out * - * @param sequence - * Sequence number + * @param id + * id * @param timeOut * Time out of waiting * @return WaitingResult */ - public WaitingResult createWaitingResult(long sequence, long timeOut); + public WaitingResult createWaitingResult(String id, long timeOut); /** * Release waiting result by sequence number and response * - * @param sequence - * Sequence number + * @param id + * id * @param result * Response */ - public void releaseWaitingResult(long sequence, T result); + public void releaseWaitingResult(String id, T result); } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManagerCommunication.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManagerCommunication.java index 63fdbac..19f0fa8 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManagerCommunication.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/ReturnsManagerCommunication.java @@ -38,7 +38,7 @@ public class ReturnsManagerCommunication implements ReturnsManager { /** * The map of the WaitingResult references with a specific sequence number */ - private Map> results; + private Map> results; /** * Create a synchronized instance of the class HashMap @@ -50,33 +50,35 @@ public ReturnsManagerCommunication() { /** * Creates a WaitingResult object for the message with the specified - * sequence number + * id number * - * @param sequence - * . The sequence number of the message + * @param id + * . The id number of the message * @return Returns the {@link WaitingResult} created */ - public WaitingResult createWaitingResult(long sequence, long timeOut) { - WaitingResult resultInWait = new WaitingResult(sequence, this, timeOut); + @Override + public WaitingResult createWaitingResult(String id, long timeOut) { + WaitingResult resultInWait = new WaitingResult(id, this, timeOut); - results.put(sequence, resultInWait); + results.put(id, resultInWait); return resultInWait; } /** * This method is responsible for releasing the WaitingResult reference with - * the specified sequence number by set the response for the message. + * the specified id number by set the response for the message. * - * @param sequence - * . The sequence number of the message + * @param id + * . The id number of the message * @param result * . The response for the message */ - public synchronized void releaseWaitingResult(long sequence, T result) { - if (results.get(sequence) == null) { + @Override + public synchronized void releaseWaitingResult(String id, T result) { + if (results.get(id) == null) { return; } - results.remove(sequence).setResult(result); + results.remove(id).setResult(result); } } diff --git a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/WaitingResult.java b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/WaitingResult.java index 4f9ab65..c99c13b 100644 --- a/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/WaitingResult.java +++ b/communication/socket-communication/src/main/java/co/edu/uniquindio/utils/communication/transfer/response/WaitingResult.java @@ -18,14 +18,14 @@ package co.edu.uniquindio.utils.communication.transfer.response; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * The {@code WaitingResult} class is responsible for waiting for a response to - * a message with a specific sequence number. When a response for a given + * a message with a specific id number. When a response for a given * message does not arrive in a specific amount of time this class return * {@code null} as the response for that message * @@ -33,21 +33,16 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ -public class WaitingResult{ +@Slf4j +public class WaitingResult { /** - * Logger + * The id number of the message */ - private static final Logger logger = Logger - .getLogger(WaitingResult.class); + private String id; /** - * The sequence number of the message - */ - private long sequence; - - /** - * The response for the message with the specific sequence number + * The response for the message with the specific id number */ private T result; @@ -70,24 +65,24 @@ public class WaitingResult{ /** * The constructor of the class. Constructs a WaitingResult instance that - * wait for the response of the message with the sequence number specified + * wait for the response of the message with the id number specified * - * @param sequence . The sequence number of the message + * @param id . The id number of the message */ - private WaitingResult(long sequence, ReturnsManager returnsManager) { - this.sequence = sequence; + private WaitingResult(String id, ReturnsManager returnsManager) { + this.id = id; this.returnsManager = returnsManager; this.countDownLatch = new CountDownLatch(1); } /** * The constructor of the class. Constructs a WaitingResult instance that - * wait for the response of the message with the sequence number specified + * wait for the response of the message with the id number specified * - * @param sequence . The sequence number of the message + * @param id . The id number of the message */ - WaitingResult(long sequence, ReturnsManager returnsManager, long timeOut) { - this(sequence, returnsManager); + WaitingResult(String id, ReturnsManager returnsManager, long timeOut) { + this(id, returnsManager); this.timeOut = timeOut; } @@ -98,19 +93,19 @@ private WaitingResult(long sequence, ReturnsManager returnsManager) { */ public T getResult() { try { - if(countDownLatch.await(timeOut, TimeUnit.MILLISECONDS)){ - logger - .debug("Response arrives for number sequence= '" - + sequence + "'"); - }else{ - logger - .debug("Timeout waiting for a response for number sequence= '" - + sequence + "'"); - - returnsManager.releaseWaitingResult(sequence, null); + if (countDownLatch.await(timeOut, TimeUnit.MILLISECONDS)) { + log + .debug("Response arrives for number id= '" + + id + "'"); + } else { + log + .debug("Timeout waiting for a response for number id= '" + + id + "'"); + + returnsManager.releaseWaitingResult(id, null); } } catch (InterruptedException e) { - logger.error("Error to close countDownLatch", e); + log.error("Error to close countDownLatch", e); } return result; diff --git a/communication/socket-communication/src/main/resources/schema/communication.xsd b/communication/socket-communication/src/main/resources/schema/communication.xsd deleted file mode 100644 index b63312e..0000000 --- a/communication/socket-communication/src/main/resources/schema/communication.xsd +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/communication/socket-communication/src/main/resources/schema/message.xsd b/communication/socket-communication/src/main/resources/schema/message.xsd deleted file mode 100644 index d294ccd..0000000 --- a/communication/socket-communication/src/main/resources/schema/message.xsd +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/communication/socket-communication/src/main/resources/schema/utils.xsd b/communication/socket-communication/src/main/resources/schema/utils.xsd deleted file mode 100644 index 4593bb9..0000000 --- a/communication/socket-communication/src/main/resources/schema/utils.xsd +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2614ad5..5c122c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,6 @@ -sonatypeUsername=xx -sonatypePassword=xx \ No newline at end of file +sonatypeUsername=estigma88 +sonatypePassword=88*07A09cdef + +signing.keyId=10F2E6B6 +signing.password=88*07a09cd +signing.secretKeyRingFile=/home/daniel/.gnupg/secring.gpg \ No newline at end of file diff --git a/it/data-structure-it/build.gradle b/it/data-structure-it/build.gradle index a1cf6bb..93e994b 100644 --- a/it/data-structure-it/build.gradle +++ b/it/data-structure-it/build.gradle @@ -9,14 +9,14 @@ repositories { mavenCentral() } -version = '2.0.0' +version = '2.1.0' dependencies { compile("org.springframework.boot:spring-boot-starter:1.5.10.RELEASE") - compile project(':main:starters:chord-spring-boot-starter') - compile project(':main:starters:dhash-spring-boot-starter') - compile project(':main:starters:data-structure-communication-spring-boot-starter') + compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.2' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '3.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-data-structure-communication-spring-boot-starter', version: '3.0.0' testCompile group: 'commons-io', name: 'commons-io', version: '2.6' testCompile 'org.projectlombok:lombok:1.16.20' diff --git a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/gets/GetsDefinitionStep.java b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/gets/GetsDefinitionStep.java index 39c7b96..b782d1e 100644 --- a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/gets/GetsDefinitionStep.java +++ b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/gets/GetsDefinitionStep.java @@ -18,12 +18,13 @@ package co.edu.uniquindio.dht.it.datastructure.gets; -import co.edu.uniquindio.dhash.resource.BytesResource; import co.edu.uniquindio.dht.it.datastructure.CucumberRoot; import co.edu.uniquindio.dht.it.datastructure.World; import co.edu.uniquindio.dht.it.datastructure.put.Content; import co.edu.uniquindio.storage.StorageNode; +import co.edu.uniquindio.storage.resource.Resource; import cucumber.api.java.en.Then; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; @@ -39,10 +40,12 @@ public void i_lookup_the_following_resources(List contents) throws Thro StorageNode storageNode = world.getRing().getNode(world.getNodeGateway()); for (Content content : contents) { - BytesResource resource = (BytesResource) storageNode.get(content.getName()); + Resource resource = storageNode.get(content.getName(), (name, count, limit) -> {}).get(); assertThat(resource).isNotNull(); - assertThat(resource.getBytes()).isEqualTo(content.getContent().getBytes()); + assertThat(IOUtils.toByteArray(resource.getInputStream())).isEqualTo(content.getContent().getBytes()); + + resource.close(); } } } diff --git a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/put/PutsDefinitionStep.java b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/put/PutsDefinitionStep.java index ba6bba6..927f905 100644 --- a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/put/PutsDefinitionStep.java +++ b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/put/PutsDefinitionStep.java @@ -18,7 +18,7 @@ package co.edu.uniquindio.dht.it.datastructure.put; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import co.edu.uniquindio.dhash.starter.DHashProperties; import co.edu.uniquindio.dht.it.datastructure.CucumberRoot; import co.edu.uniquindio.dht.it.datastructure.World; @@ -29,6 +29,7 @@ import cucumber.api.java.en.When; import org.springframework.beans.factory.annotation.Autowired; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.nio.file.Files; @@ -61,7 +62,15 @@ public void i_put_resources_into_the_network() throws Throwable { StorageNode storageNode = ring.getNode(world.getNodeGateway()); for (String contentName : contents.keySet()) { - storageNode.put(new BytesResource(contentName, contents.get(contentName).getContent().getBytes())); + FileResource resource = FileResource.withInputStream() + .id(contentName) + .inputStream(new ByteArrayInputStream(contents.get(contentName).getContent().getBytes())) + .build(); + + storageNode.put(resource, (name, count, limit) -> { + }).get(); + + resource.close(); } } diff --git a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/ring/RingDefinitionStep.java b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/ring/RingDefinitionStep.java index dd0f7b0..32ab085 100644 --- a/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/ring/RingDefinitionStep.java +++ b/it/data-structure-it/src/ittest/java/co/edu/uniquindio/dht/it/datastructure/ring/RingDefinitionStep.java @@ -92,7 +92,7 @@ public void the_left_the_network(String node) throws Throwable { DHashNode dHashNode = ring.getNode(node); - dHashNode.leave(); + dHashNode.leave((name, count, limit) -> {}); } @Given("^The \"([^\"]*)\" is added to the network$") diff --git a/it/data-structure-it/src/main/resources/log4j.xml b/it/data-structure-it/src/main/resources/log4j.xml deleted file mode 100644 index de4611c..0000000 --- a/it/data-structure-it/src/main/resources/log4j.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/it/socket-it/Dockerfile b/it/socket-it/Dockerfile index fc47e7d..c8bfbf4 100644 --- a/it/socket-it/Dockerfile +++ b/it/socket-it/Dockerfile @@ -1,4 +1,4 @@ FROM openjdk:8-jre-alpine -COPY build/libs/socket-it-2.0.0.jar /app/app.jar +COPY build/libs/socket-it-2.2.0.jar /app/app.jar WORKDIR /app CMD ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/it/socket-it/build.gradle b/it/socket-it/build.gradle index 0aab99f..dcdbf38 100644 --- a/it/socket-it/build.gradle +++ b/it/socket-it/build.gradle @@ -19,17 +19,19 @@ repositories { mavenCentral() } -version = '2.0.0' +version = '2.3.0' dependencies { compile("org.springframework.boot:spring-boot-starter:1.5.10.RELEASE") - compile project(':main:starters:chord-spring-boot-starter') - compile project(':main:starters:dhash-spring-boot-starter') - compile project(':main:starters:socket-communication-spring-boot-starter') + compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.2' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '3.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication-spring-boot-starter', version: '3.0.0' + + compile 'org.projectlombok:lombok:1.16.20' + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' testCompile group: 'commons-io', name: 'commons-io', version: '2.6' - testCompile 'org.projectlombok:lombok:1.16.20' testCompile group: 'info.cukes', name: 'cucumber-java', version: '1.2.5' testCompile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5' testCompile group: 'info.cukes', name: 'cucumber-spring', version: '1.2.5' diff --git a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/gets/GetsDefinitionStep.java b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/gets/GetsDefinitionStep.java index 841fec4..fd94a38 100644 --- a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/gets/GetsDefinitionStep.java +++ b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/gets/GetsDefinitionStep.java @@ -1,15 +1,13 @@ package co.edu.uniquindio.dht.it.socket.test.gets; -import co.edu.uniquindio.dhash.resource.BytesResource; import co.edu.uniquindio.dht.it.socket.Protocol; import co.edu.uniquindio.dht.it.socket.test.CucumberRoot; import co.edu.uniquindio.dht.it.socket.test.MessageClient; import co.edu.uniquindio.dht.it.socket.test.World; import co.edu.uniquindio.dht.it.socket.test.put.Content; -import co.edu.uniquindio.storage.StorageNode; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import cucumber.api.java.en.Then; import org.springframework.beans.factory.annotation.Autowired; @@ -21,7 +19,7 @@ public class GetsDefinitionStep extends CucumberRoot { @Autowired private World world; @Autowired - private SequenceGenerator itSequenceGenerator; + private IdGenerator itSequenceGenerator; @Then("^I lookup the following resources:$") public void i_lookup_the_following_resources(List contents) throws Throwable { @@ -29,7 +27,7 @@ public void i_lookup_the_following_resources(List contents) throws Thro for (Content content : contents) { Message get = Message.builder() - .sequenceNumber(itSequenceGenerator.getSequenceNumber()) + .id(itSequenceGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.GET) .address(Address.builder() @@ -42,8 +40,8 @@ public void i_lookup_the_following_resources(List contents) throws Thro Message response = messageClient.send(get); assertThat(response).isNotNull(); - assertThat(response.getData(Protocol.GetResponseDatas.RESOURCE.name())).isNotNull(); - assertThat(response.getData(Protocol.GetResponseDatas.RESOURCE.name())).isEqualTo(content.getContent().getBytes()); + assertThat(response.getParam(Protocol.GetResponseDatas.RESOURCE.name())).isNotNull(); + assertThat(response.getParam(Protocol.GetResponseDatas.RESOURCE.name())).isEqualTo(content.getContent()); } } } diff --git a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/put/PutsDefinitionStep.java b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/put/PutsDefinitionStep.java index dee2a46..fbcea8c 100644 --- a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/put/PutsDefinitionStep.java +++ b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/put/PutsDefinitionStep.java @@ -8,8 +8,8 @@ import co.edu.uniquindio.dht.it.socket.test.World; import co.edu.uniquindio.dht.it.socket.test.ring.Ring; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import cucumber.api.java.en.Given; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; @@ -35,7 +35,7 @@ public class PutsDefinitionStep extends CucumberRoot { @Autowired private SocketITProperties socketITProperties; @Autowired - private SequenceGenerator itSequenceGenerator; + private IdGenerator itSequenceGenerator; private Map contents; @Given("^I have the resources names and values:$") @@ -52,7 +52,7 @@ public void i_put_resources_into_the_network() throws Throwable { for (String contentName : contents.keySet()) { Message put = Message.builder() - .sequenceNumber(itSequenceGenerator.getSequenceNumber()) + .id(itSequenceGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.PUT) .address(Address.builder() @@ -60,7 +60,7 @@ public void i_put_resources_into_the_network() throws Throwable { .destination("localhost") .build()) .param(Protocol.PutParams.RESOURCE_NAME.name(), contentName) - .data(Protocol.PutDatas.RESOURCE.name(), contents.get(contentName).getContent().getBytes()) + .param(Protocol.PutDatas.RESOURCE.name(), contents.get(contentName).getContent()) .build(); Message response = messageClient.send(put); diff --git a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/ring/RingDefinitionStep.java b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/ring/RingDefinitionStep.java index 15b76b5..981d73b 100644 --- a/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/ring/RingDefinitionStep.java +++ b/it/socket-it/src/ittest/java/co/edu/uniquindio/dht/it/socket/test/ring/RingDefinitionStep.java @@ -10,7 +10,7 @@ import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.utils.communication.message.Address; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.network.MessageSerialization; import cucumber.api.java.After; import cucumber.api.java.en.Given; @@ -38,7 +38,7 @@ public class RingDefinitionStep extends CucumberRoot { @Autowired private SocketITProperties socketITProperties; @Autowired - private SequenceGenerator itSequenceGenerator; + private IdGenerator itSequenceGenerator; private List nodes; @Given("^I use the \\\"([^\\\"]*)\\\" as a gateway$") @@ -68,7 +68,7 @@ public void the_left_the_network(String node) throws Throwable { MessageClient messageClient = ring.getNode(node); Message leave = Message.builder() - .sequenceNumber(itSequenceGenerator.getSequenceNumber()) + .id(itSequenceGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.LEAVE) .address(Address.builder() @@ -129,7 +129,7 @@ public void chord_ring_is_stable_with_the_following_successors(Map { + }); return Message.builder() .sendType(Message.SendType.RESPONSE) @@ -58,8 +59,8 @@ private Message processLeave(Message request) { .build()) .param(Protocol.LeaveResponseParams.MESSAGE.name(), "OK") .build(); - } catch (StorageException e) { - logger.error("Problem doing put", e); + } catch (Exception e) { + log.error("Problem doing put", e); return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.LEAVE_RESPONSE) @@ -75,7 +76,7 @@ private Message processLeave(Message request) { private Message processGetSuccessor(Message request) { ChordNode overlayNode = (ChordNode) storageNode.getOverlayNode(); - logger.info("Querying current successor: " + Optional.ofNullable(overlayNode.getSuccessor()).orElse(new ChordKey(BigInteger.ZERO)).getValue()); + log.info("Querying current successor: " + Optional.ofNullable(overlayNode.getSuccessor()).orElse(new ChordKey(BigInteger.ZERO)).getValue()); return Message.builder() .sendType(Message.SendType.RESPONSE) @@ -89,12 +90,18 @@ private Message processGetSuccessor(Message request) { } private Message processPut(Message request) { - BytesResource resource = new BytesResource(request.getParam(Protocol.PutParams.RESOURCE_NAME.name()), request.getData(Protocol.PutDatas.RESOURCE.name())); - try { - boolean success = storageNode.put(resource); + FileResource resource = FileResource.withInputStream() + .id(request.getParam(Protocol.PutParams.RESOURCE_NAME.name())) + .inputStream(new ByteArrayInputStream(request.getParam(Protocol.PutDatas.RESOURCE.name()).getBytes())) + .build(); + + boolean success = storageNode.put(resource, (name, current, size) -> { + }).get(); - if (success){ + resource.close(); + + if (success) { return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.PUT_RESPONSE) @@ -104,7 +111,7 @@ private Message processPut(Message request) { .build()) .param(Protocol.PutResponseParams.MESSAGE.name(), "OK") .build(); - }else{ + } else { return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.PUT_RESPONSE) @@ -115,8 +122,8 @@ private Message processPut(Message request) { .param(Protocol.PutResponseParams.MESSAGE.name(), "Put unsuccessful") .build(); } - } catch (StorageException e) { - logger.error("Problem doing put", e); + } catch (Exception e) { + log.error("Problem doing put", e); return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.PUT_RESPONSE) @@ -130,9 +137,8 @@ private Message processPut(Message request) { } private Message processGet(Message request) { - try { - BytesResource resource = (BytesResource) storageNode.get(request.getParam(Protocol.GetParams.RESOURCE_NAME.name())); - + try (Resource resource = storageNode.get(request.getParam(Protocol.GetParams.RESOURCE_NAME.name()), (name, current, size) -> { + }).get()) { return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.GET_RESPONSE) @@ -141,10 +147,10 @@ private Message processGet(Message request) { .destination(request.getAddress().getSource()) .build()) .param(Protocol.GetResponseParams.MESSAGE.name(), "OK") - .data(Protocol.GetResponseDatas.RESOURCE.name(), resource.getBytes()) + .param(Protocol.GetResponseDatas.RESOURCE.name(), IOUtils.toString(resource.getInputStream(), Charset.defaultCharset())) .build(); - } catch (StorageException e) { - logger.error("Problem doing get", e); + } catch (Exception e) { + log.error("Problem doing get", e); return Message.builder() .sendType(Message.SendType.RESPONSE) .messageType(Protocol.GET_RESPONSE) diff --git a/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/ITMain.java b/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/ITMain.java index ec7103a..ebacf4b 100644 --- a/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/ITMain.java +++ b/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/ITMain.java @@ -1,8 +1,7 @@ package co.edu.uniquindio.dht.it.socket.test; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; -import co.edu.uniquindio.utils.communication.message.SequenceGeneratorImpl; -import co.edu.uniquindio.utils.communication.transfer.network.MessageSerialization; +import co.edu.uniquindio.utils.communication.message.IdGenerator; +import co.edu.uniquindio.utils.communication.message.UUIDGenerator; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.Bean; @@ -17,7 +16,7 @@ public static void main(String[] args) { } @Bean - public SequenceGenerator itSequenceGenerator() { - return new SequenceGeneratorImpl(); + public IdGenerator itSequenceGenerator() { + return new UUIDGenerator(); } } diff --git a/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/MessageClient.java b/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/MessageClient.java index 480e733..318ff58 100644 --- a/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/MessageClient.java +++ b/it/socket-it/src/main/java/co/edu/uniquindio/dht/it/socket/test/MessageClient.java @@ -2,16 +2,15 @@ import co.edu.uniquindio.utils.communication.message.Message; import co.edu.uniquindio.utils.communication.transfer.network.MessageSerialization; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; +@Slf4j public class MessageClient { - private static final Logger logger = Logger - .getLogger(MessageClient.class); private final MessageSerialization messageSerialization; private final Integer portTcp; @@ -32,7 +31,7 @@ public Message send(Message request) { return messageSerialization.decode(stringMessage); } catch (IOException | ClassNotFoundException e) { - logger.error("Error writting socket", e); + log.error("Error writting socket", e); throw new IllegalStateException("Error writting socket to: " + request.getAddress() + " in port: " + portTcp, e); } } diff --git a/it/socket-it/src/main/resources/application.yml b/it/socket-it/src/main/resources/application.yml index a49e942..94504c6 100644 --- a/it/socket-it/src/main/resources/application.yml +++ b/it/socket-it/src/main/resources/application.yml @@ -10,14 +10,13 @@ communication: socket: instances: dhash: - RESPONSE_TIME: 2000 - BUFFER_SIZE_MULTICAST: 1024 - IP_MULTICAST: 224.0.0.1 - PORT_MULTICAST: 22011 - TIMEOUT_TCP_CONNECTION: 2000 - PORT_TCP: 22013 - PORT_UDP: 22014 - BUFFER_SIZE_UDP: 1024 + response_time: 2000 + buffer_size_multicast: 1024 + ip_multicast: 224.0.0.1 + port_multicast: 22011 + timeout_tcp_connection: 2000 + port_tcp: 22013 + size_tcp_buffer: 1024 socket-it: dhash: resource-directory: build/dhash/ diff --git a/it/socket-it/src/main/resources/log4j.xml b/it/socket-it/src/main/resources/log4j.xml deleted file mode 100644 index de4611c..0000000 --- a/it/socket-it/src/main/resources/log4j.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/desktop-network-gui/build.gradle b/main/desktop-network-gui/build.gradle index 36a5e5f..0915b41 100644 --- a/main/desktop-network-gui/build.gradle +++ b/main/desktop-network-gui/build.gradle @@ -8,12 +8,15 @@ repositories { mavenCentral() } -version = '2.0.4' +version = '2.0.5' dependencies { compile("org.springframework.boot:spring-boot-starter:1.5.10.RELEASE") - compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication-spring-boot-starter', version: '2.1.0' + compileOnly 'org.projectlombok:lombok:1.16.20' + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' + + compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.2' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '3.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication-spring-boot-starter', version: '3.0.0' } \ No newline at end of file diff --git a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java index 7868ab8..a4e5451 100644 --- a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java +++ b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java @@ -18,12 +18,10 @@ package co.edu.uniquindio.dht.gui; -import co.edu.uniquindio.dhash.resource.BytesResource; import co.edu.uniquindio.dht.gui.network.task.storageservice.GetTask; import co.edu.uniquindio.dht.gui.network.task.storageservice.PutTask; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; -import org.apache.commons.io.IOUtils; import javax.swing.*; import java.awt.*; @@ -31,9 +29,8 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.File; +import java.io.IOException; //TODO Documentar @SuppressWarnings("serial") @@ -192,7 +189,7 @@ public void run() { public void exit() { try { if (dHashNode != null) - dHashNode.leave(); + dHashNode.leave((name, current, limit) -> {}); } catch (StorageException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/NetworkWindow.java b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/NetworkWindow.java index fe2bcaa..b03e3eb 100644 --- a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/NetworkWindow.java +++ b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/NetworkWindow.java @@ -19,12 +19,11 @@ package co.edu.uniquindio.dht.gui.network; -import co.edu.uniquindio.chord.node.ChordNode; import co.edu.uniquindio.dht.gui.PanelDhash; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; import co.edu.uniquindio.storage.StorageNodeFactory; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import javax.swing.*; import java.awt.*; @@ -39,6 +38,7 @@ //TODO Documentar @SuppressWarnings("serial") +@Slf4j public class NetworkWindow extends JFrame implements WindowListener { //TODO Documentar private static InetAddress localHost; @@ -49,9 +49,6 @@ public class NetworkWindow extends JFrame implements WindowListener { private InetAddress inetAddress; //TODO Documentar public static final String DHASH_CLASS = "co.edu.uniquindio.dhash.node.DHashNodeFactory"; - // TODO Adicionar documentacion - private static final Logger logger = Logger - .getLogger(ChordNode.class); //TODO Documentar static { @@ -103,7 +100,7 @@ private void createNode() { panelDhash.setDHashNode(dHashNode); } catch (UnknownHostException e) { - logger.error("Could not initialize the InetAddress", e); + log.error("Could not initialize the InetAddress", e); } catch (StorageException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -139,7 +136,7 @@ private InetAddress getInetAddress() { } } } catch (SocketException e) { - logger.error("NetworkInteface error", e); + log.error("NetworkInteface error", e); } return null; diff --git a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/GetTask.java b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/GetTask.java index 5efee7a..7032b21 100644 --- a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/GetTask.java +++ b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/GetTask.java @@ -18,14 +18,16 @@ package co.edu.uniquindio.dht.gui.network.task.storageservice; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.LocalFileResource; import co.edu.uniquindio.storage.StorageNode; +import co.edu.uniquindio.storage.resource.Resource; +import lombok.extern.slf4j.Slf4j; import javax.swing.*; -import java.io.ByteArrayInputStream; import java.nio.file.Files; import java.nio.file.Paths; +@Slf4j public class GetTask extends StorageServiceTask { private final String resourceId; private final String resourceDirectory; @@ -39,10 +41,18 @@ public GetTask(JFrame jFrame, StorageNode storageNode, String resourceId, String @Override protected Void doInBackground() throws Exception { - BytesResource resource = (BytesResource) storageNode.get(resourceId); + Resource resource = storageNode.get(resourceId, (name, current, limit) -> { + }).get(); Files.createDirectories(Paths.get(resourceDirectory + storageNode.getName() + "/gets/")); - Files.copy(new ByteArrayInputStream(resource.getBytes()), Paths.get(resourceDirectory + storageNode.getName() + "/gets/" + resource.getId())); + + LocalFileResource localFileResource = LocalFileResource.builder() + .resource(resource) + .path(resourceDirectory + storageNode.getName() + "/gets/") + .sizeBuffer(2048) + .build(); + + localFileResource.persist(((name, current, size) -> {log.info("{} - {} - {}", name, current, size);})); return null; } diff --git a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/PutTask.java b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/PutTask.java index 3e27376..c2b36e0 100644 --- a/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/PutTask.java +++ b/main/desktop-network-gui/src/main/java/co/edu/uniquindio/dht/gui/network/task/storageservice/PutTask.java @@ -18,13 +18,12 @@ package co.edu.uniquindio.dht.gui.network.task.storageservice; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import co.edu.uniquindio.storage.StorageNode; -import org.apache.commons.io.IOUtils; +import co.edu.uniquindio.storage.resource.Resource; import javax.swing.*; import java.io.File; -import java.io.FileInputStream; public class PutTask extends StorageServiceTask { private final File file; @@ -37,10 +36,15 @@ public PutTask(JFrame jFrame, StorageNode storageNode, File file) { @Override protected Void doInBackground() throws Exception { - try (FileInputStream fileInputStream = new FileInputStream(file)) { - BytesResource fileResource = new BytesResource(file.getName(), IOUtils.toByteArray(fileInputStream)); + try { + Resource fileResource = FileResource.withPath() + .path(file.getAbsolutePath()) + .id(file.getName()) + .build(); + + storageNode.put(fileResource, ((name, current, size) -> {})); + } catch (Exception e) { - storageNode.put(fileResource); } return null; } diff --git a/main/desktop-network-gui/src/main/resources/application.yml b/main/desktop-network-gui/src/main/resources/application.yml index c7d9361..4a32d69 100644 --- a/main/desktop-network-gui/src/main/resources/application.yml +++ b/main/desktop-network-gui/src/main/resources/application.yml @@ -7,11 +7,10 @@ communication: socket: instances: dhash: - RESPONSE_TIME: 2000 - BUFFER_SIZE_MULTICAST: 1024 - IP_MULTICAST: 224.0.0.1 - PORT_MULTICAST: 2000 - TIMEOUT_TCP_CONNECTION: 2000 - PORT_TCP: 2002 - PORT_UDP: 2003 - BUFFER_SIZE_UDP: 1024 \ No newline at end of file + response_time: 2000 + buffer_size_multicast: 1024 + ip_multicast: 224.0.0.1 + port_multicast: 22011 + timeout_tcp_connection: 2000 + port_tcp: 22013 + size_tcp_buffer: 1024 \ No newline at end of file diff --git a/main/desktop-network-gui/src/main/resources/log4j.xml b/main/desktop-network-gui/src/main/resources/log4j.xml deleted file mode 100644 index de4611c..0000000 --- a/main/desktop-network-gui/src/main/resources/log4j.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/desktop-structure-gui/build.gradle b/main/desktop-structure-gui/build.gradle index 5a70a3a..8951a73 100644 --- a/main/desktop-structure-gui/build.gradle +++ b/main/desktop-structure-gui/build.gradle @@ -8,12 +8,15 @@ repositories { mavenCentral() } -version = '2.0.2' +version = '2.0.3' dependencies { compile("org.springframework.boot:spring-boot-starter:1.5.10.RELEASE") - compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-data-structure-communication-spring-boot-starter', version: '2.0.0' + compileOnly 'org.projectlombok:lombok:1.16.20' + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' + + compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.2' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '3.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-data-structure-communication-spring-boot-starter', version: '3.0.0' } \ No newline at end of file diff --git a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java index 84eb59c..9d860b6 100644 --- a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java +++ b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/PanelDhash.java @@ -19,18 +19,20 @@ package co.edu.uniquindio.dht.gui; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; -import org.apache.commons.io.IOUtils; +import co.edu.uniquindio.storage.resource.Resource; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.concurrent.ExecutionException; //TODO Documentar @SuppressWarnings("serial") @@ -117,17 +119,12 @@ public void run() { loadingBar.begin(); File fichero = fileChooser.getSelectedFile(); - try { - BytesResource fileResource = new BytesResource(fichero.getName(), IOUtils.toByteArray(new FileInputStream(fichero))); - getDHashNode().put(fileResource); - } catch (StorageException e1) { - loadingBar.end(); - JOptionPane.showMessageDialog(frame, e1 - .getMessage()); - } catch (FileNotFoundException e1) { - loadingBar.end(); - JOptionPane.showMessageDialog(frame, e1 - .getMessage()); + try (Resource fileResource = FileResource.withPath() + .id(fichero.getName()) + .path(fichero.getAbsolutePath()) + .build()) { + getDHashNode().put(fileResource, ((name, current, size) -> { + })); } catch (IOException e1) { loadingBar.end(); JOptionPane.showMessageDialog(frame, e1 @@ -161,18 +158,13 @@ public void run() { loadingBar.setValue(1, "Doing Get..."); loadingBar.begin(); try { - BytesResource resource = (BytesResource) getDHashNode().get(a); + Resource resource = getDHashNode().get(a, ((name, current, size) -> { + })).get(); Files.createDirectories(Paths.get(resourceDirectory + getDHashNode().getName() + "/gets/")); - Files.copy(new ByteArrayInputStream(resource.getBytes()), Paths.get(resourceDirectory + getDHashNode().getName() + "/gets/" + resource.getId())); + Files.copy(resource.getInputStream(), Paths.get(resourceDirectory + getDHashNode().getName() + "/gets/" + resource.getId())); - } catch (StorageException e1) { - loadingBar.end(); - JOptionPane.showMessageDialog(frame, e1 - .getMessage() - + "\nPlease try again later", "ERROR", - JOptionPane.INFORMATION_MESSAGE); - } catch (IOException e1) { + } catch (InterruptedException | ExecutionException | IOException e1) { loadingBar.end(); JOptionPane.showMessageDialog(frame, e1 .getMessage() @@ -232,7 +224,8 @@ public void run() { public void exit() { try { if (dHashNode != null) - dHashNode.leave(); + dHashNode.leave(((name, current, size) -> { + })); } catch (StorageException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/controller/NewNodeTask.java b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/controller/NewNodeTask.java index 519e600..5595915 100644 --- a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/controller/NewNodeTask.java +++ b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/controller/NewNodeTask.java @@ -19,13 +19,9 @@ package co.edu.uniquindio.dht.gui.structure.task.controller; -import co.edu.uniquindio.dhash.resource.BytesResource; import co.edu.uniquindio.dht.gui.structure.controller.Controller; import javax.swing.*; -import java.io.ByteArrayInputStream; -import java.nio.file.Files; -import java.nio.file.Paths; public class NewNodeTask extends ControllerTask { private final String nodeName; diff --git a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/GetTask.java b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/GetTask.java index b262d62..52ab06a 100644 --- a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/GetTask.java +++ b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/GetTask.java @@ -19,14 +19,16 @@ package co.edu.uniquindio.dht.gui.structure.task.storageservice; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.LocalFileResource; import co.edu.uniquindio.storage.StorageNode; +import co.edu.uniquindio.storage.resource.Resource; +import lombok.extern.slf4j.Slf4j; import javax.swing.*; -import java.io.ByteArrayInputStream; import java.nio.file.Files; import java.nio.file.Paths; +@Slf4j public class GetTask extends StorageServiceTask { private final String resourceId; private final String resourceDirectory; @@ -40,10 +42,18 @@ public GetTask(JFrame jFrame, StorageNode storageNode, String resourceId, String @Override protected Void doInBackground() throws Exception { - BytesResource resource = (BytesResource) storageNode.get(resourceId); + Resource resource = storageNode.get(resourceId, ((name, current, size) -> { + })).get(); Files.createDirectories(Paths.get(resourceDirectory + storageNode.getName() + "/gets/")); - Files.copy(new ByteArrayInputStream(resource.getBytes()), Paths.get(resourceDirectory + storageNode.getName() + "/gets/" + resource.getId())); + + LocalFileResource localFileResource = LocalFileResource.builder() + .resource(resource) + .path(resourceDirectory + storageNode.getName() + "/gets/") + .sizeBuffer(2048) + .build(); + + localFileResource.persist(((name, current, size) -> {log.info("{} - {} - {}", name, current, size);})); return null; } diff --git a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/PutTask.java b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/PutTask.java index 72460f5..451b9e4 100644 --- a/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/PutTask.java +++ b/main/desktop-structure-gui/src/main/java/co/edu/uniquindio/dht/gui/structure/task/storageservice/PutTask.java @@ -19,13 +19,12 @@ package co.edu.uniquindio.dht.gui.structure.task.storageservice; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import co.edu.uniquindio.storage.StorageNode; -import org.apache.commons.io.IOUtils; +import co.edu.uniquindio.storage.resource.Resource; import javax.swing.*; import java.io.File; -import java.io.FileInputStream; public class PutTask extends StorageServiceTask { private final File file; @@ -38,11 +37,13 @@ public PutTask(JFrame jFrame, StorageNode storageNode, File file) { @Override protected Void doInBackground() throws Exception { - try (FileInputStream fileInputStream = new FileInputStream(file)) { - BytesResource fileResource = new BytesResource(file.getName(), IOUtils.toByteArray(fileInputStream)); + Resource fileResource = FileResource.withPath() + .id(file.getName()) + .path(file.getAbsolutePath()) + .build(); + + storageNode.put(fileResource, ((name, current, size) -> {})); - storageNode.put(fileResource); - } return null; } } diff --git a/main/desktop-structure-gui/src/main/resources/log4j.xml b/main/desktop-structure-gui/src/main/resources/log4j.xml deleted file mode 100644 index de4611c..0000000 --- a/main/desktop-structure-gui/src/main/resources/log4j.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/standalone-network/build.gradle b/main/standalone-network/build.gradle index 36a5e5f..708e21d 100644 --- a/main/standalone-network/build.gradle +++ b/main/standalone-network/build.gradle @@ -8,12 +8,12 @@ repositories { mavenCentral() } -version = '2.0.4' +version = '2.0.5' dependencies { compile("org.springframework.boot:spring-boot-starter:1.5.10.RELEASE") - compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '2.0.1' - compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication-spring-boot-starter', version: '2.1.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-chord-spring-boot-starter', version: '2.0.2' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash-spring-boot-starter', version: '3.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication-spring-boot-starter', version: '3.0.0' } \ No newline at end of file diff --git a/main/standalone-network/src/main/resources/application.yml b/main/standalone-network/src/main/resources/application.yml index c7d9361..4a32d69 100644 --- a/main/standalone-network/src/main/resources/application.yml +++ b/main/standalone-network/src/main/resources/application.yml @@ -7,11 +7,10 @@ communication: socket: instances: dhash: - RESPONSE_TIME: 2000 - BUFFER_SIZE_MULTICAST: 1024 - IP_MULTICAST: 224.0.0.1 - PORT_MULTICAST: 2000 - TIMEOUT_TCP_CONNECTION: 2000 - PORT_TCP: 2002 - PORT_UDP: 2003 - BUFFER_SIZE_UDP: 1024 \ No newline at end of file + response_time: 2000 + buffer_size_multicast: 1024 + ip_multicast: 224.0.0.1 + port_multicast: 22011 + timeout_tcp_connection: 2000 + port_tcp: 22013 + size_tcp_buffer: 1024 \ No newline at end of file diff --git a/main/standalone-network/src/main/resources/log4j.xml b/main/standalone-network/src/main/resources/log4j.xml deleted file mode 100644 index de4611c..0000000 --- a/main/standalone-network/src/main/resources/log4j.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/main/starters/chord-spring-boot-starter/build.gradle b/main/starters/chord-spring-boot-starter/build.gradle index 6aaba5c..c422cb5 100644 --- a/main/starters/chord-spring-boot-starter/build.gradle +++ b/main/starters/chord-spring-boot-starter/build.gradle @@ -14,7 +14,7 @@ plugins { } group = 'com.github.estigma88' -version = '2.0.1' +version = '2.0.2' sourceCompatibility = 1.8 @@ -24,8 +24,7 @@ repositories { dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-chord', version: '2.0.0' - + compile group: 'com.github.estigma88', name: 'jdhtuq-chord', version: '2.0.1' compileOnly 'org.projectlombok:lombok:1.16.20' compileOnly "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}" compile("org.springframework.boot:spring-boot-starter:${springBootVersion}") diff --git a/main/starters/chord-spring-boot-starter/src/main/java/co/edu/uniquindio/chord/starter/ChordAutoConfiguration.java b/main/starters/chord-spring-boot-starter/src/main/java/co/edu/uniquindio/chord/starter/ChordAutoConfiguration.java index b460ffc..d70b8e9 100644 --- a/main/starters/chord-spring-boot-starter/src/main/java/co/edu/uniquindio/chord/starter/ChordAutoConfiguration.java +++ b/main/starters/chord-spring-boot-starter/src/main/java/co/edu/uniquindio/chord/starter/ChordAutoConfiguration.java @@ -11,8 +11,8 @@ import co.edu.uniquindio.chord.node.command.StabilizeObserver; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.overlay.OverlayNodeFactory; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; -import co.edu.uniquindio.utils.communication.message.SequenceGeneratorImpl; +import co.edu.uniquindio.utils.communication.message.IdGenerator; +import co.edu.uniquindio.utils.communication.message.UUIDGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.CommunicationManagerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +38,7 @@ public class ChordAutoConfiguration { @Bean @ConditionalOnMissingBean - public OverlayNodeFactory overlayNodeFactory(CommunicationManager communicationManagerChord, BootStrap bootStrap, ScheduledExecutorService scheduledStableRing, List stableRingObservers, KeyFactory keyFactory, SequenceGenerator chordSequenceGenerator) { + public OverlayNodeFactory overlayNodeFactory(CommunicationManager communicationManagerChord, BootStrap bootStrap, ScheduledExecutorService scheduledStableRing, List stableRingObservers, KeyFactory keyFactory, IdGenerator chordSequenceGenerator) { return new ChordNodeFactory(communicationManagerChord, new HashSet<>(), chordProperties.getStableRingTime(), chordProperties.getSuccessorListAmount(), bootStrap, scheduledStableRing, stableRingObservers, keyFactory, chordSequenceGenerator); } @@ -62,8 +62,8 @@ public HashingGenerator hashingGenerator() { @Bean @ConditionalOnMissingBean - public SequenceGenerator chordSequenceGenerator() { - return new SequenceGeneratorImpl(); + public IdGenerator chordSequenceGenerator() { + return new UUIDGenerator(); } @Bean diff --git a/main/starters/data-structure-communication-spring-boot-starter/build.gradle b/main/starters/data-structure-communication-spring-boot-starter/build.gradle index 49ebc1c..6375603 100644 --- a/main/starters/data-structure-communication-spring-boot-starter/build.gradle +++ b/main/starters/data-structure-communication-spring-boot-starter/build.gradle @@ -14,7 +14,7 @@ plugins { } group = 'com.github.estigma88' -version = '2.0.0' +version = '3.0.0' sourceCompatibility = 1.8 @@ -24,7 +24,7 @@ repositories { dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-data-structure-communication', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-data-structure-communication', version: '3.0.0' compileOnly 'org.projectlombok:lombok:1.16.20' compileOnly "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}" diff --git a/main/starters/dhash-spring-boot-starter/build.gradle b/main/starters/dhash-spring-boot-starter/build.gradle index 6550a7d..c681711 100644 --- a/main/starters/dhash-spring-boot-starter/build.gradle +++ b/main/starters/dhash-spring-boot-starter/build.gradle @@ -14,7 +14,7 @@ plugins { } group = 'com.github.estigma88' -version = '2.0.1' +version = '3.0.0' sourceCompatibility = 1.8 @@ -24,7 +24,7 @@ repositories { dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-dhash', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-dhash', version: '3.0.0' compileOnly 'org.projectlombok:lombok:1.16.20' compileOnly "org.springframework.boot:spring-boot-configuration-processor:${springBootVersion}" diff --git a/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashAutoConfiguration.java b/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashAutoConfiguration.java index 0f31c5a..4c7b764 100644 --- a/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashAutoConfiguration.java +++ b/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashAutoConfiguration.java @@ -1,19 +1,20 @@ package co.edu.uniquindio.dhash.starter; import co.edu.uniquindio.dhash.node.DHashNodeFactory; -import co.edu.uniquindio.dhash.resource.checksum.BytesChecksumCalculator; import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; +import co.edu.uniquindio.dhash.resource.checksum.ChecksumInputStreamCalculator; import co.edu.uniquindio.dhash.resource.manager.FileResourceManagerFactory; import co.edu.uniquindio.dhash.resource.manager.ResourceManagerFactory; -import co.edu.uniquindio.dhash.resource.serialization.ObjectSerializationHandler; +import co.edu.uniquindio.dhash.resource.serialization.ObjectMapperSerializationHandler; import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.overlay.OverlayNodeFactory; import co.edu.uniquindio.storage.StorageNodeFactory; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; -import co.edu.uniquindio.utils.communication.message.SequenceGeneratorImpl; +import co.edu.uniquindio.utils.communication.message.IdGenerator; +import co.edu.uniquindio.utils.communication.message.UUIDGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.CommunicationManagerFactory; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -21,6 +22,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.concurrent.Executors; + @Configuration @ConditionalOnClass({StorageNodeFactory.class, OverlayNodeFactory.class, DHashNodeFactory.class}) @EnableConfigurationProperties(DHashProperties.class) @@ -30,8 +33,8 @@ public class DHashAutoConfiguration { @Bean @ConditionalOnMissingBean - public StorageNodeFactory storageNodeFactory(OverlayNodeFactory overlayNodeFactory, KeyFactory keyFactory, CommunicationManager communicationManagerDHash, SerializationHandler serializationHandler, ChecksumCalculator checksumeCalculator, ResourceManagerFactory resourceManagerFactory, SequenceGenerator dhashSequenceGenerator) { - return new DHashNodeFactory(communicationManagerDHash, overlayNodeFactory, serializationHandler, checksumeCalculator, resourceManagerFactory, dHashProperties.getReplicationAmount(), keyFactory, dhashSequenceGenerator); + public StorageNodeFactory storageNodeFactory(OverlayNodeFactory overlayNodeFactory, KeyFactory keyFactory, CommunicationManager communicationManagerDHash, SerializationHandler serializationHandler, ChecksumCalculator checksumeCalculator, ResourceManagerFactory resourceManagerFactory, IdGenerator dhashSequenceGenerator) { + return new DHashNodeFactory(communicationManagerDHash, overlayNodeFactory, serializationHandler, checksumeCalculator, resourceManagerFactory, dHashProperties.getReplicationAmount(), keyFactory, dhashSequenceGenerator, Executors.newCachedThreadPool()); } @Bean @@ -43,24 +46,24 @@ public CommunicationManager communicationManagerDHash(CommunicationManagerFactor @Bean @ConditionalOnMissingBean public SerializationHandler serializationHandler() { - return new ObjectSerializationHandler(); + return new ObjectMapperSerializationHandler(new ObjectMapper()); } @Bean @ConditionalOnMissingBean public ChecksumCalculator checksumeCalculator() { - return new BytesChecksumCalculator(); + return new ChecksumInputStreamCalculator(); } @Bean @ConditionalOnMissingBean - public SequenceGenerator dhashSequenceGenerator() { - return new SequenceGeneratorImpl(); + public IdGenerator dhashSequenceGenerator() { + return new UUIDGenerator(); } @Bean @ConditionalOnMissingBean public ResourceManagerFactory persistenceHandlerFactory() { - return new FileResourceManagerFactory(dHashProperties.getResourceDirectory()); + return new FileResourceManagerFactory(dHashProperties.getResourceDirectory(), dHashProperties.getBufferSize()); } } diff --git a/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashProperties.java b/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashProperties.java index a66709b..648fb16 100644 --- a/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashProperties.java +++ b/main/starters/dhash-spring-boot-starter/src/main/java/co/edu/uniquindio/dhash/starter/DHashProperties.java @@ -10,4 +10,5 @@ public class DHashProperties { private int replicationAmount = 1; private String resourceDirectory = "dhash/"; + private int bufferSize = 1024; } diff --git a/main/starters/socket-communication-spring-boot-starter/build.gradle b/main/starters/socket-communication-spring-boot-starter/build.gradle index fb6dd3e..117245d 100644 --- a/main/starters/socket-communication-spring-boot-starter/build.gradle +++ b/main/starters/socket-communication-spring-boot-starter/build.gradle @@ -14,7 +14,7 @@ plugins { } group = 'com.github.estigma88' -version = '2.1.0' +version = '3.0.0' sourceCompatibility = 1.8 @@ -24,9 +24,8 @@ repositories { dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication', version: '2.1.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-socket-communication', version: '3.0.0' - // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4' compileOnly 'org.projectlombok:lombok:1.16.20' diff --git a/p2p/chord/build.gradle b/p2p/chord/build.gradle index ca4662c..e6cf618 100644 --- a/p2p/chord/build.gradle +++ b/p2p/chord/build.gradle @@ -9,13 +9,14 @@ repositories { } group = 'com.github.estigma88' -version = '2.0.0' +version = '2.0.1' dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '3.0.0' compile group: 'com.github.estigma88', name: 'jdhtuq-lookup-service', version: '2.0.0' compileOnly 'org.projectlombok:lombok:1.16.20' + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' testCompile group: 'junit', name: 'junit', version: '4.4' testCompile 'org.mockito:mockito-core:2.8.9' diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/BootStrap.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/BootStrap.java index b5f0465..06544c0 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/BootStrap.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/BootStrap.java @@ -24,9 +24,9 @@ import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.utils.communication.message.Address; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; /** * The BootStrap class is responsible for initializing a node @@ -40,13 +40,9 @@ * @see ChordNode * @since 1.0 */ -public class BootStrap { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(BootStrap.class); +@Slf4j +public class BootStrap { /** * A Chord uses this method when is created to initializes. If there is an @@ -59,17 +55,17 @@ public class BootStrap { * * @param nodeChord node who will be added to the network. * @param communicationManager Communication manager - * @param sequenceGenerator Sequence generator + * @param idGenerator Sequence generator */ - public void boot(ChordNode nodeChord, CommunicationManager communicationManager, SequenceGenerator sequenceGenerator) { + public void boot(ChordNode nodeChord, CommunicationManager communicationManager, IdGenerator idGenerator) { - logger.info("Search node..."); + log.info("Search node..."); Key findNode; Message bootStrapMessage; bootStrapMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.BOOTSTRAP) .address(Address.builder() @@ -77,32 +73,32 @@ public void boot(ChordNode nodeChord, CommunicationManager communicationManager, .build()) .build(); - findNode = communicationManager.sendMessageMultiCast(bootStrapMessage, + findNode = communicationManager.sendMultiCast(bootStrapMessage, ChordKey.class); - logger.info("Finish search node"); + log.info("Finish search node"); if (findNode == null) { /* When no other node is found */ - Logger.getLogger(BootStrap.class).debug( + log.debug( "Node '" + nodeChord.getKey().getValue() + "' found '" + null + "'"); nodeChord.createRing(); } else { - logger.debug("Node '" + nodeChord.getKey().getValue() + "' found '" + log.debug("Node '" + nodeChord.getKey().getValue() + "' found '" + findNode.getValue() + "'"); nodeChord.join(findNode); if (nodeChord.getSuccessor() == null) { /* If the join fails the boot is done again */ - boot(nodeChord, communicationManager, sequenceGenerator); + boot(nodeChord, communicationManager, idGenerator); } } nodeChord.getFingersTable().getFingersTable()[0] = nodeChord .getSuccessor(); - logger.info("Node '" + nodeChord.getKey().getValue() + log.info("Node '" + nodeChord.getKey().getValue() + "' have by successor '" + nodeChord.getSuccessor().getValue() + "'"); } diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNode.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNode.java index d69548d..7f4fd7c 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNode.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNode.java @@ -26,10 +26,10 @@ import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.util.Observable; import java.util.Optional; @@ -55,14 +55,9 @@ * @see BootStrap * @since 1.0 */ +@Slf4j public class ChordNode extends Observable implements Chord { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(ChordNode.class); - /** * Communication manager */ @@ -95,29 +90,29 @@ public class ChordNode extends Observable implements Chord { private BootStrap bootStrap; private KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator idGenerator; private ScheduledFuture stableRing; - ChordNode(ChordKey key, CommunicationManager communicationManager, int successorListAmount, BootStrap bootStrap, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + ChordNode(ChordKey key, CommunicationManager communicationManager, int successorListAmount, BootStrap bootStrap, KeyFactory keyFactory, IdGenerator idGenerator) { this.keyFactory = keyFactory; - this.sequenceGenerator = sequenceGenerator; + this.idGenerator = idGenerator; this.fingersTable = newFingersTable(); - this.successorList = new SuccessorList(this, communicationManager, successorListAmount, keyFactory, sequenceGenerator); + this.successorList = new SuccessorList(this, communicationManager, successorListAmount, keyFactory, idGenerator); this.key = key; this.communicationManager = communicationManager; this.bootStrap = bootStrap; - logger.info("New ChordNode created = " + key); + log.info("New ChordNode created = " + key); } - ChordNode(CommunicationManager communicationManager, ChordKey successor, ChordKey predecessor, FingersTable fingersTable, SuccessorList successorList, ChordKey key, SequenceGenerator sequenceGenerator, ScheduledFuture stableRing) { + ChordNode(CommunicationManager communicationManager, ChordKey successor, ChordKey predecessor, FingersTable fingersTable, SuccessorList successorList, ChordKey key, IdGenerator idGenerator, ScheduledFuture stableRing) { this.communicationManager = communicationManager; this.successor = successor; this.predecessor = predecessor; this.fingersTable = fingersTable; this.successorList = successorList; this.key = key; - this.sequenceGenerator = sequenceGenerator; + this.idGenerator = idGenerator; this.stableRing = stableRing; } @@ -156,7 +151,7 @@ public ChordKey findSuccessor(ChordKey id, LookupType typeLookUp) { next = fingersTable.findClosestPresedingNode(id); lookupMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.LOOKUP) .address(Address.builder() @@ -167,7 +162,7 @@ public ChordKey findSuccessor(ChordKey id, LookupType typeLookUp) { .param(Protocol.LookupParams.TYPE.name(), typeLookUp.name()) .build(); - return communicationManager.sendMessageUnicast(lookupMessage, + return communicationManager.send(lookupMessage, ChordKey.class, LookupResponseParams.NODE_FIND.name()); } } @@ -197,7 +192,7 @@ public void join(Key node) { predecessor = null; lookupMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.LOOKUP) .address(Address.builder() @@ -208,7 +203,7 @@ public void join(Key node) { .param(Protocol.LookupParams.TYPE.name(), LookupType.JOIN.name()) .build(); - successor = communicationManager.sendMessageUnicast(lookupMessage, + successor = communicationManager.send(lookupMessage, ChordKey.class, LookupResponseParams.NODE_FIND.name()); successorList.initializeSuccessors(); @@ -242,11 +237,11 @@ public void notify(ChordKey node) { notifyObservers(message); clearChanged(); - logger.debug("Node: '" + key.getValue() + log.debug("Node: '" + key.getValue() + "' Predecessor changed for '" + Optional.ofNullable(predecessor).map(p -> p.getValue()).orElse(null)); } - logger.info("Notify to node '" + key.getValue() + "', predecessor is '" + log.info("Notify to node '" + key.getValue() + "', predecessor is '" + Optional.ofNullable(predecessor).map(p -> p.getValue()).orElse(null) + "'"); } @@ -264,7 +259,7 @@ public void checkPredecessor() { Message pingMessage; pingMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.PING) .address(Address.builder() @@ -273,7 +268,7 @@ public void checkPredecessor() { .build()) .build(); - Boolean success = communicationManager.sendMessageUnicast(pingMessage, + Boolean success = communicationManager.send(pingMessage, Boolean.class); if (success == null) { @@ -300,7 +295,7 @@ public void stabilize() { Message notifyMessage; pingMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.PING) .address(Address.builder() @@ -309,14 +304,14 @@ public void stabilize() { .build()) .build(); - success = communicationManager.sendMessageUnicast(pingMessage, + success = communicationManager.send(pingMessage, Boolean.class); if (success == null) { /* When node's successor fails, then node must find a new successor */ ChordKey successorNew = successorList.getNextSuccessorAvailable(); - logger.error("Node: " + key.getValue() + ", successor failed"); + log.error("Node: " + key.getValue() + ", successor failed"); if (successorNew != null) { successor = successorNew; @@ -329,7 +324,7 @@ public void stabilize() { * is, find a node to join the network. */ - logger.error("Node: " + key.getValue() + log.error("Node: " + key.getValue() + ", successor list failed... new bootstrap"); fingersTable = newFingersTable(); @@ -342,7 +337,7 @@ public void stabilize() { * predecessor */ getPredecessorMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.GET_PREDECESSOR) .address(Address.builder() @@ -351,7 +346,7 @@ public void stabilize() { .build()) .build(); - x = communicationManager.sendMessageUnicast(getPredecessorMessage, + x = communicationManager.send(getPredecessorMessage, ChordKey.class); if (x != null) { @@ -363,15 +358,15 @@ public void stabilize() { } } - logger.info("Node '" + key.getValue() + log.info("Node '" + key.getValue() + "' stabilized, its succesor is '" + successor.getValue() + "'"); - logger.debug("Node '" + key.getValue() + "' Succesor list '" + log.debug("Node '" + key.getValue() + "' Succesor list '" + successorList + "'"); notifyMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.NOTIFY) .address(Address.builder() @@ -380,12 +375,12 @@ public void stabilize() { .build()) .build(); - communicationManager.sendMessageUnicast(notifyMessage); + communicationManager.send(notifyMessage); } } void bootUp() { - bootStrap.boot(this, communicationManager, sequenceGenerator); + bootStrap.boot(this, communicationManager, idGenerator); } FingersTable newFingersTable() { @@ -508,7 +503,7 @@ public ChordKey[] leave() { if (!successor.equals(key) && predecessor != null) { setSuccessorMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.SET_SUCCESSOR) .address(Address.builder() @@ -518,10 +513,10 @@ public ChordKey[] leave() { .param(Protocol.SetSuccessorParams.SUCCESSOR.name(), successor.getValue()) .build(); - communicationManager.sendMessageUnicast(setSuccessorMessage); + communicationManager.send(setSuccessorMessage); setPredecessorMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.SET_PREDECESSOR) .address(Address.builder() @@ -531,7 +526,7 @@ public ChordKey[] leave() { .param(Protocol.SetPredecessorParams.PREDECESSOR.name(), predecessor.toString()) .build(); - communicationManager.sendMessageUnicast(setPredecessorMessage); + communicationManager.send(setPredecessorMessage); } communicationManager.removeMessageProcessor(key.getValue()); diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNodeFactory.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNodeFactory.java index 0822e01..112e991 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNodeFactory.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/ChordNodeFactory.java @@ -21,10 +21,13 @@ import co.edu.uniquindio.chord.Chord; import co.edu.uniquindio.chord.ChordKey; -import co.edu.uniquindio.overlay.*; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.overlay.KeyFactory; +import co.edu.uniquindio.overlay.OverlayException; +import co.edu.uniquindio.overlay.OverlayNode; +import co.edu.uniquindio.overlay.OverlayNodeFactory; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Observer; @@ -39,20 +42,12 @@ * chord_properties/communication.xml and initialized hashing class * * @author Daniel Pelaez - * @author Hector Hurtado - * @author Daniel Lopez - * @version 1.0, 17/06/2010 * @see Chord * @see ChordNode * @since 1.0 */ +@Slf4j public class ChordNodeFactory implements OverlayNodeFactory { - - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(ChordNodeFactory.class); public static final int START_STABLE_RING = 5000; private final int stableRingTime; @@ -66,9 +61,9 @@ public class ChordNodeFactory implements OverlayNodeFactory { private final ScheduledExecutorService scheduledStableRing; private final List stableRingObservers; private final KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator sequenceGenerator; - public ChordNodeFactory(CommunicationManager communicationManager, Set names, int stableRingTime, int successorListAmount, BootStrap bootStrap, ScheduledExecutorService scheduledStableRing, List stableRingObservers, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + public ChordNodeFactory(CommunicationManager communicationManager, Set names, int stableRingTime, int successorListAmount, BootStrap bootStrap, ScheduledExecutorService scheduledStableRing, List stableRingObservers, KeyFactory keyFactory, IdGenerator sequenceGenerator) { this.communicationManager = communicationManager; this.stableRingTime = stableRingTime; this.successorListAmount = successorListAmount; @@ -89,7 +84,7 @@ public Chord createNode(String name) throws ChordNodeFactoryException { ChordKey key = getKey(name); ChordNode chordNode = getNodeChord(key); - logger.info("Created node with name '" + chordNode.getKey().getValue() + log.info("Created node with name '" + chordNode.getKey().getValue() + "' and hashing '" + chordNode.getKey().getHashing() + "'"); diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/FingersTable.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/FingersTable.java index 1ae86c8..2f02ca7 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/FingersTable.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/FingersTable.java @@ -19,13 +19,13 @@ package co.edu.uniquindio.chord.node; -import java.math.BigInteger; -import java.util.Arrays; - import co.edu.uniquindio.chord.ChordKey; import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigInteger; +import java.util.Arrays; /** * The FingersTable class represents a routing table with up to @@ -36,187 +36,178 @@ * 1<=i<=m (and all arithmetic is modulo 2^m). We call * node s the i-th finger of node n, and * denote it by n.finger[i]. - * + * * @author Daniel Pelaez * @author Hector Hurtado * @author Daniel Lopez * @version 1.0, 17/06/2010 - * @since 1.0 * @see ChordNode * @see StableRing + * @since 1.0 */ +@Slf4j public class FingersTable { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(FingersTable.class); - - /** - * List of {@link Key} that represents the fingers table. - */ - private ChordKey[] fingersTable; - - /** - * References the chord node that has this FingersTable. - */ - private ChordNode chordNode; - - /** - * Stores the index of the next finger to fix. - */ - private int next; - - /** - * Size of the fingers table. - */ - private int size; - private KeyFactory keyFactory; - - /** - * Constructor of the class. Receives a reference of the chord node and - * initializes the size, pointer next and the fingers table. - * - * @param nodeChord - * The reference of the chord node. - */ - FingersTable(ChordNode nodeChord, KeyFactory keyFactory) { - this.size = keyFactory.getKeyLength(); - this.chordNode = nodeChord; - this.next = 0; - this.fingersTable = new ChordKey[size]; - this.keyFactory = keyFactory; - } - - FingersTable(ChordKey[] fingersTable, ChordNode chordNode, int next, int size, KeyFactory keyFactory) { - this.fingersTable = fingersTable; - this.chordNode = chordNode; - this.next = next; - this.size = size; - this.keyFactory = keyFactory; - } - - /** - * Find the closest key in its fingers list that is before a given key. - * - * @param key - * The key that will be tested. - * @return {@link Key} The key that is closest and before the given key. - */ - public ChordKey findClosestPresedingNode(ChordKey key) { - for (int i = size - 1; i >= 0; i--) { - if (fingersTable[i] != null) { - if (fingersTable[i].isBetween(chordNode.getKey(), key)) { - return fingersTable[i]; - } - } - } - return chordNode.getKey(); - } - - /** - * Called periodically in {@link StableRing }. - * - * Fixes the position next of the fingers list every time the - * method FingersTable.fixFingers is called. - */ - public void fixFingers() { - next++; - - if (next > size - 1) { - next = 0; - } - - fingersTable[next] = chordNode.findSuccessor(createNext(chordNode - .getKey()), LookupType.FINGERS_TABLE); - - if (fingersTable[next] == null) { - fingersTable[next] = chordNode.getSuccessor(); - } - - logger.debug("Node: " + chordNode.getKey().getValue() + " Next: " + next - + " ChordKey: " + createNext(chordNode.getKey())); - - logger.debug("Fingers: " + Arrays.asList(fingersTable)); - } - - /** - * Sets the successor in the position 0 in the fingers table list. - * - * @param successor - * The key to be set as successor. - */ - public void setSuccessor(ChordKey successor) { - fingersTable[0] = successor; - } - - /** - * Called always for FingersTable.fixFingers - * - * Create the i-th entry to be test in the fingers table. The - * next entry is given by - * (node.key + 2^(next-1)) mod 2^(size), 1<=k<=m - * - * @param key - * Node's key - * @return {@link Key} The key to be test in the fingers table. - */ - ChordKey createNext(ChordKey key) { - Key nextKey; - BigInteger nextValue; - BigInteger twoPow; - BigInteger maxValue; - - twoPow = new BigInteger("2"); - twoPow = twoPow.pow(next); - - nextValue = new BigInteger(key.getHashing().toByteArray()); - nextValue = nextValue.add(twoPow); - - maxValue = new BigInteger("2"); - maxValue = maxValue.pow(size); - - nextValue = nextValue.mod(maxValue); - - nextKey = keyFactory.newKey(nextValue); - - return (ChordKey) nextKey; - } - - /** - * Gets the next position to fix. - * - * @return value of the position to fix. - */ - public int getNext() { - return next; - } - - /** - * Gets the size of the fingers table - * - * @return The size of the fingers table. - */ - public int getSize() { - return size; - } - - /** - * Gets the fingers table array. - * - * @return ChordKey[] - */ - public ChordKey[] getFingersTable() { - return fingersTable; - } - - /** - * Gets the reference of the chord node. - * - * @return {@link ChordNode} - */ - public ChordNode getChordNode() { - return chordNode; - } + /** + * List of {@link Key} that represents the fingers table. + */ + private ChordKey[] fingersTable; + + /** + * References the chord node that has this FingersTable. + */ + private ChordNode chordNode; + + /** + * Stores the index of the next finger to fix. + */ + private int next; + + /** + * Size of the fingers table. + */ + private int size; + private KeyFactory keyFactory; + + /** + * Constructor of the class. Receives a reference of the chord node and + * initializes the size, pointer next and the fingers table. + * + * @param nodeChord The reference of the chord node. + */ + FingersTable(ChordNode nodeChord, KeyFactory keyFactory) { + this.size = keyFactory.getKeyLength(); + this.chordNode = nodeChord; + this.next = 0; + this.fingersTable = new ChordKey[size]; + this.keyFactory = keyFactory; + } + + FingersTable(ChordKey[] fingersTable, ChordNode chordNode, int next, int size, KeyFactory keyFactory) { + this.fingersTable = fingersTable; + this.chordNode = chordNode; + this.next = next; + this.size = size; + this.keyFactory = keyFactory; + } + + /** + * Find the closest key in its fingers list that is before a given key. + * + * @param key The key that will be tested. + * @return {@link Key} The key that is closest and before the given key. + */ + public ChordKey findClosestPresedingNode(ChordKey key) { + for (int i = size - 1; i >= 0; i--) { + if (fingersTable[i] != null) { + if (fingersTable[i].isBetween(chordNode.getKey(), key)) { + return fingersTable[i]; + } + } + } + return chordNode.getKey(); + } + + /** + * Called periodically in {@link StableRing }. + *

+ * Fixes the position next of the fingers list every time the + * method FingersTable.fixFingers is called. + */ + public void fixFingers() { + next++; + + if (next > size - 1) { + next = 0; + } + + fingersTable[next] = chordNode.findSuccessor(createNext(chordNode + .getKey()), LookupType.FINGERS_TABLE); + + if (fingersTable[next] == null) { + fingersTable[next] = chordNode.getSuccessor(); + } + + log.debug("Node: " + chordNode.getKey().getValue() + " Next: " + next + + " ChordKey: " + createNext(chordNode.getKey())); + + log.debug("Fingers: " + Arrays.asList(fingersTable)); + } + + /** + * Sets the successor in the position 0 in the fingers table list. + * + * @param successor The key to be set as successor. + */ + public void setSuccessor(ChordKey successor) { + fingersTable[0] = successor; + } + + /** + * Called always for FingersTable.fixFingers + *

+ * Create the i-th entry to be test in the fingers table. The + * next entry is given by + * (node.key + 2^(next-1)) mod 2^(size), 1<=k<=m + * + * @param key Node's key + * @return {@link Key} The key to be test in the fingers table. + */ + ChordKey createNext(ChordKey key) { + Key nextKey; + BigInteger nextValue; + BigInteger twoPow; + BigInteger maxValue; + + twoPow = new BigInteger("2"); + twoPow = twoPow.pow(next); + + nextValue = new BigInteger(key.getHashing().toByteArray()); + nextValue = nextValue.add(twoPow); + + maxValue = new BigInteger("2"); + maxValue = maxValue.pow(size); + + nextValue = nextValue.mod(maxValue); + + nextKey = keyFactory.newKey(nextValue); + + return (ChordKey) nextKey; + } + + /** + * Gets the next position to fix. + * + * @return value of the position to fix. + */ + public int getNext() { + return next; + } + + /** + * Gets the size of the fingers table + * + * @return The size of the fingers table. + */ + public int getSize() { + return size; + } + + /** + * Gets the fingers table array. + * + * @return ChordKey[] + */ + public ChordKey[] getFingersTable() { + return fingersTable; + } + + /** + * Gets the reference of the chord node. + * + * @return {@link ChordNode} + */ + public ChordNode getChordNode() { + return chordNode; + } } \ No newline at end of file diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/NodeEnvironment.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/NodeEnvironment.java index c90f633..2c86ef9 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/NodeEnvironment.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/NodeEnvironment.java @@ -22,15 +22,14 @@ import co.edu.uniquindio.chord.ChordKey; import co.edu.uniquindio.chord.protocol.Protocol; import co.edu.uniquindio.chord.protocol.Protocol.*; -import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; import co.edu.uniquindio.utils.communication.message.Message.SendType; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.math.BigInteger; @@ -47,14 +46,8 @@ * @see ChordNode * @since 1.0 */ +@Slf4j class NodeEnvironment implements MessageProcessor { - - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(NodeEnvironment.class); - /** * Communication manager */ @@ -74,9 +67,9 @@ class NodeEnvironment implements MessageProcessor { * The thread that uses the commands for stabilizing the node. */ private final KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator sequenceGenerator; - NodeEnvironment(CommunicationManager communicationManager, ChordNode chordNode, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + NodeEnvironment(CommunicationManager communicationManager, ChordNode chordNode, KeyFactory keyFactory, IdGenerator sequenceGenerator) { this.communicationManager = communicationManager; this.chordNode = chordNode; this.keyFactory = keyFactory; @@ -91,7 +84,7 @@ class NodeEnvironment implements MessageProcessor { */ public Message process(Message message) { - logger.debug("Message to '" + chordNode.getKey().getValue() + "', [" + log.debug("Message to '" + chordNode.getKey().getValue() + "', [" + message.toString()); Message response = null; @@ -144,7 +137,7 @@ private Message processGetSuccessorList(Message message) { successorList = chordNode.getSuccessorList().toString(); getSuccesorListResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) + .id(message.getId()) .sendType(SendType.RESPONSE) .messageType(Protocol.GET_SUCCESSOR_LIST_RESPONSE) .address(Address.builder() @@ -204,7 +197,7 @@ private Message processLeave(Message message) { if (!chordNode.getSuccessor().equals(chordNode.getKey())) { setSuccessorMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(sequenceGenerator.newId()) .sendType(SendType.REQUEST) .messageType(Protocol.SET_SUCCESSOR) .address(Address.builder() @@ -214,10 +207,10 @@ private Message processLeave(Message message) { .param(SetSuccessorParams.SUCCESSOR.name(), chordNode.getSuccessor().getValue()) .build(); - communicationManager.sendMessageUnicast(setSuccessorMessage); + communicationManager.send(setSuccessorMessage); setPredecessorMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(sequenceGenerator.newId()) .sendType(SendType.REQUEST) .messageType(Protocol.SET_PREDECESSOR) .address(Address.builder() @@ -227,7 +220,7 @@ private Message processLeave(Message message) { .param(SetPredecessorParams.PREDECESSOR.name(), chordNode.getPredecessor().toString()) .build(); - communicationManager.sendMessageUnicast(setPredecessorMessage); + communicationManager.send(setPredecessorMessage); } communicationManager.removeMessageProcessor(this.chordNode.getKey().getValue()); @@ -249,7 +242,7 @@ private Message processBootStrap(Message message) { } bootstrapResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) + .id(message.getId()) .sendType(SendType.RESPONSE) .messageType(Protocol.BOOTSTRAP_RESPONSE) .address(Address.builder() @@ -272,7 +265,7 @@ private Message processGetPredecessor(Message message) { Message.MessageBuilder getPredecessorResponseMessage; getPredecessorResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) + .id(message.getId()) .sendType(SendType.RESPONSE) .messageType(Protocol.GET_PREDECESSOR_RESPONSE) .address(Address.builder() @@ -316,7 +309,7 @@ private Message processPing(Message message) { Message pingMessage; pingMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) + .id(message.getId()) .sendType(SendType.RESPONSE) .messageType(Protocol.PING_RESPONSE) .address(Address.builder() @@ -339,7 +332,7 @@ private Message processLookUp(Message message) { Message.MessageBuilder lookupResponseMessage; lookupResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) + .id(message.getId()) .sendType(SendType.RESPONSE) .messageType(Protocol.LOOKUP_RESPONSE) .address(Address.builder() diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/StableRing.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/StableRing.java index a1eecd7..b01e11f 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/StableRing.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/StableRing.java @@ -19,7 +19,7 @@ package co.edu.uniquindio.chord.node; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.util.Observable; @@ -34,13 +34,9 @@ * @see ChordNode * @since 1.0 */ -public class StableRing extends Observable implements Runnable { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(StableRing.class); +@Slf4j +public class StableRing extends Observable implements Runnable { /** * The reference of the chord node @@ -62,7 +58,7 @@ public void run() { clearChanged(); } catch (Exception e) { - logger.error(" node " + node.getKey() + "could not be stabilized", e); + log.error(" node " + node.getKey() + "could not be stabilized", e); } } } \ No newline at end of file diff --git a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/SuccessorList.java b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/SuccessorList.java index e71bd3d..4364b0b 100644 --- a/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/SuccessorList.java +++ b/p2p/chord/src/main/java/co/edu/uniquindio/chord/node/SuccessorList.java @@ -21,13 +21,13 @@ import co.edu.uniquindio.chord.ChordKey; import co.edu.uniquindio.chord.protocol.Protocol; +import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.overlay.Key; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; /** * The SuccessorList class represents a list of m @@ -41,14 +41,9 @@ * @see StableRing * @since 1.0 */ +@Slf4j public class SuccessorList { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(SuccessorList.class); - /** * Communication manager */ @@ -74,9 +69,9 @@ public class SuccessorList { */ private ChordNode chordNode; private KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator sequenceGenerator; - SuccessorList(ChordNode chordNode, CommunicationManager communicationManager, int successorListAmount, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + SuccessorList(ChordNode chordNode, CommunicationManager communicationManager, int successorListAmount, KeyFactory keyFactory, IdGenerator sequenceGenerator) { this.size = successorListAmount; this.sequenceGenerator = sequenceGenerator; this.keyList = new ChordKey[size]; @@ -85,7 +80,7 @@ public class SuccessorList { this.keyFactory = keyFactory; } - SuccessorList(CommunicationManager communicationManager, ChordKey[] keyList, int size, ChordNode chordNode, SequenceGenerator sequenceGenerator, KeyFactory keyFactory) { + SuccessorList(CommunicationManager communicationManager, ChordKey[] keyList, int size, ChordNode chordNode, IdGenerator sequenceGenerator, KeyFactory keyFactory) { this.communicationManager = communicationManager; this.keyList = keyList; this.size = size; @@ -105,7 +100,7 @@ public void fixSuccessors() { Message getSuccessorListMesssage; getSuccessorListMesssage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(sequenceGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.GET_SUCCESSOR_LIST) .address(Address.builder() @@ -114,7 +109,7 @@ public void fixSuccessors() { .build()) .build(); - successorList = communicationManager.sendMessageUnicast( + successorList = communicationManager.send( getSuccessorListMesssage, String.class); if (successorList == null) @@ -126,7 +121,7 @@ public void fixSuccessors() { keyList[i] = (ChordKey) keyFactory.newKey(successors[i - 1]); } - logger.debug("Node: " + chordNode.getKey().getValue() + log.debug("Node: " + chordNode.getKey().getValue() + " Successors: " + toString()); } @@ -147,7 +142,7 @@ public void initializeSuccessors() { public void setSuccessor(ChordKey successor) { keyList[0] = successor; - logger.debug("Node: " + chordNode.getKey().getValue() + log.debug("Node: " + chordNode.getKey().getValue() + " New successor: " + successor); } @@ -164,7 +159,7 @@ public ChordKey getNextSuccessorAvailable() { for (int i = 0; i < keyList.length; i++) { pingMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + .id(sequenceGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.PING) .address(Address.builder() @@ -173,7 +168,7 @@ public ChordKey getNextSuccessorAvailable() { .build()) .build(); - success = communicationManager.sendMessageUnicast(pingMessage, + success = communicationManager.send(pingMessage, Boolean.class); if (success != null) { diff --git a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/BootStrapTest.java b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/BootStrapTest.java index 516787a..0210a3b 100644 --- a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/BootStrapTest.java +++ b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/BootStrapTest.java @@ -21,9 +21,8 @@ import co.edu.uniquindio.chord.ChordKey; import co.edu.uniquindio.chord.protocol.Protocol; -import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,7 +55,7 @@ public class BootStrapTest { @Captor private ArgumentCaptor messageCaptor; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @InjectMocks private BootStrap bootStrap; @@ -71,7 +70,7 @@ public void boot_notOtherNodeFound_createRing() { bootStrap.boot(nodeChord, communicationManager, sequenceGenerator); verify(nodeChord).createRing(); - verify(communicationManager).sendMessageMultiCast(messageCaptor.capture(), + verify(communicationManager).sendMultiCast(messageCaptor.capture(), eq(ChordKey.class)); assertThat(fingersTable.getFingersTable()[0]).isEqualTo(successor); @@ -87,12 +86,12 @@ public void boot_otherNodeFound_join() { when(nodeChord.getSuccessor()).thenReturn(successor); when(nodeChord.getKey()).thenReturn(key); when(key.getValue()).thenReturn("keyHash"); - when(communicationManager.sendMessageMultiCast(any(), eq(ChordKey.class))).thenReturn(foundNode); + when(communicationManager.sendMultiCast(any(), eq(ChordKey.class))).thenReturn(foundNode); bootStrap.boot(nodeChord, communicationManager, sequenceGenerator); verify(nodeChord).join(foundNode); - verify(communicationManager).sendMessageMultiCast(messageCaptor.capture(), + verify(communicationManager).sendMultiCast(messageCaptor.capture(), eq(ChordKey.class)); assertThat(fingersTable.getFingersTable()[0]).isEqualTo(successor); diff --git a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeFactoryTest.java b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeFactoryTest.java index 04e8101..6688969 100644 --- a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeFactoryTest.java +++ b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeFactoryTest.java @@ -21,10 +21,9 @@ import co.edu.uniquindio.chord.Chord; import co.edu.uniquindio.chord.ChordKey; -import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.overlay.OverlayException; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Test; @@ -61,7 +60,7 @@ public class ChordNodeFactoryTest { @Mock private KeyFactory keyFactory; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @Mock private ScheduledFuture stableRingTask; @Mock diff --git a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeTest.java b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeTest.java index 32ebd46..dd61c1c 100644 --- a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeTest.java +++ b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/ChordNodeTest.java @@ -24,8 +24,8 @@ import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.OverlayException; import co.edu.uniquindio.utils.communication.Observable; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Test; @@ -62,7 +62,7 @@ public class ChordNodeTest { @Captor private ArgumentCaptor messageCaptor; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @Mock private ScheduledFuture stableRing; @Mock @@ -94,13 +94,13 @@ public void lookUp_isNotBetweenRightIncluded_successor() { when(id.isBetweenRightIncluded(key, successor)).thenReturn(false); when(fingersTable.findClosestPresedingNode(id)).thenReturn(next); - when(communicationManager.sendMessageUnicast(any(), + when(communicationManager.send(any(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name()))).thenReturn(lookUpKey); when(id.getHashing()).thenReturn(new BigInteger("123565")); Key result = chordNode.lookUp(id); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name())); assertThat(messageCaptor.getValue().getMessageType()).isEqualTo(Protocol.LOOKUP); @@ -121,13 +121,13 @@ public void lookUp_successorIsNull_successor() { ChordKey lookUpKey = mock(ChordKey.class); when(fingersTable.findClosestPresedingNode(id)).thenReturn(next); - when(communicationManager.sendMessageUnicast(any(), + when(communicationManager.send(any(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name()))).thenReturn(lookUpKey); when(id.getHashing()).thenReturn(new BigInteger("123565")); Key result = chordNode.lookUp(id); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name())); assertThat(messageCaptor.getValue().getMessageType()).isEqualTo(Protocol.LOOKUP); @@ -156,12 +156,12 @@ public void join_sendMessage_initializeSuccessors() { ChordKey successorResult = mock(ChordKey.class); - when(communicationManager.sendMessageUnicast(any(), + when(communicationManager.send(any(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name()))).thenReturn(successorResult); chordNode.join(node); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class), eq(Protocol.LookupResponseParams.NODE_FIND.name())); assertThat(chordNode.getPredecessor()).isNull(); @@ -260,14 +260,14 @@ public void checkPredecessor_predecessorIsNotNull_doNothing() { @Test public void checkPredecessor_pingSuccess_predecessorNotNull() { - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(true); when(predecessor.getValue()).thenReturn("hashPredecessor"); when(key.getValue()).thenReturn("hashKey"); chordNode.checkPredecessor(); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); @@ -279,14 +279,14 @@ public void checkPredecessor_pingSuccess_predecessorNotNull() { @Test public void checkPredecessor_pingNoSuccess_predecessorNull() { - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(null); when(predecessor.getValue()).thenReturn("hashPredecessor"); when(key.getValue()).thenReturn("hashKey"); chordNode.checkPredecessor(); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); assertThat(chordNode.getPredecessor()).isNull(); @@ -299,11 +299,11 @@ public void checkPredecessor_pingNoSuccess_predecessorNull() { public void stabilize_pingSuccessorNotNullNotPredecessor_notifyChange() { ChordKey getPredecessor = null; - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(true); when(successor.getValue()).thenReturn("hashSuccessor"); when(key.getValue()).thenReturn("hashKey"); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(ChordKey.class))).thenReturn(getPredecessor); chordNode.stabilize(); @@ -313,11 +313,11 @@ public void stabilize_pingSuccessorNotNullNotPredecessor_notifyChange() { verifyZeroInteractions(successorList); verifyZeroInteractions(fingersTable); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture()); + verify(communicationManager).send(messageCaptor.capture()); assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.PING); assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("hashSuccessor"); @@ -334,11 +334,11 @@ public void stabilize_pingSuccessorNotNullNotPredecessor_notifyChange() { public void stabilize_pingSuccessorNotNullGetPredecessorNotBetweenNotKey_notifyChange() { ChordKey getPredecessor = mock(ChordKey.class); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(true); when(successor.getValue()).thenReturn("hashSuccessor"); when(key.getValue()).thenReturn("hashKey"); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(ChordKey.class))).thenReturn(getPredecessor); chordNode.stabilize(); @@ -348,11 +348,11 @@ public void stabilize_pingSuccessorNotNullGetPredecessorNotBetweenNotKey_notifyC verifyZeroInteractions(successorList); verifyZeroInteractions(fingersTable); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture()); + verify(communicationManager).send(messageCaptor.capture()); assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.PING); assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("hashSuccessor"); @@ -370,12 +370,12 @@ public void stabilize_pingSuccessorNotNullGetPredecessorIsBetweenNotKey_notifyCh ChordKey getPredecessor = mock(ChordKey.class); when(getPredecessor.isBetween(key, successor)).thenReturn(true); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(true); when(successor.getValue()).thenReturn("hashSuccessor"); when(getPredecessor.getValue()).thenReturn("hashGetPredecessor"); when(key.getValue()).thenReturn("hashKey"); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(ChordKey.class))).thenReturn(getPredecessor); chordNode.stabilize(); @@ -384,11 +384,11 @@ public void stabilize_pingSuccessorNotNullGetPredecessorIsBetweenNotKey_notifyCh verify(successorList).setSuccessor(getPredecessor); verify(fingersTable).setSuccessor(getPredecessor); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture()); + verify(communicationManager).send(messageCaptor.capture()); assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.PING); assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("hashSuccessor"); @@ -407,11 +407,11 @@ public void stabilize_pingSuccessorNotNullGetPredecessorNotBetweenKeyEqual_notif chordNode = new ChordNode(communicationManager, successor, predecessor, fingersTable, successorList, successor, sequenceGenerator, stableRing); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(Boolean.class))).thenReturn(true); when(successor.getValue()).thenReturn("hashSuccessor"); when(getPredecessor.getValue()).thenReturn("hashGetPredecessor"); - when(communicationManager.sendMessageUnicast(anyObject(), + when(communicationManager.send(anyObject(), eq(ChordKey.class))).thenReturn(getPredecessor); chordNode.stabilize(); @@ -420,11 +420,11 @@ public void stabilize_pingSuccessorNotNullGetPredecessorNotBetweenKeyEqual_notif verify(successorList).setSuccessor(getPredecessor); verify(fingersTable).setSuccessor(getPredecessor); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), + verify(communicationManager).send(messageCaptor.capture(), eq(ChordKey.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture()); + verify(communicationManager).send(messageCaptor.capture()); assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.PING); assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("hashSuccessor"); @@ -442,7 +442,7 @@ public void stabilize_pingSuccessorNull_setNextSuccessor() { ChordKey successorNew = mock(ChordKey.class); when(successorList.getNextSuccessorAvailable()).thenReturn(successorNew); - when(communicationManager.sendMessageUnicast(any(), + when(communicationManager.send(any(), eq(Boolean.class))).thenReturn(null); chordNode.stabilize(); @@ -546,7 +546,7 @@ public void leave_successorNotEqualsKey_notifyAndUnlinkNode() throws OverlayExce assertThat(keysResult).isEqualTo(keys); - verify(communicationManager, times(2)).sendMessageUnicast(messageCaptor.capture()); + verify(communicationManager, times(2)).send(messageCaptor.capture()); verify(communicationManager).removeMessageProcessor(chordNode.getKey().getValue()); assertThat(messageCaptor.getAllValues().get(0).getSendType()).isEqualTo(Message.SendType.REQUEST); diff --git a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/NodeEnvironmentTest.java b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/NodeEnvironmentTest.java index 849a0e2..4db37e8 100644 --- a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/NodeEnvironmentTest.java +++ b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/NodeEnvironmentTest.java @@ -24,7 +24,7 @@ import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.utils.communication.message.Address; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Test; @@ -65,7 +65,7 @@ public class NodeEnvironmentTest { @Mock private KeyFactory keyFactory; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @Before public void before() { diff --git a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/SuccessorListTest.java b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/SuccessorListTest.java index eda82a3..d5a8378 100644 --- a/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/SuccessorListTest.java +++ b/p2p/chord/src/test/java/co/edu/uniquindio/chord/node/SuccessorListTest.java @@ -25,7 +25,7 @@ import co.edu.uniquindio.overlay.KeyFactory; import co.edu.uniquindio.utils.communication.message.Message; import co.edu.uniquindio.overlay.Key; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Test; @@ -63,7 +63,7 @@ public class SuccessorListTest { @Mock private KeyFactory keyFactory; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @Captor private ArgumentCaptor messageCaptor; private SuccessorList successorList; @@ -78,11 +78,11 @@ public void fixSuccessors_successorListFromSuccessorNull_doNothing() { when(key1.getValue()).thenReturn("successor"); when(key.getValue()).thenReturn("key"); when(chordNode.getKey()).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(String.class))).thenReturn(null); + when(communicationManager.send(any(), eq(String.class))).thenReturn(null); successorList.fixSuccessors(); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), eq(String.class)); + verify(communicationManager).send(messageCaptor.capture(), eq(String.class)); assertThat(new Key[]{key1, key2, key3}).isEqualTo(successorList.getKeyList()); assertThat(messageCaptor.getValue().getSendType()).isEqualTo(Message.SendType.REQUEST); @@ -103,11 +103,11 @@ public void fixSuccessors_successorListFromSuccessorAndGreaterThan3_doNothing() when(keyFactory.newKey("123")).thenReturn(newKey1); when(keyFactory.newKey("456")).thenReturn(newKey2); when(chordNode.getKey()).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(String.class))).thenReturn("123->456->798->753"); + when(communicationManager.send(any(), eq(String.class))).thenReturn("123->456->798->753"); successorList.fixSuccessors(); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), eq(String.class)); + verify(communicationManager).send(messageCaptor.capture(), eq(String.class)); assertThat(key1).isEqualTo(successorList.getKeyList()[0]); assertThat("123").isEqualTo(successorList.getKeyList()[1].getValue()); @@ -130,11 +130,11 @@ public void fixSuccessors_successorListFromSuccessorAndLowerThan3_doNothing() { when(keyFactory.newKey("123")).thenReturn(newKey1); when(keyFactory.newKey("456")).thenReturn(newKey2); when(chordNode.getKey()).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(String.class))).thenReturn("123->456"); + when(communicationManager.send(any(), eq(String.class))).thenReturn("123->456"); successorList.fixSuccessors(); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), eq(String.class)); + verify(communicationManager).send(messageCaptor.capture(), eq(String.class)); assertThat(key1).isEqualTo(successorList.getKeyList()[0]); assertThat("123").isEqualTo(successorList.getKeyList()[1].getValue()); @@ -174,11 +174,11 @@ public void getNextSuccessorAvailable_notFound_returnNull() { when(key3.getValue()).thenReturn("key3"); when(key.getValue()).thenReturn("key"); when(chordNode.getKey()).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenReturn(null); + when(communicationManager.send(any(), eq(Boolean.class))).thenReturn(null); Key successor = successorList.getNextSuccessorAvailable(); - verify(communicationManager, times(3)).sendMessageUnicast(messageCaptor.capture(), eq(Boolean.class)); + verify(communicationManager, times(3)).send(messageCaptor.capture(), eq(Boolean.class)); assertThat(successor).isNull(); assertThat(messageCaptor.getAllValues().get(0).getSendType()).isEqualTo(Message.SendType.REQUEST); @@ -204,7 +204,7 @@ public void getNextSuccessorAvailable_found_returnSuccessor() { when(key3.getValue()).thenReturn("key3"); when(key.getValue()).thenReturn("key"); when(chordNode.getKey()).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenAnswer(new Answer() { + when(communicationManager.send(any(), eq(Boolean.class))).thenAnswer(new Answer() { private int count = 0; public Object answer(InvocationOnMock invocation) { @@ -217,7 +217,7 @@ public Object answer(InvocationOnMock invocation) { Key successor = successorList.getNextSuccessorAvailable(); - verify(communicationManager, times(2)).sendMessageUnicast(messageCaptor.capture(), eq(Boolean.class)); + verify(communicationManager, times(2)).send(messageCaptor.capture(), eq(Boolean.class)); assertThat(successor).isEqualTo(key2); assertThat(messageCaptor.getAllValues().get(0).getSendType()).isEqualTo(Message.SendType.REQUEST); diff --git a/storage/dhash/build.gradle b/storage/dhash/build.gradle index d457bbb..17f75a7 100644 --- a/storage/dhash/build.gradle +++ b/storage/dhash/build.gradle @@ -9,16 +9,17 @@ repositories { } group = 'com.github.estigma88' -version = '2.0.0' +version = '3.0.0' dependencies { - compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-communication-api', version: '3.0.0' compile group: 'com.github.estigma88', name: 'jdhtuq-lookup-service', version: '2.0.0' - compile group: 'com.github.estigma88', name: 'jdhtuq-storage-service', version: '2.0.0' + compile group: 'com.github.estigma88', name: 'jdhtuq-storage-service', version: '3.0.0' - // https://mvnrepository.com/artifact/commons-io/commons-io + compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4' + compileOnly 'org.projectlombok:lombok:1.16.20' compile group: 'commons-io', name: 'commons-io', version: '2.6' - + compile group: 'org.slf4j', name:'slf4j-api', version: '1.7.2' testCompile group: 'junit', name: 'junit', version: '4.4' testCompile 'org.mockito:mockito-core:2.8.9' diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashEnvironment.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashEnvironment.java deleted file mode 100644 index 60e2d12..0000000 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashEnvironment.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * DHash project implement a storage management - * Copyright (C) 2010 - 2018 Daniel Pelaez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package co.edu.uniquindio.dhash.node; - -import co.edu.uniquindio.dhash.protocol.Protocol; -import co.edu.uniquindio.dhash.protocol.Protocol.*; -import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; -import co.edu.uniquindio.dhash.resource.manager.ResourceManager; -import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; -import co.edu.uniquindio.overlay.OverlayException; -import co.edu.uniquindio.storage.resource.Resource; -import co.edu.uniquindio.utils.communication.message.Address; -import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.Message.SendType; -import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; -import org.apache.log4j.Logger; - -/** - * The DHashEnviroment class is the node responsible for handling - * with the messages. This class is notified when a message arrives and decides - * what the dhash node must do. - * - * @author Daniel Pelaez - * @author Hector Hurtado - * @author Daniel Lopez - * @version 1.0, 17/06/2010 - * @see DHashNode - * @since 1.0 - */ -public class DHashEnvironment implements MessageProcessor { - private static final Logger logger = Logger - .getLogger(DHashEnvironment.class); - - private final CommunicationManager communicationManager; - private final DHashNode dHashNode; - private final SerializationHandler serializationHandler; - private final ChecksumCalculator checksumeCalculator; - private final ResourceManager resourceManager; - - DHashEnvironment(CommunicationManager communicationManager, DHashNode dHashNode, SerializationHandler serializationHandler, ChecksumCalculator checksumeCalculator, ResourceManager resourceManager) { - this.communicationManager = communicationManager; - this.dHashNode = dHashNode; - this.serializationHandler = serializationHandler; - this.checksumeCalculator = checksumeCalculator; - this.resourceManager = resourceManager; - } - - /** - * This method is called when a new message has arrived, and uses a - * TransferManagerto receive the messages - * The interface that will be used for receiving the messages. - */ - @Override - public Message process(Message message) { - - logger.debug("Message to: " + dHashNode.getName() + " Message:[" - + message.toString() + "]"); - logger.debug("Node " + dHashNode.getName() + ", arrived message of " - + message.getMessageType()); - - Message response = null; - - if (message.getMessageType().equals(Protocol.PUT)) { - response = processPut(message); - } - - if (message.getMessageType().equals(Protocol.RESOURCE_COMPARE)) { - response = processResourceCompare(message); - } - - if (message.getMessageType().equals(Protocol.GET)) { - response = processGet(message); - } - if (message.getMessageType().equals(Protocol.RESOURCE_TRANSFER)) { - response = processResourceTransfer(message); - } - - return response; - } - - /** - * Process message of type is RESOURCE_TRANSFER - * - * @param message Message RESOURCE_TRANSFER - */ - private Message processResourceTransfer(Message message) { - - Message.MessageBuilder resourceTransferResponseMessage; - - resourceTransferResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) - .sendType(SendType.RESPONSE) - .messageType(Protocol.RESOURCE_TRANSFER_RESPONSE) - .address(Address.builder() - .destination(message.getAddress().getSource()) - .source(dHashNode.getName()) - .build()); - - if (resourceManager.hasResource( - message.getParam(ResourceTransferParams.RESOURCE_KEY.name()))) { - - Resource resource = resourceManager.find( - message - .getParam(ResourceTransferParams.RESOURCE_KEY - .name())); - - resourceTransferResponseMessage.data( - ResourceTransferResponseData.RESOURCE.name(), serializationHandler.encode(resource)); - - } else { - - resourceTransferResponseMessage.data( - ResourceTransferResponseData.RESOURCE.name(), new byte[0]); - - } - - return resourceTransferResponseMessage.build(); - } - - /** - * Process message of type is RESOURCE_COMPARE - * - * @param message Message RESOURCE_COMPARE - */ - private Message processResourceCompare(Message message) { - - boolean isChecksumEquals = false; - Message resourceCompareResponseMessage; - - if (resourceManager.hasResource( - message.getParam(ResourceCompareParams.RESOURCE_KEY.name()))) { - - String checkSum = checksumeCalculator.calculate(resourceManager - .find( - message.getParam(ResourceCompareParams.RESOURCE_KEY - .name()))); - - isChecksumEquals = checkSum.equals(message - .getParam(ResourceCompareParams.CHECK_SUM.name())); - } - - resourceCompareResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) - .sendType(SendType.RESPONSE) - .messageType(Protocol.RESOURCE_COMPARE_RESPONSE) - .address(Address.builder() - .destination(message.getAddress().getSource()) - .source(dHashNode.getName()) - .build()) - .param(ResourceCompareResponseParams.EXIST_RESOURCE.name(), String.valueOf(isChecksumEquals)) - .build(); - - return resourceCompareResponseMessage; - } - - /** - * Process message of type is GET - * - * @param message Message GET - */ - private Message processGet(Message message) { - - Message.MessageBuilder getResponseMessage = Message.builder() - .sequenceNumber(message.getSequenceNumber()) - .sendType(SendType.RESPONSE) - .messageType(Protocol.RESOURCE_COMPARE_RESPONSE) - .address(Address.builder() - .destination(message.getAddress().getSource()) - .source(dHashNode.getName()) - .build()); - - if (resourceManager.hasResource( - message.getParam(GetParams.RESOURCE_KEY.name()))) { - - getResponseMessage.param(GetResponseParams.HAS_RESOURCE.name(), - String.valueOf(true)); - - } else { - - getResponseMessage.param(GetResponseParams.HAS_RESOURCE.name(), - String.valueOf(false)); - - } - - logger.debug("Node " + dHashNode.getName() + ", confirmation for "); - logger.debug("Response message: [" + getResponseMessage.toString() - + "]"); - - return getResponseMessage.build(); - } - - /** - * Process message of type is PUT - * - * @param message Message PUT - */ - private Message processPut(Message message) { - try { - Resource resource = serializationHandler.decode( - message.getData(PutDatas.RESOURCE.name())); - - resourceManager.save(resource); - - Boolean replicate = Boolean.valueOf(message - .getParam(PutParams.REPLICATE.name())); - - if (replicate) { - dHashNode.replicateData(resource); - } - }catch (OverlayException e) { - logger.error("Error replicating data", e); - } - - return null; - } -} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNode.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNode.java index 1b1de0e..a143dec 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNode.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNode.java @@ -19,9 +19,9 @@ package co.edu.uniquindio.dhash.node; import co.edu.uniquindio.dhash.protocol.Protocol; -import co.edu.uniquindio.dhash.protocol.Protocol.*; -import co.edu.uniquindio.dhash.resource.ResourceNotFoundException; -import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; +import co.edu.uniquindio.dhash.protocol.Protocol.ContainParams; +import co.edu.uniquindio.dhash.protocol.Protocol.GetParams; +import co.edu.uniquindio.dhash.protocol.Protocol.PutParams; import co.edu.uniquindio.dhash.resource.manager.ResourceManager; import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; import co.edu.uniquindio.overlay.Key; @@ -30,14 +30,20 @@ import co.edu.uniquindio.overlay.OverlayNode; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; +import co.edu.uniquindio.storage.resource.ProgressStatus; import co.edu.uniquindio.storage.resource.Resource; import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.MessageStream; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; +import java.io.IOException; import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutorService; /** * The {@code DHashNode} class implements the services of {@code put} and @@ -49,207 +55,198 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ +@Slf4j public class DHashNode implements StorageNode { - private static final Logger logger = Logger - .getLogger(DHashNode.class); - private final CommunicationManager communicationManager; private final OverlayNode overlayNode; private final int replicationFactor; private final String name; private final SerializationHandler serializationHandler; - private final ChecksumCalculator checksumCalculator; private final ResourceManager resourceManager; private final KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator idGenerator; + private final ExecutorService executorService; - public DHashNode(OverlayNode overlayNode, int replicationFactor, String name, CommunicationManager communicationManager, SerializationHandler serializationHandler, ChecksumCalculator checksumCalculator, ResourceManager resourceManager, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + public DHashNode(OverlayNode overlayNode, int replicationFactor, String name, CommunicationManager communicationManager, SerializationHandler serializationHandler, ResourceManager resourceManager, KeyFactory keyFactory, IdGenerator idGenerator, ExecutorService executorService) { this.overlayNode = overlayNode; this.replicationFactor = replicationFactor; this.name = name; this.communicationManager = communicationManager; this.serializationHandler = serializationHandler; - this.checksumCalculator = checksumCalculator; this.resourceManager = resourceManager; this.keyFactory = keyFactory; - this.sequenceGenerator = sequenceGenerator; + this.idGenerator = idGenerator; + this.executorService = executorService; } - /* - * (non-Javadoc) - * - * @see co.edu.uniquindio.storage.StorageNode#get(java.lang.String) - */ - public Resource get(String id) throws StorageException { + @Override + public CompletableFuture get(String id, ProgressStatus progressStatus) { + return CompletableFuture.supplyAsync(() -> { + try { + return getSync(id, progressStatus); + } catch (StorageException e) { + throw new CompletionException("Get failed", e); + } + }, executorService); + } - Key key = keyFactory.newKey(id); - Key lookupKey = overlayNode.lookUp(key); - Message getMessage; - Message resourceTransferMessage; + @Override + public CompletableFuture put(Resource resource, ProgressStatus progressStatus) { + return CompletableFuture.supplyAsync(() -> { + try { + return putSync(resource, progressStatus); + } catch (StorageException e) { + throw new CompletionException("Put failed", e); + } + }, executorService); + } + + Resource getSync(String id, ProgressStatus progressStatus) throws StorageException { + + progressStatus.status("overlay-node-lookup", 0L, 1L); + + Key lookupKey = overlayNode.lookUp(keyFactory.newKey(id)); if (lookupKey == null) { - logger.error("Imposible to do get to resource: " + id + log.error("Impossible to do get to resource: " + id + " in this moment"); throw new StorageException( - "Imposible to do get to resource, lookup fails"); + "Impossible to do get to resource, lookup fails"); } - getMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + progressStatus.status("overlay-node-lookup", 1L, 1L); + progressStatus.status("dhash-file-validation", 0L, 1L); + + Message containMessage = Message.builder() + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) - .messageType(Protocol.GET) + .messageType(Protocol.CONTAIN) .address(Address.builder() .destination(lookupKey.getValue()) .source(name) .build()) - .param(GetParams.RESOURCE_KEY.name(), id) + .param(ContainParams.RESOURCE_KEY.name(), id) .build(); - Boolean hasResource = communicationManager.sendMessageUnicast(getMessage, + Boolean hasResource = communicationManager.send(containMessage, Boolean.class); - if (hasResource) { + progressStatus.status("dhash-file-validation", 1L, 1L); - resourceTransferMessage = Message.builder() + if (hasResource) { + Message getMessage = Message.builder() .sendType(Message.SendType.REQUEST) - .sequenceNumber(sequenceGenerator.getSequenceNumber()) - .messageType(Protocol.RESOURCE_TRANSFER) + .id(idGenerator.newId()) + .messageType(Protocol.GET) .address(Address.builder() .destination(lookupKey.getValue()) .source(name) .build()) - .param(ResourceTransferParams.RESOURCE_KEY.name(), id) + .param(GetParams.RESOURCE_KEY.name(), id) .build(); - Message resource = communicationManager - .sendMessageUnicast(resourceTransferMessage, Message.class); + MessageStream resource = communicationManager + .receive(getMessage, progressStatus::status); - return serializationHandler.decode(resource - .getData(ResourceTransferResponseData.RESOURCE.name())); + return serializationHandler.decode(resource.getMessage().getParam(Protocol.GetResponseData.RESOURCE.name()), resource.getInputStream()); } else { - ResourceNotFoundException resourceNotFoundException = new ResourceNotFoundException( - "Resource '" + id + "' not found"); - - logger.warn("The resource '" + id + "' was not found"); - - throw resourceNotFoundException; + return null; } } - /* - * (non-Javadoc) - * - * @see - * co.edu.uniquindio.storage.StorageNode#put(co.edu.uniquindio.storage.resource - * .Resource) - */ - public boolean put(Resource resource) throws StorageException { + boolean putSync(Resource resource, ProgressStatus progressStatus) throws StorageException { + + progressStatus.status("overlay-node-lookup", 0L, 1L); Key key = keyFactory.newKey(resource.getId()); - logger.debug("Resource to put: [" + resource.getId() + "] Hashing: [" + log.debug("Resource to put: [" + resource.getId() + "] Hashing: [" + key.getHashing() + "]"); Key lookupKey = overlayNode.lookUp(key); - if (lookupKey == null) { + progressStatus.status("overlay-node-lookup", 1L, 1L); - logger.error("Imposible to do put to resource: " + if (lookupKey == null) { + log.error("Impossible to do put the resource: " + resource.getId() + " in this moment"); - throw new StorageException("Imposible to do put to resource: " + throw new StorageException("Impossible to do put the resource: " + resource.getId() + " in this moment"); } - logger.debug("Lookup key for " + key.getHashing() + ": [" + log.debug("Lookup key for " + key.getHashing() + ": [" + lookupKey.getValue() + "]"); - return put(resource, lookupKey, true); - } - - /** - * Replicates the specified file in its successors. - * - * @param resource The specified {@link Resource} to replicate. - * @throws OverlayException - */ - public void replicateData(Resource resource) - throws OverlayException { - Key[] succesorList = overlayNode.getNeighborsList(); - - for (int i = 0; i < Math.min(replicationFactor, succesorList.length); i++) { - logger - .debug("Replicate File: [" + resource.getId() - + "] Hashing: [" - + succesorList[i].getHashing() + "]"); - logger.debug("Replicate to " + succesorList[i].getHashing()); - - put(resource, succesorList[i], false); - } + return put(resource, lookupKey, true, progressStatus); } /** * Puts the specified resource into the network. * - * @param resource The resource to put. - * @param lookupKey The key where the file will be put. - * @param replicate Determines if the file will be replicated. - * @return False if the resource already exists, true if it does not exist + * @param resource The resource to put. + * @param lookupKey The key where the file will be put. + * @param replicate Determines if the file will be replicated. + * @param progressStatus + * @return False if the resource already exists, true if it does not exist */ - boolean put(Resource resource, Key lookupKey, boolean replicate) { - - Message resourceCompareMessage; - Message putMessage; - - resourceCompareMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) - .sendType(Message.SendType.REQUEST) - .messageType(Protocol.RESOURCE_COMPARE) - .address(Address.builder() - .destination(lookupKey.getValue()) - .source(name) - .build()) - .param(ResourceCompareParams.CHECK_SUM.name(), checksumCalculator.calculate(resource)) - .param(ResourceCompareParams.RESOURCE_KEY.name(), resource.getId()) - .build(); - - Boolean existResource = communicationManager.sendMessageUnicast( - resourceCompareMessage, Boolean.class); - - if (existResource) { - return false; - } - - putMessage = Message.builder() - .sequenceNumber(sequenceGenerator.getSequenceNumber()) + boolean put(Resource resource, Key lookupKey, boolean replicate, ProgressStatus progressStatus) throws StorageException { + Message putMessage = Message.builder() + .id(idGenerator.newId()) .sendType(Message.SendType.REQUEST) .messageType(Protocol.PUT) .address(Address.builder() .destination(lookupKey.getValue()) .source(name) .build()) - .param(PutParams.RESOURCE_KEY.name(), resource.getId()) + .param(Protocol.PutDatas.RESOURCE.name(), serializationHandler.encode(resource)) .param(PutParams.REPLICATE.name(), String.valueOf(replicate)) - .data(PutDatas.RESOURCE.name(), serializationHandler.encode(resource)) .build(); - communicationManager.sendMessageUnicast(putMessage); + communicationManager.send(MessageStream.builder() + .message(putMessage) + .inputStream(resource.getInputStream()) + .size(resource.getSize()) + .build(), progressStatus::status); return true; } + /** + * Replicates the specified file in its successors. + * + * @param resourceId The specified {@link Resource} to replicate. + * @throws OverlayException + */ + public void replicateData(String resourceId, ProgressStatus progressStatus) + throws OverlayException, StorageException { + Key[] succesorList = overlayNode.getNeighborsList(); + + for (int i = 0; i < Math.min(replicationFactor, succesorList.length); i++) { + Resource resource = resourceManager.find(resourceId); + + log + .debug("Replicate File: [" + resource.getId() + + "] Hashing: [" + + succesorList[i].getHashing() + "]"); + log.debug("Replicate to " + succesorList[i].getHashing()); + + put(resource, succesorList[i], false, progressStatus); + } + } + /** * Relocates the resources of the node. * * @param key The node where the files will be relocated. */ - public void relocateAllResources(Key key) { + public void relocateAllResources(Key key, ProgressStatus progressStatus) throws StorageException { Set resourcesNames = resourceManager.getAllKeys(); - logger.info("Relocating Files..."); - logger.debug("Number of files: [" + resourcesNames.size() + "]"); + log.info("Relocating Files..."); + log.debug("Number of files: [" + resourcesNames.size() + "]"); int filesRelocated = 0; for (String name : resourcesNames) { @@ -258,47 +255,44 @@ public void relocateAllResources(Key key) { Key fileKey = getFileKey(name); if (!fileKey.isBetween(key, overlayNode.getKey())) { - boolean relocate = put(resource, key, false); + boolean relocate = put(resource, key, false, progressStatus); filesRelocated++; } } - logger.info("Files relocated: [" + filesRelocated + "]"); + log.info("Files relocated: [" + filesRelocated + "]"); } Key getFileKey(String name) { return keyFactory.newKey(name); } - /* - * (non-Javadoc) - * - * @see co.edu.uniquindio.storage.StorageNode#leave() - */ - public void leave() throws StorageException { + public void leave(ProgressStatus progressStatus) throws StorageException { try { Key[] keys = overlayNode.leave(); Set resourcesNames = resourceManager.getAllKeys(); - logger.info("Leaving..."); - logger.debug("Number of files to transfer: [" + log.info("Leaving..."); + log.debug("Number of files to transfer: [" + resourcesNames.size() + "]"); if (!keys[0].equals(overlayNode.getKey())) { for (String name : resourcesNames) { Resource resource = resourceManager.find(name); - put(resource, keys[0], false); + put(resource, keys[0], false, progressStatus); + + resource.close(); } } resourceManager.deleteAll(); communicationManager.removeObserver(overlayNode.getKey().getValue()); - } catch (OverlayException e) { - logger.error("Error while leaving dhash node: '" + } catch (OverlayException | IOException e) { + log.error("Error while leaving dhash node: '" + overlayNode.getKey().toString() + "'"); } } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNodeFactory.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNodeFactory.java index b0b1353..ce0de12 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNodeFactory.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/DHashNodeFactory.java @@ -18,6 +18,8 @@ package co.edu.uniquindio.dhash.node; +import co.edu.uniquindio.dhash.node.processor.MessageProcessorGateway; +import co.edu.uniquindio.dhash.node.processor.stream.MessageStreamProcessorGateway; import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; import co.edu.uniquindio.dhash.resource.manager.ResourceManager; import co.edu.uniquindio.dhash.resource.manager.ResourceManagerFactory; @@ -29,9 +31,12 @@ import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; import co.edu.uniquindio.storage.StorageNodeFactory; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.storage.resource.ProgressStatus; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ExecutorService; /** * The DHashNodeFactory class creates nodes for storage management @@ -44,14 +49,8 @@ * @see DHashNode * @since 1.0 */ +@Slf4j public class DHashNodeFactory implements StorageNodeFactory { - - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(DHashNodeFactory.class); - private final int replicationFactor; private final CommunicationManager communicationManager; private final OverlayNodeFactory overlayNodeFactory; @@ -59,9 +58,10 @@ public class DHashNodeFactory implements StorageNodeFactory { private final ChecksumCalculator checksumeCalculator; private final ResourceManagerFactory resourceManagerFactory; private final KeyFactory keyFactory; - private final SequenceGenerator sequenceGenerator; + private final IdGenerator sequenceGenerator; + private final ExecutorService executorService; - public DHashNodeFactory(CommunicationManager communicationManager, OverlayNodeFactory overlayNodeFactory, SerializationHandler serializationHandler, ChecksumCalculator checksumeCalculator, ResourceManagerFactory resourceManagerFactory, int replicationFactor, KeyFactory keyFactory, SequenceGenerator sequenceGenerator) { + public DHashNodeFactory(CommunicationManager communicationManager, OverlayNodeFactory overlayNodeFactory, SerializationHandler serializationHandler, ChecksumCalculator checksumeCalculator, ResourceManagerFactory resourceManagerFactory, int replicationFactor, KeyFactory keyFactory, IdGenerator sequenceGenerator, ExecutorService executorService) { this.communicationManager = communicationManager; this.overlayNodeFactory = overlayNodeFactory; this.serializationHandler = serializationHandler; @@ -70,6 +70,7 @@ public DHashNodeFactory(CommunicationManager communicationManager, OverlayNodeFa this.replicationFactor = replicationFactor; this.keyFactory = keyFactory; this.sequenceGenerator = sequenceGenerator; + this.executorService = executorService; } /* @@ -106,39 +107,44 @@ public StorageNode createNode(String name) throws DHashFactoryException { private DHashNode createNode(String name, OverlayNode overlayNode) { DHashNode dhashNode; - DHashEnvironment dHashEnviroment; + MessageProcessorGateway dHashEnviroment; ResourceManager resourceManager = resourceManagerFactory.of(name); - dhashNode = getDhashNode(name, overlayNode, resourceManager); + dhashNode = getDHashNode(name, overlayNode, resourceManager); ReAssignObserver reAssignObserver = getReAssignObserver(dhashNode); overlayNode.getObservable().addObserver(reAssignObserver); - dHashEnviroment = getDHashEnviroment(dhashNode, resourceManager); + dHashEnviroment = getMessageProcessor(dhashNode, resourceManager); communicationManager.addMessageProcessor(name, dHashEnviroment); + communicationManager.addMessageStreamProcessor(name, getMessageStreamProcessor(dhashNode, resourceManager)); - logger.debug("DHash Node " + name + " Created"); + log.debug("DHash Node " + name + " Created"); return dhashNode; } + MessageStreamProcessorGateway getMessageStreamProcessor(DHashNode dhashNode, ResourceManager resourceManager) { + return new MessageStreamProcessorGateway(resourceManager, dhashNode, serializationHandler); + } + ReAssignObserver getReAssignObserver(DHashNode dhashNode) { return new ReAssignObserver(dhashNode, keyFactory); } - DHashEnvironment getDHashEnviroment(DHashNode dhashNode, ResourceManager resourceManager) { - return new DHashEnvironment(communicationManager, dhashNode, serializationHandler, checksumeCalculator, resourceManager); + MessageProcessorGateway getMessageProcessor(DHashNode dhashNode, ResourceManager resourceManager) { + return new MessageProcessorGateway(dhashNode, resourceManager); } - DHashNode getDhashNode(String name, OverlayNode overlayNode, ResourceManager resourceManager) { - return new DHashNode(overlayNode, replicationFactor, name, communicationManager, serializationHandler, checksumeCalculator, resourceManager, keyFactory, sequenceGenerator); + DHashNode getDHashNode(String name, OverlayNode overlayNode, ResourceManager resourceManager) { + return new DHashNode(overlayNode, replicationFactor, name, communicationManager, serializationHandler, resourceManager, keyFactory, sequenceGenerator, executorService); } @Override - public void destroyNode(StorageNode storageNode) throws StorageException { - storageNode.leave(); + public void destroyNode(StorageNode storageNode, ProgressStatus progressStatus) throws StorageException { + storageNode.leave(progressStatus); } } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/ReAssignObserver.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/ReAssignObserver.java index 026c4fa..8a30d4f 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/ReAssignObserver.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/ReAssignObserver.java @@ -19,8 +19,9 @@ package co.edu.uniquindio.dhash.node; import co.edu.uniquindio.overlay.KeyFactory; +import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.utils.communication.message.Message; -import org.apache.log4j.Logger; +import lombok.extern.slf4j.Slf4j; import java.util.Observable; import java.util.Observer; @@ -36,12 +37,8 @@ * @version 1.0, 17/06/2010 * @since 1.0 */ +@Slf4j public class ReAssignObserver implements Observer { - /** - * Logger - */ - private static final Logger logger = Logger - .getLogger(ReAssignObserver.class); public static final String RE_ASSIGN = "RE_ASSIGN"; public static final String PREDECESSOR = "PREDECESSOR"; @@ -58,10 +55,15 @@ public void update(Observable observable, Object object) { if (object instanceof Message) { Message message = (Message) object; - logger.info("Update: " + message); + log.info("Update: " + message); if (message.getMessageType().getName().equals(RE_ASSIGN)) { - dHashNode.relocateAllResources(keyFactory.newKey(message.getParam(PREDECESSOR))); + try { + dHashNode.relocateAllResources(keyFactory.newKey(message.getParam(PREDECESSOR)), (name, current, size) -> { + }); + } catch (StorageException e) { + log.error("Problem relocating files", e); + } } } } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/ContainProcessor.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/ContainProcessor.java new file mode 100644 index 0000000..9634a75 --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/ContainProcessor.java @@ -0,0 +1,51 @@ +package co.edu.uniquindio.dhash.node.processor; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ContainProcessor implements MessageProcessor { + private final DHashNode dHashNode; + private final ResourceManager resourceManager; + + ContainProcessor(DHashNode dHashNode, ResourceManager resourceManager) { + this.dHashNode = dHashNode; + this.resourceManager = resourceManager; + } + + @Override + public Message process(Message message) { + Message.MessageBuilder containResponseMessage = Message.builder() + .id(message.getId()) + .sendType(Message.SendType.RESPONSE) + .messageType(Protocol.CONTAIN_RESPONSE) + .address(Address.builder() + .destination(message.getAddress().getSource()) + .source(dHashNode.getName()) + .build()); + + if (resourceManager.hasResource( + message.getParam(Protocol.ContainParams.RESOURCE_KEY.name()))) { + + containResponseMessage.param(Protocol.ContainResponseParams.HAS_RESOURCE.name(), + String.valueOf(true)); + + } else { + + containResponseMessage.param(Protocol.ContainResponseParams.HAS_RESOURCE.name(), + String.valueOf(false)); + + } + + log.debug("Node " + dHashNode.getName() + ", confirmation for "); + log.debug("Response message: [" + containResponseMessage.toString() + + "]"); + + return containResponseMessage.build(); + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGateway.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGateway.java new file mode 100644 index 0000000..5039e59 --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGateway.java @@ -0,0 +1,77 @@ +/* + * DHash project implement a storage management + * Copyright (C) 2010 - 2018 Daniel Pelaez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package co.edu.uniquindio.dhash.node.processor; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageType; +import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * The DHashEnviroment class is the node responsible for handling + * with the messages. This class is notified when a message arrives and decides + * what the dhash node must do. + * + * @author Daniel Pelaez + * @author Hector Hurtado + * @author Daniel Lopez + * @version 1.0, 17/06/2010 + * @see DHashNode + * @since 1.0 + */ +@Slf4j +public class MessageProcessorGateway implements MessageProcessor { + private final DHashNode dHashNode; + private final Map messageProcessorMap; + + public MessageProcessorGateway(DHashNode dHashNode, ResourceManager resourceManager) { + this.dHashNode = dHashNode; + + this.messageProcessorMap = new HashMap<>(); + this.messageProcessorMap.put(Protocol.CONTAIN, createContainProcessor(dHashNode, resourceManager)); + } + + @Override + public Message process(Message message) { + + log.debug("Message to: " + dHashNode.getName() + " Message:[" + + message.toString() + "]"); + log.debug("Node " + dHashNode.getName() + ", arrived message of " + + message.getMessageType()); + + return Optional.ofNullable(messageProcessorMap.get(message.getMessageType())) + .orElseThrow(() -> new IllegalStateException("Message " + message.getMessageType() + " was not found")) + .process(message); + } + + ContainProcessor createContainProcessor(DHashNode dHashNode, ResourceManager resourceManager) { + return new ContainProcessor(dHashNode, resourceManager); + } + + Map getMessageProcessorMap() { + return messageProcessorMap; + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessor.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessor.java new file mode 100644 index 0000000..090963f --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessor.java @@ -0,0 +1,51 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; +import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GetMessageStreamProcessor implements MessageStreamProcessor { + private final ResourceManager resourceManager; + private final DHashNode dHashNode; + private final SerializationHandler serializationHandler; + + GetMessageStreamProcessor(ResourceManager resourceManager, DHashNode dHashNode, SerializationHandler serializationHandler) { + this.resourceManager = resourceManager; + this.dHashNode = dHashNode; + this.serializationHandler = serializationHandler; + } + + @Override + public MessageStream process(MessageStream messageStream) { + Message message = messageStream.getMessage(); + + Resource resource = resourceManager.find( + message + .getParam(Protocol.GetParams.RESOURCE_KEY + .name())); + + Message resourceTransferResponseMessage = Message.builder() + .id(message.getId()) + .sendType(Message.SendType.RESPONSE) + .messageType(Protocol.GET_RESPONSE) + .param(Protocol.GetResponseData.RESOURCE.name(), serializationHandler.encode(resource)) + .address(Address.builder() + .destination(message.getAddress().getSource()) + .source(dHashNode.getName()) + .build()).build(); + + return MessageStream.builder() + .message(resourceTransferResponseMessage) + .inputStream(resource.getInputStream()) + .size(resource.getSize()) + .build(); + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGateway.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGateway.java new file mode 100644 index 0000000..2a887ed --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGateway.java @@ -0,0 +1,47 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.message.MessageType; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +public class MessageStreamProcessorGateway implements MessageStreamProcessor { + private final DHashNode dHashNode; + private final Map messageStreamProcessorMap; + + public MessageStreamProcessorGateway(ResourceManager resourceManager, DHashNode dHashNode, SerializationHandler serializationHandler) { + this.dHashNode = dHashNode; + + this.messageStreamProcessorMap = new HashMap<>(); + this.messageStreamProcessorMap.put(Protocol.PUT, new PutMessageStreamProcessor(resourceManager, dHashNode, serializationHandler)); + this.messageStreamProcessorMap.put(Protocol.GET, new GetMessageStreamProcessor(resourceManager, dHashNode, serializationHandler)); + } + + @Override + public MessageStream process(MessageStream messageStream) { + Message message = messageStream.getMessage(); + + log.debug("Message to: " + dHashNode.getName() + " Message:[" + + message.toString() + "]"); + log.debug("Node " + dHashNode.getName() + ", arrived message of " + + message.getMessageType()); + + return Optional.ofNullable(messageStreamProcessorMap.get(message.getMessageType())) + .orElseThrow(() -> new IllegalStateException("Message " + message.getMessageType() + " was not found")) + .process(messageStream); + } + + Map getMessageStreamProcessorMap() { + return messageStreamProcessorMap; + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessor.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessor.java new file mode 100644 index 0000000..d4e9593 --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessor.java @@ -0,0 +1,55 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; +import co.edu.uniquindio.overlay.OverlayException; +import co.edu.uniquindio.storage.StorageException; +import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import lombok.extern.slf4j.Slf4j; + +import java.io.InputStream; +import java.io.OutputStream; + +@Slf4j +public class PutMessageStreamProcessor implements MessageStreamProcessor { + private final ResourceManager resourceManager; + private final DHashNode dHashNode; + private final SerializationHandler serializationHandler; + + PutMessageStreamProcessor(ResourceManager resourceManager, DHashNode dHashNode, SerializationHandler serializationHandler) { + this.resourceManager = resourceManager; + this.dHashNode = dHashNode; + this.serializationHandler = serializationHandler; + } + + @Override + public MessageStream process(MessageStream messageStream) { + try { + Message message = messageStream.getMessage(); + + Resource resource = serializationHandler.decode( + message.getParam(Protocol.PutDatas.RESOURCE.name()), messageStream.getInputStream()); + + resourceManager.save(resource); + + Boolean replicate = Boolean.valueOf(message + .getParam(Protocol.PutParams.REPLICATE.name())); + + if (replicate) { + dHashNode.replicateData(resource.getId(), (name, current, size) -> { + }); + } + + return null; + } catch (OverlayException | StorageException e) { + log.error("Error putting data", e); + throw new IllegalStateException("Error putting data", e); + } + + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/protocol/Protocol.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/protocol/Protocol.java index 3502b21..75450b0 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/protocol/Protocol.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/protocol/Protocol.java @@ -53,91 +53,59 @@ public enum PutDatas { */ /** - * GET BEGIN + * CONTAIN BEGIN */ - public static final MessageType GET = MessageType.builder() - .name("GET") - .amountParams(GetParams.values().length) + public static final MessageType CONTAIN = MessageType.builder() + .name("CONTAIN") + .amountParams(ContainParams.values().length) .build(); - public enum GetParams { + public enum ContainParams { RESOURCE_KEY } /** - * GET END + * CONTAIN END */ /** - * GET_RESPONSE BEGIN + * CONTAIN_RESPONSE BEGIN */ - public static final MessageType GET_RESPONSE = MessageType.builder() - .name("GET_RESPONSE") - .amountParams(GetResponseParams.values().length) + public static final MessageType CONTAIN_RESPONSE = MessageType.builder() + .name("CONTAIN_RESPONSE") + .amountParams(ContainResponseParams.values().length) .build(); - public enum GetResponseParams { + public enum ContainResponseParams { HAS_RESOURCE } /** - * GET_RESPONSE END - */ - - /** - * RESOURCE_COMPARE BEGIN - */ - public static final MessageType RESOURCE_COMPARE = MessageType.builder() - .name("RESOURCE_COMPARE") - .amountParams(ResourceCompareParams.values().length) - .build(); - - public enum ResourceCompareParams { - CHECK_SUM, RESOURCE_KEY - } - - /** - * RESOURCE_COMPARE END - */ - - /** - * RESOURCE_COMPARE_RESPONSE BEGIN - */ - public static final MessageType RESOURCE_COMPARE_RESPONSE = MessageType.builder() - .name("RESOURCE_COMPARE_RESPONSE") - .amountParams(ResourceCompareResponseParams.values().length) - .build(); - - public enum ResourceCompareResponseParams { - EXIST_RESOURCE - } - - /** - * RESOURCE_COMPARE_RESPONSE END + * CONTAIN_RESPONSE END */ /** * TRANSFER_FILES BEGIN */ - public static final MessageType RESOURCE_TRANSFER = MessageType.builder() - .name("RESOURCE_TRANSFER") - .amountParams(ResourceTransferParams.values().length) + public static final MessageType GET = MessageType.builder() + .name("GET") + .amountParams(GetParams.values().length) .build(); - public enum ResourceTransferParams { + public enum GetParams { RESOURCE_KEY } /** * TRANSFER_FILES BEGIN */ - public static final MessageType RESOURCE_TRANSFER_RESPONSE = MessageType.builder() - .name("RESOURCE_TRANSFER_RESPONSE") + public static final MessageType GET_RESPONSE = MessageType.builder() + .name("GET_RESPONSE") .amountParams(0) .build(); - public enum ResourceTransferResponseData { - RESOURCE + public enum GetResponseData { + RESOURCE, RESOURCE_EXIST } /** diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BasicResource.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BasicResource.java new file mode 100644 index 0000000..65dbedd --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/BasicResource.java @@ -0,0 +1,28 @@ +package co.edu.uniquindio.dhash.resource; + +import co.edu.uniquindio.storage.resource.Resource; +import lombok.Data; +import lombok.NonNull; + +import java.io.IOException; +import java.io.InputStream; + +@Data +public abstract class BasicResource implements Resource{ + @NonNull + private final String id; + @NonNull + private final InputStream inputStream; + private final Long size; + + protected BasicResource(String id, InputStream inputStream, Long size) { + this.id = id; + this.inputStream = inputStream; + this.size = size; + } + + @Override + public void close() throws IOException { + this.inputStream.close(); + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/FileResource.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/FileResource.java new file mode 100644 index 0000000..63424cf --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/FileResource.java @@ -0,0 +1,45 @@ +/* + * DHash project implement a storage management + * Copyright (C) 2010 - 2018 Daniel Pelaez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package co.edu.uniquindio.dhash.resource; + +import lombok.*; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +@Getter +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class FileResource extends BasicResource { + private String path; + + @Builder(builderMethodName = "withPath", builderClassName = "WithPathBuilder") + public FileResource(String id, String path) throws IOException { + super(id, Files.newInputStream(Paths.get(path)), Files.size(Paths.get(path))); + this.path = path; + } + + @Builder(builderMethodName = "withInputStream", builderClassName = "WithInputStreamBuilder") + public FileResource(String id, InputStream inputStream, Long size){ + super(id, inputStream, size); + this.path = null; + } + +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/LocalFileResource.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/LocalFileResource.java new file mode 100644 index 0000000..6017f4d --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/LocalFileResource.java @@ -0,0 +1,44 @@ +package co.edu.uniquindio.dhash.resource; + +import co.edu.uniquindio.storage.resource.ProgressStatus; +import co.edu.uniquindio.storage.resource.Resource; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; + +import java.io.*; +import java.util.Objects; + +@Builder +@Data +public class LocalFileResource { + @NonNull + private final Resource resource; + @NonNull + private final String path; + @NonNull + private final Integer sizeBuffer; + + public boolean persist(ProgressStatus progressStatus) throws IOException { + Objects.requireNonNull(progressStatus); + + OutputStream destination = new FileOutputStream(path + "/" + resource.getId()); + InputStream source = resource.getInputStream(); + + int count; + long sent = 0L; + byte[] buffer = new byte[sizeBuffer]; + + progressStatus.status("resource-persist", sent, resource.getSize()); + + while ((count = source.read(buffer)) > 0) { + destination.write(buffer, 0, count); + + sent += count; + + progressStatus.status("resource-persist", sent, resource.getSize()); + } + + return true; + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculator.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculator.java similarity index 68% rename from storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculator.java rename to storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculator.java index dfd4740..0b5f757 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculator.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculator.java @@ -18,30 +18,39 @@ package co.edu.uniquindio.dhash.resource.checksum; -import co.edu.uniquindio.dhash.resource.BytesResource; import co.edu.uniquindio.storage.resource.Resource; +import java.io.IOException; +import java.io.InputStream; import java.math.BigInteger; +import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -public class BytesChecksumCalculator implements ChecksumCalculator { - private String algorithm = "MD5"; +public class ChecksumInputStreamCalculator implements ChecksumCalculator { + private final String algorithm = "MD5"; @Override public String calculate(Resource resource) { - BytesResource bytesResource = (BytesResource) resource; - - try { + try (InputStream source = resource.getInputStream()){ MessageDigest digest = MessageDigest.getInstance(algorithm); - byte[] md5sum = digest.digest(bytesResource.getBytes()); + int count; + byte[] buffer = new byte[2048]; + while ((count = source.read(buffer)) > 0) + { + digest.update(buffer, 0, count); + } + + byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); return bigInt.toString(16); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Error with algorithm", e); + } catch (IOException e) { + throw new IllegalArgumentException("Error reading input stream", e); } } } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManager.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManager.java index bc705ed..fd0c108 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManager.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManager.java @@ -18,9 +18,8 @@ package co.edu.uniquindio.dhash.resource.manager; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import co.edu.uniquindio.storage.resource.Resource; -import org.apache.commons.io.IOUtils; import java.io.*; import java.util.Arrays; @@ -31,11 +30,13 @@ public class FileResourceManager implements ResourceManager { private final String directory; private final String name; private final Set keys; + private final Integer bufferSize; - public FileResourceManager(String directory, String name, Set keys) { + public FileResourceManager(String directory, String name, Set keys, Integer bufferSize) { this.directory = directory; this.name = name; this.keys = keys; + this.bufferSize = bufferSize; } @Override @@ -44,13 +45,7 @@ public void save(Resource resource) { StringBuilder directoryPath; File directoryFile; - BytesResource bytesResource = (BytesResource) resource; try { - byte[] bytesFile = bytesResource.getBytes(); - if (bytesFile == null) { - return; - } - directoryPath = new StringBuilder(directory); directoryPath.append(name); directoryPath.append("/"); @@ -61,15 +56,17 @@ public void save(Resource resource) { File file = new File(directoryFile, resource.getId()); fileOutputStream = new FileOutputStream(file); + InputStream source = resource.getInputStream(); - fileOutputStream.write(bytesFile); + int count; + byte[] buffer = new byte[bufferSize]; + while ((count = source.read(buffer)) > 0) { + fileOutputStream.write(buffer, 0, count); + } fileOutputStream.close(); - bytesFile = null; - keys.add(resource.getId()); - } catch (IOException e) { throw new IllegalStateException("Error reading file", e); } @@ -108,18 +105,15 @@ public Resource find(String key) { StringBuilder directoryPath = new StringBuilder(directory); directoryPath.append(name); directoryPath.append("/"); - - File directoryFile = new File(directoryPath.toString()); - directoryFile.mkdirs(); - - File file = new File(directoryFile, key); + directoryPath.append(key); try { - return new BytesResource(key, IOUtils.toByteArray(new FileInputStream(file))); - } catch (FileNotFoundException e) { - throw new RuntimeException("", e); + return FileResource.withPath() + .id(key) + .path(directoryPath.toString()) + .build(); } catch (IOException e) { - throw new RuntimeException("", e); + throw new IllegalStateException("Error reading file", e); } } else { return null; diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManagerFactory.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManagerFactory.java index c351d22..3b99ad7 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManagerFactory.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/FileResourceManagerFactory.java @@ -22,13 +22,15 @@ public class FileResourceManagerFactory implements ResourceManagerFactory { private final String directory; + private final Integer bufferSize; - public FileResourceManagerFactory(String directory) { + public FileResourceManagerFactory(String directory, Integer bufferSize) { this.directory = directory; + this.bufferSize = bufferSize; } @Override public ResourceManager of(String name) { - return new FileResourceManager(directory, name, new HashSet<>()); + return new FileResourceManager(directory, name, new HashSet<>(), bufferSize); } } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/ResourceManager.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/ResourceManager.java index 949a73e..ed6cc1f 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/ResourceManager.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/manager/ResourceManager.java @@ -20,6 +20,7 @@ import co.edu.uniquindio.storage.resource.Resource; +import java.io.OutputStream; import java.util.Set; /** diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandler.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandler.java new file mode 100644 index 0000000..80dcb7a --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandler.java @@ -0,0 +1,51 @@ +package co.edu.uniquindio.dhash.resource.serialization; + +import co.edu.uniquindio.dhash.resource.FileResource; +import co.edu.uniquindio.dhash.resource.serialization.jackson.FileResourceBuilderMixIn; +import co.edu.uniquindio.dhash.resource.serialization.jackson.FileResourceMixIn; +import co.edu.uniquindio.storage.resource.Resource; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.InjectableValues; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; + +public class ObjectMapperSerializationHandler implements SerializationHandler { + private final ObjectMapper objectMapper; + + public ObjectMapperSerializationHandler(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + + this.objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, JsonTypeInfo.As.WRAPPER_OBJECT); + this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + this.objectMapper.addMixIn(FileResource.class, FileResourceMixIn.class) + .addMixIn(FileResource.WithInputStreamBuilder.class, FileResourceBuilderMixIn.class); + } + + @Override + public String encode(Resource resource) { + try { + return objectMapper.writeValueAsString(resource); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Problem with json convertion", e); + } + } + + @Override + public Resource decode(String resource, InputStream inputStream) { + try { + InjectableValues inject = new InjectableValues.Std() + .addValue(InputStream.class, inputStream); + + return objectMapper.reader(inject) + .forType(Resource.class) + .readValue(resource); + } catch (IOException e) { + throw new IllegalArgumentException("Problem decoding", e); + } + } +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandler.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandler.java deleted file mode 100644 index 708effe..0000000 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * DHash project implement a storage management - * Copyright (C) 2010 - 2018 Daniel Pelaez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package co.edu.uniquindio.dhash.resource.serialization; - -import co.edu.uniquindio.storage.resource.Resource; - -import java.io.*; - -public class ObjectSerializationHandler implements SerializationHandler { - @Override - public byte[] encode(Resource resource) { - try (ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream(); - ObjectOutputStream objectOutput = new ObjectOutputStream(byteArrayOutput)) { - - objectOutput.writeObject(resource); - - return byteArrayOutput.toByteArray(); - } catch (IOException e) { - throw new IllegalStateException("Error meanwhile serialization", e); - } - } - - @Override - public Resource decode(byte[] bytes) { - try (ByteArrayInputStream byteArrayOutput = new ByteArrayInputStream(bytes); - ObjectInputStream objectOutput = new ObjectInputStream(byteArrayOutput)) { - - return (Resource) objectOutput.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new IllegalStateException("Error meanwhile deserialization", e); - } - } -} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/SerializationHandler.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/SerializationHandler.java index e55e538..744dee7 100644 --- a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/SerializationHandler.java +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/SerializationHandler.java @@ -20,6 +20,8 @@ import co.edu.uniquindio.storage.resource.Resource; +import java.io.InputStream; + /** * Serialization handler */ @@ -30,13 +32,11 @@ public interface SerializationHandler { * @param resource resource * @return bytes */ - byte[] encode(Resource resource); + String encode(Resource resource); /** * Decode a resource - * - * @param bytes data * @return Resource */ - Resource decode(byte[] bytes); + Resource decode(String resource, InputStream inputStream); } diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceBuilderMixIn.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceBuilderMixIn.java new file mode 100644 index 0000000..2219fc5 --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceBuilderMixIn.java @@ -0,0 +1,15 @@ +package co.edu.uniquindio.dhash.resource.serialization.jackson; + +import co.edu.uniquindio.dhash.resource.FileResource; +import com.fasterxml.jackson.annotation.JacksonInject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; + +import java.io.InputStream; + +@JsonPOJOBuilder(withPrefix="") +@JsonIgnoreProperties(ignoreUnknown = true) +public interface FileResourceBuilderMixIn { + @JacksonInject + FileResource.WithInputStreamBuilder inputStream(InputStream inputStream); +} diff --git a/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceMixIn.java b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceMixIn.java new file mode 100644 index 0000000..93f8e61 --- /dev/null +++ b/storage/dhash/src/main/java/co/edu/uniquindio/dhash/resource/serialization/jackson/FileResourceMixIn.java @@ -0,0 +1,21 @@ +package co.edu.uniquindio.dhash.resource.serialization.jackson; + +import co.edu.uniquindio.dhash.resource.FileResource; +import co.edu.uniquindio.utils.communication.message.Address; +import com.fasterxml.jackson.annotation.JacksonInject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.io.InputStream; + +import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.WRAPPER_OBJECT; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.CLASS; + +@JsonDeserialize(builder = FileResource.WithInputStreamBuilder.class) +@JsonTypeInfo(use = CLASS, include = WRAPPER_OBJECT) +public interface FileResourceMixIn { + @JsonIgnore + InputStream getInputStream(); +} diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashEnvironmentTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashEnvironmentTest.java deleted file mode 100644 index 93b9669..0000000 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashEnvironmentTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * DHash project implement a storage management - * Copyright (C) 2010 - 2018 Daniel Pelaez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package co.edu.uniquindio.dhash.node; - -import co.edu.uniquindio.dhash.protocol.Protocol; -import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; -import co.edu.uniquindio.dhash.resource.manager.ResourceManager; -import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; -import co.edu.uniquindio.overlay.OverlayException; -import co.edu.uniquindio.storage.resource.Resource; -import co.edu.uniquindio.utils.communication.message.Address; -import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import java.io.IOException; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.Mockito.*; - -@RunWith(MockitoJUnitRunner.class) -public class DHashEnvironmentTest { - @Mock - private CommunicationManager communicationManager; - @Mock - private DHashNode dHashNode; - @Mock - private SerializationHandler serializationHandler; - @Mock - private ChecksumCalculator checksumeCalculator; - @Mock - private ResourceManager resourceManager; - @Mock - private Message bigMessage; - @Mock - private Message message; - @Mock - private Resource serializableResource; - @InjectMocks - private DHashEnvironment dHashEnvironment; - @Captor - private ArgumentCaptor messageCaptor; - @Captor - private ArgumentCaptor bigMessageCaptor; - - @Test - public void put_bigMessageNotReplicate_save() throws OverlayException { - when(bigMessage.getMessageType()).thenReturn(Protocol.PUT); - when(bigMessage.getData(Protocol.PutDatas.RESOURCE.name())).thenReturn(new byte[]{1, 2, 3, 5}); - when(bigMessage.getParam(Protocol.PutParams.REPLICATE.name())).thenReturn("false"); - when(serializationHandler.decode(new byte[]{1, 2, 3, 5})).thenReturn(serializableResource); - - dHashEnvironment.process(bigMessage); - - verify(dHashNode, times(0)).replicateData(any()); - verify(resourceManager).save(serializableResource); - } - - @Test - public void put_bigMessageReplicate_replicate() throws OverlayException, IOException, ClassNotFoundException { - when(bigMessage.getMessageType()).thenReturn(Protocol.PUT); - when(bigMessage.getData(Protocol.PutDatas.RESOURCE.name())).thenReturn(new byte[]{1, 2, 3, 5}); - when(bigMessage.getParam(Protocol.PutParams.REPLICATE.name())).thenReturn("true"); - when(serializationHandler.decode(new byte[]{1, 2, 3, 5})).thenReturn(serializableResource); - - dHashEnvironment.process(bigMessage); - - verify(dHashNode).replicateData(serializableResource); - verify(resourceManager).save(serializableResource); - } - - @Test - public void resourceCompare_notExist_returnFalse() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.RESOURCE_COMPARE); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(false); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getParam(Protocol.ResourceCompareResponseParams.EXIST_RESOURCE.name())).isEqualTo("false"); - - } - - @Test - public void resourceCompare_existChecksumNotEqual_returnFalse() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.RESOURCE_COMPARE); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getParam(Protocol.ResourceCompareParams.CHECK_SUM.name())).thenReturn("checksum"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(true); - when(resourceManager.find("resource")).thenReturn(serializableResource); - when(checksumeCalculator.calculate(serializableResource)).thenReturn("checksumother"); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getParam(Protocol.ResourceCompareResponseParams.EXIST_RESOURCE.name())).isEqualTo("false"); - - } - - @Test - public void resourceCompare_existChecksumEqual_returnTrue() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.RESOURCE_COMPARE); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getParam(Protocol.ResourceCompareParams.CHECK_SUM.name())).thenReturn("checksum"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(true); - when(resourceManager.find("resource")).thenReturn(serializableResource); - when(checksumeCalculator.calculate(serializableResource)).thenReturn("checksum"); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getParam(Protocol.ResourceCompareResponseParams.EXIST_RESOURCE.name())).isEqualTo("true"); - - } - - @Test - public void get_hasResource_returnTrue() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.GET); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(true); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getParam(Protocol.GetResponseParams.HAS_RESOURCE.name())).isEqualTo("true"); - - } - - @Test - public void get_notHasResource_returnTrue() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.GET); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(false); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getParam(Protocol.GetResponseParams.HAS_RESOURCE.name())).isEqualTo("false"); - - } - - @Test - public void resourceTransfere_hasResource_returnTrue() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.RESOURCE_TRANSFER); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(true); - when(resourceManager.find("resource")).thenReturn(serializableResource); - when(serializationHandler.encode(serializableResource)).thenReturn(new byte[]{1, 2, 3}); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_TRANSFER_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getData(Protocol.ResourceTransferResponseData.RESOURCE.name())).isEqualTo(new byte[]{1, 2, 3}); - - } - - @Test - public void resourceTransfere_notHasResource_returnTrue() throws OverlayException { - when(message.getMessageType()).thenReturn(Protocol.RESOURCE_TRANSFER); - when(message.getParam(Protocol.ResourceCompareParams.RESOURCE_KEY.name())).thenReturn("resource"); - when(message.getAddress()).thenReturn(Address.builder().source("source").build()); - when(dHashNode.getName()).thenReturn("dhash"); - when(resourceManager.hasResource("resource")).thenReturn(false); - - Message response = dHashEnvironment.process(message); - - assertThat(response.getSendType()).isEqualTo(Message.SendType.RESPONSE); - assertThat(response.getMessageType()).isEqualTo(Protocol.RESOURCE_TRANSFER_RESPONSE); - assertThat(response.getAddress().getDestination()).isEqualTo("source"); - assertThat(response.getAddress().getSource()).isEqualTo("dhash"); - assertThat(response.getData(Protocol.ResourceTransferResponseData.RESOURCE.name())).isEqualTo(new byte[0]); - - } -} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeFactoryTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeFactoryTest.java index 90a5fe0..fe0cb94 100644 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeFactoryTest.java +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeFactoryTest.java @@ -18,6 +18,8 @@ package co.edu.uniquindio.dhash.node; +import co.edu.uniquindio.dhash.node.processor.MessageProcessorGateway; +import co.edu.uniquindio.dhash.node.processor.stream.MessageStreamProcessorGateway; import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; import co.edu.uniquindio.dhash.resource.manager.ResourceManager; import co.edu.uniquindio.dhash.resource.manager.ResourceManagerFactory; @@ -25,7 +27,8 @@ import co.edu.uniquindio.overlay.*; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNode; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.storage.resource.ProgressStatus; +import co.edu.uniquindio.utils.communication.message.IdGenerator; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Test; @@ -34,6 +37,7 @@ import org.mockito.junit.MockitoJUnitRunner; import java.util.Observable; +import java.util.concurrent.ExecutorService; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -55,7 +59,7 @@ public class DHashNodeFactoryTest { @Mock private KeyFactory keyFactory; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator sequenceGenerator; @Mock private Key key; @Mock @@ -63,16 +67,20 @@ public class DHashNodeFactoryTest { @Mock private DHashNode dhashNode; @Mock - private DHashEnvironment dHashEnviroment; + private MessageProcessorGateway messageProcessorGateway; + @Mock + private MessageStreamProcessorGateway messageStreamProcessorGateway; private DHashNodeFactory dHashNodeFactory; @Mock private Observable observable; @Mock private ReAssignObserver reAssignObserver; + @Mock + private ExecutorService executorService; @Before public void before() { - dHashNodeFactory = spy(new DHashNodeFactory(communicationManager, overlayNodeFactory, serializationHandler, checksumeCalculator, resourceManagerFactory, 2, keyFactory, sequenceGenerator)); + dHashNodeFactory = spy(new DHashNodeFactory(communicationManager, overlayNodeFactory, serializationHandler, checksumeCalculator, resourceManagerFactory, 2, keyFactory, sequenceGenerator, executorService)); } @Test @@ -80,22 +88,27 @@ public void create_byName_nodeCreated() throws OverlayException, DHashFactoryExc when(overlayNodeFactory.createNode("node")).thenReturn(overlayNode); when(overlayNode.getObservable()).thenReturn(observable); when(resourceManagerFactory.of("node")).thenReturn(resourceManager); - doReturn(dhashNode).when(dHashNodeFactory).getDhashNode("node", overlayNode, resourceManager); - doReturn(dHashEnviroment).when(dHashNodeFactory).getDHashEnviroment(dhashNode, resourceManager); + doReturn(dhashNode).when(dHashNodeFactory).getDHashNode("node", overlayNode, resourceManager); + doReturn(messageProcessorGateway).when(dHashNodeFactory).getMessageProcessor(dhashNode, resourceManager); doReturn(reAssignObserver).when(dHashNodeFactory).getReAssignObserver(dhashNode); + doReturn(messageStreamProcessorGateway).when(dHashNodeFactory).getMessageStreamProcessor(dhashNode, resourceManager); StorageNode node = dHashNodeFactory.createNode("node"); assertThat(node).isEqualTo(dhashNode); verify(observable).addObserver(reAssignObserver); - verify(communicationManager).addMessageProcessor("node", dHashEnviroment); + verify(communicationManager).addMessageProcessor("node", messageProcessorGateway); + verify(communicationManager).addMessageStreamProcessor("node", messageStreamProcessorGateway); } @Test public void destroyNode_nodeDestroyed() throws OverlayException, StorageException { - dHashNodeFactory.destroyNode(dhashNode); + ProgressStatus progressStatus = (name, current, size) -> { + }; + + dHashNodeFactory.destroyNode(dhashNode, progressStatus); - verify(dhashNode).leave(); + verify(dhashNode).leave(progressStatus); } } \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeTest.java index 7a82fcb..570bd3b 100644 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeTest.java +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/DHashNodeTest.java @@ -19,7 +19,6 @@ package co.edu.uniquindio.dhash.node; import co.edu.uniquindio.dhash.protocol.Protocol; -import co.edu.uniquindio.dhash.resource.ResourceNotFoundException; import co.edu.uniquindio.dhash.resource.checksum.ChecksumCalculator; import co.edu.uniquindio.dhash.resource.manager.ResourceManager; import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; @@ -29,9 +28,12 @@ import co.edu.uniquindio.overlay.OverlayNode; import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.storage.StorageNodeFactory; +import co.edu.uniquindio.storage.resource.ProgressStatus; import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Address; import co.edu.uniquindio.utils.communication.message.Message; -import co.edu.uniquindio.utils.communication.message.SequenceGenerator; +import co.edu.uniquindio.utils.communication.message.IdGenerator; +import co.edu.uniquindio.utils.communication.message.MessageStream; import co.edu.uniquindio.utils.communication.transfer.CommunicationManager; import org.junit.Before; import org.junit.Rule; @@ -43,9 +45,11 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ExecutorService; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -69,7 +73,7 @@ public class DHashNodeTest { @Mock private KeyFactory keyFactory; @Mock - private SequenceGenerator sequenceGenerator; + private IdGenerator idGenerator; @Mock private Key key; @Mock @@ -88,6 +92,10 @@ public class DHashNodeTest { private Resource resource3; @Mock private StorageNodeFactory dhashNodeFactory; + @Mock + private ProgressStatus progressStatus; + @Mock + private ExecutorService executorService; @Captor private ArgumentCaptor keyCaptor; @Captor @@ -100,121 +108,137 @@ public class DHashNodeTest { public void before() throws IOException, ClassNotFoundException { when(key.getValue()).thenReturn("key"); - dHashNode = spy(new DHashNode(overlayNode, 3, "dhash", communicationManager, serializationHandler, checksumeCalculator, resourceManager, keyFactory, sequenceGenerator)); + dHashNode = spy(new DHashNode(overlayNode, 3, "dhash", communicationManager, serializationHandler, resourceManager, keyFactory, idGenerator, executorService)); } @Test public void get_keyNotFound_exception() throws StorageException { thrown.expect(StorageException.class); - thrown.expectMessage("Imposible to do get to resource, lookup fails"); + thrown.expectMessage("Impossible to do get to resource, lookup fails"); - dHashNode.get("resourceKey"); + dHashNode.getSync("resourceKey", (name, current, size) -> {}); } @Test - public void get_nodeNotHaveResource_exception() throws StorageException { - thrown.expect(ResourceNotFoundException.class); - thrown.expectMessage("Resource 'resourceKey' not found"); - + public void get_nodeNotHaveResource_null() throws StorageException { + Message getMessage = Message.builder() + .id("id") + .sendType(Message.SendType.REQUEST) + .messageType(Protocol.CONTAIN) + .address(Address.builder() + .destination("key") + .source("dhash") + .build()) + .param(Protocol.ContainParams.RESOURCE_KEY.name(), "resourceKey") + .build(); + + when(idGenerator.newId()).thenReturn("id"); when(keyFactory.newKey("resourceKey")).thenReturn(key1); when(overlayNode.lookUp(key1)).thenReturn(key); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenReturn(false); + when(communicationManager.send(getMessage, Boolean.class)).thenReturn(false); + + Resource result = dHashNode.getSync("resourceKey", (name, current, size) -> { + }); + + assertThat(result).isNull(); - dHashNode.get("resourceKey"); + verify(communicationManager).send(getMessage, Boolean.class); + verify(communicationManager, times(0)).receive(any(), any()); } @Test public void get_nodeHaveResource_exception() throws StorageException, IOException, ClassNotFoundException { - when(serializationHandler.decode(new byte[10])).thenReturn(resource1); + Message getMessage = Message.builder() + .id("id") + .sendType(Message.SendType.REQUEST) + .messageType(Protocol.CONTAIN) + .address(Address.builder() + .destination("key") + .source("dhash") + .build()) + .param(Protocol.ContainParams.RESOURCE_KEY.name(), "resourceKey") + .build(); + + Message resourceTransferMessage = Message.builder() + .sendType(Message.SendType.REQUEST) + .id("id") + .messageType(Protocol.GET) + .address(Address.builder() + .destination("key") + .source("dhash") + .build()) + .param(Protocol.GetParams.RESOURCE_KEY.name(), "resourceKey") + .build(); + + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[8]); + MessageStream messageStream = MessageStream.builder() + .message(Message.builder() + .param(Protocol.GetResponseData.RESOURCE.name(), "resource") + .build()) + .inputStream(inputStream) + .build(); + + when(idGenerator.newId()).thenReturn("id"); when(keyFactory.newKey("resourceKey")).thenReturn(key1); when(overlayNode.lookUp(key1)).thenReturn(key); - when(bigMessage.getData(Protocol.ResourceTransferResponseData.RESOURCE.name())).thenReturn(new byte[10]); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenReturn(true); - when(communicationManager.sendMessageUnicast(any(), eq(Message.class))).thenReturn(bigMessage); - - Resource resourceResult = dHashNode.get("resourceKey"); - - verify(overlayNode).lookUp(key1); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), - eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), eq(Message.class)); - - assertThat(resourceResult).isEqualTo(resource1); - assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.GET); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("key"); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getSource()).isEqualTo("dhash"); - assertThat(messageCaptor.getAllValues().get(0).getParam(Protocol.GetParams.RESOURCE_KEY.name())).isEqualTo("resourceKey"); - assertThat(messageCaptor.getAllValues().get(1).getMessageType()).isEqualTo(Protocol.RESOURCE_TRANSFER); - assertThat(messageCaptor.getAllValues().get(1).getAddress().getDestination()).isEqualTo("key"); - assertThat(messageCaptor.getAllValues().get(1).getAddress().getSource()).isEqualTo("dhash"); - assertThat(messageCaptor.getAllValues().get(1).getParam(Protocol.GetParams.RESOURCE_KEY.name())).isEqualTo("resourceKey"); + when(communicationManager.send(getMessage, Boolean.class)).thenReturn(true); + when(communicationManager.receive(eq(resourceTransferMessage), any())).thenReturn(messageStream); + when(serializationHandler.decode("resource", inputStream)).thenReturn(resource1); + + Resource result = dHashNode.getSync("resourceKey", (name, current, size) -> { + }); + + assertThat(result).isEqualTo(resource1); } @Test public void put_keyNotFound_exception() throws StorageException { thrown.expect(StorageException.class); - thrown.expectMessage("Imposible to do put to resource: resourceKey in this moment"); + thrown.expectMessage("Impossible to do put the resource: resourceKey in this moment"); when(keyFactory.newKey("resourceKey")).thenReturn(key1); when(resource1.getId()).thenReturn("resourceKey"); when(overlayNode.lookUp(key1)).thenReturn(null); - dHashNode.put(resource1); - - verify(overlayNode).lookUp(key1); + dHashNode.putSync(resource1, (name, current, size) -> {}); } @Test - public void put_existResource_exception() throws StorageException { + public void put_send_resource() throws StorageException, IOException, ClassNotFoundException { + Message putMessage = Message.builder() + .id("id") + .sendType(Message.SendType.REQUEST) + .messageType(Protocol.PUT) + .address(Address.builder() + .destination("key") + .source("dhash") + .build()) + .param(Protocol.PutDatas.RESOURCE.name(), "resource") + .param(Protocol.PutParams.REPLICATE.name(), "true") + .build(); + + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[8]); + MessageStream messageStream = MessageStream.builder() + .message(putMessage) + .inputStream(inputStream) + .size(8L) + .build(); + + when(idGenerator.newId()).thenReturn("id"); when(keyFactory.newKey("resourceKey")).thenReturn(key1); when(resource1.getId()).thenReturn("resourceKey"); when(overlayNode.lookUp(key1)).thenReturn(key); - when(checksumeCalculator.calculate(resource1)).thenReturn("checksum"); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenReturn(true); + when(serializationHandler.encode(resource1)).thenReturn("resource"); + when(resource1.getInputStream()).thenReturn(inputStream); + when(resource1.getSize()).thenReturn(8L); - boolean result = dHashNode.put(resource1); + dHashNode.putSync(resource1, (name, current, size) -> {}); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), eq(Boolean.class)); - verify(overlayNode).lookUp(key1); - - assertThat(result).isFalse(); - assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("key"); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getSource()).isEqualTo("dhash"); - assertThat(messageCaptor.getAllValues().get(0).getParam(Protocol.ResourceCompareParams.CHECK_SUM.name())).isEqualTo("checksum"); - assertThat(messageCaptor.getAllValues().get(0).getParam(Protocol.PutParams.RESOURCE_KEY.name())).isEqualTo("resourceKey"); - - } - - @Test - public void put_send_resource() throws StorageException, IOException, ClassNotFoundException { - when(keyFactory.newKey("resourceKey")).thenReturn(key1); - when(resource1.getId()).thenReturn("resourceKey"); - when(overlayNode.lookUp(key1)).thenReturn(key); - when(checksumeCalculator.calculate(resource1)).thenReturn("checksum"); - when(communicationManager.sendMessageUnicast(any(), eq(Boolean.class))).thenReturn(false); - - dHashNode.put(resource1); - - verify(overlayNode).lookUp(key1); - verify(communicationManager).sendMessageUnicast(messageCaptor.capture(), - eq(Boolean.class)); - verify(communicationManager).sendMessageUnicast(bigMessageCaptor.capture()); - - assertThat(messageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.RESOURCE_COMPARE); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("key"); - assertThat(messageCaptor.getAllValues().get(0).getAddress().getSource()).isEqualTo("dhash"); - assertThat(messageCaptor.getAllValues().get(0).getParam(Protocol.ResourceCompareParams.CHECK_SUM.name())).isEqualTo("checksum"); - assertThat(messageCaptor.getAllValues().get(0).getParam(Protocol.PutParams.RESOURCE_KEY.name())).isEqualTo("resourceKey"); - assertThat(bigMessageCaptor.getAllValues().get(0).getMessageType()).isEqualTo(Protocol.PUT); - assertThat(bigMessageCaptor.getAllValues().get(0).getAddress().getDestination()).isEqualTo("key"); - assertThat(bigMessageCaptor.getAllValues().get(0).getAddress().getSource()).isEqualTo("dhash"); - assertThat(bigMessageCaptor.getAllValues().get(0).getParam(Protocol.PutParams.RESOURCE_KEY.name())).isEqualTo("resourceKey"); - assertThat(bigMessageCaptor.getAllValues().get(0).getParam(Protocol.PutParams.REPLICATE.name())).isEqualTo("true"); + verify(communicationManager).send(eq(messageStream), any()); } @Test - public void relocateAllResources_put_relocate2() { + public void relocateAllResources_put_relocate2() throws StorageException { Set resourcesNames = new HashSet<>(); resourcesNames.add("resource1"); resourcesNames.add("resource2"); @@ -233,13 +257,13 @@ public void relocateAllResources_put_relocate2() { when(key1.isBetween(relocateKey, key)).thenReturn(false); when(key2.isBetween(relocateKey, key)).thenReturn(true); when(key3.isBetween(relocateKey, key)).thenReturn(false); - doReturn(true).when(dHashNode).put(any(), any(), anyBoolean()); + doReturn(true).when(dHashNode).put(any(), any(), anyBoolean(), eq(progressStatus)); - dHashNode.relocateAllResources(relocateKey); + dHashNode.relocateAllResources(relocateKey, progressStatus); - verify(dHashNode).put(resource1, relocateKey, false); - verify(dHashNode).put(resource3, relocateKey, false); - verify(dHashNode, times(0)).put(resource2, relocateKey, false); + verify(dHashNode).put(resource1, relocateKey, false, progressStatus); + verify(dHashNode).put(resource3, relocateKey, false, progressStatus); + verify(dHashNode, times(0)).put(resource2, relocateKey, false, progressStatus); } @Test @@ -254,7 +278,7 @@ public void leave_keyEqualsSuccessor_notRelocate() throws StorageException, Over when(key.getValue()).thenReturn("key"); when(resourceManager.getAllKeys()).thenReturn(resourcesNames); - dHashNode.leave(); + dHashNode.leave((name, current, size) -> {}); verify(resourceManager).deleteAll(); verify(communicationManager).removeObserver("key"); @@ -274,50 +298,53 @@ public void leave_put_relocate2() throws StorageException, OverlayException { when(resourceManager.find("resource1")).thenReturn(resource1); when(resourceManager.find("resource2")).thenReturn(resource2); when(resourceManager.find("resource3")).thenReturn(resource3); - doReturn(true).when(dHashNode).put(any(), any(), anyBoolean()); + doReturn(true).when(dHashNode).put(any(), any(), anyBoolean(), eq(progressStatus)); - dHashNode.leave(); + dHashNode.leave(progressStatus); - verify(dHashNode).put(resource1, key1, false); - verify(dHashNode).put(resource2, key1, false); - verify(dHashNode).put(resource3, key1, false); + verify(dHashNode).put(resource1, key1, false, progressStatus); + verify(dHashNode).put(resource2, key1, false, progressStatus); + verify(dHashNode).put(resource3, key1, false, progressStatus); verify(resourceManager).deleteAll(); verify(communicationManager).removeObserver("key"); } @Test - public void replicateData_neighborsListEqualReplicationFactor_replicateAll() throws OverlayException { + public void replicateData_neighborsListEqualReplicationFactor_replicateAll() throws OverlayException, StorageException { when(overlayNode.getNeighborsList()).thenReturn(new Key[]{key1, key2, key3}); - doReturn(true).when(dHashNode).put(any(), any(), anyBoolean()); + when(resourceManager.find(resource1.getId())).thenReturn(resource1); + doReturn(true).when(dHashNode).put(any(), any(), anyBoolean(), eq(progressStatus)); - dHashNode.replicateData(resource1); + dHashNode.replicateData(resource1.getId(), progressStatus); - verify(dHashNode).put(resource1, key1, false); - verify(dHashNode).put(resource1, key2, false); - verify(dHashNode).put(resource1, key3, false); + verify(dHashNode).put(resource1, key1, false, progressStatus); + verify(dHashNode).put(resource1, key2, false, progressStatus); + verify(dHashNode).put(resource1, key3, false, progressStatus); } @Test - public void replicateData_neighborsListLessThanReplicationFactor_replicate2() throws OverlayException { + public void replicateData_neighborsListLessThanReplicationFactor_replicate2() throws OverlayException, StorageException { when(overlayNode.getNeighborsList()).thenReturn(new Key[]{key1, key2}); - doReturn(true).when(dHashNode).put(any(), any(), anyBoolean()); + when(resourceManager.find(resource1.getId())).thenReturn(resource1); + doReturn(true).when(dHashNode).put(any(), any(), anyBoolean(), eq(progressStatus)); - dHashNode.replicateData(resource1); + dHashNode.replicateData(resource1.getId(), progressStatus); - verify(dHashNode).put(resource1, key1, false); - verify(dHashNode).put(resource1, key2, false); + verify(dHashNode).put(resource1, key1, false, progressStatus); + verify(dHashNode).put(resource1, key2, false, progressStatus); } @Test - public void replicateData_neighborsListGreaterThanReplicationFactor_replicate3() throws OverlayException { + public void replicateData_neighborsListGreaterThanReplicationFactor_replicate3() throws OverlayException, StorageException { when(overlayNode.getNeighborsList()).thenReturn(new Key[]{key1, key2, key3, key}); - doReturn(true).when(dHashNode).put(any(), any(), anyBoolean()); + when(resourceManager.find(resource1.getId())).thenReturn(resource1); + doReturn(true).when(dHashNode).put(any(), any(), anyBoolean(), eq(progressStatus)); - dHashNode.replicateData(resource1); + dHashNode.replicateData(resource1.getId(), progressStatus); - verify(dHashNode).put(resource1, key1, false); - verify(dHashNode).put(resource1, key2, false); - verify(dHashNode).put(resource1, key3, false); - verify(dHashNode, times(0)).put(resource1, key, false); + verify(dHashNode).put(resource1, key1, false, progressStatus); + verify(dHashNode).put(resource1, key2, false, progressStatus); + verify(dHashNode).put(resource1, key3, false, progressStatus); + verify(dHashNode, times(0)).put(resource1, key, false, progressStatus); } } \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/ReAssignObserverTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/ReAssignObserverTest.java index 1308fd7..e3f72f0 100644 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/ReAssignObserverTest.java +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/ReAssignObserverTest.java @@ -20,6 +20,7 @@ import co.edu.uniquindio.overlay.Key; import co.edu.uniquindio.overlay.KeyFactory; +import co.edu.uniquindio.storage.StorageException; import co.edu.uniquindio.utils.communication.message.Message; import co.edu.uniquindio.utils.communication.message.MessageType; import org.junit.Test; @@ -74,7 +75,7 @@ public void update_messageTypeWrong_doNothing() { } @Test - public void update_messageCorrect_relocateAllResources() { + public void update_messageCorrect_relocateAllResources() throws StorageException { Message message = Message.builder() .messageType(MessageType.builder().name("RE_ASSIGN").build()) .param("PREDECESSOR", "123") @@ -84,6 +85,6 @@ public void update_messageCorrect_relocateAllResources() { reAssignObserver.update(null, message); - verify(dhashNode).relocateAllResources(key); + verify(dhashNode).relocateAllResources(eq(key), any()); } } \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/ContainProcessorTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/ContainProcessorTest.java new file mode 100644 index 0000000..ea9b26e --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/ContainProcessorTest.java @@ -0,0 +1,86 @@ +package co.edu.uniquindio.dhash.node.processor; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.overlay.OverlayException; +import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.Message; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ContainProcessorTest { + @Mock + private DHashNode dHashNode; + @Mock + private ResourceManager resourceManager; + @InjectMocks + private ContainProcessor containProcessor; + + @Test + public void contain_hasResource_returnTrue() throws OverlayException { + Message message = Message.builder() + .messageType(Protocol.CONTAIN) + .address(Address.builder() + .source("source") + .build()) + .param(Protocol.ContainParams.RESOURCE_KEY.name(), "resource") + .build(); + + Message expectedResponse = Message.builder() + .sendType(Message.SendType.RESPONSE) + .messageType(Protocol.CONTAIN_RESPONSE) + .address(Address.builder() + .source("dhash") + .destination("source") + .build()) + .param(Protocol.ContainResponseParams.HAS_RESOURCE.name(), "true") + .build(); + + when(dHashNode.getName()).thenReturn("dhash"); + when(resourceManager.hasResource("resource")).thenReturn(true); + + Message response = containProcessor.process(message); + + assertThat(response).isEqualTo(expectedResponse); + + } + + @Test + public void contain_notHasResource_returnFalse() throws OverlayException { + Message message = Message.builder() + .messageType(Protocol.CONTAIN) + .address(Address.builder() + .source("source") + .build()) + .param(Protocol.ContainParams.RESOURCE_KEY.name(), "resource") + .build(); + + Message expectedResponse = Message.builder() + .sendType(Message.SendType.RESPONSE) + .messageType(Protocol.CONTAIN_RESPONSE) + .address(Address.builder() + .source("dhash") + .destination("source") + .build()) + .param(Protocol.ContainResponseParams.HAS_RESOURCE.name(), "false") + .build(); + + when(dHashNode.getName()).thenReturn("dhash"); + when(resourceManager.hasResource("resource")).thenReturn(false); + + Message response = containProcessor.process(message); + + assertThat(response).isEqualTo(expectedResponse); + + } + + +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGatewayTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGatewayTest.java new file mode 100644 index 0000000..9df82ae --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/MessageProcessorGatewayTest.java @@ -0,0 +1,67 @@ +package co.edu.uniquindio.dhash.node.processor; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.transfer.MessageProcessor; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + + +@RunWith(MockitoJUnitRunner.class) +public class MessageProcessorGatewayTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Mock + private DHashNode dHashNode; + @Mock + private ResourceManager resourceManager; + @Mock + private MessageProcessor messageProcessor; + @InjectMocks + private MessageProcessorGateway messageProcessorGateway; + + @Test + public void new_construct() { + assertThat(messageProcessorGateway.getMessageProcessorMap().size()).isEqualTo(1); + assertThat(messageProcessorGateway.getMessageProcessorMap().get(Protocol.CONTAIN)).isNotNull(); + } + + @Test + public void process_rightMessageType_returnResponse() { + messageProcessorGateway.getMessageProcessorMap().put(Protocol.CONTAIN, messageProcessor); + + Message expectedResponse = Message.builder().build(); + + Message message = Message.builder() + .messageType(Protocol.CONTAIN) + .build(); + + when(messageProcessor.process(message)).thenReturn(expectedResponse); + + Message response = messageProcessorGateway.process(message); + + assertThat(response).isEqualTo(expectedResponse); + } + + @Test + public void process_wrongMessageType_throwException() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Message " + Protocol.GET + " was not found"); + + Message message = Message.builder() + .messageType(Protocol.GET) + .build(); + + messageProcessorGateway.process(message); + } +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessorTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessorTest.java new file mode 100644 index 0000000..051f8d7 --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/GetMessageStreamProcessorTest.java @@ -0,0 +1,75 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.FileResource; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; +import co.edu.uniquindio.overlay.OverlayException; +import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.ByteArrayInputStream; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GetMessageStreamProcessorTest { + @Mock + private ResourceManager resourceManager; + @Mock + private DHashNode dHashNode; + @Mock + private SerializationHandler serializationHandler; + @InjectMocks + private GetMessageStreamProcessor getMessageStreamProcessor; + + @Test + public void get_hasResource_returnTrue() throws OverlayException { + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[5]); + + Resource resource = FileResource.withInputStream() + .id("resource") + .size(10L) + .inputStream(inputStream) + .build(); + + MessageStream expectedResponse = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.GET_RESPONSE) + .sendType(Message.SendType.RESPONSE) + .address(Address.builder().destination("source").source("dhash").build()) + .param(Protocol.GetResponseData.RESOURCE.name(), "serializableResource") + .build()) + .size(10L) + .inputStream(inputStream) + .build(); + + MessageStream message = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.GET) + .address(Address.builder().source("source").build()) + .param(Protocol.GetParams.RESOURCE_KEY.name(), "resource") + .build()) + .build(); + + when(dHashNode.getName()).thenReturn("dhash"); + when(resourceManager.find("resource")).thenReturn(resource); + when(serializationHandler.encode(resource)).thenReturn("serializableResource"); + + MessageStream response = getMessageStreamProcessor.process(message); + + assertThat(response).isEqualTo(expectedResponse); + + } + + +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGatewayTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGatewayTest.java new file mode 100644 index 0000000..f6c7cf1 --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/MessageStreamProcessorGatewayTest.java @@ -0,0 +1,75 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import co.edu.uniquindio.utils.communication.transfer.MessageStreamProcessor; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class MessageStreamProcessorGatewayTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Mock + private DHashNode dHashNode; + @Mock + private ResourceManager resourceManager; + @Mock + private MessageStreamProcessor messageStreamProcessor; + @InjectMocks + private MessageStreamProcessorGateway messageStreamProcessorGateway; + + @Test + public void new_construct() { + assertThat(messageStreamProcessorGateway.getMessageStreamProcessorMap().size()).isEqualTo(2); + assertThat(messageStreamProcessorGateway.getMessageStreamProcessorMap().get(Protocol.GET)).isNotNull(); + assertThat(messageStreamProcessorGateway.getMessageStreamProcessorMap().get(Protocol.PUT)).isNotNull(); + } + + @Test + public void process_rightMessageType_returnResponse() { + messageStreamProcessorGateway.getMessageStreamProcessorMap().put(Protocol.GET, messageStreamProcessor); + + MessageStream expectedResponse = MessageStream.builder() + .message(Message.builder() + .build()) + .build(); + + MessageStream message = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.GET) + .build()) + .build(); + + when(messageStreamProcessor.process(message)).thenReturn(expectedResponse); + + MessageStream response = messageStreamProcessorGateway.process(message); + + assertThat(response).isEqualTo(expectedResponse); + } + + @Test + public void process_wrongMessageType_throwException() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Message " + Protocol.CONTAIN + " was not found"); + + MessageStream message = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.CONTAIN) + .build()) + .build(); + + messageStreamProcessorGateway.process(message); + } +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessorTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessorTest.java new file mode 100644 index 0000000..5b688a2 --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/node/processor/stream/PutMessageStreamProcessorTest.java @@ -0,0 +1,105 @@ +package co.edu.uniquindio.dhash.node.processor.stream; + +import co.edu.uniquindio.dhash.node.DHashNode; +import co.edu.uniquindio.dhash.protocol.Protocol; +import co.edu.uniquindio.dhash.resource.FileResource; +import co.edu.uniquindio.dhash.resource.manager.ResourceManager; +import co.edu.uniquindio.dhash.resource.serialization.SerializationHandler; +import co.edu.uniquindio.overlay.OverlayException; +import co.edu.uniquindio.storage.StorageException; +import co.edu.uniquindio.storage.resource.Resource; +import co.edu.uniquindio.utils.communication.message.Address; +import co.edu.uniquindio.utils.communication.message.Message; +import co.edu.uniquindio.utils.communication.message.MessageStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.ByteArrayInputStream; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class PutMessageStreamProcessorTest { + @Mock + private ResourceManager resourceManager; + @Mock + private DHashNode dHashNode; + @Mock + private SerializationHandler serializationHandler; + @InjectMocks + private PutMessageStreamProcessor putMessageStreamProcessor; + + @Test + public void put_replicate_ok() throws OverlayException, StorageException { + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[5]); + + Resource resource = FileResource.withInputStream() + .id("resource") + .size(10L) + .inputStream(inputStream) + .build(); + + MessageStream message = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.PUT) + .sendType(Message.SendType.RESPONSE) + .address(Address.builder().destination("source").source("dhash").build()) + .param(Protocol.GetResponseData.RESOURCE.name(), "serializableResource") + .param(Protocol.PutParams.REPLICATE.name(), "true") + .build()) + .size(10L) + .inputStream(inputStream) + .build(); + + when(serializationHandler.decode("serializableResource", inputStream)).thenReturn(resource); + + MessageStream response = putMessageStreamProcessor.process(message); + + assertThat(response).isNull(); + + verify(resourceManager).save(resource); + verify(dHashNode).replicateData(eq("resource"), any()); + + } + + @Test + public void put_notReplicate_ok() throws OverlayException, StorageException { + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[5]); + + Resource resource = FileResource.withInputStream() + .id("resource") + .size(10L) + .inputStream(inputStream) + .build(); + + MessageStream message = MessageStream.builder() + .message(Message.builder() + .messageType(Protocol.PUT) + .sendType(Message.SendType.RESPONSE) + .address(Address.builder().destination("source").source("dhash").build()) + .param(Protocol.GetResponseData.RESOURCE.name(), "serializableResource") + .param(Protocol.PutParams.REPLICATE.name(), "false") + .build()) + .size(10L) + .inputStream(inputStream) + .build(); + + when(serializationHandler.decode("serializableResource", inputStream)).thenReturn(resource); + + MessageStream response = putMessageStreamProcessor.process(message); + + assertThat(response).isNull(); + + verify(resourceManager).save(resource); + verify(dHashNode, times(0)).replicateData(any(), any()); + + } +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculatorTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculatorTest.java similarity index 70% rename from storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculatorTest.java rename to storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculatorTest.java index e319233..8d7080c 100644 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/BytesChecksumCalculatorTest.java +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/checksum/ChecksumInputStreamCalculatorTest.java @@ -18,24 +18,29 @@ package co.edu.uniquindio.dhash.resource.checksum; -import co.edu.uniquindio.dhash.resource.BytesResource; +import co.edu.uniquindio.dhash.resource.FileResource; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.junit.MockitoJUnitRunner; +import java.io.ByteArrayInputStream; + import static org.assertj.core.api.Assertions.assertThat; @RunWith(MockitoJUnitRunner.class) -public class BytesChecksumCalculatorTest { +public class ChecksumInputStreamCalculatorTest { @InjectMocks - private BytesChecksumCalculator bytesChecksumCalculator; + private ChecksumInputStreamCalculator checksumInputStreamCalculator; @Test public void calculate() { - BytesResource bytesResource = new BytesResource("resource", new byte[]{1, 2, 3}); + FileResource fileResource = FileResource.withInputStream() + .id("resource") + .inputStream(new ByteArrayInputStream(new byte[]{1, 2, 3})) + .build(); - String checksum = bytesChecksumCalculator.calculate(bytesResource); + String checksum = checksumInputStreamCalculator.calculate(fileResource); assertThat(checksum).isEqualTo("5289df737df57326fcdd22597afb1fac"); } diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandlerTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandlerTest.java new file mode 100644 index 0000000..26392f5 --- /dev/null +++ b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectMapperSerializationHandlerTest.java @@ -0,0 +1,71 @@ +/* + * DHash project implement a storage management + * Copyright (C) 2010 - 2018 Daniel Pelaez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package co.edu.uniquindio.dhash.resource.serialization; + +import co.edu.uniquindio.dhash.resource.FileResource; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.ByteArrayInputStream; + +import static org.assertj.core.api.Java6Assertions.assertThat; + + +@RunWith(MockitoJUnitRunner.class) +public class ObjectMapperSerializationHandlerTest { + private ObjectMapperSerializationHandler objectSerializationHandler; + + @Before + public void before(){ + this.objectSerializationHandler = new ObjectMapperSerializationHandler(new ObjectMapper()); + } + + @Test + public void encode() { + FileResource resource = FileResource.withInputStream() + .id("resource") + .size(10L) + .inputStream(new ByteArrayInputStream("data".getBytes())) + .build(); + + String result = objectSerializationHandler.encode(resource); + + assertThat(result).isEqualTo("{\"co.edu.uniquindio.dhash.resource.FileResource\":{\"id\":\"resource\",\"size\":10}}"); + } + + @Test + public void decode() { + ByteArrayInputStream inputStream = new ByteArrayInputStream("data".getBytes()); + + FileResource resource = FileResource.withInputStream() + .id("resource") + .size(10L) + .inputStream(inputStream) + .build(); + + FileResource result = (FileResource) objectSerializationHandler.decode("{\"co.edu.uniquindio.dhash.resource.FileResource\":{\"id\":\"resource\",\"size\":10}}", inputStream); + + assertThat(result).isEqualTo(resource); + } + +} \ No newline at end of file diff --git a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandlerTest.java b/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandlerTest.java deleted file mode 100644 index 024d41b..0000000 --- a/storage/dhash/src/test/java/co/edu/uniquindio/dhash/resource/serialization/ObjectSerializationHandlerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * DHash project implement a storage management - * Copyright (C) 2010 - 2018 Daniel Pelaez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package co.edu.uniquindio.dhash.resource.serialization; - -import co.edu.uniquindio.dhash.resource.BytesResource; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - - -@RunWith(MockitoJUnitRunner.class) -public class ObjectSerializationHandlerTest { - @InjectMocks - private ObjectSerializationHandler objectSerializationHandler; - - @Test - public void encode() { - BytesResource bytesResource = new BytesResource("resource", new byte[]{1, 2, 3}); - - byte[] result = objectSerializationHandler.encode(bytesResource); - - assertThat(result).isEqualTo(new byte[]{-84, -19, 0, 5, 115, 114, 0, 46, 99, 111, 46, 101, 100, 117, 46, 117, 110, 105, 113, 117, 105, 110, 100, 105, 111, 46, 100, 104, 97, 115, 104, 46, 114, 101, 115, 111, 117, 114, 99, 101, 46, 66, 121, 116, 101, 115, 82, 101, 115, 111, 117, 114, 99, 101, -116, 103, 98, 44, 108, 42, 75, -122, 2, 0, 2, 91, 0, 5, 98, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0, 2, 105, 100, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 3, 1, 2, 3, 116, 0, 8, 114, 101, 115, 111, 117, 114, 99, 101}); - } - - @Test - public void decode() { - BytesResource bytesResource = new BytesResource("resource", new byte[]{1, 2, 3}); - - BytesResource result = (BytesResource) objectSerializationHandler.decode(new byte[]{-84, -19, 0, 5, 115, 114, 0, 46, 99, 111, 46, 101, 100, 117, 46, 117, 110, 105, 113, 117, 105, 110, 100, 105, 111, 46, 100, 104, 97, 115, 104, 46, 114, 101, 115, 111, 117, 114, 99, 101, 46, 66, 121, 116, 101, 115, 82, 101, 115, 111, 117, 114, 99, 101, -116, 103, 98, 44, 108, 42, 75, -122, 2, 0, 2, 91, 0, 5, 98, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0, 2, 105, 100, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 3, 1, 2, 3, 116, 0, 8, 114, 101, 115, 111, 117, 114, 99, 101}); - - assertThat(result.getId()).isEqualTo(bytesResource.getId()); - assertThat(result.getBytes()).isEqualTo(bytesResource.getBytes()); - } - -} \ No newline at end of file diff --git a/storage/storage-service/build.gradle b/storage/storage-service/build.gradle index c8b716b..75ff726 100644 --- a/storage/storage-service/build.gradle +++ b/storage/storage-service/build.gradle @@ -9,7 +9,7 @@ repositories { } group = 'com.github.estigma88' -version = '2.0.0' +version = '3.0.0' dependencies { } diff --git a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNode.java b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNode.java index 0ec6f61..fe0e690 100644 --- a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNode.java +++ b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNode.java @@ -18,8 +18,11 @@ package co.edu.uniquindio.storage; +import co.edu.uniquindio.storage.resource.ProgressStatus; import co.edu.uniquindio.storage.resource.Resource; +import java.util.concurrent.CompletableFuture; + /** * The {@code StorageNode} interface offer the services of {@code put} and {@code * get} of a specific file. @@ -37,25 +40,23 @@ public interface StorageNode { * * @param id The name of the required resource. * @return The {@link Resource} - * @throws StorageException throw when occur an error. */ - Resource get(String id) throws StorageException; + CompletableFuture get(String id, ProgressStatus progressStatus); /** * Puts the specified resource into the network. * * @param resource The resource that will be put. * @return False if the resource already exists, true if the put was successful - * @throws StorageException throw when occur an error. */ - boolean put(Resource resource) throws StorageException; + CompletableFuture put(Resource resource, ProgressStatus progressStatus); /** * Allows the node to leave in a regular mode. * * @throws StorageException throw when occur an error. */ - void leave() throws StorageException; + void leave(ProgressStatus progressStatus) throws StorageException; /** * Gets the name of the storage node. diff --git a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNodeFactory.java b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNodeFactory.java index 15912ae..ee083b4 100644 --- a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNodeFactory.java +++ b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/StorageNodeFactory.java @@ -18,6 +18,8 @@ package co.edu.uniquindio.storage; +import co.edu.uniquindio.storage.resource.ProgressStatus; + /** * The StorageNodeFactory abstract class defined methods for to create * StorageNode nodes. The class is a single instance. @@ -44,5 +46,5 @@ public interface StorageNodeFactory { * @param storageNode node * @throws StorageException throw when occur an error */ - void destroyNode(StorageNode storageNode) throws StorageException; + void destroyNode(StorageNode storageNode, ProgressStatus progressStatus) throws StorageException; } diff --git a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/ProgressStatus.java b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/ProgressStatus.java new file mode 100644 index 0000000..ef71e95 --- /dev/null +++ b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/ProgressStatus.java @@ -0,0 +1,5 @@ +package co.edu.uniquindio.storage.resource; + +public interface ProgressStatus { + void status(String name, Long current, Long size); +} diff --git a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/Resource.java b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/Resource.java index 0e19142..1d9a6f1 100644 --- a/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/Resource.java +++ b/storage/storage-service/src/main/java/co/edu/uniquindio/storage/resource/Resource.java @@ -18,14 +18,31 @@ package co.edu.uniquindio.storage.resource; +import java.io.Closeable; +import java.io.InputStream; + /** * Class to handle a Resource */ -public interface Resource { +public interface Resource extends Closeable{ /** * Gets id of resource * * @return id of resource */ String getId(); + + /** + * Get an input stream that represents the resource content + * + * @return resource content + */ + InputStream getInputStream(); + + /** + * Get the resource size in bytes + * + * @return bytes amount + */ + Long getSize(); }