Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-14088

This commit is contained in:
amit2103
2019-04-14 23:36:44 +05:30
45 changed files with 926 additions and 61 deletions
@@ -0,0 +1,18 @@
package com.baeldung.inputstream
import java.io.InputStream
fun InputStream.readUpToChar(stopChar: Char): String {
val stringBuilder = StringBuilder()
var currentChar = this.read().toChar()
while (currentChar != stopChar) {
stringBuilder.append(currentChar)
currentChar = this.read().toChar()
if (this.available() <= 0) {
stringBuilder.append(currentChar)
break
}
}
return stringBuilder.toString()
}
@@ -0,0 +1,71 @@
package com.baeldung.inputstream
import kotlinx.io.core.use
import org.junit.Test
import java.io.BufferedReader
import java.io.File
import kotlin.test.assertEquals
class InputStreamToStringTest {
private val fileName = "src/test/resources/inputstream2string.txt"
private val fileFullContent = "Computer programming can be a hassle\r\n" +
"It's like trying to take a defended castle"
@Test
fun whenReadFileWithBufferedReader_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.bufferedReader().use(BufferedReader::readText)
assertEquals(fileFullContent, content)
}
@Test
fun whenReadFileWithBufferedReaderReadText_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val reader = BufferedReader(inputStream.reader())
var content: String
try {
content = reader.readText()
} finally {
reader.close()
}
assertEquals(fileFullContent, content)
}
@Test
fun whenReadFileWithBufferedReaderManually_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val reader = BufferedReader(inputStream.reader())
val content = StringBuilder()
try {
var line = reader.readLine()
while (line != null) {
content.append(line)
line = reader.readLine()
}
} finally {
reader.close()
}
assertEquals(fileFullContent.replace("\r\n", ""), content.toString())
}
@Test
fun whenReadFileUpToStopChar_thenPartBeforeStopCharIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.use { it.readUpToChar(' ') }
assertEquals("Computer", content)
}
@Test
fun whenReadFileWithoutContainingStopChar_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.use { it.readUpToChar('-') }
assertEquals(fileFullContent, content)
}
}
@@ -0,0 +1,2 @@
Computer programming can be a hassle
It's like trying to take a defended castle
+7
View File
@@ -32,6 +32,12 @@
<version>${scribejava.version}</version>
</dependency>
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>${tink.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -55,6 +61,7 @@
<scribejava.version>5.6.0</scribejava.version>
<spring-security-oauth2.version>2.3.3.RELEASE</spring-security-oauth2.version>
<passay.version>1.3.1</passay.version>
<tink.version>1.2.2</tink.version>
<cryptacular.version>1.2.2</cryptacular.version>
</properties>
</project>
@@ -0,0 +1,101 @@
package com.baeldung.tink;
import com.google.crypto.tink.*;
import com.google.crypto.tink.aead.AeadConfig;
import com.google.crypto.tink.aead.AeadFactory;
import com.google.crypto.tink.aead.AeadKeyTemplates;
import com.google.crypto.tink.config.TinkConfig;
import com.google.crypto.tink.hybrid.HybridDecryptFactory;
import com.google.crypto.tink.hybrid.HybridEncryptFactory;
import com.google.crypto.tink.hybrid.HybridKeyTemplates;
import com.google.crypto.tink.mac.MacFactory;
import com.google.crypto.tink.mac.MacKeyTemplates;
import com.google.crypto.tink.signature.PublicKeySignFactory;
import com.google.crypto.tink.signature.PublicKeyVerifyFactory;
import com.google.crypto.tink.signature.SignatureKeyTemplates;
import org.junit.Assert;
import org.junit.Test;
import java.security.GeneralSecurityException;
public class TinkUnitTest {
private static final String PLAINTEXT = "BAELDUNG";
private static final String DATA = "TINK";
@Test
public void givenPlaintext_whenEncryptWithAead_thenPlaintextIsEncrypted() throws GeneralSecurityException {
AeadConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.AES256_GCM);
Aead aead = AeadFactory.getPrimitive(keysetHandle);
byte[] ciphertext = aead.encrypt(PLAINTEXT.getBytes(),
DATA.getBytes());
Assert.assertNotEquals(PLAINTEXT, new String(ciphertext));
}
@Test
public void givenData_whenComputeMAC_thenVerifyMAC() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
MacKeyTemplates.HMAC_SHA256_128BITTAG);
Mac mac = MacFactory.getPrimitive(keysetHandle);
byte[] tag = mac.computeMac(DATA.getBytes());
mac.verifyMac(tag, DATA.getBytes());
}
@Test
public void givenData_whenSignData_thenVerifySignature() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
SignatureKeyTemplates.ECDSA_P256);
PublicKeySign signer = PublicKeySignFactory.getPrimitive(privateKeysetHandle);
byte[] signature = signer.sign(DATA.getBytes());
KeysetHandle publicKeysetHandle =
privateKeysetHandle.getPublicKeysetHandle();
PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive(publicKeysetHandle);
verifier.verify(signature, DATA.getBytes());
}
@Test
public void givenPlaintext_whenEncryptWithHybridEncryption_thenVerifyDecryptedIsEqual() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256);
KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle();
HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle);
HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(privateKeysetHandle);
String contextInfo = "Tink";
byte[] ciphertext = hybridEncrypt.encrypt(PLAINTEXT.getBytes(), contextInfo.getBytes());
byte[] plaintextDecrypted = hybridDecrypt.decrypt(ciphertext, contextInfo.getBytes());
Assert.assertEquals(PLAINTEXT,new String(plaintextDecrypted));
}
}
+5 -1
View File
@@ -540,7 +540,8 @@
<module>software-security/sql-injection-samples</module>
<module>tensorflow-java</module>
<module>spring-boot-flowable</module>
</modules>
</profile>
@@ -766,6 +767,7 @@
<module>xstream</module>
<module>tensorflow-java</module>
<module>spring-boot-flowable</module>
</modules>
@@ -908,6 +910,8 @@
<module>persistence-modules/spring-data-eclipselink</module>
<module>persistence-modules/spring-data-solr</module>
<module>persistence-modules/spring-hibernate-5</module>
<module>spring-boot-flowable</module>
</modules>
</profile>
+3
View File
@@ -0,0 +1,3 @@
### Relevant articles
- [Introduction to Flowable](http://www.baeldung.com/flowable)
+58
View File
@@ -0,0 +1,58 @@
<?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>
<artifactId>spring-boot-flowable</artifactId>
<packaging>war</packaging>
<name>spring-boot-flowable</name>
<description>Spring Boot Flowable Module</description>
<parent>
<artifactId>parent-boot-2</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-rest</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-actuator</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<flowable.version>6.4.1</flowable.version>
</properties>
</project>
@@ -0,0 +1,13 @@
package com.baeldung;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@@ -0,0 +1,32 @@
package com.baeldung.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.domain.Approval;
import com.baeldung.domain.Article;
import com.baeldung.service.ArticleWorkflowService;
@RestController
public class ArticleWorkflowController {
@Autowired
private ArticleWorkflowService service;
@PostMapping("/submit")
public void submit(@RequestBody Article article) {
service.startProcess(article);
}
@GetMapping("/tasks")
public List<Article> getTasks(@RequestParam String assignee) {
return service.getTasks(assignee);
}
@PostMapping("/review")
public void review(@RequestBody Approval approval) {
service.submitReview(approval);
}
}
@@ -0,0 +1,24 @@
package com.baeldung.domain;
public class Approval {
private String id;
private boolean status;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
@@ -0,0 +1,52 @@
package com.baeldung.domain;
public class Article {
private String id;
private String author;
private String url;
public Article() {
}
public Article(String author, String url) {
this.author = author;
this.url = url;
}
public Article(String id, String author, String url) {
this.id = id;
this.author = author;
this.url = url;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return ("[" + this.author + " " + this.url + "]");
}
}
@@ -0,0 +1,55 @@
package com.baeldung.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baeldung.domain.Approval;
import com.baeldung.domain.Article;
@Service
public class ArticleWorkflowService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Transactional
public void startProcess(Article article) {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("author", article.getAuthor());
variables.put("url", article.getUrl());
runtimeService.startProcessInstanceByKey("articleReview", variables);
}
@Transactional
public List<Article> getTasks(String assignee) {
List<Task> tasks = taskService.createTaskQuery()
.taskCandidateGroup(assignee)
.list();
List<Article> articles = tasks.stream()
.map(task -> {
Map<String, Object> variables = taskService.getVariables(task.getId());
return new Article(
task.getId(), (String) variables.get("author"), (String) variables.get("url"));
})
.collect(Collectors.toList());
return articles;
}
@Transactional
public void submitReview(Approval approval) {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("approved", approval.isStatus());
taskService.complete(approval.getId(), variables);
}
}
@@ -0,0 +1,10 @@
package com.baeldung.service;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
public class PublishArticleService implements JavaDelegate {
public void execute(DelegateExecution execution) {
System.out.println("Publishing the approved article.");
}
}
@@ -0,0 +1,10 @@
package com.baeldung.service;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
public class SendMailService implements JavaDelegate {
public void execute(DelegateExecution execution) {
System.out.println("Sending rejection mail to author.");
}
}
@@ -0,0 +1 @@
management.endpoint.flowable.enabled=true
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
xmlns:flowable="http://flowable.org/bpmn"
typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/processdef">
<process id="articleReview"
name="A simple process for article review." isExecutable="true">
<startEvent id="start" />
<sequenceFlow sourceRef="start" targetRef="reviewArticle" />
<userTask id="reviewArticle"
name="Review the submitted tutorial"
flowable:candidateGroups="editors" />
<sequenceFlow sourceRef="reviewArticle"
targetRef="decision" />
<exclusiveGateway id="decision" />
<sequenceFlow sourceRef="decision"
targetRef="tutorialApproved">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${approved}
]]>
</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="decision"
targetRef="tutorialRejected">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${!approved}
]]>
</conditionExpression>
</sequenceFlow>
<serviceTask id="tutorialApproved"
name="Publish the approved tutorial."
flowable:class="com.sapient.learning.service.PublishArticleService" />
<sequenceFlow sourceRef="tutorialApproved"
targetRef="end" />
<serviceTask id="tutorialRejected"
name="Send out rejection email"
flowable:class="com.sapient.learning.service.SendMailService" />
<sequenceFlow sourceRef="tutorialRejected"
targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
@@ -0,0 +1,40 @@
package com.baeldung.processes;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.test.Deployment;
import org.flowable.spring.impl.test.FlowableSpringExtension;
import org.flowable.task.api.Task;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(FlowableSpringExtension.class)
@ExtendWith(SpringExtension.class)
public class ArticleWorkflowUnitTest {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Test
@Deployment(resources = { "processes/article-workflow.bpmn20.xml" })
void articleApprovalTest() {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("author", "[email protected]");
variables.put("url", "http://baeldung.com/dummy");
runtimeService.startProcessInstanceByKey("articleReview", variables);
Task task = taskService.createTaskQuery()
.singleResult();
assertEquals("Review the submitted tutorial", task.getName());
variables.put("approved", true);
taskService.complete(task.getId(), variables);
assertEquals(0, runtimeService.createProcessInstanceQuery()
.count());
}
}
@@ -0,0 +1,21 @@
package com.baeldung.rest;
public class GitHubUser {
private String login;
public GitHubUser() {
super();
}
// API
public String getLogin() {
return login;
}
public void setLogin(final String login) {
this.login = login;
}
}
@@ -1,4 +1,4 @@
package org.baeldung.rest;
package com.baeldung.rest;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.hamcrest.Matchers.equalTo;
@@ -0,0 +1,21 @@
package com.baeldung.rest;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class RetrieveUtil {
// API
public static <T> T retrieveResourceFromResponse(final HttpResponse response, final Class<T> clazz) throws IOException {
final String jsonFromResponse = EntityUtils.toString(response.getEntity());
final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.readValue(jsonFromResponse, clazz);
}
}
@@ -1,4 +1,4 @@
package org.baeldung;
package com.baeldung.spring.cloud.config.client;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -6,12 +6,15 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.baeldung.spring.cloud.config.client.ConfigClient;
/**
*
* The app needs the server running on port 8888. Can be started with docker
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ConfigClient.class)
@WebAppConfiguration
public class SpringContextIntegrationTest {
public class SpringContextLiveTest {
@Test
public void contextLoads() {
}
@@ -6,16 +6,10 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
/**
*
* The context will load successfully with some properties provided by docker
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ConfigServer.class)
@WebAppConfiguration
public class SpringContextLiveTest {
public class SpringContextIntegrationTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
@@ -0,0 +1,2 @@
### This should be provided by the docker config
spring.cloud.config.server.git.uri=classpath:.
@@ -4,5 +4,6 @@ spring.datasource.maxIdle=5
spring.datasource.minIdle=2
spring.datasource.initialSize=5
spring.datasource.removeAbandoned=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
@@ -1,4 +1,4 @@
package org.baeldung;
package com.baeldung.spring.cloud.connectors.heroku;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -0,0 +1,2 @@
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
@@ -1,4 +1,4 @@
package org.baeldung;
package com.baeldung.spring.cloud.consul;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -9,10 +9,18 @@ import com.baeldung.spring.cloud.consul.discovery.DiscoveryClientApplication;
import com.baeldung.spring.cloud.consul.health.ServiceDiscoveryApplication;
import com.baeldung.spring.cloud.consul.properties.DistributedPropertiesApplication;
/**
*
* This Live test requires:
* * a Consul instance running on port 8500
* * Consul configured with particular properties (e.g. 'my.prop')
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { DiscoveryClientApplication.class, ServiceDiscoveryApplication.class,
DistributedPropertiesApplication.class })
public class SpringContextIntegrationTest {
public class SpringContextLiveTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
@@ -5,9 +5,15 @@ import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
*
* This Live Test requires:
* * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`)
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BooksApiApplication.class)
public class SpringContextIntegrationTest {
public class SpringContextLiveTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
@@ -0,0 +1,21 @@
package org.baeldung;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
*
* This Live Test requires:
* * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`)
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringCloudRestServerApplication.class)
public class SpringContextLiveTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

Some files were not shown because too many files have changed in this diff Show More