diff --git a/publisher-subscriber/README.md b/publish-subscribe/README.md
similarity index 94%
rename from publisher-subscriber/README.md
rename to publish-subscribe/README.md
index fe7a110fca89..5e4d5c9ffb41 100644
--- a/publisher-subscriber/README.md
+++ b/publish-subscribe/README.md
@@ -1,5 +1,5 @@
---
-title: Publish-Subscribe pattern
+title: Publish-Subscribe
category: Behavioral
language: en
tag:
@@ -135,7 +135,7 @@ public class TLender {
LOGGER.error("An error has occurred!", e);
}
- TLender tLender = new TLender(topicCFName, topicName);
+ TLender lender = new TLender(topicCFName, topicName);
System.out.println ("TLender Application Started");
System.out.println ("Press enter to quit application");
@@ -151,11 +151,11 @@ public class TLender {
//Exit if user pressed enter or line is blank
if (line == null || line.trim().length() == 0) {
System.out.println("Exiting...");
- tLender.exit();
+ lender.exit();
}
else { //publish the entered rate
double newRate = Double.parseDouble(line);
- tLender.publishRate(newRate);
+ lender.publishRate(newRate);
}
}
} catch(IOException e) {
@@ -186,15 +186,6 @@ Initial rate is 6.0
Waiting for new rates...
Press enter to quit application
-Running the class:
-
-The class must be run after the TLender class is running since TLender spins up the activeMQ broker.
-
-In order to see the messages being sent to multiple subscribers multiple instance of the TBorrower class need to be run. Either run multiple instances in an IDE or execute the following command in a command line from the root folder after generating the target folder:
-
-
-mvn exec:java -Dexec.mainClass=com.iluwatar.publishersubscriber.TBorrower -Dexec.args="TopicCF RateTopic 6"
-
```java
public class TBorrower implements MessageListener {
@@ -282,7 +273,7 @@ public class TBorrower implements MessageListener {
System.exit(0);
}
- TBorrower tBorrower = new TBorrower(topicCF, topicName, rate);
+ TBorrower borrower = new TBorrower(topicCF, topicName, rate);
try {
// Run until enter is pressed
@@ -291,7 +282,7 @@ public class TBorrower implements MessageListener {
System.out.println ("TBorrower application started");
System.out.println ("Press enter to quit application");
reader.readLine();
- tBorrower.exit();
+ borrower.exit();
} catch (IOException ioe) {
ioe.printStackTrace();
}
@@ -316,6 +307,7 @@ public class TBorrower implements MessageListener {
```
## Class diagram
+![alt text](./etc/publishsubscribe.urm.png "Publish Subscribe class diagram")
## Applicability
diff --git a/publish-subscribe/USAGE.md b/publish-subscribe/USAGE.md
new file mode 100644
index 000000000000..92f82e688b25
--- /dev/null
+++ b/publish-subscribe/USAGE.md
@@ -0,0 +1,8 @@
+Running the Borrower class:
+
+The class must be run after the TLender class is running since TLender spins up the activeMQ broker.
+
+In order to see the messages being sent to multiple subscribers multiple instance of the TBorrower class need to be run. Either run multiple instances in an IDE or execute the following command in a command line from the root folder after generating the target folder:
+
+
+mvn exec:java -Dexec.mainClass=com.iluwatar.publishsubscribe.Borrower -Dexec.args="TopicCF RateTopic 6"
\ No newline at end of file
diff --git a/publisher-subscriber/pom.xml b/publish-subscribe/pom.xml
similarity index 92%
rename from publisher-subscriber/pom.xml
rename to publish-subscribe/pom.xml
index 42b58399d89b..8b4d2806cd90 100644
--- a/publisher-subscriber/pom.xml
+++ b/publish-subscribe/pom.xml
@@ -35,7 +35,7 @@
java-design-patterns
1.26.0-SNAPSHOT
- publishersubscriber
+ publishsubscribe
@@ -58,11 +58,6 @@
xbean-spring
4.24
-
- log4j
- log4j
- 1.2.17
-
org.apache.activemq.tooling
activemq-junit
diff --git a/publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TBorrower.java b/publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Borrower.java
similarity index 79%
rename from publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TBorrower.java
rename to publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Borrower.java
index 1d489bdd00e0..1198fc5eeef3 100644
--- a/publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TBorrower.java
+++ b/publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Borrower.java
@@ -1,4 +1,4 @@
-package com.iluwatar.publishersubscriber;
+package com.iluwatar.publishsubscribe;
import lombok.extern.slf4j.Slf4j;
import javax.jms.BytesMessage;
@@ -19,14 +19,16 @@
import java.io.InputStreamReader;
@Slf4j
-public class TBorrower implements MessageListener {
+public class Borrower implements MessageListener {
private TopicConnection tConnection;
private TopicSession tSession;
private Topic topic;
private double currentRate;
+ private static final String ERROR = "An error has occured!";
+ private double newRate;
- public TBorrower(String topicCFName, String topicName, double initialRate) {
+ public Borrower(String topicCFName, String topicName, double initialRate) {
currentRate = initialRate;
@@ -50,44 +52,37 @@ public TBorrower(String topicCFName, String topicName, double initialRate) {
tConnection.start();
System.out.println("Initial rate is " + currentRate + " \nWaiting for new rates...");
} catch(NamingException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
}
}
//This method is called asynchronously by the activeMQ broker
public void onMessage(Message message) {
-
try {
BytesMessage bMessage = (BytesMessage) message;
- double newRate = ((BytesMessage) bMessage).readDouble();
+ double newRate = bMessage.readDouble();
+ setNewRate(newRate);
if (currentRate - newRate >= 1)
System.out.println("New Rate is " + newRate + " - Consider refinancing");
else
System.out.println("New Rate is " + newRate + " - Consider keeping current rate");
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
}
System.out.println("Waiting for new rates...");
}
- private void exit() {
+ public boolean close() {
try {
tConnection.close();
+ return true;
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
+ return false;
}
- System.exit(0);
}
public static void main(String[] args) {
@@ -105,7 +100,7 @@ public static void main(String[] args) {
System.exit(0);
}
- TBorrower tBorrower = new TBorrower(topicCF, topicName, rate);
+ Borrower borrower = new Borrower(topicCF, topicName, rate);
try {
// Run until enter is pressed
@@ -114,9 +109,10 @@ public static void main(String[] args) {
System.out.println ("TBorrower application started");
System.out.println ("Press enter to quit application");
reader.readLine();
- tBorrower.exit();
- } catch (IOException ioe) {
- ioe.printStackTrace();
+ borrower.close();
+ System.exit(0);
+ } catch (IOException e) {
+ LOGGER.error(ERROR, e);
}
}
@@ -135,4 +131,8 @@ public Topic getTopic() {
public double getCurrentRate() {
return currentRate;
}
+
+ public double getNewRate() { return newRate; }
+
+ private void setNewRate(double newRate) { this.newRate = newRate; }
}
diff --git a/publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TLender.java b/publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Lender.java
similarity index 67%
rename from publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TLender.java
rename to publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Lender.java
index 3536d69fdffa..dd504e57f49a 100644
--- a/publisher-subscriber/src/main/java/com/iluwatar/publishersubscriber/TLender.java
+++ b/publish-subscribe/src/main/java/com/iluwatar/publishsubscribe/Lender.java
@@ -1,4 +1,4 @@
-package com.iluwatar.publishersubscriber;
+package com.iluwatar.publishsubscribe;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.broker.BrokerService;
@@ -14,18 +14,23 @@
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.Properties;
@Slf4j
-public class TLender {
+public class Lender {
private TopicConnection tConnection;
private TopicSession tSession;
private Topic topic;
private TopicPublisher publisher;
+ private static final String ERROR = "An error has occured!";
- public TLender(String topicCFName, String topicName) {
+ public Lender(String topicCFName, String topicName) {
try {
//create context and retrieve objects from directory
@@ -44,17 +49,13 @@ public TLender(String topicCFName, String topicName) {
tConnection.start();
} catch(NamingException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
}
}
- private void publishRate(double newRate) {
+ public void publishRate(double newRate) {
try {
//create JMS message
@@ -64,21 +65,18 @@ private void publishRate(double newRate) {
//publish message
publisher.publish(message);
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
}
}
- private void exit() {
+ public boolean close() {
try {
tConnection.close();
+ return true;
} catch(JMSException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
- System.exit(1);
+ LOGGER.error(ERROR, e);
+ return false;
}
- System.exit(0);
}
public static void main(String[] args) {
@@ -90,26 +88,35 @@ public static void main(String[] args) {
topicCFName = args[0];
topicName = args[1];
} else {
- System.out.println("Invalid arguments. Should be: ");
- System.out.println("java TLender [factory] [topic]");
+ LOGGER.info("Invalid arguments. Should be: ");
+ LOGGER.info("java TLender [factory] [topic]");
System.exit(1);
}
try {
+ //Get configuration properties
+ Properties props = new Properties();
+ InputStream in = new FileInputStream("publish-subscribe/src/main/resources/config.properties");
+ props.load(in);
+ in.close();
+
// Create and start activeMQ broker. Broker decouples publishers and subscribers.
- //Additionally brokers manage threads and asynchronous sending and receiving of messages.
+ // Additionally brokers manage threads and asynchronous sending and receiving of messages.
BrokerService broker = new BrokerService();
- broker.addConnector("tcp://localhost:61616");
+ broker.addConnector(props.getProperty("ADDRESS"));
broker.start();
+ } catch(FileNotFoundException e) {
+ LOGGER.error(ERROR, e);
+ } catch(IOException e) {
+ LOGGER.error(ERROR, e);
} catch(Exception e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
+ LOGGER.error(ERROR, e);
}
- TLender tLender = new TLender(topicCFName, topicName);
+ Lender lender = new Lender(topicCFName, topicName);
- System.out.println ("TLender Application Started");
+ LOGGER.info("TLender Application Started");
System.out.println ("Press enter to quit application");
System.out.println ("Enter: Rate");
System.out.println("\ne.g. 6.8");
@@ -123,16 +130,16 @@ public static void main(String[] args) {
//Exit if user pressed enter or line is blank
if (line == null || line.trim().length() == 0) {
System.out.println("Exiting...");
- tLender.exit();
+ lender.close();
+ System.exit(0);
}
else { //publish the entered rate
double newRate = Double.parseDouble(line);
- tLender.publishRate(newRate);
+ lender.publishRate(newRate);
}
}
} catch(IOException e) {
- e.printStackTrace();
- LOGGER.error("An error has occurred!", e);
+ LOGGER.error(ERROR, e);
}
}
diff --git a/publish-subscribe/src/main/resources/config.properties b/publish-subscribe/src/main/resources/config.properties
new file mode 100644
index 000000000000..c90ed24de061
--- /dev/null
+++ b/publish-subscribe/src/main/resources/config.properties
@@ -0,0 +1 @@
+ADDRESS=tcp://localhost:61616
\ No newline at end of file
diff --git a/publisher-subscriber/src/main/resources/jndi.properties b/publish-subscribe/src/main/resources/jndi.properties
similarity index 100%
rename from publisher-subscriber/src/main/resources/jndi.properties
rename to publish-subscribe/src/main/resources/jndi.properties
diff --git a/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/BorrowerTest.java b/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/BorrowerTest.java
new file mode 100644
index 000000000000..ded88e244087
--- /dev/null
+++ b/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/BorrowerTest.java
@@ -0,0 +1,78 @@
+package com.iluwatar.publishsubscribe;
+
+import org.apache.activemq.Message;
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.command.ActiveMQTextMessage;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.sql.SQLOutput;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class BorrowerTest {
+
+ private Borrower borrower;
+ private static BrokerService broker;
+
+ @BeforeAll
+ static void setUp() throws Exception {
+ broker = new BrokerService();
+ broker.setPersistent(false);
+ broker.start();
+ }
+
+ @AfterAll
+ static void tearDown() throws Exception {
+ broker.stop();
+ }
+
+ @Test
+ void testTBorrowerConstructor() {
+ //act
+ borrower = new Borrower("TopicCF", "RateTopic", 6.0); //Arbitrary rate
+
+ //assert
+ Assertions.assertNotNull(borrower.gettConnection());
+ Assertions.assertNotNull(borrower.getTopic());
+ Assertions.assertNotNull(borrower.gettSession());
+ }
+
+ @Test
+ void testOnMessage() throws JMSException {
+ //assemble
+ borrower = new Borrower("TopicCF", "RateTopic", 6.0);
+ BytesMessage msg = borrower.gettSession().createBytesMessage();
+ msg.writeDouble(5);
+ msg.reset();
+
+ //act
+ borrower.onMessage(msg);
+
+ //assert
+ Assertions.assertEquals(borrower.getNewRate(), 5);
+ }
+
+ @Test
+ void testClose() {
+ //assemble
+ borrower = new Borrower("TopicCF", "RateTopic", 6.0);
+
+ //act
+ boolean isClosed = borrower.close();
+
+ //assert
+ Assertions.assertTrue(isClosed);
+ }
+}
diff --git a/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/LenderTest.java b/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/LenderTest.java
new file mode 100644
index 000000000000..a103b0d9850f
--- /dev/null
+++ b/publish-subscribe/src/test/java/com/iluwatar/publishsubscribe/LenderTest.java
@@ -0,0 +1,50 @@
+package com.iluwatar.publishsubscribe;
+
+import org.apache.activemq.broker.BrokerService;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class LenderTest {
+
+ private Lender lender;
+ private static BrokerService broker;
+
+ @BeforeAll
+ static void setUp() throws Exception {
+ broker = new BrokerService();
+ broker.setPersistent(false);
+ broker.start();
+ }
+
+ @AfterAll
+ static void tearDown() throws Exception {
+ broker.stop();
+ }
+
+ @Test
+ void testTLenderConstructor() {
+ //act
+ lender = new Lender("TopicCF", "RateTopic");
+
+ //assert
+ Assertions.assertNotNull(lender.gettConnection());
+ Assertions.assertNotNull(lender.getTopic());
+ Assertions.assertNotNull(lender.gettSession());
+ }
+
+ @Test
+ void textExit() {
+ //assemble
+ lender = new Lender("TopicCF", "RateTopic");
+
+ //act
+ boolean isClosed = lender.close();
+
+ //assert
+ Assertions.assertTrue(isClosed);
+ }
+}
diff --git a/publisher-subscriber/src/test/resources/jndi.properties b/publish-subscribe/src/test/resources/jndi.properties
similarity index 100%
rename from publisher-subscriber/src/test/resources/jndi.properties
rename to publish-subscribe/src/test/resources/jndi.properties
diff --git a/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TBorrowerTest.java b/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TBorrowerTest.java
deleted file mode 100644
index b59e421d5b90..000000000000
--- a/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TBorrowerTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.iluwatar.publishersubscriber;
-
-import org.apache.activemq.broker.BrokerService;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class TBorrowerTest {
-
- private TBorrower tBorrower;
-
- void setUp() throws Exception {
- BrokerService broker = new BrokerService();
- broker.setPersistent(false);
- broker.start();
- }
-
- @Test
- void testTBorrowerConstructor() {
- //act
- tBorrower = new TBorrower("TopicCF", "RateTopic", 6.0); //Arbitrary rate
-
- //assert
- Assertions.assertNotNull(tBorrower.gettConnection());
- Assertions.assertNotNull(tBorrower.getTopic());
- Assertions.assertNotNull(tBorrower.gettSession());
- }
-}
diff --git a/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TLenderTest.java b/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TLenderTest.java
deleted file mode 100644
index 9ec82e02109f..000000000000
--- a/publisher-subscriber/src/test/java/com/iluwatar/publishersubscriber/TLenderTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.iluwatar.publishersubscriber;
-
-import org.apache.activemq.broker.BrokerService;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.jms.TopicConnectionFactory;
-import javax.jms.TopicPublisher;
-
-public class TLenderTest {
-
- private TLender tLender;
-
- void setUp() throws Exception {
- BrokerService broker = new BrokerService();
- broker.setPersistent(false);
- broker.start();
- }
-
- @Test
- void testTLenderConstructor() {
- //act
- tLender = new TLender("TopicCF", "RateTopic");
-
- //assert
- Assertions.assertNotNull(tLender.gettConnection());
- Assertions.assertNotNull(tLender.getTopic());
- Assertions.assertNotNull(tLender.gettSession());
- }
-}