diff --git a/pom.xml b/pom.xml index 01690d5..5ae9233 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,15 @@ provided + + org.springframework + spring-web + + + com.fasterxml.jackson.core + jackson-databind + + com.github.stefanbirkner system-rules diff --git a/src/main/java/cz/brmlab/wm/Application.java b/src/main/java/cz/brmlab/wm/Application.java index 04623d1..b6cd28c 100644 --- a/src/main/java/cz/brmlab/wm/Application.java +++ b/src/main/java/cz/brmlab/wm/Application.java @@ -2,18 +2,24 @@ package cz.brmlab.wm; import cz.brmlab.wm.utils.Exceptions.BrmException; import cz.brmlab.wm.wekan.WekanConfiguration; +import cz.brmlab.wm.wekan.pojo.card.PostCardResponse; +import cz.brmlab.wm.wekan.rest.CardPost; +import cz.brmlab.wm.wekan.rest.LoginPost; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +@Slf4j @SpringBootApplication public class Application implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(Application.class); public static void main(String[] args) { + log.trace("Starting wekan-mailer app..."); SpringApplication.run(Application.class, args); } @@ -23,7 +29,14 @@ public class Application implements CommandLineRunner { try { WekanConfiguration wekanConfiguration = new WekanConfiguration(); + LoginPost loginPost = new LoginPost(wekanConfiguration); + loginPost.login(); + + CardPost cardPost = new CardPost(loginPost.getToken(), wekanConfiguration); + PostCardResponse postCardResponse = cardPost.postCard("Test from spring", "Test card from awesome spring app.\nAnd next line"); + } catch (BrmException ex) { + log.error("Error {} encountered, shutting down!", ex.getExitCode()); System.exit(ex.getExitCode().getCode()); } } diff --git a/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java b/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java index fe95534..c41b965 100644 --- a/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java +++ b/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java @@ -4,7 +4,8 @@ import lombok.Getter; public enum ExitCode { - CONFIGURATION_MISSING(10, "Missing configuration property: "); + CONFIGURATION_MISSING(10, "Missing configuration property: "), + POST_ERROR(20, "Failed POST request, RC: "); @Getter private String reason; diff --git a/src/main/java/cz/brmlab/wm/utils/LogMarker/LogMarker.java b/src/main/java/cz/brmlab/wm/utils/LogMarker/LogMarker.java new file mode 100644 index 0000000..0547713 --- /dev/null +++ b/src/main/java/cz/brmlab/wm/utils/LogMarker/LogMarker.java @@ -0,0 +1,17 @@ +package cz.brmlab.wm.utils.LogMarker; + +import lombok.Getter; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +public enum LogMarker { + + SECRET("SECRET"); + + @Getter + private Marker marker; + + LogMarker(String markerText) { + this.marker = MarkerFactory.getMarker(markerText); + } +} diff --git a/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java b/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java index 9d69546..7ba64c5 100644 --- a/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java +++ b/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java @@ -3,20 +3,15 @@ package cz.brmlab.wm.wekan; import cz.brmlab.wm.utils.Exceptions.BrmException; import cz.brmlab.wm.utils.Exceptions.ExitCode; import lombok.Getter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +@Slf4j public class WekanConfiguration { - /** - * Class logger - */ - private static final Logger LOG = LoggerFactory.getLogger(WekanConfiguration.class); - //ENV variables for wekan private static final String WEKAN_URL = "WEKAN_URL"; private static final String WEKAN_USER = "WEKAN_USER"; @@ -33,7 +28,7 @@ public class WekanConfiguration { * @throws BrmException if some of the properties is missing in ENV variables. */ public WekanConfiguration() throws BrmException { - LOG.trace("{}() - start.", this.getClass().getSimpleName()); + log.trace("{}() - start.", this.getClass().getSimpleName()); for (String prop : properties) { checkProp(prop); @@ -44,7 +39,7 @@ public class WekanConfiguration { this.wekanBoard = System.getenv(WEKAN_TARGET_BOARD); this.wekanList = System.getenv(WEKAN_TARGET_LIST); - LOG.info("Wekan config loaded successfully."); + log.info("Wekan config loaded successfully."); } @Getter @@ -63,11 +58,11 @@ public class WekanConfiguration { private String wekanList; private void checkProp(String prop) throws BrmException { - LOG.trace("checkProp({}) - start.", prop); + log.trace("checkProp({}) - start.", prop); if (System.getenv(prop) == null) { String message = ExitCode.CONFIGURATION_MISSING.getReason() + prop; - LOG.error(message, ExitCode.CONFIGURATION_MISSING); + log.error(message, ExitCode.CONFIGURATION_MISSING); throw new BrmException(message, ExitCode.CONFIGURATION_MISSING); } } diff --git a/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardRequest.java b/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardRequest.java new file mode 100644 index 0000000..5d1deb5 --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardRequest.java @@ -0,0 +1,13 @@ +package cz.brmlab.wm.wekan.pojo.card; + +import lombok.Data; + +@Data +public class PostCardRequest { + + private String title; + private String description; + private String authorId; + private final String swimlaneId = "Default"; + +} diff --git a/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardResponse.java b/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardResponse.java new file mode 100644 index 0000000..1a47ae2 --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/pojo/card/PostCardResponse.java @@ -0,0 +1,10 @@ +package cz.brmlab.wm.wekan.pojo.card; + +import lombok.Data; + +@Data +public class PostCardResponse { + + private String _id; + +} diff --git a/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginRequest.java b/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginRequest.java new file mode 100644 index 0000000..1d812d5 --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginRequest.java @@ -0,0 +1,13 @@ +package cz.brmlab.wm.wekan.pojo.login; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class LoginRequest implements Serializable { + + private String username; + private String password; + +} diff --git a/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginToken.java b/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginToken.java new file mode 100644 index 0000000..5a1874c --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/pojo/login/LoginToken.java @@ -0,0 +1,10 @@ +package cz.brmlab.wm.wekan.pojo.login; + +import lombok.Data; + +@Data +public class LoginToken { + private String id; + private String token; + private String tokenExpires; +} diff --git a/src/main/java/cz/brmlab/wm/wekan/rest/CardPost.java b/src/main/java/cz/brmlab/wm/wekan/rest/CardPost.java new file mode 100644 index 0000000..9d1068b --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/rest/CardPost.java @@ -0,0 +1,59 @@ +package cz.brmlab.wm.wekan.rest; + +import cz.brmlab.wm.utils.Exceptions.BrmException; +import cz.brmlab.wm.utils.Exceptions.ExitCode; +import cz.brmlab.wm.wekan.WekanConfiguration; +import cz.brmlab.wm.wekan.pojo.card.PostCardRequest; +import cz.brmlab.wm.wekan.pojo.card.PostCardResponse; +import cz.brmlab.wm.wekan.pojo.login.LoginToken; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.*; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; + +@Slf4j +public class CardPost { + + private final LoginToken token; + private static final String POST_CARD_URL_TEMPLATE = "${host}/api/boards/${boardId}/lists/${listId}/cards"; + private final String postCardUrl; + + public CardPost(LoginToken token, WekanConfiguration configuration) { + log.trace("{}() - start.", this.getClass().getSimpleName()); + this.token = token; + postCardUrl = POST_CARD_URL_TEMPLATE.replace("${host}", configuration.getWekanUrl()) + .replace("${boardId}", configuration.getWekanBoard()) + .replace("${listId}", configuration.getWekanList()); + log.debug("Card post URL: {}", postCardUrl); + } + + public PostCardResponse postCard(String title, String description) throws BrmException { + log.trace("postCard({}, {}) - start.", title, description); + + PostCardRequest postCardRequest = new PostCardRequest(); + postCardRequest.setAuthorId(token.getId()); + postCardRequest.setTitle(title); + postCardRequest.setDescription(description); + + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + headers.set("Authorization", "Bearer " + token.getToken()); + HttpEntity entity = new HttpEntity<>(postCardRequest, headers); + + log.debug("Sending card: {}", postCardRequest); + try { + ResponseEntity responseEntity = restTemplate.exchange(postCardUrl, HttpMethod.POST, entity, PostCardResponse.class); + PostCardResponse postCardResponse = responseEntity.getBody(); + log.info("Card {} successfully sent - cardId: {}", title, postCardResponse != null ? postCardResponse.get_id() : null); + return postCardResponse; + } catch (HttpStatusCodeException ex) { + log.error("Unable to POST a card, status code: {}", ex.getStatusCode()); + throw new BrmException(ExitCode.POST_ERROR.getReason() + ex.getStatusCode(), ExitCode.POST_ERROR); + } + + } + +} diff --git a/src/main/java/cz/brmlab/wm/wekan/rest/LoginPost.java b/src/main/java/cz/brmlab/wm/wekan/rest/LoginPost.java new file mode 100644 index 0000000..4fa9574 --- /dev/null +++ b/src/main/java/cz/brmlab/wm/wekan/rest/LoginPost.java @@ -0,0 +1,40 @@ +package cz.brmlab.wm.wekan.rest; + +import cz.brmlab.wm.utils.LogMarker.LogMarker; +import cz.brmlab.wm.wekan.WekanConfiguration; +import cz.brmlab.wm.wekan.pojo.login.LoginRequest; +import cz.brmlab.wm.wekan.pojo.login.LoginToken; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.client.RestTemplate; + +@Slf4j +public class LoginPost { + + private final WekanConfiguration configuration; + + @Getter + private LoginToken token; + + public LoginPost(WekanConfiguration configuration) { + this.configuration = configuration; + } + + + public void login() { + log.trace("login() - start."); + + String loginUrl = configuration.getWekanUrl() + "/users/login"; + log.debug("Wekan login endpoint: {}", loginUrl); + + LoginRequest loginRequest = new LoginRequest(); + loginRequest.setUsername(configuration.getWekanUser()); + loginRequest.setPassword(configuration.getWekanPassword()); + + log.info("Sending login request..."); + RestTemplate restTemplate = new RestTemplate(); + token = restTemplate.postForObject(loginUrl, loginRequest, LoginToken.class); + log.info("Login successful, token obtained."); + log.debug(LogMarker.SECRET.getMarker(), "Token: {}", token.toString()); + } +}