Initial commit.

This commit is contained in:
Florian THIERRY
2021-05-17 22:22:54 +02:00
commit 0d5bdffea2
16 changed files with 347 additions and 0 deletions

33
.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

69
pom.xml Normal file
View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>fr.ippon.example</groupId>
<artifactId>intellij-features</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>intellij-features</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.pebbletemplates</groupId>
<artifactId>pebble</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,7 @@
version: '3.6'
services:
mailer:
image: "mailhog/mailhog"
ports:
- "1025:1025"
- "8025:8025"

View File

@@ -0,0 +1,13 @@
package fr.ippon.example.intellijfeatures;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class IntellijFeaturesApplication {
public static void main(String[] args) {
SpringApplication.run(IntellijFeaturesApplication.class, args);
}
}

View File

@@ -0,0 +1,16 @@
package fr.ippon.example.intellijfeatures.config;
import com.mitchellbosecke.pebble.PebbleEngine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServiceConfiguration {
/**
* Basic pebble engine.
*/
@Bean
public PebbleEngine pebbleEngine() {
return new PebbleEngine.Builder().build();
}
}

View File

@@ -0,0 +1,23 @@
package fr.ippon.example.intellijfeatures.controller;
import fr.ippon.example.intellijfeatures.model.User;
import fr.ippon.example.intellijfeatures.services.mail.EmailService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/mails")
public class MailController {
private final EmailService emailService;
public MailController(EmailService emailService) {
this.emailService = emailService;
}
@PostMapping("/send")
public void sendMail(@RequestBody User user) {
emailService.sendMail(user);
}
}

View File

@@ -0,0 +1,15 @@
package fr.ippon.example.intellijfeatures.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public class InternalServerErrorException extends TechnicalException {
public InternalServerErrorException(String message) {
super(message);
}
public InternalServerErrorException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,23 @@
package fr.ippon.example.intellijfeatures.exception;
/**
* Technical exception.
*/
public class TechnicalException extends RuntimeException {
/**
* Constructs an exception with a message.
* @param message The description of the error met.
*/
public TechnicalException(final String message) {
super(message);
}
/**
* Constructs an exception with a message and a code.
* @param message The description of the error met.
* @param cause The cause of the exception.
*/
public TechnicalException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package fr.ippon.example.intellijfeatures.model;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
private String name;
private String email;
}

View File

@@ -0,0 +1,25 @@
package fr.ippon.example.intellijfeatures.services;
import com.mitchellbosecke.pebble.PebbleEngine;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
@Service
public class PebbleService {
private final PebbleEngine engine;
public PebbleService(PebbleEngine engine) {
this.engine = engine;
}
public String loadTemplate(String templatePath, Map<String, Object> templateVars) throws IOException {
Writer writer = new StringWriter();
engine.getTemplate(templatePath)
.evaluate(writer, templateVars);
return writer.toString();
}
}

View File

@@ -0,0 +1,27 @@
package fr.ippon.example.intellijfeatures.services.mail;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
@Service
public class EmailSender {
private final JavaMailSender javaMailSender;
public EmailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void sendEmail(String recipient, String subject, String htmlContent, String textContent) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setTo(recipient);
helper.setSubject(subject);
helper.setText(textContent, htmlContent);
javaMailSender.send(mimeMessage);
}
}

View File

@@ -0,0 +1,45 @@
package fr.ippon.example.intellijfeatures.services.mail;
import fr.ippon.example.intellijfeatures.exception.InternalServerErrorException;
import fr.ippon.example.intellijfeatures.model.User;
import fr.ippon.example.intellijfeatures.services.PebbleService;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import java.io.IOException;
import java.util.Map;
@Service
public class EmailService {
private final EmailSender emailSender;
private final PebbleService pebbleService;
public EmailService(EmailSender emailSender, PebbleService pebbleService) {
this.emailSender = emailSender;
this.pebbleService = pebbleService;
}
public void sendMail(User user) {
String htmlContent;
String textContent;
try {
htmlContent = pebbleService.loadTemplate(
"templates/mail/user-mail.html",
Map.of("user", user)
);
textContent = pebbleService.loadTemplate(
"templates/mail/user-mail.txt",
Map.of("user", user)
);
} catch (IOException exception) {
throw new InternalServerErrorException("Unable to send mail, cause to a template loading error.", exception);
}
try {
emailSender.sendEmail(user.getEmail(), "Hello", htmlContent, textContent);
} catch (MessagingException exception) {
throw new InternalServerErrorException("Unable to send mail, cause to a technical sending error.", exception);
}
}
}

View File

@@ -0,0 +1,4 @@
spring:
mail:
host: localhost
port: 1025

View File

@@ -0,0 +1,20 @@
<html>
<head>
<title>Hello world!</title>
<style type="text/css">
#content {
color: white;
background-color: #349ed6;
padding: 10px;
margin: 25px auto;
border-radius: 7px;
width: max-content;
}
</style>
</head>
<body>
<div id="content">
Hello {{ user.name }}!
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
Hello {{ user.name }}!

View File

@@ -0,0 +1,13 @@
package fr.ippon.example.intellijfeatures;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class IntellijFeaturesApplicationTests {
@Test
void contextLoads() {
}
}