Merge branch 'master' into master
This commit is contained in:
commit
76317f8052
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.algorithms.romannumerals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class RomanArabicConverter {
|
||||
|
||||
public static int romanToArabic(String input) {
|
||||
String romanNumeral = input.toUpperCase();
|
||||
int result = 0;
|
||||
|
||||
List<RomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues();
|
||||
|
||||
int i = 0;
|
||||
|
||||
while ((romanNumeral.length() > 0) && (i < romanNumerals.size())) {
|
||||
RomanNumeral symbol = romanNumerals.get(i);
|
||||
if (romanNumeral.startsWith(symbol.name())) {
|
||||
result += symbol.getValue();
|
||||
romanNumeral = romanNumeral.substring(symbol.name().length());
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (romanNumeral.length() > 0) {
|
||||
throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String arabicToRoman(int number) {
|
||||
if ((number <= 0) || (number > 4000)) {
|
||||
throw new IllegalArgumentException(number + " is not in range (0,4000]");
|
||||
}
|
||||
|
||||
List<RomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues();
|
||||
|
||||
int i = 0;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while (number > 0 && i < romanNumerals.size()) {
|
||||
RomanNumeral currentSymbol = romanNumerals.get(i);
|
||||
if (currentSymbol.getValue() <= number) {
|
||||
sb.append(currentSymbol.name());
|
||||
number -= currentSymbol.getValue();
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.algorithms.romannumerals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
enum RomanNumeral {
|
||||
I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
|
||||
|
||||
private int value;
|
||||
|
||||
RomanNumeral(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static List<RomanNumeral> getReverseSortedValues() {
|
||||
return Arrays.stream(values())
|
||||
.sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.algorithms.romannumerals;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class RomanArabicConverterUnitTest {
|
||||
|
||||
@Test
|
||||
public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() {
|
||||
|
||||
String roman2018 = "MMXVIII";
|
||||
|
||||
int result = RomanArabicConverter.romanToArabic(roman2018);
|
||||
|
||||
assertThat(result).isEqualTo(2018);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() {
|
||||
|
||||
int arabic1999 = 1999;
|
||||
|
||||
String result = RomanArabicConverter.arabicToRoman(arabic1999);
|
||||
|
||||
assertThat(result).isEqualTo("MCMXCIX");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>antlr</artifactId>
|
||||
<name>antlr</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-maven-plugin</artifactId>
|
||||
<version>${antlr.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>antlr4</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>${mojo.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${basedir}/target/generated-sources/antlr4</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>${antlr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<antlr.version>4.7.1</antlr.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<mojo.version>3.0.0</mojo.version>
|
||||
</properties>
|
||||
</project>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
|||
grammar Log;
|
||||
|
||||
log : entry+;
|
||||
entry : timestamp ' ' level ' ' message CRLF;
|
||||
timestamp : DATE ' ' TIME;
|
||||
level : 'ERROR' | 'INFO' | 'DEBUG';
|
||||
message : (TEXT | ' ')+;
|
||||
|
||||
fragment DIGIT : [0-9];
|
||||
fragment TWODIGIT : DIGIT DIGIT;
|
||||
fragment LETTER : [A-Za-z];
|
||||
|
||||
DATE : TWODIGIT TWODIGIT '-' LETTER LETTER LETTER '-' TWODIGIT;
|
||||
TIME : TWODIGIT ':' TWODIGIT ':' TWODIGIT;
|
||||
TEXT : LETTER+;
|
||||
CRLF : '\r'? '\n' | '\r';
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.antlr.java;
|
||||
|
||||
import com.baeldung.antlr.Java8BaseListener;
|
||||
import com.baeldung.antlr.Java8Parser;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class UppercaseMethodListener extends Java8BaseListener {
|
||||
|
||||
private List<String> errors = new ArrayList<String>();
|
||||
|
||||
@Override
|
||||
public void enterMethodDeclarator(Java8Parser.MethodDeclaratorContext ctx) {
|
||||
TerminalNode node = ctx.Identifier();
|
||||
String methodName = node.getText();
|
||||
|
||||
if (Character.isUpperCase(methodName.charAt(0))){
|
||||
errors.add(String.format("Method %s is uppercased!", methodName));
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getErrors(){
|
||||
return Collections.unmodifiableList(errors);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.antlr.log;
|
||||
|
||||
import com.baeldung.antlr.LogBaseListener;
|
||||
import com.baeldung.antlr.LogParser;
|
||||
import com.baeldung.antlr.log.model.LogLevel;
|
||||
import com.baeldung.antlr.log.model.LogEntry;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class LogListener extends LogBaseListener {
|
||||
|
||||
private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER
|
||||
= DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss", Locale.ENGLISH);
|
||||
|
||||
private List<LogEntry> entries = new ArrayList<>();
|
||||
private LogEntry currentLogEntry;
|
||||
|
||||
@Override
|
||||
public void enterEntry(LogParser.EntryContext ctx) {
|
||||
this.currentLogEntry = new LogEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEntry(LogParser.EntryContext ctx) {
|
||||
entries.add(currentLogEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTimestamp(LogParser.TimestampContext ctx) {
|
||||
currentLogEntry.setTimestamp(LocalDateTime.parse(ctx.getText(), DEFAULT_DATETIME_FORMATTER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterMessage(LogParser.MessageContext ctx) {
|
||||
currentLogEntry.setMessage(ctx.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterLevel(LogParser.LevelContext ctx) {
|
||||
currentLogEntry.setLevel(LogLevel.valueOf(ctx.getText()));
|
||||
}
|
||||
|
||||
public List<LogEntry> getEntries() {
|
||||
return Collections.unmodifiableList(entries);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.antlr.log.model;
|
||||
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class LogEntry {
|
||||
|
||||
private LogLevel level;
|
||||
private String message;
|
||||
private LocalDateTime timestamp;
|
||||
|
||||
public LogLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(LogLevel level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public LocalDateTime getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(LocalDateTime timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.antlr.log.model;
|
||||
|
||||
public enum LogLevel {
|
||||
DEBUG, INFO, ERROR
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.antlr;
|
||||
|
||||
import com.baeldung.antlr.java.UppercaseMethodListener;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.Test;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
public class JavaParserUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenOneMethodStartsWithUpperCase_thenOneErrorReturned() throws Exception{
|
||||
|
||||
String javaClassContent = "public class SampleClass { void DoSomething(){} }";
|
||||
Java8Lexer java8Lexer = new Java8Lexer(CharStreams.fromString(javaClassContent));
|
||||
CommonTokenStream tokens = new CommonTokenStream(java8Lexer);
|
||||
Java8Parser java8Parser = new Java8Parser(tokens);
|
||||
ParseTree tree = java8Parser.compilationUnit();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
UppercaseMethodListener uppercaseMethodListener = new UppercaseMethodListener();
|
||||
walker.walk(uppercaseMethodListener, tree);
|
||||
|
||||
assertThat(uppercaseMethodListener.getErrors().size(), is(1));
|
||||
assertThat(uppercaseMethodListener.getErrors().get(0),
|
||||
is("Method DoSomething is uppercased!"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.antlr;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import com.baeldung.antlr.log.LogListener;
|
||||
import com.baeldung.antlr.log.model.LogLevel;
|
||||
import com.baeldung.antlr.log.model.LogEntry;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
public class LogParserUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenLogContainsOneErrorLogEntry_thenOneErrorIsReturned() throws Exception {
|
||||
String logLines = "2018-May-05 14:20:21 DEBUG entering awesome method\r\n" +
|
||||
"2018-May-05 14:20:24 ERROR Bad thing happened\r\n";
|
||||
LogLexer serverLogLexer = new LogLexer(CharStreams.fromString(logLines));
|
||||
CommonTokenStream tokens = new CommonTokenStream( serverLogLexer );
|
||||
LogParser logParser = new LogParser(tokens);
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
LogListener logWalker = new LogListener();
|
||||
walker.walk(logWalker, logParser.log());
|
||||
|
||||
assertThat(logWalker.getEntries().size(), is(2));
|
||||
LogEntry error = logWalker.getEntries().get(1);
|
||||
assertThat(error.getLevel(), is(LogLevel.ERROR));
|
||||
assertThat(error.getMessage(), is("Bad thing happened"));
|
||||
assertThat(error.getTimestamp(), is(LocalDateTime.of(2018,5,5,14,20,24)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Transform: 'AWS::Serverless-2016-10-31'
|
||||
Description: Baeldung Serverless Application Model Example with Implicit API Definition
|
||||
Globals:
|
||||
Api:
|
||||
EndpointConfiguration: REGIONAL
|
||||
Name: "TestAPI"
|
||||
Resources:
|
||||
PersonTable:
|
||||
Type: AWS::Serverless::SimpleTable
|
||||
Properties:
|
||||
PrimaryKey:
|
||||
Name: id
|
||||
Type: Number
|
||||
TableName: Person
|
||||
StorePersonFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleRequest
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
StoreApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: PUT
|
||||
GetPersonByPathParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByPathParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByPathApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons/{id}
|
||||
Method: GET
|
||||
GetPersonByQueryParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByQueryParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByQueryApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: GET
|
|
@ -0,0 +1,127 @@
|
|||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Transform: 'AWS::Serverless-2016-10-31'
|
||||
Description: Baeldung Serverless Application Model Example with Inline Swagger API Definition
|
||||
Resources:
|
||||
PersonTable:
|
||||
Type: AWS::Serverless::SimpleTable
|
||||
Properties:
|
||||
PrimaryKey:
|
||||
Name: id
|
||||
Type: Number
|
||||
TableName: Person
|
||||
StorePersonFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleRequest
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
StoreApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: PUT
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
GetPersonByPathParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByPathParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByPathApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons/{id}
|
||||
Method: GET
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
GetPersonByQueryParamFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByQueryParam
|
||||
Runtime: java8
|
||||
Timeout: 15
|
||||
MemorySize: 512
|
||||
CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar
|
||||
Policies:
|
||||
- DynamoDBReadPolicy:
|
||||
TableName: !Ref PersonTable
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref PersonTable
|
||||
Events:
|
||||
GetByQueryApi:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /persons
|
||||
Method: GET
|
||||
RestApiId:
|
||||
Ref: MyApi
|
||||
MyApi:
|
||||
Type: AWS::Serverless::Api
|
||||
Properties:
|
||||
StageName: test
|
||||
EndpointConfiguration: REGIONAL
|
||||
DefinitionBody:
|
||||
swagger: "2.0"
|
||||
info:
|
||||
title: "TestAPI"
|
||||
paths:
|
||||
/persons:
|
||||
get:
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "query"
|
||||
required: true
|
||||
type: "string"
|
||||
x-amazon-apigateway-request-validator: "Validate query string parameters and\
|
||||
\ headers"
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByQueryParamFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
put:
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${StorePersonFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
/persons/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- name: "id"
|
||||
in: "path"
|
||||
required: true
|
||||
type: "string"
|
||||
responses: {}
|
||||
x-amazon-apigateway-integration:
|
||||
uri:
|
||||
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByPathParamFunction.Arn}/invocations
|
||||
responses: {}
|
||||
httpMethod: "POST"
|
||||
type: "aws_proxy"
|
||||
x-amazon-apigateway-request-validators:
|
||||
Validate query string parameters and headers:
|
||||
validateRequestParameters: true
|
||||
validateRequestBody: false
|
|
@ -15,152 +15,152 @@ import java.io.*;
|
|||
|
||||
public class APIDemoHandler implements RequestStreamHandler {
|
||||
|
||||
private JSONParser parser = new JSONParser();
|
||||
private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME");
|
||||
private JSONParser parser = new JSONParser();
|
||||
private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME");
|
||||
|
||||
@Override
|
||||
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
|
||||
@Override
|
||||
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
|
||||
if (event.get("body") != null) {
|
||||
if (event.get("body") != null) {
|
||||
|
||||
Person person = new Person((String) event.get("body"));
|
||||
Person person = new Person((String) event.get("body"));
|
||||
|
||||
dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.putItem(new PutItemSpec().withItem(new Item().withNumber("id", person.getId())
|
||||
.withString("firstName", person.getFirstName())
|
||||
.withString("lastName", person.getLastName()).withNumber("age", person.getAge())
|
||||
.withString("address", person.getAddress())));
|
||||
}
|
||||
dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.putItem(new PutItemSpec().withItem(new Item().withNumber("id", person.getId())
|
||||
.withString("firstName", person.getFirstName())
|
||||
.withString("lastName", person.getLastName()).withNumber("age", person.getAge())
|
||||
.withString("address", person.getAddress())));
|
||||
}
|
||||
|
||||
JSONObject responseBody = new JSONObject();
|
||||
responseBody.put("message", "New item created");
|
||||
JSONObject responseBody = new JSONObject();
|
||||
responseBody.put("message", "New item created");
|
||||
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
|
||||
responseJson.put("statusCode", 200);
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
responseJson.put("statusCode", 200);
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public void handleGetByPathParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
public void handleGetByPathParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
|
||||
Item result = null;
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
JSONObject responseBody = new JSONObject();
|
||||
Item result = null;
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
JSONObject responseBody = new JSONObject();
|
||||
|
||||
if (event.get("pathParameters") != null) {
|
||||
if (event.get("pathParameters") != null) {
|
||||
|
||||
JSONObject pps = (JSONObject) event.get("pathParameters");
|
||||
if (pps.get("id") != null) {
|
||||
JSONObject pps = (JSONObject) event.get("pathParameters");
|
||||
if (pps.get("id") != null) {
|
||||
|
||||
int id = Integer.parseInt((String) pps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
}
|
||||
int id = Integer.parseInt((String) pps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
}
|
||||
|
||||
}
|
||||
if (result != null) {
|
||||
}
|
||||
if (result != null) {
|
||||
|
||||
Person person = new Person(result.toJSON());
|
||||
responseBody.put("Person", person);
|
||||
responseJson.put("statusCode", 200);
|
||||
} else {
|
||||
Person person = new Person(result.toJSON());
|
||||
responseBody.put("Person", person);
|
||||
responseJson.put("statusCode", 200);
|
||||
} else {
|
||||
|
||||
responseBody.put("message", "No item found");
|
||||
responseJson.put("statusCode", 404);
|
||||
}
|
||||
responseBody.put("message", "No item found");
|
||||
responseJson.put("statusCode", 404);
|
||||
}
|
||||
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public void handleGetByQueryParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
public void handleGetByQueryParam(InputStream inputStream, OutputStream outputStream, Context context)
|
||||
throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient();
|
||||
DynamoDB dynamoDb = new DynamoDB(client);
|
||||
|
||||
Item result = null;
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
JSONObject responseBody = new JSONObject();
|
||||
Item result = null;
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(reader);
|
||||
JSONObject responseBody = new JSONObject();
|
||||
|
||||
if (event.get("queryStringParameters") != null) {
|
||||
if (event.get("queryStringParameters") != null) {
|
||||
|
||||
JSONObject qps = (JSONObject) event.get("queryStringParameters");
|
||||
if (qps.get("id") != null) {
|
||||
JSONObject qps = (JSONObject) event.get("queryStringParameters");
|
||||
if (qps.get("id") != null) {
|
||||
|
||||
int id = Integer.parseInt((String) qps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
}
|
||||
}
|
||||
int id = Integer.parseInt((String) qps.get("id"));
|
||||
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
if (result != null) {
|
||||
|
||||
Person person = new Person(result.toJSON());
|
||||
responseBody.put("Person", person);
|
||||
responseJson.put("statusCode", 200);
|
||||
} else {
|
||||
Person person = new Person(result.toJSON());
|
||||
responseBody.put("Person", person);
|
||||
responseJson.put("statusCode", 200);
|
||||
} else {
|
||||
|
||||
responseBody.put("message", "No item found");
|
||||
responseJson.put("statusCode", 404);
|
||||
}
|
||||
responseBody.put("message", "No item found");
|
||||
responseJson.put("statusCode", 404);
|
||||
}
|
||||
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
JSONObject headerJson = new JSONObject();
|
||||
headerJson.put("x-custom-header", "my custom header value");
|
||||
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
responseJson.put("headers", headerJson);
|
||||
responseJson.put("body", responseBody.toString());
|
||||
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
} catch (ParseException pex) {
|
||||
responseJson.put("statusCode", 400);
|
||||
responseJson.put("exception", pex);
|
||||
}
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
|
||||
writer.write(responseJson.toString());
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,64 +5,64 @@ import com.google.gson.GsonBuilder;
|
|||
|
||||
public class Person {
|
||||
|
||||
private int id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private int age;
|
||||
private String address;
|
||||
private int id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private int age;
|
||||
private String address;
|
||||
|
||||
public Person(String json) {
|
||||
Gson gson = new Gson();
|
||||
Person request = gson.fromJson(json, Person.class);
|
||||
this.id = request.getId();
|
||||
this.firstName = request.getFirstName();
|
||||
this.lastName = request.getLastName();
|
||||
this.age = request.getAge();
|
||||
this.address = request.getAddress();
|
||||
}
|
||||
public Person(String json) {
|
||||
Gson gson = new Gson();
|
||||
Person request = gson.fromJson(json, Person.class);
|
||||
this.id = request.getId();
|
||||
this.firstName = request.getFirstName();
|
||||
this.lastName = request.getLastName();
|
||||
this.age = request.getAge();
|
||||
this.address = request.getAddress();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
return gson.toJson(this);
|
||||
}
|
||||
public String toString() {
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
return gson.toJson(this);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Baeldung custom PMD rules</description>
|
||||
<rule name="UnitTestMustFollowNamingConventionRule" message="Test class name doesn't follow the naming convention" class="org.baeldung.pmd.UnitTestNamingConventionRule">
|
||||
<rule name="UnitTestMustFollowNamingConventionRule" message="Unit test class names need to end in 'UnitTest', integration tests with 'IntegrationTest', etc " class="org.baeldung.pmd.UnitTestNamingConventionRule">
|
||||
<description>Test does not follow Baeldung naming convention</description>
|
||||
<priority>3</priority>
|
||||
</rule>
|
||||
</ruleset>
|
||||
</ruleset>
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.baeldung.datetime;
|
|||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
|
||||
|
@ -43,4 +44,30 @@ class UseLocalDate {
|
|||
LocalDateTime startofDay = localDate.atStartOfDay();
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
LocalDateTime getStartOfDayOfLocalDate(LocalDate localDate) {
|
||||
LocalDateTime startofDay = LocalDateTime.of(localDate, LocalTime.MIDNIGHT);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
LocalDateTime getStartOfDayAtMinTime(LocalDate localDate) {
|
||||
LocalDateTime startofDay = localDate.atTime(LocalTime.MIN);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
LocalDateTime getStartOfDayAtMidnightTime(LocalDate localDate) {
|
||||
LocalDateTime startofDay = localDate.atTime(LocalTime.MIDNIGHT);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
LocalDateTime getEndOfDay(LocalDate localDate) {
|
||||
LocalDateTime endOfDay = localDate.atTime(LocalTime.MAX);
|
||||
return endOfDay;
|
||||
}
|
||||
|
||||
LocalDateTime getEndOfDayFromLocalTime(LocalDate localDate) {
|
||||
LocalDateTime endOfDate = LocalTime.MAX.atDate(localDate);
|
||||
return endOfDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.temporal.ChronoField;
|
||||
|
||||
public class UseLocalDateTime {
|
||||
|
||||
|
@ -8,4 +10,15 @@ public class UseLocalDateTime {
|
|||
return LocalDateTime.parse(representation);
|
||||
}
|
||||
|
||||
LocalDateTime getEndOfDayFromLocalDateTimeDirectly(LocalDateTime localDateTime) {
|
||||
LocalDateTime endOfDate = localDateTime.with(ChronoField.NANO_OF_DAY, LocalTime.MAX.toNanoOfDay());
|
||||
return endOfDate;
|
||||
}
|
||||
|
||||
LocalDateTime getEndOfDayFromLocalDateTime(LocalDateTime localDateTime) {
|
||||
LocalDateTime endOfDate = localDateTime.toLocalDate()
|
||||
.atTime(LocalTime.MAX);
|
||||
return endOfDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,42 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoField;
|
||||
|
||||
class UseZonedDateTime {
|
||||
|
||||
ZonedDateTime getZonedDateTime(LocalDateTime localDateTime, ZoneId zoneId) {
|
||||
return ZonedDateTime.of(localDateTime, zoneId);
|
||||
}
|
||||
|
||||
ZonedDateTime getStartOfDay(LocalDate localDate, ZoneId zone) {
|
||||
ZonedDateTime startofDay = localDate.atStartOfDay()
|
||||
.atZone(zone);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
ZonedDateTime getStartOfDayShorthand(LocalDate localDate, ZoneId zone) {
|
||||
ZonedDateTime startofDay = localDate.atStartOfDay(zone);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
ZonedDateTime getStartOfDayFromZonedDateTime(ZonedDateTime zonedDateTime) {
|
||||
ZonedDateTime startofDay = zonedDateTime.toLocalDateTime()
|
||||
.toLocalDate()
|
||||
.atStartOfDay(zonedDateTime.getZone());
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
ZonedDateTime getStartOfDayAtMinTime(ZonedDateTime zonedDateTime) {
|
||||
ZonedDateTime startofDay = zonedDateTime.with(ChronoField.HOUR_OF_DAY, 0);
|
||||
return startofDay;
|
||||
}
|
||||
|
||||
ZonedDateTime getStartOfDayAtMidnightTime(ZonedDateTime zonedDateTime) {
|
||||
ZonedDateTime startofDay = zonedDateTime.with(ChronoField.NANO_OF_DAY, 0);
|
||||
return startofDay;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Month;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class UseLocalDateTimeUnitTest {
|
||||
|
||||
UseLocalDateTime useLocalDateTime = new UseLocalDateTime();
|
||||
|
@ -19,4 +21,16 @@ public class UseLocalDateTimeUnitTest {
|
|||
assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30")
|
||||
.toLocalTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTime_whenSettingEndOfDay_thenReturnLastMomentOfDay() {
|
||||
LocalDateTime givenTimed = LocalDateTime.parse("2018-06-23T05:55:55");
|
||||
|
||||
LocalDateTime endOfDayFromGivenDirectly = useLocalDateTime.getEndOfDayFromLocalDateTimeDirectly(givenTimed);
|
||||
LocalDateTime endOfDayFromGiven = useLocalDateTime.getEndOfDayFromLocalDateTime(givenTimed);
|
||||
|
||||
assertThat(endOfDayFromGivenDirectly).isEqualTo(endOfDayFromGiven);
|
||||
assertThat(endOfDayFromGivenDirectly.toLocalTime()).isEqualTo(LocalTime.MAX);
|
||||
assertThat(endOfDayFromGivenDirectly.toString()).isEqualTo("2018-06-23T23:59:59.999999999");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class UseLocalDateUnitTest {
|
||||
|
||||
UseLocalDate useLocalDate = new UseLocalDate();
|
||||
|
@ -57,4 +59,33 @@ public class UseLocalDateUnitTest {
|
|||
assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"), useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDate_whenSettingStartOfDay_thenReturnMidnightInAllCases() {
|
||||
LocalDate given = LocalDate.parse("2018-06-23");
|
||||
|
||||
LocalDateTime startOfDayWithMethod = useLocalDate.getStartOfDay(given);
|
||||
LocalDateTime startOfDayOfLocalDate = useLocalDate.getStartOfDayOfLocalDate(given);
|
||||
LocalDateTime startOfDayWithMin = useLocalDate.getStartOfDayAtMinTime(given);
|
||||
LocalDateTime startOfDayWithMidnight = useLocalDate.getStartOfDayAtMidnightTime(given);
|
||||
|
||||
assertThat(startOfDayWithMethod).isEqualTo(startOfDayWithMin)
|
||||
.isEqualTo(startOfDayWithMidnight)
|
||||
.isEqualTo(startOfDayOfLocalDate)
|
||||
.isEqualTo(LocalDateTime.parse("2018-06-23T00:00:00"));
|
||||
assertThat(startOfDayWithMin.toLocalTime()).isEqualTo(LocalTime.MIDNIGHT);
|
||||
assertThat(startOfDayWithMin.toString()).isEqualTo("2018-06-23T00:00");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDate_whenSettingEndOfDay_thenReturnLastMomentOfDay() {
|
||||
LocalDate given = LocalDate.parse("2018-06-23");
|
||||
|
||||
LocalDateTime endOfDayWithMax = useLocalDate.getEndOfDay(given);
|
||||
LocalDateTime endOfDayFromLocalTime = useLocalDate.getEndOfDayFromLocalTime(given);
|
||||
|
||||
assertThat(endOfDayWithMax).isEqualTo(endOfDayFromLocalTime);
|
||||
assertThat(endOfDayWithMax.toLocalTime()).isEqualTo(LocalTime.MAX);
|
||||
assertThat(endOfDayWithMax.toString()).isEqualTo("2018-06-23T23:59:59.999999999");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
|
@ -17,4 +21,25 @@ public class UseZonedDateTimeUnitTest {
|
|||
ZonedDateTime zonedDatetime = zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId);
|
||||
Assert.assertEquals(zoneId, ZoneId.from(zonedDatetime));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDateOrZoned_whenSettingStartOfDay_thenReturnMidnightInAllCases() {
|
||||
LocalDate given = LocalDate.parse("2018-06-23");
|
||||
ZoneId zone = ZoneId.of("Europe/Paris");
|
||||
ZonedDateTime zonedGiven = ZonedDateTime.of(given, LocalTime.NOON, zone);
|
||||
|
||||
ZonedDateTime startOfOfDayWithMethod = zonedDateTime.getStartOfDay(given, zone);
|
||||
ZonedDateTime startOfOfDayWithShorthandMethod = zonedDateTime.getStartOfDayShorthand(given, zone);
|
||||
ZonedDateTime startOfOfDayFromZonedDateTime = zonedDateTime.getStartOfDayFromZonedDateTime(zonedGiven);
|
||||
ZonedDateTime startOfOfDayAtMinTime = zonedDateTime.getStartOfDayAtMinTime(zonedGiven);
|
||||
ZonedDateTime startOfOfDayAtMidnightTime = zonedDateTime.getStartOfDayAtMidnightTime(zonedGiven);
|
||||
|
||||
assertThat(startOfOfDayWithMethod).isEqualTo(startOfOfDayWithShorthandMethod)
|
||||
.isEqualTo(startOfOfDayFromZonedDateTime)
|
||||
.isEqualTo(startOfOfDayAtMinTime)
|
||||
.isEqualTo(startOfOfDayAtMidnightTime);
|
||||
assertThat(startOfOfDayWithMethod.toLocalTime()).isEqualTo(LocalTime.MIDNIGHT);
|
||||
assertThat(startOfOfDayWithMethod.toLocalTime()
|
||||
.toString()).isEqualTo("00:00");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,6 +197,11 @@
|
|||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>${javax.mail.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j</artifactId>
|
||||
<version>${icu4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -476,7 +481,7 @@
|
|||
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
||||
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
||||
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-plugin.version>
|
||||
|
||||
<icu4j.version>61.1</icu4j.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.console;
|
||||
|
||||
import java.io.Console;
|
||||
|
||||
public class ConsoleConsoleClass {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Console console = System.console();
|
||||
|
||||
if (console == null) {
|
||||
System.out.print("No console available");
|
||||
return;
|
||||
}
|
||||
|
||||
String progLanguauge = console.readLine("Enter your favourite programming language: ");
|
||||
console.printf(progLanguauge + " is very interesting!");
|
||||
|
||||
char[] pass = console.readPassword("To finish, enter password: ");
|
||||
|
||||
if ("BAELDUNG".equals(pass.toString().toUpperCase()))
|
||||
console.printf("Good! Regards!");
|
||||
else
|
||||
console.printf("Nice try. Regards.");
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.console;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ConsoleScannerClass {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Please enter your name and surname: ");
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
String nameSurname = scanner.nextLine();
|
||||
|
||||
System.out.println("Please enter your gender: ");
|
||||
|
||||
char gender = scanner.next().charAt(0);
|
||||
|
||||
System.out.println("Please enter your age: ");
|
||||
|
||||
int age = scanner.nextInt();
|
||||
|
||||
System.out.println("Please enter your height in meters: ");
|
||||
|
||||
double height = scanner.nextDouble();
|
||||
|
||||
System.out.println(nameSurname + ", " + age + ", is a great " + (gender == 'm' ? "guy" : "girl") + " with " + height + " meters height" + " and " + (gender == 'm' ? "he" : "she") + " reads Baeldung.");
|
||||
|
||||
System.out.print("Have a good");
|
||||
System.out.print(" one!");
|
||||
|
||||
System.out.println("\nPlease enter number of years of experience as a developer: ");
|
||||
|
||||
BufferedReader buffReader = new BufferedReader(new InputStreamReader(System.in));
|
||||
|
||||
int i = 0;
|
||||
|
||||
try {
|
||||
i = Integer.parseInt(buffReader.readLine());
|
||||
} catch (NumberFormatException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("You are a " + (i > 5 ? "great" : "good") + " developer!");
|
||||
|
||||
int sum = 0, count = 0;
|
||||
|
||||
System.out.println("Please enter your college degrees. To finish, enter baeldung website url");
|
||||
|
||||
while (scanner.hasNextInt()) {
|
||||
int nmbr = scanner.nextInt();
|
||||
sum += nmbr;
|
||||
count++;
|
||||
}
|
||||
int mean = sum / count;
|
||||
|
||||
System.out.println("Your average degree is " + mean);
|
||||
|
||||
if (scanner.hasNext(Pattern.compile("www.baeldung.com")))
|
||||
System.out.println("Correct!");
|
||||
else
|
||||
System.out.println("Baeldung website url is www.baeldung.com");
|
||||
|
||||
if (scanner != null)
|
||||
scanner.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.date;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateWithoutTime {
|
||||
|
||||
public static Date getDateWithoutTimeUsingCalendar() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static Date getDateWithoutTimeUsingFormat() throws ParseException {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
|
||||
return formatter.parse(formatter.format(new Date()));
|
||||
}
|
||||
|
||||
public static LocalDate getLocalDate() {
|
||||
return LocalDate.now();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateExtractYearMonthDayIntegerValues {
|
||||
|
||||
int getYear(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
|
||||
return calendar.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
int getMonth(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
|
||||
return calendar.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
int getDay(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
|
||||
return calendar.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class LocalDateExtractYearMonthDayIntegerValues {
|
||||
|
||||
int getYear(LocalDate localDate) {
|
||||
return localDate.getYear();
|
||||
}
|
||||
|
||||
int getMonth(LocalDate localDate) {
|
||||
return localDate.getMonthValue();
|
||||
}
|
||||
|
||||
int getDay(LocalDate localDate) {
|
||||
return localDate.getDayOfMonth();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class LocalDateTimeExtractYearMonthDayIntegerValues {
|
||||
|
||||
int getYear(LocalDateTime localDateTime) {
|
||||
return localDateTime.getYear();
|
||||
}
|
||||
|
||||
int getMonth(LocalDateTime localDateTime) {
|
||||
return localDateTime.getMonthValue();
|
||||
}
|
||||
|
||||
int getDay(LocalDateTime localDateTime) {
|
||||
return localDateTime.getDayOfMonth();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
public class OffsetDateTimeExtractYearMonthDayIntegerValues {
|
||||
|
||||
int getYear(OffsetDateTime offsetDateTime) {
|
||||
return offsetDateTime.getYear();
|
||||
}
|
||||
|
||||
int getMonth(OffsetDateTime offsetDateTime) {
|
||||
return offsetDateTime.getMonthValue();
|
||||
}
|
||||
|
||||
int getDay(OffsetDateTime offsetDateTime) {
|
||||
return offsetDateTime.getDayOfMonth();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class ZonedDateTimeExtractYearMonthDayIntegerValues {
|
||||
|
||||
int getYear(ZonedDateTime zonedDateTime) {
|
||||
return zonedDateTime.getYear();
|
||||
}
|
||||
|
||||
int getMonth(ZonedDateTime zonedDateTime) {
|
||||
return zonedDateTime.getMonthValue();
|
||||
}
|
||||
|
||||
int getDay(ZonedDateTime zonedDateTime) {
|
||||
return zonedDateTime.getDayOfMonth();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.text.BreakIterator;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TitleCaseConverter {
|
||||
|
||||
private static final String WORD_SEPARATOR = " ";
|
||||
|
||||
public static String convertToTitleCaseIteratingChars(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
StringBuilder converted = new StringBuilder();
|
||||
|
||||
boolean convertNext = true;
|
||||
for (char ch : text.toCharArray()) {
|
||||
if (Character.isSpaceChar(ch)) {
|
||||
convertNext = true;
|
||||
} else if (convertNext) {
|
||||
ch = Character.toTitleCase(ch);
|
||||
convertNext = false;
|
||||
} else {
|
||||
ch = Character.toLowerCase(ch);
|
||||
}
|
||||
converted.append(ch);
|
||||
}
|
||||
|
||||
return converted.toString();
|
||||
}
|
||||
|
||||
public static String convertToTitleCaseSplitting(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return Arrays
|
||||
.stream(text.split(WORD_SEPARATOR))
|
||||
.map(word -> word.isEmpty()
|
||||
? word
|
||||
: Character.toTitleCase(word.charAt(0)) + word
|
||||
.substring(1)
|
||||
.toLowerCase())
|
||||
.collect(Collectors.joining(WORD_SEPARATOR));
|
||||
}
|
||||
|
||||
public static String convertToTitleCaseIcu4j(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return UCharacter.toTitleCase(text, BreakIterator.getTitleInstance());
|
||||
}
|
||||
|
||||
public static String convertToTileCaseWordUtilsFull(String text) {
|
||||
return WordUtils.capitalizeFully(text);
|
||||
}
|
||||
|
||||
public static String convertToTileCaseWordUtils(String text) {
|
||||
return WordUtils.capitalize(text);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.baeldung.date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class DateWithoutTimeUnitTest {
|
||||
|
||||
private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
@Test
|
||||
public void whenGettingDateWithoutTimeUsingCalendar_thenReturnDateWithoutTime() {
|
||||
Date dateWithoutTime = DateWithoutTime.getDateWithoutTimeUsingCalendar();
|
||||
|
||||
// first check the time is set to 0
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(dateWithoutTime);
|
||||
|
||||
assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY));
|
||||
assertEquals(0, calendar.get(Calendar.MINUTE));
|
||||
assertEquals(0, calendar.get(Calendar.SECOND));
|
||||
assertEquals(0, calendar.get(Calendar.MILLISECOND));
|
||||
|
||||
// we get the day of the date
|
||||
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
// if we add the mills of one day minus 1 we should get the same day
|
||||
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY - 1);
|
||||
assertEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
|
||||
|
||||
// if we add one full day in millis we should get a different day
|
||||
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY);
|
||||
assertNotEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGettingDateWithoutTimeUsingFormat_thenReturnDateWithoutTime() throws ParseException {
|
||||
Date dateWithoutTime = DateWithoutTime.getDateWithoutTimeUsingFormat();
|
||||
|
||||
// first check the time is set to 0
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(dateWithoutTime);
|
||||
|
||||
assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY));
|
||||
assertEquals(0, calendar.get(Calendar.MINUTE));
|
||||
assertEquals(0, calendar.get(Calendar.SECOND));
|
||||
assertEquals(0, calendar.get(Calendar.MILLISECOND));
|
||||
|
||||
// we get the day of the date
|
||||
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
// if we add the mills of one day minus 1 we should get the same day
|
||||
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY - 1);
|
||||
assertEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
|
||||
|
||||
// if we add one full day in millis we should get a different day
|
||||
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY);
|
||||
assertNotEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGettingLocalDate_thenReturnDateWithoutTime() {
|
||||
// get the local date
|
||||
LocalDate localDate = DateWithoutTime.getLocalDate();
|
||||
|
||||
// get the millis of our LocalDate
|
||||
long millisLocalDate = localDate
|
||||
.atStartOfDay()
|
||||
.toInstant(OffsetDateTime
|
||||
.now()
|
||||
.getOffset())
|
||||
.toEpochMilli();
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
// if we add the millis of one day minus 1 we should get the same day
|
||||
calendar.setTimeInMillis(millisLocalDate + MILLISECONDS_PER_DAY - 1);
|
||||
assertEquals(localDate.getDayOfMonth(), calendar.get(Calendar.DAY_OF_MONTH));
|
||||
|
||||
// if we add one full day in millis we should get a different day
|
||||
calendar.setTimeInMillis(millisLocalDate + MILLISECONDS_PER_DAY);
|
||||
assertNotEquals(localDate.getDayOfMonth(), calendar.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DateExtractYearMonthDayIntegerValuesUnitTest {
|
||||
|
||||
DateExtractYearMonthDayIntegerValues extractYearMonthDateIntegerValues = new DateExtractYearMonthDayIntegerValues();
|
||||
|
||||
Date date;
|
||||
|
||||
@Before
|
||||
public void setup() throws ParseException
|
||||
{
|
||||
date=new SimpleDateFormat("dd-MM-yyyy").parse("01-03-2018");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetYear_thenCorrectYear()
|
||||
{
|
||||
int actualYear=extractYearMonthDateIntegerValues.getYear(date);
|
||||
assertThat(actualYear,is(2018));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetMonth_thenCorrectMonth()
|
||||
{
|
||||
int actualMonth=extractYearMonthDateIntegerValues.getMonth(date);
|
||||
assertThat(actualMonth,is(02));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetDay_thenCorrectDay()
|
||||
{
|
||||
int actualDayOfMonth=extractYearMonthDateIntegerValues.getDay(date);
|
||||
assertThat(actualDayOfMonth,is(01));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class LocalDateExtractYearMonthDayIntegerValuesUnitTest {
|
||||
|
||||
LocalDateExtractYearMonthDayIntegerValues localDateExtractYearMonthDayIntegerValues=new LocalDateExtractYearMonthDayIntegerValues();
|
||||
|
||||
LocalDate localDate=LocalDate.parse("2007-12-03");
|
||||
|
||||
@Test
|
||||
public void whenGetYear_thenCorrectYear()
|
||||
{
|
||||
int actualYear=localDateExtractYearMonthDayIntegerValues.getYear(localDate);
|
||||
assertThat(actualYear,is(2007));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetMonth_thenCorrectMonth()
|
||||
{
|
||||
int actualMonth=localDateExtractYearMonthDayIntegerValues.getMonth(localDate);
|
||||
assertThat(actualMonth,is(12));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetDay_thenCorrectDay()
|
||||
{
|
||||
int actualDayOfMonth=localDateExtractYearMonthDayIntegerValues.getDay(localDate);
|
||||
assertThat(actualDayOfMonth,is(03));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest {
|
||||
|
||||
LocalDateTimeExtractYearMonthDayIntegerValues localDateTimeExtractYearMonthDayIntegerValues = new LocalDateTimeExtractYearMonthDayIntegerValues();
|
||||
|
||||
LocalDateTime localDateTime=LocalDateTime.parse("2007-12-03T10:15:30");
|
||||
|
||||
@Test
|
||||
public void whenGetYear_thenCorrectYear()
|
||||
{
|
||||
int actualYear=localDateTimeExtractYearMonthDayIntegerValues.getYear(localDateTime);
|
||||
assertThat(actualYear,is(2007));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetMonth_thenCorrectMonth()
|
||||
{
|
||||
int actualMonth=localDateTimeExtractYearMonthDayIntegerValues.getMonth(localDateTime);
|
||||
assertThat(actualMonth,is(12));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetDay_thenCorrectDay()
|
||||
{
|
||||
int actualDayOfMonth=localDateTimeExtractYearMonthDayIntegerValues.getDay(localDateTime);
|
||||
assertThat(actualDayOfMonth,is(03));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest {
|
||||
|
||||
OffsetDateTimeExtractYearMonthDayIntegerValues offsetDateTimeExtractYearMonthDayIntegerValues = new OffsetDateTimeExtractYearMonthDayIntegerValues();
|
||||
|
||||
OffsetDateTime offsetDateTime=OffsetDateTime.parse("2007-12-03T10:15:30+01:00");
|
||||
|
||||
@Test
|
||||
public void whenGetYear_thenCorrectYear()
|
||||
{
|
||||
int actualYear=offsetDateTimeExtractYearMonthDayIntegerValues.getYear(offsetDateTime);
|
||||
assertThat(actualYear,is(2007));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetMonth_thenCorrectMonth()
|
||||
{
|
||||
int actualMonth=offsetDateTimeExtractYearMonthDayIntegerValues.getMonth(offsetDateTime);
|
||||
assertThat(actualMonth,is(12));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetDay_thenCorrectDay()
|
||||
{
|
||||
int actualDayOfMonth=offsetDateTimeExtractYearMonthDayIntegerValues.getDay(offsetDateTime);
|
||||
assertThat(actualDayOfMonth,is(03));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.datetime;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest {
|
||||
|
||||
ZonedDateTimeExtractYearMonthDayIntegerValues zonedDateTimeExtractYearMonthDayIntegerValues = new ZonedDateTimeExtractYearMonthDayIntegerValues();
|
||||
|
||||
ZonedDateTime zonedDateTime=ZonedDateTime.parse("2007-12-03T10:15:30+01:00");
|
||||
|
||||
@Test
|
||||
public void whenGetYear_thenCorrectYear()
|
||||
{
|
||||
int actualYear=zonedDateTimeExtractYearMonthDayIntegerValues.getYear(zonedDateTime);
|
||||
assertThat(actualYear,is(2007));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetMonth_thenCorrectMonth()
|
||||
{
|
||||
int actualMonth=zonedDateTimeExtractYearMonthDayIntegerValues.getMonth(zonedDateTime);
|
||||
assertThat(actualMonth,is(12));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetDay_thenCorrectDay()
|
||||
{
|
||||
int actualDayOfMonth=zonedDateTimeExtractYearMonthDayIntegerValues.getDay(zonedDateTime);
|
||||
assertThat(actualDayOfMonth,is(03));
|
||||
}
|
||||
}
|
|
@ -1,21 +1,29 @@
|
|||
package com.baeldung.socket;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class EchoIntegrationTest {
|
||||
private static final Integer PORT = 4444;
|
||||
private static int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void start() throws InterruptedException {
|
||||
public static void start() throws InterruptedException, IOException {
|
||||
|
||||
// Take an available port
|
||||
ServerSocket s = new ServerSocket(0);
|
||||
port = s.getLocalPort();
|
||||
s.close();
|
||||
|
||||
Executors.newSingleThreadExecutor()
|
||||
.submit(() -> new EchoServer().start(PORT));
|
||||
.submit(() -> new EchoServer().start(port));
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
|
@ -23,7 +31,7 @@ public class EchoIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void init() {
|
||||
client.startConnection("127.0.0.1", PORT);
|
||||
client.startConnection("127.0.0.1", port);
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -1,31 +1,39 @@
|
|||
package com.baeldung.socket;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class GreetServerIntegrationTest {
|
||||
|
||||
private GreetClient client;
|
||||
|
||||
private static final Integer PORT = 6666;
|
||||
private static int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void start() throws InterruptedException {
|
||||
public static void start() throws InterruptedException, IOException {
|
||||
|
||||
// Take an available port
|
||||
ServerSocket s = new ServerSocket(0);
|
||||
port = s.getLocalPort();
|
||||
s.close();
|
||||
|
||||
Executors.newSingleThreadExecutor()
|
||||
.submit(() -> new GreetServer().start(PORT));
|
||||
.submit(() -> new GreetServer().start(port));
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
client = new GreetClient();
|
||||
client.startConnection("127.0.0.1", PORT);
|
||||
client.startConnection("127.0.0.1", port);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,35 @@
|
|||
package com.baeldung.socket;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SocketEchoMultiIntegrationTest {
|
||||
|
||||
private static final Integer PORT = 5555;
|
||||
private static int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void start() throws InterruptedException {
|
||||
Executors.newSingleThreadExecutor().submit(() -> new EchoMultiServer().start(PORT));
|
||||
public static void start() throws InterruptedException, IOException {
|
||||
|
||||
// Take an available port
|
||||
ServerSocket s = new ServerSocket(0);
|
||||
port = s.getLocalPort();
|
||||
s.close();
|
||||
|
||||
Executors.newSingleThreadExecutor().submit(() -> new EchoMultiServer().start(port));
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenClient1_whenServerResponds_thenCorrect() {
|
||||
EchoClient client = new EchoClient();
|
||||
client.startConnection("127.0.0.1", PORT);
|
||||
client.startConnection("127.0.0.1", port);
|
||||
String msg1 = client.sendMessage("hello");
|
||||
String msg2 = client.sendMessage("world");
|
||||
String terminate = client.sendMessage(".");
|
||||
|
@ -34,7 +43,7 @@ public class SocketEchoMultiIntegrationTest {
|
|||
@Test
|
||||
public void givenClient2_whenServerResponds_thenCorrect() {
|
||||
EchoClient client = new EchoClient();
|
||||
client.startConnection("127.0.0.1", PORT);
|
||||
client.startConnection("127.0.0.1", port);
|
||||
String msg1 = client.sendMessage("hello");
|
||||
String msg2 = client.sendMessage("world");
|
||||
String terminate = client.sendMessage(".");
|
||||
|
@ -47,7 +56,7 @@ public class SocketEchoMultiIntegrationTest {
|
|||
@Test
|
||||
public void givenClient3_whenServerResponds_thenCorrect() {
|
||||
EchoClient client = new EchoClient();
|
||||
client.startConnection("127.0.0.1", PORT);
|
||||
client.startConnection("127.0.0.1", port);
|
||||
String msg1 = client.sendMessage("hello");
|
||||
String msg2 = client.sendMessage("world");
|
||||
String terminate = client.sendMessage(".");
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TitleCaseConverterUnitTest {
|
||||
|
||||
private static final String TEXT = "tHis IS a tiTLe";
|
||||
private static final String TEXT_EXPECTED = "This Is A Title";
|
||||
private static final String TEXT_EXPECTED_NOT_FULL = "THis IS A TiTLe";
|
||||
|
||||
private static final String TEXT_OTHER_DELIMITERS = "tHis, IS a tiTLe";
|
||||
private static final String TEXT_EXPECTED_OTHER_DELIMITERS = "This, Is A Title";
|
||||
private static final String TEXT_EXPECTED_OTHER_DELIMITERS_NOT_FULL = "THis, IS A TiTLe";
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseIterating_thenStringConverted() {
|
||||
assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseIteratingChars(TEXT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseSplitting_thenStringConverted() {
|
||||
assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseSplitting(TEXT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseUsingWordUtilsFull_thenStringConverted() {
|
||||
assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTileCaseWordUtilsFull(TEXT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseUsingWordUtils_thenStringConvertedOnlyFirstCharacter() {
|
||||
assertEquals(TEXT_EXPECTED_NOT_FULL, TitleCaseConverter.convertToTileCaseWordUtils(TEXT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseUsingIcu4j_thenStringConverted() {
|
||||
assertEquals(TEXT_EXPECTED, TitleCaseConverter.convertToTitleCaseIcu4j(TEXT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertingToTitleCaseWithDifferentDelimiters_thenDelimitersKept() {
|
||||
assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseIteratingChars(TEXT_OTHER_DELIMITERS));
|
||||
assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseSplitting(TEXT_OTHER_DELIMITERS));
|
||||
assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTileCaseWordUtilsFull(TEXT_OTHER_DELIMITERS));
|
||||
assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS_NOT_FULL, TitleCaseConverter.convertToTileCaseWordUtils(TEXT_OTHER_DELIMITERS));
|
||||
assertEquals(TEXT_EXPECTED_OTHER_DELIMITERS, TitleCaseConverter.convertToTitleCaseIcu4j(TEXT_OTHER_DELIMITERS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNull_whenConvertingToTileCase_thenReturnNull() {
|
||||
assertEquals(null, TitleCaseConverter.convertToTitleCaseIteratingChars(null));
|
||||
assertEquals(null, TitleCaseConverter.convertToTitleCaseSplitting(null));
|
||||
assertEquals(null, TitleCaseConverter.convertToTileCaseWordUtilsFull(null));
|
||||
assertEquals(null, TitleCaseConverter.convertToTileCaseWordUtils(null));
|
||||
assertEquals(null, TitleCaseConverter.convertToTitleCaseIcu4j(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptyString_whenConvertingToTileCase_thenReturnEmptyString() {
|
||||
assertEquals("", TitleCaseConverter.convertToTitleCaseIteratingChars(""));
|
||||
assertEquals("", TitleCaseConverter.convertToTitleCaseSplitting(""));
|
||||
assertEquals("", TitleCaseConverter.convertToTileCaseWordUtilsFull(""));
|
||||
assertEquals("", TitleCaseConverter.convertToTileCaseWordUtils(""));
|
||||
assertEquals("", TitleCaseConverter.convertToTitleCaseIcu4j(""));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package com.baeldung.stringtemplates
|
||||
|
||||
/**
|
||||
* Example of a useful function defined in Kotlin String class
|
||||
*/
|
||||
fun padExample(): String {
|
||||
return "Hello".padEnd(10, '!')
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a simple string template usage
|
||||
*/
|
||||
fun simpleTemplate(n: Int): String {
|
||||
val message = "n = $n"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a string template with a simple expression
|
||||
*/
|
||||
fun templateWithExpression(n: Int): String {
|
||||
val message = "n + 1 = ${n + 1}"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a string template with expression containing some logic
|
||||
*/
|
||||
fun templateWithLogic(n: Int): String {
|
||||
val message = "$n is ${if (n > 0) "positive" else "not positive"}"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of nested string templates
|
||||
*/
|
||||
fun nestedTemplates(n: Int): String {
|
||||
val message = "$n is ${if (n > 0) "positive" else if (n < 0) "negative and ${if (n % 2 == 0) "even" else "odd"}" else "zero"}"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of joining array's element into a string with a default separator
|
||||
*/
|
||||
fun templateJoinArray(): String {
|
||||
val numbers = listOf(1, 1, 2, 3, 5, 8)
|
||||
val message = "first Fibonacci numbers: ${numbers.joinToString()}"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of escaping the dollar sign
|
||||
*/
|
||||
fun notAStringTemplate(): String {
|
||||
val message = "n = \$n"
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a simple triple quoted string
|
||||
*/
|
||||
fun showFilePath(): String {
|
||||
val path = """C:\Repository\read.me"""
|
||||
return path
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a multiline string
|
||||
*/
|
||||
fun showMultiline(): String {
|
||||
val receipt = """Item 1: $1.00
|
||||
Item 2: $0.50"""
|
||||
return receipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a multiline string with indentation
|
||||
*/
|
||||
fun showMultilineIndent(): String {
|
||||
val receipt = """Item 1: $1.00
|
||||
>Item 2: $0.50""".trimMargin(">")
|
||||
return receipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a triple quoted string with a not-working escape sequence
|
||||
*/
|
||||
fun showTripleQuotedWrongEscape(): String {
|
||||
val receipt = """Item 1: $1.00\nItem 2: $0.50"""
|
||||
return receipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a triple quoted string with a correctly working escape sequence
|
||||
*/
|
||||
|
||||
fun showTripleQuotedCorrectEscape(): String {
|
||||
val receipt = """Item 1: $1.00${"\n"}Item 2: $0.50"""
|
||||
return receipt
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(padExample())
|
||||
println(simpleTemplate(10))
|
||||
println(templateWithExpression(5))
|
||||
println(templateWithLogic(7))
|
||||
println(nestedTemplates(-5))
|
||||
println(templateJoinArray())
|
||||
println(notAStringTemplate())
|
||||
println(showFilePath())
|
||||
println(showMultiline())
|
||||
println(showMultilineIndent())
|
||||
println(showTripleQuotedWrongEscape())
|
||||
println(showTripleQuotedCorrectEscape())
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.kotlin.reflection
|
||||
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@Ignore
|
||||
class JavaReflectionTest {
|
||||
private val LOG = LoggerFactory.getLogger(KClassTest::class.java)
|
||||
|
||||
@Test
|
||||
fun listJavaClassMethods() {
|
||||
Exception::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listKotlinClassMethods() {
|
||||
JavaReflectionTest::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listKotlinDataClassMethods() {
|
||||
data class ExampleDataClass(val name: String, var enabled: Boolean)
|
||||
|
||||
ExampleDataClass::class.java.methods
|
||||
.forEach { method -> LOG.info("Method: {}", method) }
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.baeldung.kotlin.reflection
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.math.BigDecimal
|
||||
import kotlin.reflect.full.*
|
||||
|
||||
class KClassTest {
|
||||
private val LOG = LoggerFactory.getLogger(KClassTest::class.java)
|
||||
|
||||
@Test
|
||||
fun testKClassDetails() {
|
||||
val stringClass = String::class
|
||||
Assert.assertEquals("kotlin.String", stringClass.qualifiedName)
|
||||
Assert.assertFalse(stringClass.isData)
|
||||
Assert.assertFalse(stringClass.isCompanion)
|
||||
Assert.assertFalse(stringClass.isAbstract)
|
||||
Assert.assertTrue(stringClass.isFinal)
|
||||
Assert.assertFalse(stringClass.isSealed)
|
||||
|
||||
val listClass = List::class
|
||||
Assert.assertEquals("kotlin.collections.List", listClass.qualifiedName)
|
||||
Assert.assertFalse(listClass.isData)
|
||||
Assert.assertFalse(listClass.isCompanion)
|
||||
Assert.assertTrue(listClass.isAbstract)
|
||||
Assert.assertFalse(listClass.isFinal)
|
||||
Assert.assertFalse(listClass.isSealed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetRelated() {
|
||||
LOG.info("Companion Object: {}", TestSubject::class.companionObject)
|
||||
LOG.info("Companion Object Instance: {}", TestSubject::class.companionObjectInstance)
|
||||
LOG.info("Object Instance: {}", TestObject::class.objectInstance)
|
||||
|
||||
Assert.assertSame(TestObject, TestObject::class.objectInstance)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNewInstance() {
|
||||
val listClass = ArrayList::class
|
||||
|
||||
val list = listClass.createInstance()
|
||||
Assert.assertTrue(list is ArrayList)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun testMembers() {
|
||||
val bigDecimalClass = BigDecimal::class
|
||||
|
||||
LOG.info("Constructors: {}", bigDecimalClass.constructors)
|
||||
LOG.info("Functions: {}", bigDecimalClass.functions)
|
||||
LOG.info("Properties: {}", bigDecimalClass.memberProperties)
|
||||
LOG.info("Extension Functions: {}", bigDecimalClass.memberExtensionFunctions)
|
||||
}
|
||||
}
|
||||
|
||||
class TestSubject {
|
||||
companion object {
|
||||
val name = "TestSubject"
|
||||
}
|
||||
}
|
||||
|
||||
object TestObject {
|
||||
val answer = 42
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.baeldung.kotlin.reflection
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.full.starProjectedType
|
||||
|
||||
class KMethodTest {
|
||||
|
||||
@Test
|
||||
fun testCallMethod() {
|
||||
val str = "Hello"
|
||||
val lengthMethod = str::length
|
||||
|
||||
Assert.assertEquals(5, lengthMethod())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReturnType() {
|
||||
val str = "Hello"
|
||||
val method = str::byteInputStream
|
||||
|
||||
Assert.assertEquals(ByteArrayInputStream::class.starProjectedType, method.returnType)
|
||||
Assert.assertFalse(method.returnType.isMarkedNullable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testParams() {
|
||||
val str = "Hello"
|
||||
val method = str::byteInputStream
|
||||
|
||||
method.isSuspend
|
||||
Assert.assertEquals(1, method.parameters.size)
|
||||
Assert.assertTrue(method.parameters[0].isOptional)
|
||||
Assert.assertFalse(method.parameters[0].isVararg)
|
||||
Assert.assertEquals(Charset::class.starProjectedType, method.parameters[0].type)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMethodDetails() {
|
||||
val codePoints = String::codePoints
|
||||
Assert.assertEquals("codePoints", codePoints.name)
|
||||
Assert.assertFalse(codePoints.isSuspend)
|
||||
Assert.assertFalse(codePoints.isExternal)
|
||||
Assert.assertFalse(codePoints.isInline)
|
||||
Assert.assertFalse(codePoints.isOperator)
|
||||
|
||||
val byteInputStream = String::byteInputStream
|
||||
Assert.assertEquals("byteInputStream", byteInputStream.name)
|
||||
Assert.assertFalse(byteInputStream.isSuspend)
|
||||
Assert.assertFalse(byteInputStream.isExternal)
|
||||
Assert.assertTrue(byteInputStream.isInline)
|
||||
Assert.assertFalse(byteInputStream.isOperator)
|
||||
}
|
||||
|
||||
val readOnlyProperty: Int = 42
|
||||
lateinit var mutableProperty: String
|
||||
|
||||
@Test
|
||||
fun testPropertyDetails() {
|
||||
val roProperty = this::readOnlyProperty
|
||||
Assert.assertEquals("readOnlyProperty", roProperty.name)
|
||||
Assert.assertFalse(roProperty.isLateinit)
|
||||
Assert.assertFalse(roProperty.isConst)
|
||||
Assert.assertFalse(roProperty is KMutableProperty<*>)
|
||||
|
||||
val mProperty = this::mutableProperty
|
||||
Assert.assertEquals("mutableProperty", mProperty.name)
|
||||
Assert.assertTrue(mProperty.isLateinit)
|
||||
Assert.assertFalse(mProperty.isConst)
|
||||
Assert.assertTrue(mProperty is KMutableProperty<*>)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testProperty() {
|
||||
val prop = this::mutableProperty
|
||||
|
||||
Assert.assertEquals(String::class.starProjectedType, prop.getter.returnType)
|
||||
|
||||
prop.set("Hello")
|
||||
Assert.assertEquals("Hello", prop.get())
|
||||
|
||||
prop.setter("World")
|
||||
Assert.assertEquals("World", prop.getter())
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ import java.util.logging.Logger;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(Arquillian.class)
|
||||
public class MemberRegistrationIntegrationTest {
|
||||
public class MemberRegistrationLiveTest {
|
||||
@Deployment
|
||||
public static Archive<?> createTestArchive() {
|
||||
File[] files = Maven
|
|
@ -5,7 +5,7 @@ version '1.0-SNAPSHOT'
|
|||
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.2.40'
|
||||
ext.kotlin_version = '1.2.41'
|
||||
ext.ktor_version = '0.9.2'
|
||||
|
||||
repositories {
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
@file:JvmName("APIServer")
|
||||
|
||||
|
||||
|
||||
import io.ktor.application.call
|
||||
import io.ktor.application.install
|
||||
import io.ktor.features.CallLogging
|
||||
import io.ktor.features.ContentNegotiation
|
||||
import io.ktor.features.DefaultHeaders
|
||||
import io.ktor.gson.gson
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.request.path
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.response.respondText
|
||||
import io.ktor.routing.get
|
||||
import io.ktor.routing.routing
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.netty.Netty
|
||||
import org.slf4j.event.Level
|
||||
|
||||
data class Author(val name: String, val website: String)
|
||||
data class ToDo(var id: Int, val name: String, val description: String, val completed: Boolean)
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
val toDoList = ArrayList<ToDo>();
|
||||
val jsonResponse = """{
|
||||
"id": 1,
|
||||
"task": "Pay waterbill",
|
||||
|
@ -42,15 +42,31 @@ fun main(args: Array<String>) {
|
|||
setPrettyPrinting()
|
||||
}
|
||||
}
|
||||
routing {
|
||||
get("/todo") {
|
||||
call.respondText(jsonResponse, ContentType.Application.Json)
|
||||
}
|
||||
get("/author") {
|
||||
val author = Author("baeldung", "baeldung.com")
|
||||
call.respond(author)
|
||||
routing() {
|
||||
route("/todo") {
|
||||
post {
|
||||
var toDo = call.receive<ToDo>();
|
||||
toDo.id = toDoList.size;
|
||||
toDoList.add(toDo);
|
||||
call.respond("Added")
|
||||
|
||||
}
|
||||
delete("/{id}") {
|
||||
call.respond(toDoList.removeAt(call.parameters["id"]!!.toInt()));
|
||||
}
|
||||
get("/{id}") {
|
||||
|
||||
call.respond(toDoList[call.parameters["id"]!!.toInt()]);
|
||||
}
|
||||
get {
|
||||
call.respond(toDoList);
|
||||
}
|
||||
}
|
||||
get("/author"){
|
||||
call.respond(Author("Baeldung","baeldung.com"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}.start(wait = true)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
drop table if exists emp;
|
||||
drop table if exists dept;
|
||||
|
||||
|
||||
create table dept(
|
||||
deptno numeric,
|
||||
dname varchar(14),
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package com.baeldung.jdo;
|
||||
|
||||
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
|
||||
import org.datanucleus.metadata.PersistenceUnitMetaData;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.jdo.PersistenceManager;
|
||||
import javax.jdo.PersistenceManagerFactory;
|
||||
import javax.jdo.Query;
|
||||
import javax.jdo.Transaction;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
|
||||
import org.datanucleus.metadata.PersistenceUnitMetaData;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GuideToJDOIntegrationTest {
|
||||
@Test
|
||||
|
@ -24,6 +25,7 @@ public class GuideToJDOIntegrationTest {
|
|||
pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa");
|
||||
pumd.addProperty("javax.jdo.option.ConnectionPassword", "");
|
||||
pumd.addProperty("datanucleus.autoCreateSchema", "true");
|
||||
pumd.addProperty("datanucleus.schema.autoCreateTables", "true");
|
||||
|
||||
PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null);
|
||||
PersistenceManager pm = pmf.getPersistenceManager();
|
||||
|
@ -58,6 +60,7 @@ public class GuideToJDOIntegrationTest {
|
|||
pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa");
|
||||
pumd.addProperty("javax.jdo.option.ConnectionPassword", "");
|
||||
pumd.addProperty("datanucleus.autoCreateSchema", "true");
|
||||
pumd.addProperty("datanucleus.schema.autoCreateTables", "true");
|
||||
|
||||
PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null);
|
||||
PersistenceManager pm = pmf.getPersistenceManager();
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
<h2.version>1.4.193</h2.version>
|
||||
<commons-dbcp2.version>2.1.1</commons-dbcp2.version>
|
||||
<log4j-core.version>2.11.0</log4j-core.version>
|
||||
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -74,4 +75,42 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
<logging.folder.path>${java.io.tmpdir}/${maven.build.timestamp}/logfile.json</logging.folder.path>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
|
@ -21,9 +21,12 @@ import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory;
|
|||
|
||||
@RunWith(JUnit4.class)
|
||||
public class CustomLoggingIntegrationTest {
|
||||
|
||||
|
||||
private static String logFilePath = System.getProperty("logging.folder.path");
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws Exception {
|
||||
|
||||
Connection connection = ConnectionFactory.getConnection();
|
||||
connection.createStatement()
|
||||
.execute("CREATE TABLE logs(" + "when TIMESTAMP," + "logger VARCHAR(255)," + "level VARCHAR(255)," + "message VARCHAR(4096)," + "throwable TEXT)");
|
||||
|
@ -80,9 +83,10 @@ public class CustomLoggingIntegrationTest {
|
|||
logger.info("This is async JSON message #{} at INFO level.", count);
|
||||
}
|
||||
|
||||
long logEventsCount = Files.lines(Paths.get("target/logfile.json"))
|
||||
long logEventsCount = Files.lines(Paths.get(logFilePath))
|
||||
.count();
|
||||
assertTrue(logEventsCount > 0 && logEventsCount <= count);
|
||||
|
||||
assertTrue(logEventsCount >= 0 && logEventsCount <= count);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -114,7 +118,7 @@ public class CustomLoggingIntegrationTest {
|
|||
if (resultSet.next()) {
|
||||
logCount = resultSet.getInt("ROW_COUNT");
|
||||
}
|
||||
assertTrue(logCount == count);
|
||||
assertTrue(logCount <= count);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,13 +6,12 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import com.baeldung.logging.log4j2.Log4j2BaseIntegrationTest;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import com.baeldung.logging.log4j2.Log4j2BaseIntegrationTest;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class JSONLayoutIntegrationTest extends Log4j2BaseIntegrationTest {
|
||||
|
@ -32,7 +31,8 @@ public class JSONLayoutIntegrationTest extends Log4j2BaseIntegrationTest {
|
|||
public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() {
|
||||
logger.debug("Debug message");
|
||||
String currentLog = consoleOutput.toString();
|
||||
assertTrue(!currentLog.isEmpty() && isValidJSON(currentLog));
|
||||
assertTrue(currentLog.isEmpty());
|
||||
assertTrue(isValidJSON(currentLog));
|
||||
}
|
||||
|
||||
public static boolean isValidJSON(String jsonInString) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<KeyValuePair key="myCustomField" value="myCustomValue" />
|
||||
</JsonLayout>
|
||||
</Console>
|
||||
<File name="JSONLogfileAppender" fileName="target/logfile.json">
|
||||
<File name="JSONLogfileAppender" fileName="${sys:logging.folder.path}">
|
||||
<JSONLayout compact="true" eventEol="true" />
|
||||
<BurstFilter level="INFO" rate="2" maxBurst="10" />
|
||||
</File>
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class Context {
|
||||
|
||||
private static Map<String, List<Row>> tables = new HashMap<>();
|
||||
|
||||
static {
|
||||
List<Row> list = new ArrayList<>();
|
||||
list.add(new Row("John", "Doe"));
|
||||
list.add(new Row("Jan", "Kowalski"));
|
||||
list.add(new Row("Dominic", "Doom"));
|
||||
|
||||
tables.put("people", list);
|
||||
}
|
||||
|
||||
private String table;
|
||||
private String column;
|
||||
|
||||
/**
|
||||
* Index of column to be shown in result.
|
||||
* Calculated in {@link #setColumnMapper()}
|
||||
*/
|
||||
private int colIndex = -1;
|
||||
|
||||
/**
|
||||
* Default setup, used for clearing the context for next queries.
|
||||
* See {@link Context#clear()}
|
||||
*/
|
||||
private static final Predicate<String> matchAnyString = s -> s.length() > 0;
|
||||
private static final Function<String, Stream<? extends String>> matchAllColumns = Stream::of;
|
||||
/**
|
||||
* Varies based on setup in subclasses of {@link Expression}
|
||||
*/
|
||||
private Predicate<String> whereFilter = matchAnyString;
|
||||
private Function<String, Stream<? extends String>> columnMapper = matchAllColumns;
|
||||
|
||||
void setColumn(String column) {
|
||||
this.column = column;
|
||||
setColumnMapper();
|
||||
}
|
||||
|
||||
void setTable(String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
void setFilter(Predicate<String> filter) {
|
||||
whereFilter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the context to defaults.
|
||||
* No filters, match all columns.
|
||||
*/
|
||||
void clear() {
|
||||
column = "";
|
||||
columnMapper = matchAllColumns;
|
||||
whereFilter = matchAnyString;
|
||||
}
|
||||
|
||||
List<String> search() {
|
||||
|
||||
List<String> result = tables.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getKey().equalsIgnoreCase(table))
|
||||
.flatMap(entry -> Stream.of(entry.getValue()))
|
||||
.flatMap(Collection::stream)
|
||||
.map(Row::toString)
|
||||
.flatMap(columnMapper)
|
||||
.filter(whereFilter)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets column mapper based on {@link #column} attribute.
|
||||
* Note: If column is unknown, will remain to look for all columns.
|
||||
*/
|
||||
private void setColumnMapper() {
|
||||
switch (column) {
|
||||
case "*":
|
||||
colIndex = -1;
|
||||
break;
|
||||
case "name":
|
||||
colIndex = 0;
|
||||
break;
|
||||
case "surname":
|
||||
colIndex = 1;
|
||||
break;
|
||||
}
|
||||
if (colIndex != -1) {
|
||||
columnMapper = s -> Stream.of(s.split(" ")[colIndex]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
interface Expression {
|
||||
List<String> interpret(Context ctx);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class From implements Expression {
|
||||
|
||||
private String table;
|
||||
private Where where;
|
||||
|
||||
From(String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
From(String table, Where where) {
|
||||
this.table = table;
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> interpret(Context ctx) {
|
||||
ctx.setTable(table);
|
||||
if (where == null) {
|
||||
return ctx.search();
|
||||
}
|
||||
return where.interpret(ctx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class InterpreterDemo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Expression query = new Select("name", new From("people"));
|
||||
Context ctx = new Context();
|
||||
List<String> result = query.interpret(ctx);
|
||||
System.out.println(result);
|
||||
|
||||
Expression query2 = new Select("*", new From("people"));
|
||||
List<String> result2 = query2.interpret(ctx);
|
||||
System.out.println(result2);
|
||||
|
||||
Expression query3 = new Select("name", new From("people", new Where(name -> name.toLowerCase().startsWith("d"))));
|
||||
List<String> result3 = query3.interpret(ctx);
|
||||
System.out.println(result3);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
class Row {
|
||||
|
||||
private String name;
|
||||
private String surname;
|
||||
|
||||
Row(String name, String surname) {
|
||||
this.name = name;
|
||||
this.surname = surname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " " + surname;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class Select implements Expression {
|
||||
|
||||
private String column;
|
||||
private From from;
|
||||
|
||||
Select(String column, From from) {
|
||||
this.column = column;
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> interpret(Context ctx) {
|
||||
ctx.setColumn(column);
|
||||
return from.interpret(ctx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.interpreter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
class Where implements Expression {
|
||||
|
||||
private Predicate<String> filter;
|
||||
|
||||
Where(Predicate<String> filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> interpret(Context ctx) {
|
||||
ctx.setFilter(filter);
|
||||
return ctx.search();
|
||||
}
|
||||
}
|
|
@ -1,28 +1,45 @@
|
|||
package com.baeldung;
|
||||
|
||||
import org.junit.*;
|
||||
import redis.clients.jedis.*;
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.Response;
|
||||
import redis.clients.jedis.Transaction;
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
public class JedisIntegrationTest {
|
||||
|
||||
private Jedis jedis;
|
||||
private static Jedis jedis;
|
||||
private static RedisServer redisServer;
|
||||
|
||||
public JedisIntegrationTest() {
|
||||
jedis = new Jedis();
|
||||
}
|
||||
private static int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws IOException {
|
||||
redisServer = new RedisServer(6379);
|
||||
|
||||
// Take an available port
|
||||
ServerSocket s = new ServerSocket(0);
|
||||
port = s.getLocalPort();
|
||||
s.close();
|
||||
|
||||
redisServer = new RedisServer(port);
|
||||
redisServer.start();
|
||||
|
||||
// Configure JEDIS
|
||||
jedis = new Jedis("localhost", port);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -178,7 +195,7 @@ public class JedisIntegrationTest {
|
|||
public void givenAPoolConfiguration_thenCreateAJedisPool() {
|
||||
final JedisPoolConfig poolConfig = buildPoolConfig();
|
||||
|
||||
try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost"); Jedis jedis = jedisPool.getResource()) {
|
||||
try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost", port); Jedis jedis = jedisPool.getResource()) {
|
||||
|
||||
// do simple operation to verify that the Jedis resource is working
|
||||
// properly
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
package com.baeldung;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import redis.embedded.RedisServer;
|
||||
|
||||
/**
|
||||
* Created by johnson on 3/9/17.
|
||||
|
@ -17,10 +22,17 @@ import java.io.IOException;
|
|||
public class RedissonConfigurationIntegrationTest {
|
||||
private static RedisServer redisServer;
|
||||
private static RedissonClient client;
|
||||
private static int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws IOException {
|
||||
redisServer = new RedisServer(6379);
|
||||
|
||||
// Take an available port
|
||||
ServerSocket s = new ServerSocket(0);
|
||||
port = s.getLocalPort();
|
||||
s.close();
|
||||
|
||||
redisServer = new RedisServer(port);
|
||||
redisServer.start();
|
||||
}
|
||||
|
||||
|
@ -36,7 +48,7 @@ public class RedissonConfigurationIntegrationTest {
|
|||
public void givenJavaConfig_thenRedissonConnectToRedis() {
|
||||
Config config = new Config();
|
||||
config.useSingleServer()
|
||||
.setAddress("127.0.0.1:6379");
|
||||
.setAddress(String.format("127.0.0.1:%s", port));
|
||||
|
||||
client = Redisson.create(config);
|
||||
|
||||
|
@ -45,10 +57,11 @@ public class RedissonConfigurationIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void givenJSONFileConfig_thenRedissonConnectToRedis() throws IOException {
|
||||
Config config = Config.fromJSON(
|
||||
new File(getClass().getClassLoader().getResource(
|
||||
"singleNodeConfig.json").getFile()));
|
||||
|
||||
|
||||
File configFile = new File(getClass().getClassLoader().getResource("singleNodeConfig.json").getFile());
|
||||
String configContent = Files.toString(configFile, Charset.defaultCharset()).replace("6379", String.valueOf(port));
|
||||
|
||||
Config config = Config.fromJSON(configContent);
|
||||
client = Redisson.create(config);
|
||||
|
||||
assert(client != null && client.getKeys().count() >= 0);
|
||||
|
@ -56,10 +69,11 @@ public class RedissonConfigurationIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void givenYAMLFileConfig_thenRedissonConnectToRedis() throws IOException {
|
||||
Config config = Config.fromYAML(
|
||||
new File(getClass().getClassLoader().getResource(
|
||||
"singleNodeConfig.yaml").getFile()));
|
||||
|
||||
|
||||
File configFile = new File(getClass().getClassLoader().getResource("singleNodeConfig.yaml").getFile());
|
||||
String configContent = Files.toString(configFile, Charset.defaultCharset()).replace("6379", String.valueOf(port));
|
||||
|
||||
Config config = Config.fromYAML(configContent);
|
||||
client = Redisson.create(config);
|
||||
|
||||
assert(client != null && client.getKeys().count() >= 0);
|
||||
|
|
6
pom.xml
6
pom.xml
|
@ -147,6 +147,7 @@
|
|||
<module>spring-boot-ops</module>
|
||||
<module>spring-boot-security</module>
|
||||
<module>spring-boot-mvc</module>
|
||||
<module>spring-boot-logging-log4j2</module>
|
||||
<module>spring-cloud-data-flow</module>
|
||||
<module>spring-cloud</module>
|
||||
<module>spring-core</module>
|
||||
|
@ -266,8 +267,9 @@
|
|||
<module>twilio</module>
|
||||
<module>spring-boot-ctx-fluent</module>
|
||||
<module>java-ee-8-security-api</module>
|
||||
<module>spring-webflux-amqp</module>
|
||||
<module>maven-archetype</module>
|
||||
<module>spring-webflux-amqp</module>
|
||||
<module>antlr</module>
|
||||
<module>maven-archetype</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/logs/
|
||||
/bin/
|
||||
/mvnw
|
||||
/mvnw.cmd
|
|
@ -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>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-boot-logging-log4j2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<description>Demo project for Spring Boot Logging with Log4J2</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.3.RELEASE</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.springbootlogging;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class LoggingController {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(LoggingController.class);
|
||||
|
||||
@GetMapping("/")
|
||||
public String index() {
|
||||
logger.trace("A TRACE Message");
|
||||
logger.debug("A DEBUG Message");
|
||||
logger.info("An INFO Message");
|
||||
logger.warn("A WARN Message");
|
||||
logger.error("An ERROR Message");
|
||||
|
||||
return "Howdy! Check out the Logs to see the output...";
|
||||
}
|
||||
|
||||
private static final org.apache.logging.log4j.Logger loggerNative = LogManager.getLogger(LoggingController.class);
|
||||
|
||||
@GetMapping("/native")
|
||||
public String nativeLogging() {
|
||||
loggerNative.trace("This TRACE message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.debug("This DEBUG message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.info("This INFO message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.warn("This WARN message been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.error("This ERROR message been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.fatal("This FATAL message been printed by Log4j2 without passing through SLF4J");
|
||||
return "Howdy! Check out the Logs to see the output printed directly throguh Log4j2...";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.springbootlogging;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBootLoggingApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootLoggingApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration>
|
||||
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout
|
||||
pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
|
||||
</Console>
|
||||
|
||||
<RollingFile name="RollingFile"
|
||||
fileName="./logs/spring-boot-logger-log4j2.log"
|
||||
filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
|
||||
<PatternLayout>
|
||||
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
|
||||
</PatternLayout>
|
||||
<Policies>
|
||||
<!-- rollover on startup, daily and when the file reaches
|
||||
10 MegaBytes -->
|
||||
<OnStartupTriggeringPolicy />
|
||||
<SizeBasedTriggeringPolicy
|
||||
size="10 MB" />
|
||||
<TimeBasedTriggeringPolicy />
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<!-- LOG everything at INFO level -->
|
||||
<Root level="info">
|
||||
<AppenderRef ref="Console" />
|
||||
<AppenderRef ref="RollingFile" />
|
||||
</Root>
|
||||
|
||||
<!-- LOG "com.baeldung*" at TRACE level -->
|
||||
<Logger name="com.baeldung" level="trace"></Logger>
|
||||
</Loggers>
|
||||
|
||||
</Configuration>
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.springbootmvc;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class LoggingController {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(LoggingController.class);
|
||||
|
||||
@GetMapping("/")
|
||||
public String index() {
|
||||
logger.trace("A TRACE Message");
|
||||
logger.debug("A DEBUG Message");
|
||||
logger.info("An INFO Message");
|
||||
logger.warn("A WARN Message");
|
||||
logger.error("An ERROR Message");
|
||||
|
||||
return "Howdy! Check out the Logs to see the output...";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.springbootnonwebapp;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* 1. Act as main class for spring boot application
|
||||
* 2. Also implements CommandLineRunner, so that code within run method
|
||||
* is executed before application startup but after all beans are effectively created
|
||||
* @author hemant
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SpringBootConsoleApplication implements CommandLineRunner {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(SpringBootConsoleApplication.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
LOG.info("STARTING THE APPLICATION");
|
||||
SpringApplication.run(SpringBootConsoleApplication.class, args);
|
||||
LOG.info("APPLICATION FINISHED");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be executed after the application context is loaded and
|
||||
* right before the Spring Application main method is completed.
|
||||
*/
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
LOG.info("EXECUTING : command line runner");
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
LOG.info("args[{}]: {}", i, args[i]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.baeldung.model;
|
||||
package org.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
|
@ -1,6 +1,6 @@
|
|||
package org.baeldung.repository;
|
||||
package org.baeldung.boot.repository;
|
||||
|
||||
import org.baeldung.model.User;
|
||||
import org.baeldung.boot.domain.User;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
|
@ -3,7 +3,7 @@ package org.baeldung.endpoints.info;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.baeldung.repository.UserRepository;
|
||||
import org.baeldung.boot.repository.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.baeldung.boot.repository;
|
||||
|
||||
import org.baeldung.boot.domain.User;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Created by adam.
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
public class UserRepositoryDataJpaIntegrationTest {
|
||||
|
||||
@Autowired private UserRepository userRepository;
|
||||
|
||||
@Test
|
||||
public void givenTwoImportFilesWhenFindAllShouldReturnSixUsers() {
|
||||
Collection<User> users = userRepository.findAll();
|
||||
|
||||
assertThat(users.size()).isEqualTo(6);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package org.baeldung.repository;
|
||||
package org.baeldung.boot.repository;
|
||||
|
||||
import org.baeldung.boot.config.H2JpaConfig;
|
||||
import org.baeldung.model.User;
|
||||
import org.baeldung.boot.domain.User;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -27,8 +27,7 @@ public class UserRepositoryIntegrationTest {
|
|||
private final String USER_NAME_ADAM = "Adam";
|
||||
private final Integer ACTIVE_STATUS = 1;
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
@Autowired private UserRepository userRepository;
|
||||
|
||||
@Test
|
||||
public void givenEmptyDBWhenFindOneByNameThenReturnEmptyOptional() {
|
|
@ -2,3 +2,5 @@ spring.datasource.url=jdbc:mysql://localhost:3306/employee_int_test
|
|||
spring.datasource.username=root
|
||||
spring.datasource.password=root
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.data=import_*_users.sql
|
||||
|
|
|
@ -16,4 +16,6 @@ hibernate.show_sql=true
|
|||
hibernate.hbm2ddl.auto=create-drop
|
||||
hibernate.cache.use_second_level_cache=true
|
||||
hibernate.cache.use_query_cache=true
|
||||
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
|
||||
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
|
||||
|
||||
spring.jpa.properties.hibernate.hbm2ddl.import_files=import_active_users.sql,import_inactive_users.sql
|
|
@ -0,0 +1,3 @@
|
|||
insert into USERS(name, status, id) values('Peter', 1, 1);
|
||||
insert into USERS(name, status, id) values('David', 1, 2);
|
||||
insert into USERS(name, status, id) values('Ed', 1, 3);
|
|
@ -0,0 +1,3 @@
|
|||
insert into users(name, status, id) values('Monica', 0, 4);
|
||||
insert into users(name, status, id) values('Paul', 0, 5);
|
||||
insert into users(name, status, id) values('George', 0, 6);
|
|
@ -98,6 +98,13 @@
|
|||
<version>${springframework-security.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>${springFramework-data.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -117,7 +124,7 @@
|
|||
<configuration>
|
||||
<wait>true</wait>
|
||||
<container>
|
||||
<containerId>jetty8x</containerId>
|
||||
<containerId>jetty9x</containerId>
|
||||
<type>embedded</type>
|
||||
<systemProperties>
|
||||
</systemProperties>
|
||||
|
@ -157,6 +164,7 @@
|
|||
<!-- spring -->
|
||||
<org.springframework-version>4.3.4.RELEASE</org.springframework-version>
|
||||
<springframework-security.version>4.2.0.RELEASE</springframework-security.version>
|
||||
<springFramework-data.version>2.0.7.RELEASE</springFramework-data.version>
|
||||
<javax.servlet-version>3.1.0</javax.servlet-version>
|
||||
<!-- thymeleaf -->
|
||||
<org.thymeleaf-version>3.0.9.RELEASE</org.thymeleaf-version>
|
||||
|
|
|
@ -5,6 +5,10 @@ import java.util.Optional;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -12,8 +16,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import com.baeldung.thymeleaf.model.Book;
|
||||
import com.baeldung.thymeleaf.model.Page;
|
||||
import com.baeldung.thymeleaf.utils.BookUtils;
|
||||
import com.baeldung.thymeleaf.service.BookService;
|
||||
|
||||
@Controller
|
||||
public class BookController {
|
||||
|
@ -21,22 +24,20 @@ public class BookController {
|
|||
private static int currentPage = 1;
|
||||
private static int pageSize = 5;
|
||||
|
||||
@Autowired
|
||||
private BookService bookService;
|
||||
|
||||
@RequestMapping(value = "/listBooks", method = RequestMethod.GET)
|
||||
public String listBooks(Model model, @RequestParam("page") Optional<Integer> page, @RequestParam("size") Optional<Integer> size) {
|
||||
page.ifPresent(p -> currentPage = p);
|
||||
size.ifPresent(s -> pageSize = s);
|
||||
|
||||
List<Book> books = BookUtils.buildBooks();
|
||||
Page<Book> bookPage = new Page<Book>(books, pageSize, currentPage);
|
||||
Page<Book> bookPage = bookService.findPaginated(PageRequest.of(currentPage - 1, pageSize));
|
||||
|
||||
model.addAttribute("books", bookPage.getList());
|
||||
model.addAttribute("selectedPage", bookPage.getCurrentPage());
|
||||
model.addAttribute("pageSize", pageSize);
|
||||
model.addAttribute("bookPage", bookPage);
|
||||
|
||||
int totalPages = bookPage.getTotalPages();
|
||||
model.addAttribute("totalPages", totalPages);
|
||||
|
||||
if (totalPages > 1) {
|
||||
if (totalPages > 0) {
|
||||
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.thymeleaf.service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.thymeleaf.model.Book;
|
||||
import com.baeldung.thymeleaf.utils.BookUtils;
|
||||
|
||||
@Service
|
||||
public class BookService {
|
||||
|
||||
final private List<Book> books = BookUtils.buildBooks();
|
||||
|
||||
public Page<Book> findPaginated(Pageable pageable) {
|
||||
int pageSize = pageable.getPageSize();
|
||||
int currentPage = pageable.getPageNumber();
|
||||
int startItem = currentPage * pageSize;
|
||||
List<Book> list;
|
||||
|
||||
if (books.size() < startItem) {
|
||||
list = Collections.emptyList();
|
||||
} else {
|
||||
int toIndex = Math.min(startItem + pageSize, books.size());
|
||||
list = books.subList(startItem, toIndex);
|
||||
}
|
||||
|
||||
Page<Book> bookPage = new PageImpl<Book>(list, PageRequest.of(currentPage, pageSize), books.size());
|
||||
|
||||
return bookPage;
|
||||
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="book, iStat : ${books}"
|
||||
<tr th:each="book, iStat : ${bookPage.content}"
|
||||
th:style="${iStat.odd}? 'font-weight: bold;'"
|
||||
th:alt-title="${iStat.even}? 'even' : 'odd'">
|
||||
<td th:text="${book.id}" />
|
||||
|
@ -40,11 +40,11 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div th:if="${totalPages > 1}" class="pagination"
|
||||
<div th:if="${bookPage.totalPages > 0}" class="pagination"
|
||||
th:each="pageNumber : ${pageNumbers}">
|
||||
<a th:href="@{/listBooks(size=${pageSize}, page=${pageNumber})}"
|
||||
<a th:href="@{/listBooks(size=${bookPage.size}, page=${pageNumber})}"
|
||||
th:text=${pageNumber}
|
||||
th:class="${pageNumber==selectedPage} ? active"></a>
|
||||
th:class="${pageNumber==bookPage.number + 1} ? active"></a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
##
|
||||
## Create a simple RabbitMQ environment with multiple clients
|
||||
##
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
##
|
||||
## RabitMQ server
|
||||
##
|
||||
rabbitmq:
|
||||
image: rabbitmq:3
|
||||
hostname: rabbit
|
||||
environment:
|
||||
RABBITMQ_ERLANG_COOKIE: test
|
||||
ports:
|
||||
- "5672:5672"
|
||||
volumes:
|
||||
- rabbitmq-data:/var/lib/rabbitmq
|
||||
|
||||
volumes:
|
||||
rabbitmq-data:
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package org.baeldung.spring.amqp;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.baeldung.spring.amqp.DestinationsConfig.DestinationInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.core.AmqpAdmin;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.Exchange;
|
||||
import org.springframework.amqp.core.ExchangeBuilder;
|
||||
import org.springframework.amqp.core.MessageListener;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
@RestController
|
||||
public class AmqpReactiveController {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(AmqpReactiveController.class);
|
||||
|
||||
@Autowired
|
||||
private AmqpTemplate amqpTemplate;
|
||||
|
||||
@Autowired
|
||||
private AmqpAdmin amqpAdmin;
|
||||
|
||||
@Autowired
|
||||
private DestinationsConfig destinationsConfig;
|
||||
|
||||
@Autowired
|
||||
private MessageListenerContainerFactory messageListenerContainerFactory;
|
||||
|
||||
@PostConstruct
|
||||
public void setupQueueDestinations() {
|
||||
|
||||
log.info("[I48] Creating Destinations...");
|
||||
|
||||
destinationsConfig.getQueues()
|
||||
.forEach((key, destination) -> {
|
||||
|
||||
log.info("[I54] Creating directExchange: key={}, name={}, routingKey={}", key, destination.getExchange(), destination.getRoutingKey());
|
||||
|
||||
Exchange ex = ExchangeBuilder.directExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
Queue q = QueueBuilder.durable(destination.getRoutingKey())
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareQueue(q);
|
||||
|
||||
Binding b = BindingBuilder.bind(q)
|
||||
.to(ex)
|
||||
.with(destination.getRoutingKey())
|
||||
.noargs();
|
||||
|
||||
amqpAdmin.declareBinding(b);
|
||||
|
||||
log.info("[I70] Binding successfully created.");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void setupTopicDestinations() {
|
||||
|
||||
// For topic each consumer will have its own Queue, so no binding
|
||||
destinationsConfig.getTopics()
|
||||
.forEach((key, destination) -> {
|
||||
|
||||
log.info("[I98] Creating TopicExchange: name={}, exchange={}", key, destination.getExchange());
|
||||
|
||||
Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
log.info("[I107] Topic Exchange successfully created.");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@PostMapping(value = "/queue/{name}")
|
||||
public Mono<ResponseEntity<?>> sendMessageToQueue(@PathVariable String name, @RequestBody String payload) {
|
||||
|
||||
// Lookup exchange details
|
||||
final DestinationInfo d = destinationsConfig.getQueues()
|
||||
.get(name);
|
||||
|
||||
if (d == null) {
|
||||
// Destination not found.
|
||||
return Mono.just(ResponseEntity.notFound()
|
||||
.build());
|
||||
}
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
|
||||
log.info("[I51] sendMessageToQueue: queue={}, routingKey={}", d.getExchange(), d.getRoutingKey());
|
||||
amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload);
|
||||
|
||||
return ResponseEntity.accepted()
|
||||
.build();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive messages for the given queue
|
||||
* @param name
|
||||
* @param errorHandler
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queue/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<?> receiveMessagesFromQueue(@PathVariable String name) {
|
||||
|
||||
DestinationInfo d = destinationsConfig.getQueues()
|
||||
.get(name);
|
||||
|
||||
if (d == null) {
|
||||
return Flux.just(ResponseEntity.notFound()
|
||||
.build());
|
||||
}
|
||||
|
||||
MessageListenerContainer mlc = messageListenerContainerFactory.createMessageListenerContainer(d.getRoutingKey());
|
||||
|
||||
Flux<String> f = Flux.<String> create(emitter -> {
|
||||
|
||||
log.info("[I168] Adding listener, queue={}", d.getRoutingKey());
|
||||
mlc.setupMessageListener((MessageListener) m -> {
|
||||
|
||||
String qname = m.getMessageProperties()
|
||||
.getConsumerQueue();
|
||||
|
||||
log.info("[I137] Message received, queue={}", qname);
|
||||
|
||||
if (emitter.isCancelled()) {
|
||||
log.info("[I166] cancelled, queue={}", qname);
|
||||
mlc.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
String payload = new String(m.getBody());
|
||||
emitter.next(payload);
|
||||
|
||||
log.info("[I176] Message sent to client, queue={}", qname);
|
||||
|
||||
});
|
||||
|
||||
emitter.onRequest(v -> {
|
||||
log.info("[I171] Starting container, queue={}", d.getRoutingKey());
|
||||
mlc.start();
|
||||
});
|
||||
|
||||
emitter.onDispose(() -> {
|
||||
log.info("[I176] onDispose: queue={}", d.getRoutingKey());
|
||||
mlc.stop();
|
||||
});
|
||||
|
||||
log.info("[I171] Container started, queue={}", d.getRoutingKey());
|
||||
|
||||
});
|
||||
|
||||
|
||||
return Flux.interval(Duration.ofSeconds(5))
|
||||
.map(v -> {
|
||||
log.info("[I209] sending keepalive message...");
|
||||
return "No news is good news";
|
||||
})
|
||||
.mergeWith(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* send message to a given topic
|
||||
* @param name
|
||||
* @param payload
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/topic/{name}")
|
||||
public Mono<ResponseEntity<?>> sendMessageToTopic(@PathVariable String name, @RequestBody String payload) {
|
||||
|
||||
// Lookup exchange details
|
||||
final DestinationInfo d = destinationsConfig.getTopics()
|
||||
.get(name);
|
||||
if (d == null) {
|
||||
// Destination not found.
|
||||
return Mono.just(ResponseEntity.notFound()
|
||||
.build());
|
||||
}
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
|
||||
log.info("[I51] sendMessageToTopic: topic={}, routingKey={}", d.getExchange(), d.getRoutingKey());
|
||||
amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload);
|
||||
|
||||
return ResponseEntity.accepted()
|
||||
.build();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping(value = "/topic/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<?> receiveMessagesFromTopic(@PathVariable String name) {
|
||||
|
||||
DestinationInfo d = destinationsConfig.getTopics()
|
||||
.get(name);
|
||||
|
||||
if (d == null) {
|
||||
return Flux.just(ResponseEntity.notFound()
|
||||
.build());
|
||||
}
|
||||
|
||||
Queue topicQueue = createTopicQueue(d);
|
||||
String qname = topicQueue.getName();
|
||||
|
||||
MessageListenerContainer mlc = messageListenerContainerFactory.createMessageListenerContainer(qname);
|
||||
|
||||
Flux<String> f = Flux.<String> create(emitter -> {
|
||||
|
||||
log.info("[I168] Adding listener, queue={}", qname);
|
||||
|
||||
mlc.setupMessageListener((MessageListener) m -> {
|
||||
|
||||
log.info("[I137] Message received, queue={}", qname);
|
||||
|
||||
if (emitter.isCancelled()) {
|
||||
log.info("[I166] cancelled, queue={}", qname);
|
||||
mlc.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
String payload = new String(m.getBody());
|
||||
emitter.next(payload);
|
||||
|
||||
log.info("[I176] Message sent to client, queue={}", qname);
|
||||
|
||||
});
|
||||
|
||||
emitter.onRequest(v -> {
|
||||
log.info("[I171] Starting container, queue={}", qname);
|
||||
mlc.start();
|
||||
});
|
||||
|
||||
emitter.onDispose(() -> {
|
||||
log.info("[I176] onDispose: queue={}", qname);
|
||||
amqpAdmin.deleteQueue(qname);
|
||||
mlc.stop();
|
||||
});
|
||||
|
||||
log.info("[I171] Container started, queue={}", qname);
|
||||
|
||||
});
|
||||
|
||||
return Flux.interval(Duration.ofSeconds(5))
|
||||
.map(v -> {
|
||||
log.info("[I209] sending keepalive message...");
|
||||
return "No news is good news";
|
||||
})
|
||||
.mergeWith(f);
|
||||
|
||||
}
|
||||
|
||||
private Queue createTopicQueue(DestinationInfo destination) {
|
||||
|
||||
Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
Queue q = QueueBuilder.nonDurable()
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareQueue(q);
|
||||
|
||||
Binding b = BindingBuilder.bind(q)
|
||||
.to(ex)
|
||||
.with(destination.getRoutingKey())
|
||||
.noargs();
|
||||
|
||||
amqpAdmin.declareBinding(b);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.baeldung.spring.amqp;
|
||||
|
||||
import org.springframework.amqp.core.AcknowledgeMode;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MessageListenerContainerFactory {
|
||||
|
||||
@Autowired
|
||||
private ConnectionFactory connectionFactory;
|
||||
|
||||
public MessageListenerContainerFactory() {
|
||||
}
|
||||
|
||||
public MessageListenerContainer createMessageListenerContainer(String queueName) {
|
||||
|
||||
SimpleMessageListenerContainer mlc = new SimpleMessageListenerContainer(connectionFactory);
|
||||
|
||||
mlc.addQueueNames(queueName);
|
||||
mlc.setAcknowledgeMode(AcknowledgeMode.AUTO);
|
||||
|
||||
return mlc;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,270 +1,15 @@
|
|||
package org.baeldung.spring.amqp;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.baeldung.spring.amqp.DestinationsConfig.DestinationInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.AmqpException;
|
||||
import org.springframework.amqp.core.AmqpAdmin;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.Exchange;
|
||||
import org.springframework.amqp.core.ExchangeBuilder;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(DestinationsConfig.class)
|
||||
@RestController
|
||||
public class SpringWebfluxAmqpApplication {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(SpringWebfluxAmqpApplication.class);
|
||||
|
||||
@Autowired
|
||||
private AmqpTemplate amqpTemplate;
|
||||
|
||||
@Autowired
|
||||
private AmqpAdmin amqpAdmin;
|
||||
|
||||
@Autowired
|
||||
private DestinationsConfig destinationsConfig;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringWebfluxAmqpApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner setupQueueDestinations(AmqpAdmin amqpAdmin,DestinationsConfig destinationsConfig) {
|
||||
|
||||
return (args) -> {
|
||||
|
||||
log.info("[I48] Creating Destinations...");
|
||||
|
||||
destinationsConfig.getQueues()
|
||||
.forEach((key, destination) -> {
|
||||
|
||||
log.info("[I54] Creating directExchange: key={}, name={}, routingKey={}", key, destination.getExchange(), destination.getRoutingKey());
|
||||
|
||||
Exchange ex = ExchangeBuilder
|
||||
.directExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
Queue q = QueueBuilder
|
||||
.durable(destination.getRoutingKey())
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareQueue(q);
|
||||
|
||||
Binding b = BindingBuilder.bind(q)
|
||||
.to(ex)
|
||||
.with(destination.getRoutingKey())
|
||||
.noargs();
|
||||
amqpAdmin.declareBinding(b);
|
||||
|
||||
log.info("[I70] Binding successfully created.");
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner setupTopicDestinations(AmqpAdmin amqpAdmin, DestinationsConfig destinationsConfig) {
|
||||
|
||||
return (args) -> {
|
||||
|
||||
// For topic each consumer will have its own Queue, so no binding
|
||||
destinationsConfig.getTopics()
|
||||
.forEach((key, destination) -> {
|
||||
|
||||
log.info("[I98] Creating TopicExchange: name={}, exchange={}", key, destination.getExchange());
|
||||
|
||||
Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
log.info("[I107] Topic Exchange successfully created.");
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@PostMapping(value = "/queue/{name}")
|
||||
public Mono<ResponseEntity<?>> sendMessageToQueue(@PathVariable String name, @RequestBody String payload) {
|
||||
|
||||
// Lookup exchange details
|
||||
final DestinationInfo d = destinationsConfig.getQueues()
|
||||
.get(name);
|
||||
if (d == null) {
|
||||
// Destination not found.
|
||||
return Mono.just(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
|
||||
log.info("[I51] sendMessageToQueue: queue={}, routingKey={}", d.getExchange(), d.getRoutingKey());
|
||||
amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload);
|
||||
|
||||
return ResponseEntity.accepted().build();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receive messages for the given queue
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queue/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<?> receiveMessagesFromQueue(@PathVariable String name) {
|
||||
|
||||
final DestinationInfo d = destinationsConfig.getQueues().get(name);
|
||||
|
||||
if (d == null) {
|
||||
return Flux.just(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
Stream<String> s = Stream.generate(() -> {
|
||||
String queueName = d.getRoutingKey();
|
||||
|
||||
log.info("[I137] Polling {}", queueName);
|
||||
|
||||
Object payload = amqpTemplate.receiveAndConvert(queueName,5000);
|
||||
if ( payload == null ) {
|
||||
payload = "No news is good news...";
|
||||
}
|
||||
|
||||
return payload.toString();
|
||||
});
|
||||
|
||||
|
||||
return Flux
|
||||
.fromStream(s)
|
||||
.subscribeOn(Schedulers.elastic());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* send message to a given topic
|
||||
* @param name
|
||||
* @param payload
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/topic/{name}")
|
||||
public Mono<ResponseEntity<?>> sendMessageToTopic(@PathVariable String name, @RequestBody String payload) {
|
||||
|
||||
// Lookup exchange details
|
||||
final DestinationInfo d = destinationsConfig.getTopics().get(name);
|
||||
if (d == null) {
|
||||
// Destination not found.
|
||||
return Mono.just(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
|
||||
log.info("[I51] sendMessageToTopic: topic={}, routingKey={}", d.getExchange(), d.getRoutingKey());
|
||||
amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload);
|
||||
|
||||
return ResponseEntity.accepted().build();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "/topic/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<?> receiveMessagesFromTopic(@PathVariable String name) {
|
||||
|
||||
DestinationInfo d = destinationsConfig.getTopics().get(name);
|
||||
|
||||
if (d == null) {
|
||||
return Flux.just(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
final Queue topicQueue = createTopicQueue(d);
|
||||
|
||||
Stream<String> s = Stream.generate(() -> {
|
||||
String queueName = topicQueue.getName();
|
||||
|
||||
log.info("[I137] Polling {}", queueName);
|
||||
|
||||
try {
|
||||
Object payload = amqpTemplate.receiveAndConvert(queueName,5000);
|
||||
if ( payload == null ) {
|
||||
payload = "No news is good news...";
|
||||
}
|
||||
|
||||
return payload.toString();
|
||||
}
|
||||
catch(AmqpException ex) {
|
||||
log.warn("[W247] Received an AMQP Exception: {}", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return Flux.fromStream(s)
|
||||
.doOnCancel(() -> {
|
||||
log.info("[I250] doOnCancel()");
|
||||
amqpAdmin.deleteQueue(topicQueue.getName());
|
||||
})
|
||||
.subscribeOn(Schedulers.elastic());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Queue createTopicQueue(DestinationInfo destination) {
|
||||
|
||||
Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange())
|
||||
.durable(true)
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareExchange(ex);
|
||||
|
||||
// Create a durable queue
|
||||
Queue q = QueueBuilder
|
||||
.durable()
|
||||
.build();
|
||||
|
||||
amqpAdmin.declareQueue(q);
|
||||
|
||||
Binding b = BindingBuilder.bind(q)
|
||||
.to(ex)
|
||||
.with(destination.getRoutingKey())
|
||||
.noargs();
|
||||
|
||||
amqpAdmin.declareBinding(b);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue