From c54441e08ef093941a3b0bff56e6556677756de6 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 17:43:10 +0100 Subject: [PATCH 01/13] Add dependencies for RabbitMQ and AMQP --- pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cdeb4c0..3be77a6 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,6 @@ - org.springframework.boot spring-boot-starter-web @@ -43,10 +42,21 @@ org.springframework.boot spring-boot-starter-data-jpa + org.springframework.boot spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.amqp + spring-rabbit-test + test + From edc50e7c0a9fe0d03e495da7a1923b83a67c8469 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 17:45:52 +0100 Subject: [PATCH 02/13] Add Message Queue config file with Beans for queue, exchange, binding, messageConverter (to Json) and rabbit template --- .../crimedatabase/messaging/MQConfig.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/se/iths/crimedatabase/messaging/MQConfig.java diff --git a/src/main/java/se/iths/crimedatabase/messaging/MQConfig.java b/src/main/java/se/iths/crimedatabase/messaging/MQConfig.java new file mode 100644 index 0000000..529bba4 --- /dev/null +++ b/src/main/java/se/iths/crimedatabase/messaging/MQConfig.java @@ -0,0 +1,46 @@ +package se.iths.crimedatabase.messaging; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MQConfig { + public static final String QUEUE = "message_queue"; + public static final String EXCHANGE = "message_exchange"; + public static final String ROUTING_KEY = "message_routingKey"; + + @Bean + public Queue queue() { + return new Queue(QUEUE); + } + + @Bean + public TopicExchange exchange() { + return new TopicExchange(EXCHANGE); + } + + @Bean + public Binding binding(Queue queue, TopicExchange exchange) { + return BindingBuilder + .bind(queue) + .to(exchange) + .with(ROUTING_KEY); + } + + @Bean + public MessageConverter messageConverter() { + return new Jackson2JsonMessageConverter(); + } + + @Bean + public AmqpTemplate template(ConnectionFactory connectionFactory) { + RabbitTemplate template = new RabbitTemplate(connectionFactory); + template.setMessageConverter(messageConverter()); + return template; + } +} From 6805944b2089cd5ca78f8cc7cbd2238f8d28161a Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 18:00:57 +0100 Subject: [PATCH 03/13] Add CustomMessage entity that will contain the data for the messages we will send --- .../messaging/CustomMessage.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java diff --git a/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java new file mode 100644 index 0000000..2346659 --- /dev/null +++ b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java @@ -0,0 +1,50 @@ +package se.iths.crimedatabase.messaging; + +import java.time.LocalDateTime; + +public class CustomMessage { + private String messageID; + private String message; + private LocalDateTime messageDate; + + public CustomMessage(String messageID, String message, LocalDateTime messageDate) { + this.messageID = messageID; + this.message = message; + this.messageDate = messageDate; + } + + public CustomMessage() {} + + public String getMessageID() { + return messageID; + } + + public void setMessageID(String messageID) { + this.messageID = messageID; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public LocalDateTime getMessageDate() { + return messageDate; + } + + public void setMessageDate(LocalDateTime messageDate) { + this.messageDate = messageDate; + } + + @Override + public String toString() { + return "CustomMessage{" + + "messageID='" + messageID + '\'' + + ", message='" + message + '\'' + + ", messageDate=" + messageDate + + '}'; + } +} From 24c783a12ec762dd52fb3e851faab59e04e47b7a Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 18:03:44 +0100 Subject: [PATCH 04/13] Add Publisher to publish sample message when using endpoint /publish, with JSON format ("message": "sample message") --- .../messaging/MessagePublisher.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java diff --git a/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java b/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java new file mode 100644 index 0000000..ed1e686 --- /dev/null +++ b/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java @@ -0,0 +1,28 @@ +package se.iths.crimedatabase.messaging; + +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.UUID; + +@RestController +public class MessagePublisher { + + private final RabbitTemplate template; + + public MessagePublisher(RabbitTemplate template) { + this.template = template; + } + + @PostMapping("/publish") + public String publishMessage(@RequestBody CustomMessage message) { + message.setMessageID(UUID.randomUUID().toString()); + message.setMessageDate(LocalDateTime.now()); + template.convertAndSend(MQConfig.EXCHANGE, MQConfig.ROUTING_KEY, message); + + return "Message Published"; + } +} From f0cd6408392d24a52c21e794b6dba5ecd96aa0fe Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 18:05:12 +0100 Subject: [PATCH 05/13] Add Listener to listen for messages from the Publisher and simply print them in the console for demo --- .../crimedatabase/messaging/MessageListener.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/se/iths/crimedatabase/messaging/MessageListener.java diff --git a/src/main/java/se/iths/crimedatabase/messaging/MessageListener.java b/src/main/java/se/iths/crimedatabase/messaging/MessageListener.java new file mode 100644 index 0000000..4d14448 --- /dev/null +++ b/src/main/java/se/iths/crimedatabase/messaging/MessageListener.java @@ -0,0 +1,13 @@ +package se.iths.crimedatabase.messaging; + +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +@Component +public class MessageListener { + + @RabbitListener(queues = MQConfig.QUEUE) + public void listener(CustomMessage message) { + System.out.println(message); + } +} From 3b5514809b1415a5cba904bdc905fabbba7fd78d Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 18:11:25 +0100 Subject: [PATCH 06/13] Change LocalDate to java.util.Date to fix bug --- .../se/iths/crimedatabase/messaging/CustomMessage.java | 9 +++++---- .../iths/crimedatabase/messaging/MessagePublisher.java | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java index 2346659..23e909d 100644 --- a/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java +++ b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java @@ -1,13 +1,14 @@ package se.iths.crimedatabase.messaging; import java.time.LocalDateTime; +import java.util.Date; public class CustomMessage { private String messageID; private String message; - private LocalDateTime messageDate; + private Date messageDate; - public CustomMessage(String messageID, String message, LocalDateTime messageDate) { + public CustomMessage(String messageID, String message, Date messageDate) { this.messageID = messageID; this.message = message; this.messageDate = messageDate; @@ -31,11 +32,11 @@ public void setMessage(String message) { this.message = message; } - public LocalDateTime getMessageDate() { + public Date getMessageDate() { return messageDate; } - public void setMessageDate(LocalDateTime messageDate) { + public void setMessageDate(Date messageDate) { this.messageDate = messageDate; } diff --git a/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java b/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java index ed1e686..7854ebf 100644 --- a/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java +++ b/src/main/java/se/iths/crimedatabase/messaging/MessagePublisher.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; +import java.util.Date; import java.util.UUID; @RestController @@ -20,7 +20,7 @@ public MessagePublisher(RabbitTemplate template) { @PostMapping("/publish") public String publishMessage(@RequestBody CustomMessage message) { message.setMessageID(UUID.randomUUID().toString()); - message.setMessageDate(LocalDateTime.now()); + message.setMessageDate(new Date()); template.convertAndSend(MQConfig.EXCHANGE, MQConfig.ROUTING_KEY, message); return "Message Published"; From 36614c598fc3a533763c9b47bc4a972fd2eb6d68 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 18:19:23 +0100 Subject: [PATCH 07/13] Update README.md with instructions to deploy RabbitMQ message broker, as well as info about login to the management console --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 80e756b..229f036 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,18 @@ different degree of access throughout the application. 1. Clone/Fork this repo in your favorite IDE 2. Install Docker Desktop 3. Create and run MySQL docker image/container: - 1. Run command in - Console: `docker run --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` -4. Create a .jar file: Go to the folder of the application and run the following from your + - Run command in + Console: `docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` +4. Create and run RabbitMQ message broker image/container: + - Run command in Console: `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management` + - You can access management console at: `http://localhost:15672/` + - Username: guest + - Password: guest +5. Create a .jar file: Go to the folder of the application and run the following from your Console: `./mvnw clean package` -5. Build the image: Go to the folder of the application and run the following from your Console: +6. Build the image: Go to the folder of the application and run the following from your Console: `docker image build -t crimedb .` -6. Run the application: `docker container run crimedb` +7. Run the application: `docker container run crimedb` --- From 8e8836ee1b5dfab3e8e6ad925db7579164f37c6b Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Thu, 24 Mar 2022 19:04:25 +0100 Subject: [PATCH 08/13] Fix ability to make POST and PUT calls in Insomnia for testing purposes by disabling CSRF (.csrf().disable()) --- .../crimedatabase/security/SecurityConfig.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java b/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java index 1ef40a0..a424151 100644 --- a/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java +++ b/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java @@ -12,21 +12,20 @@ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { - - //Used to authorize requests @Override protected void configure(HttpSecurity http) throws Exception { http - .authorizeRequests() - .antMatchers("/criminals").hasRole("ADMIN") //Only admin can access criminals - .antMatchers("/victims").hasRole("ADMIN") //Only admin can access victims - .antMatchers("/users").hasRole("ADMIN") //Only admin can access users - .anyRequest().authenticated() //Authenticated users are authorized to make any request except the above. + .csrf().disable() + .httpBasic() .and() - .httpBasic(); //Uses http basic as authentication + .authorizeRequests() + .antMatchers("/publish").permitAll() + .antMatchers("/criminals").hasRole("ADMIN") + .antMatchers("/victims").hasRole("ADMIN") + .antMatchers("/users").hasRole("ADMIN") + .anyRequest().authenticated(); } - @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); From ef6658e25e92aabcddc64e460822a80cdc5adf88 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Fri, 25 Mar 2022 12:34:58 +0100 Subject: [PATCH 09/13] Revert "Update README.md with instructions to deploy RabbitMQ message broker, as well as info about login to the management console" This reverts commit 36614c598fc3a533763c9b47bc4a972fd2eb6d68. --- README.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 229f036..80e756b 100644 --- a/README.md +++ b/README.md @@ -40,18 +40,13 @@ different degree of access throughout the application. 1. Clone/Fork this repo in your favorite IDE 2. Install Docker Desktop 3. Create and run MySQL docker image/container: - - Run command in - Console: `docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` -4. Create and run RabbitMQ message broker image/container: - - Run command in Console: `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management` - - You can access management console at: `http://localhost:15672/` - - Username: guest - - Password: guest -5. Create a .jar file: Go to the folder of the application and run the following from your + 1. Run command in + Console: `docker run --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` +4. Create a .jar file: Go to the folder of the application and run the following from your Console: `./mvnw clean package` -6. Build the image: Go to the folder of the application and run the following from your Console: +5. Build the image: Go to the folder of the application and run the following from your Console: `docker image build -t crimedb .` -7. Run the application: `docker container run crimedb` +6. Run the application: `docker container run crimedb` --- From ff9a8f32d630a996f3d601af90cdc25965d3ae23 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Fri, 25 Mar 2022 14:47:59 +0100 Subject: [PATCH 10/13] Update SecurityConfig --- .../java/se/iths/crimedatabase/security/SecurityConfig.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java b/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java index c3223a4..a263d0e 100644 --- a/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java +++ b/src/main/java/se/iths/crimedatabase/security/SecurityConfig.java @@ -12,9 +12,8 @@ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { - private final String[] urls = {"/addresses", "/categories", "/crimes", "/criminals", "/users", "/victims"}; + private final String[] urls = {"/addresses", "/categories", "/crimes", "/criminals", "/users", "/victims", "/publish"}; - //Used to authorize requests @Override protected void configure(HttpSecurity http) throws Exception { http @@ -28,13 +27,10 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers("/victims").hasRole("ADMIN") .antMatchers("/users").hasRole("ADMIN") .anyRequest().authenticated(); - } - @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } - } From 385c668547fd41ae4c47894d450ccd86cee03c48 Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Fri, 25 Mar 2022 14:48:26 +0100 Subject: [PATCH 11/13] Update CustomMessage --- src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java index 23e909d..33284df 100644 --- a/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java +++ b/src/main/java/se/iths/crimedatabase/messaging/CustomMessage.java @@ -1,6 +1,5 @@ package se.iths.crimedatabase.messaging; -import java.time.LocalDateTime; import java.util.Date; public class CustomMessage { From 41161a39f457b0fe3abaae4e3a9e34917246d4cb Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Fri, 25 Mar 2022 14:48:40 +0100 Subject: [PATCH 12/13] Update README.md --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 80e756b..2023fd4 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,19 @@ different degree of access throughout the application. 1. Clone/Fork this repo in your favorite IDE 2. Install Docker Desktop 3. Create and run MySQL docker image/container: - 1. Run command in - Console: `docker run --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` -4. Create a .jar file: Go to the folder of the application and run the following from your + - Run command in + Console: `docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` +4. Create and run RabbitMQ message broker image/container: + - Run command in + Console: `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management` + - You can access management console at: `http://localhost:15672/` + - Username: guest + - Password: guest +5. Create a .jar file: Go to the folder of the application and run the following from your Console: `./mvnw clean package` -5. Build the image: Go to the folder of the application and run the following from your Console: +6. Build the image: Go to the folder of the application and run the following from your Console: `docker image build -t crimedb .` -6. Run the application: `docker container run crimedb` +7. Run the application: `docker container run crimedb` --- From 5b58e0953930186d56588de9e2294f399e6c16cd Mon Sep 17 00:00:00 2001 From: Patrik Fallqvist Magnusson Date: Fri, 25 Mar 2022 16:01:59 +0100 Subject: [PATCH 13/13] Update README.md with instructions and features --- README.md | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2023fd4..41890b0 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ different degree of access throughout the application. * Database relations * Dockerfile + Container * Custom exceptions +* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/1) +* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/2) +* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/5) ### Planned features -* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/1) -* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/2) * ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/3) * ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/4) -* ![GitHub milestone](https://img.shields.io/github/milestones/progress-percent/Patlenlix/CrimeDatabase/5) * MySQL database @@ -39,20 +39,16 @@ different degree of access throughout the application. 1. Clone/Fork this repo in your favorite IDE 2. Install Docker Desktop -3. Create and run MySQL docker image/container: - - Run command in - Console: `docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=my_secret_password -e 'MYSQL_ROOT_HOST=%' -e MYSQL_DATABASE=crime -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p 3309:3306 mysql:latest` -4. Create and run RabbitMQ message broker image/container: - - Run command in - Console: `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management` - - You can access management console at: `http://localhost:15672/` - - Username: guest - - Password: guest -5. Create a .jar file: Go to the folder of the application and run the following from your - Console: `./mvnw clean package` -6. Build the image: Go to the folder of the application and run the following from your Console: - `docker image build -t crimedb .` -7. Run the application: `docker container run crimedb` +3. Create and run RabbitMQ message broker image/container: + - Run command in + Console: `docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management` + - You can access management console at: `http://localhost:15672/` + - Username: guest + - Password: guest +4. Build the image: + - Go to the folder of the application and run the following from your Console: + `docker image build -t crimedb .` +5. Run the application: `docker container run crimedb` --- @@ -156,3 +152,17 @@ POST and PUT needs a Body with a JSON object. Example of body for POST (PUT also "time": "2022-03-18 15:48" } ``` + +#### Publish RabbitMQ Messaging Service: + +| HTTP-verb | URL | Authorization | Info | +|-----------|----------|-------------------------|--------------------------------------| +| POST | /publish | All authenticated users | Sends message internally to Listener | + +POST needs a Body with a JSON object. Example of body for POST: + +```json +{ + "message": "Sample message" +} +```