Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mercury #4

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
86da5ec
initial commit
maciejwalkowiak Jan 10, 2015
b903966
- sending email with Java Mail
maciejwalkowiak Jan 10, 2015
ed74e73
- mail listener received mercury message so it can update it's status…
maciejwalkowiak Jan 11, 2015
21eba83
- replaced MBassador with plain Spring application events
maciejwalkowiak Jan 11, 2015
1fd3de4
changing message status after message is sent
maciejwalkowiak Jan 11, 2015
87ffeb4
changing message status after message sending failed
maciejwalkowiak Jan 11, 2015
29b2644
HATEOAS based API controllers
maciejwalkowiak Jan 11, 2015
808588e
Replaced Spring ApplicationEvent based messaging with Reactor
maciejwalkowiak Jan 12, 2015
958c32a
Minor refactoring
maciejwalkowiak Jan 12, 2015
01cf84e
SendGrid integration
maciejwalkowiak Jan 12, 2015
b42e75c
readme update
maciejwalkowiak Jan 12, 2015
df7e6f1
Minor cleanup
maciejwalkowiak Jan 12, 2015
5f1a51f
Unit & Integration tests, minor refactoring
maciejwalkowiak Jan 12, 2015
4bf8aa0
Readme update
maciejwalkowiak Jan 12, 2015
5c80ada
JavaMailSenderImpl based mail server health check with MailServerHeal…
maciejwalkowiak Jan 13, 2015
31b1845
SendGrid proxy-aware health indicator
maciejwalkowiak Jan 13, 2015
44c830c
Javadocs for 'core' module
maciejwalkowiak Jan 13, 2015
a34d4cb
Javadocs for 'mail' module
maciejwalkowiak Jan 13, 2015
d7fedf6
Added fields to SendMailRequest: "cc", "bcc". It's possible now to se…
maciejwalkowiak Jan 13, 2015
e1ec988
Added validation to SendMailRequest
maciejwalkowiak Jan 13, 2015
8fe9630
Refactored test to not hit SendGrid
maciejwalkowiak Jan 13, 2015
27a1bcd
readme update
maciejwalkowiak Jan 13, 2015
a57107c
Update README.adoc
maciejwalkowiak Jan 13, 2015
35f8153
Added drone.io badge to README
maciejwalkowiak Jan 13, 2015
a6942d3
Reactor uses not threadpool
maciejwalkowiak Jan 13, 2015
e788277
Added assembly plugin for building zip releases
maciejwalkowiak Jan 13, 2015
89fd604
Removed defaults from application.properties
maciejwalkowiak Jan 13, 2015
73ec138
Assembly creates now zip with files nested inside a directory
maciejwalkowiak Jan 13, 2015
4f12ee4
Version 0.0.1
maciejwalkowiak Jan 13, 2015
739dd2c
Update README.adoc
maciejwalkowiak Jan 13, 2015
a75947d
Update README.adoc
maciejwalkowiak Jan 14, 2015
c515784
Slack integration
maciejwalkowiak Jan 15, 2015
8240786
Version 0.0.2-SNAPSHOT
maciejwalkowiak Jan 15, 2015
4844a93
Improved exception handling and formatting error messages to user fri…
maciejwalkowiak Jan 15, 2015
74d2429
Minor refactoring and cleanup
maciejwalkowiak Jan 15, 2015
27a6e7b
Improved HTTP responses. Now return proper status code and headers
maciejwalkowiak Jan 15, 2015
6f71a38
Fixed unit test
maciejwalkowiak Jan 15, 2015
1a5e04f
Running tests is now possible without running MongoDB instance thanks…
maciejwalkowiak Jan 16, 2015
24aad56
Replaced Reactor with custom solution
maciejwalkowiak Jan 16, 2015
309d816
- simplified SendGrid functionality
maciejwalkowiak Jan 16, 2015
87239e4
- simplified SendGrid functionality
maciejwalkowiak Jan 16, 2015
58619d5
Fixed unit test
maciejwalkowiak Jan 16, 2015
591ce8b
Cleanup and refactoring
maciejwalkowiak Jan 16, 2015
f1a9383
Update README.adoc
maciejwalkowiak Jan 16, 2015
d4eded9
Update README.adoc
maciejwalkowiak Jan 16, 2015
d381e2d
Minor refactoring
maciejwalkowiak Jan 16, 2015
e4ee237
Added optional configuration for Fongo for user that do not care if m…
maciejwalkowiak Jan 16, 2015
67903eb
Update README.adoc
maciejwalkowiak Jan 16, 2015
f1090ef
Update README.adoc
maciejwalkowiak Jan 16, 2015
6752666
Update README.adoc
maciejwalkowiak Jan 16, 2015
de7f475
Added metrics
maciejwalkowiak Jan 16, 2015
4272c39
Documentation update
maciejwalkowiak Jan 17, 2015
63df3d6
removed docs
maciejwalkowiak Jan 17, 2015
66c74da
Added logs, updated default config
maciejwalkowiak Jan 17, 2015
07e1ee9
Version 0.0.2
maciejwalkowiak Jan 17, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Intellij IDEA
.idea/
*.iml
*.iws

# Mac
.DS_Store

# Maven
target/
40 changes: 10 additions & 30 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,36 +1,16 @@
== _Learning Spring Boot_ Contest
image::https://raw.githubusercontent.com/maciejwalkowiak/contest/gh-pages/mercury.png[]

This is a contest based on _Learning Spring Boot_. The idea is to submit a small, pithy, cool Spring Boot application to win a prize. We will soon announce the prizes.
image:https://drone.io/github.com/maciejwalkowiak/contest/status.png[link=https://drone.io/github.com/maciejwalkowiak/contest/latest]

=== Calling all Spring Boot apps
____
In Roman mythology *Mercury* is the patron god of messages and communication.
____

Years ago, the http://www.ioccc.org/years.html[The International Obfuscated C Code Contest] was invented. Seeing http://blog.aerojockey.com/post/iocccsim[Carl Banks' flight simulator] forever impressed me as a neat, pithy little app.
*Mercury* is an application initially created for http://blog.greglturnquist.com/2014/12/announcing-learningspringboot-contest-cc-packtpub-springcentral.html[_Learning Spring Boot_] contest.
Source code is available at GitHub: https://github.com/maciejwalkowiak/contest/

Well, we aren't looking for obfuscated, complex, impossible to read apps. But we *ARE* looking for slick, cool apps that show off the power/coolness/wicked abilities of Spring Boot mixed with your hackable creativity. Characteristics the judges evaluate include:
TIP: If you like the application *star* this Github repository and *tweet* about it with #mercuryapp hashtag.

* Stylish
* Short and sweet
* Custom auto-configurations are welcome
* Custom health indicators, metrics, and fancy usage thereof
* Nice on the server side OR cool frontends (You don't have to build a web frontend to have a slick, elegeant, and original UI.)
* Popularity. Tweet things up while you work on your submission. We will definitely look at stars on your forked repo of this contest, volume of traffic your generate, and other evidence of popularity.
Mercury goal is to provide single **HTTP API** to send notifications in a company with internal applications in mind.

=== How/when to submit

IMPORANT: Deadline is 11:59pm January 17th CST (UTC-6). (I hate midnight deadlines, since they're so ambiguous.)

To submit an entery:

. Fork this repo.
. Code your solution inside your fork.
. Tweet/blog/reddit/facebook your efforts and gather evidence of your apps popularity (stars on your repo, total hits on your blog entry, total number of registered userse for your slick app, etc.)
. Replace this README.adoc with your own documentation (cuteness rewarded!).
. Submit a pull request (before the deadline!!!)
. Wait to see the announcement.
. Collect your prize!

Those of you that can't wait, use the holiday time as you wish. Those of you that are enjoying time with family and friends, we included enough time so you can still get into the contest.

NOTE: No member of Pivotal Inc. is permitted to enter this contest. Only one submission per person or team. If there is evidence of multiple "sock puppet" entries coming from the same group of people, the judges reserve the right to disqualify anyone involved. All decisions are final.

Good luck!
Read more on project website: https://maciejwalkowiak.github.io/contest/
22 changes: 22 additions & 0 deletions etc/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Mercury configuration

mercury.db.inMemory=true

# MongoDB - optional
#spring.data.mongodb.uri=mongodb://localhost/test # connection URL
#spring.data.mongodb.database=
#spring.data.mongodb.username=
#spring.data.mongodb.password=

# JavaMail configuration - optional
#spring.mail.host=
#spring.mail.port=
#spring.mail.username=
#spring.mail.password=

# SendGrid configuration - optional
#sendgrid.username=
#sendgrid.password=

# Slack configuration - optional
#slack.hook.url=
91 changes: 91 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.maciejwalkowiak</groupId>
<artifactId>mercury</artifactId>
<version>0.0.2</version>
<packaging>jar</packaging>

<name>Hermes Messenger</name>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.maciejwalkowiak.mercury.MercuryApplication</start-class>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>1.5.9</version>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<descriptor>src/main/assembly/zip.xml</descriptor>
</configuration>
</plugin>
</plugins>
</build>

</project>
25 changes: 25 additions & 0 deletions src/main/assembly/zip.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/etc</directory>
<outputDirectory>${project.artifactId}-${project.version}/config</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${project.artifactId}-${project.version}</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
16 changes: 16 additions & 0 deletions src/main/java/com/maciejwalkowiak/mercury/MercuryApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.maciejwalkowiak.mercury;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(includeFilters = @ComponentScan.Filter(Configuration.class), useDefaultFilters = false)
@EnableAutoConfiguration
public class MercuryApplication {

public static void main(String[] args) {
SpringApplication.run(MercuryApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.maciejwalkowiak.mercury.core;

import com.github.fakemongo.Fongo;
import com.mongodb.Mongo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;

@Configuration
@ComponentScan
@EnableAsync
class CoreConfiguration {
@Configuration
@ConditionalOnProperty(name = "mercury.db.inMemory", havingValue = "true")
static class FongoConfig {
@Bean
Mongo mongo() {
return new Fongo("mongo").getMongo();
}
}

@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.maciejwalkowiak.mercury.core;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Stream.concat;

/**
* Converts exceptions to user friendly error messages.
*
* Inspired by http://www.jayway.com/2012/09/16/improve-your-spring-rest-api-part-i/
*
* @author Maciej Walkowiak
*/
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException(MethodArgumentNotValidException ex) {
Stream<String> fieldErrorsStream = ex.getBindingResult().getFieldErrors().stream()
.map(error -> error.getField() + ", " + error.getDefaultMessage());

Stream<String> globalErrorsStream = ex.getBindingResult().getGlobalErrors().stream()
.map(error -> error.getObjectName() + ", " + error.getDefaultMessage());

List<String> errors = concat(fieldErrorsStream, globalErrorsStream).collect(Collectors.toList());

return new ErrorMessage(errors);
}

private static class ErrorMessage {
private final List<String> errors;

public ErrorMessage(List<String> errors) {
this.errors = errors;
}

public List<String> getErrors() {
return errors;
}
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/maciejwalkowiak/mercury/core/Request.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.maciejwalkowiak.mercury.core;

/**
* Base class for incoming requests data structures.
* {@see com.maciejwalkowiak.mercury.mail.common.SendMailRequest}
*
* @author Maciej Walkowiak
*/
public abstract class Request {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.maciejwalkowiak.mercury.core.api;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;

/**
* In Mercury API is dynamic and depending how application is configured some URLs are available and some are not.
* {@link com.maciejwalkowiak.mercury.core.api.ApiController} exposes an array of all available URLs with current configuration
*
* @author Maciej Walkowiak
*/
@Controller
@RequestMapping(value = "/api")
class ApiController {
private final Optional<List<HateoasController>> controllers;

@Autowired
ApiController(Optional<List<HateoasController>> controllers) {
this.controllers = controllers;
}

@RequestMapping(method = { RequestMethod.GET, RequestMethod.OPTIONS })
public HttpEntity<ApiResource> links() {
ApiResource apiResource = new ApiResource();
apiResource.add(linkTo(ApiController.class).withSelfRel());

if (controllers.isPresent()) {
controllers.get().forEach(c ->
apiResource.add(
c.links().stream()
.map(link -> new BracketsLink(link))
.collect(Collectors.toList())
)
);
}

return new HttpEntity<>(apiResource);
}

private static class ApiResource extends ResourceSupport {
}

/**
* Spring HATEOAS performs URL encoding and replaces characters "{" and "}" that are useful to show templated URL.
*
* BracketsLink is a hacky class that takes {@link org.springframework.hateoas.Link}
* from Spring HATEOAS package and brings back brackets "{" and "}"
*
* @author Maciej Walkowiak
*/
private static class BracketsLink extends Link {
public BracketsLink(Link link) {
super(link.getHref().replaceAll("%7B", "{").replaceAll("%7D", "}"), link.getRel());
}
}
}
Loading