diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9c5cdb8f2d..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "testgitrepo"] - path = testgitrepo - url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/ diff --git a/algorithms/README.md b/algorithms/README.md index 50cdfbbd4f..7e37ef3ec5 100644 --- a/algorithms/README.md +++ b/algorithms/README.md @@ -22,3 +22,6 @@ - [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words) - [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations) - [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum) +- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic) +- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) +- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java index f428df45d3..a4918f674d 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java @@ -10,7 +10,7 @@ public class MonteCarloTreeSearch { private static final int WIN_SCORE = 10; private int level; - private int oponent; + private int opponent; public MonteCarloTreeSearch() { this.level = 3; @@ -32,11 +32,11 @@ public class MonteCarloTreeSearch { long start = System.currentTimeMillis(); long end = start + 60 * getMillisForCurrentLevel(); - oponent = 3 - playerNo; + opponent = 3 - playerNo; Tree tree = new Tree(); Node rootNode = tree.getRoot(); rootNode.getState().setBoard(board); - rootNode.getState().setPlayerNo(oponent); + rootNode.getState().setPlayerNo(opponent); while (System.currentTimeMillis() < end) { // Phase 1 - Selection @@ -93,7 +93,7 @@ public class MonteCarloTreeSearch { State tempState = tempNode.getState(); int boardStatus = tempState.getBoard().checkStatus(); - if (boardStatus == oponent) { + if (boardStatus == opponent) { tempNode.getParent().getState().setWinScore(Integer.MIN_VALUE); return boardStatus; } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java new file mode 100644 index 0000000000..ab0922ecf4 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java @@ -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 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 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(); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java new file mode 100644 index 0000000000..219f0b5090 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java @@ -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 getReverseSortedValues() { + return Arrays.stream(values()) + .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed()) + .collect(Collectors.toList()); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java new file mode 100644 index 0000000000..b289ec6bc9 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java @@ -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"); + } + +} diff --git a/antlr/README.md b/antlr/README.md new file mode 100644 index 0000000000..419d9ddfbb --- /dev/null +++ b/antlr/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Java with ANTLR](http://www.baeldung.com/java-antlr) diff --git a/apache-meecrowave/pom.xml b/apache-meecrowave/pom.xml new file mode 100644 index 0000000000..cf13aa1c1b --- /dev/null +++ b/apache-meecrowave/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + apache-meecrowave + 0.0.1 + apache-meecrowave + A sample REST API application with Meecrowave + + + 1.8 + 1.8 + + + + + org.apache.meecrowave + meecrowave-core + 1.2.1 + + + + org.apache.meecrowave + meecrowave-jpa + 1.2.1 + + + + com.squareup.okhttp3 + okhttp + 3.10.0 + + + org.apache.meecrowave + meecrowave-junit + 1.2.0 + test + + + + junit + junit + 4.10 + test + + + + + + + org.apache.meecrowave + meecrowave-maven-plugin + 1.2.1 + + + + \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java new file mode 100644 index 0000000000..7925e8ff99 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java @@ -0,0 +1,30 @@ +package com.baeldung.meecrowave; + +public class Article { + private String name; + private String author; + + public Article() { + } + + public Article(String name, String author) { + this.author = author; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java new file mode 100644 index 0000000000..6cb7012c64 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java @@ -0,0 +1,32 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@RequestScoped +@Path("article") +public class ArticleEndpoints { + + @Inject + ArticleService articleService; + + @GET + public Response getArticle() { + return Response.ok() + .entity(new Article("name", "author")) + .build(); + + } + + @POST + public Response createArticle(Article article) { + return Response.status(Status.CREATED) + .entity(articleService.createArticle(article)) + .build(); + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java new file mode 100644 index 0000000000..7bd6b87345 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ArticleService { + public Article createArticle(Article article) { + return article; + } +} diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java new file mode 100644 index 0000000000..2aa7d0556f --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java @@ -0,0 +1,16 @@ +package com.baeldung.meecrowave; + +import org.apache.meecrowave.Meecrowave; + +public class Server { + public static void main(String[] args) { + final Meecrowave.Builder builder = new Meecrowave.Builder(); + builder.setScanningPackageIncludes("com.baeldung.meecrowave"); + builder.setJaxrsMapping("/api/*"); + builder.setJsonpPrettify(true); + + try (Meecrowave meecrowave = new Meecrowave(builder)) { + meecrowave.bake().await(); + } + } +} diff --git a/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java new file mode 100644 index 0000000000..0dc9773490 --- /dev/null +++ b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.meecrowave; + + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.meecrowave.Meecrowave; +import org.apache.meecrowave.junit.MonoMeecrowave; +import org.apache.meecrowave.testing.ConfigurationInject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@RunWith(MonoMeecrowave.Runner.class) +public class ArticleEndpointsTest { + + @ConfigurationInject + private Meecrowave.Builder config; + private static OkHttpClient client; + + @BeforeClass + public static void setup() { + client = new OkHttpClient(); + } + + @Test + public void whenRetunedArticle_thenCorrect() throws IOException { + final String base = "http://localhost:"+config.getHttpPort(); + + Request request = new Request.Builder() + .url(base+"/article") + .build(); + Response response = client.newCall(request).execute(); + assertEquals(200, response.code()); + } +} diff --git a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java similarity index 98% rename from apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java rename to apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java index 8b5fe77c6f..eaf0271b55 100644 --- a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java +++ b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java @@ -12,7 +12,7 @@ import org.apache.solr.common.SolrDocumentList; import org.junit.Before; import org.junit.Test; -public class SolrJavaIntegrationTest { +public class SolrJavaLiveTest { private SolrJavaIntegration solrJavaIntegration; diff --git a/aws-lambda/README.md b/aws-lambda/README.md new file mode 100644 index 0000000000..921b699bdd --- /dev/null +++ b/aws-lambda/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Using AWS Lambda with API Gateway](http://www.baeldung.com/aws-lambda-api-gateway) +- [Introduction to AWS Serverless Application Model](http://www.baeldung.com/aws-serverless) diff --git a/aws-lambda/sam-templates/template-implicit.yaml b/aws-lambda/sam-templates/template-implicit.yaml new file mode 100644 index 0000000000..3e5b12763e --- /dev/null +++ b/aws-lambda/sam-templates/template-implicit.yaml @@ -0,0 +1,60 @@ +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 + GetPersonByHTTPParamFunction: + Type: AWS::Serverless::Function + Properties: + Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam + 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 + GetByQueryApi: + Type: Api + Properties: + Path: /persons + Method: GET \ No newline at end of file diff --git a/aws-lambda/sam-templates/template-inline-swagger.yaml b/aws-lambda/sam-templates/template-inline-swagger.yaml new file mode 100644 index 0000000000..8422bcead2 --- /dev/null +++ b/aws-lambda/sam-templates/template-inline-swagger.yaml @@ -0,0 +1,112 @@ +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 + GetPersonByHTTPParamFunction: + Type: AWS::Serverless::Function + Properties: + Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam + 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 + 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/${GetPersonByHTTPParamFunction.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/${GetPersonByHTTPParamFunction.Arn}/invocations + responses: {} + httpMethod: "POST" + type: "aws_proxy" + x-amazon-apigateway-request-validators: + Validate query string parameters and headers: + validateRequestParameters: true + validateRequestBody: false \ No newline at end of file diff --git a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java index 328915c028..31bcd0b952 100644 --- a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java +++ b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java @@ -15,152 +15,107 @@ 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("name", person.getName()))); + } - 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 handleGetByParam(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) { + } else if (event.get("queryStringParameters") != null) { - Person person = new Person(result.toJSON()); - responseBody.put("Person", person); - responseJson.put("statusCode", 200); - } else { + JSONObject qps = (JSONObject) event.get("queryStringParameters"); + if (qps.get("id") != null) { - responseBody.put("message", "No item found"); - responseJson.put("statusCode", 404); - } + int id = Integer.parseInt((String) qps.get("id")); + result = dynamoDb.getTable(DYNAMODB_TABLE_NAME) + .getItem("id", id); + } + } + if (result != null) { - JSONObject headerJson = new JSONObject(); - headerJson.put("x-custom-header", "my custom header value"); + Person person = new Person(result.toJSON()); + responseBody.put("Person", person); + responseJson.put("statusCode", 200); + } else { - responseJson.put("headers", headerJson); - responseJson.put("body", responseBody.toString()); + responseBody.put("message", "No item found"); + responseJson.put("statusCode", 404); + } - } catch (ParseException pex) { - responseJson.put("statusCode", 400); - responseJson.put("exception", pex); - } + JSONObject headerJson = new JSONObject(); + headerJson.put("x-custom-header", "my custom header value"); - OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); - writer.write(responseJson.toString()); - writer.close(); - } + responseJson.put("headers", headerJson); + responseJson.put("body", responseBody.toString()); - public void handleGetByQueryParam(InputStream inputStream, OutputStream outputStream, Context context) - throws IOException { - - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - JSONObject responseJson = new JSONObject(); - - AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient(); - DynamoDB dynamoDb = new DynamoDB(client); - - Item result = null; - try { - JSONObject event = (JSONObject) parser.parse(reader); - JSONObject responseBody = new JSONObject(); - - if (event.get("queryStringParameters") != 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); - } - } - - if (result != null) { - - 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); - } - - JSONObject headerJson = new JSONObject(); - headerJson.put("x-custom-header", "my custom header value"); - - responseJson.put("headers", headerJson); - responseJson.put("body", responseBody.toString()); - - } catch (ParseException pex) { - responseJson.put("statusCode", 400); - responseJson.put("exception", pex); - } - - OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); - writer.write(responseJson.toString()); - writer.close(); - } + } catch (ParseException pex) { + responseJson.put("statusCode", 400); + responseJson.put("exception", pex); + } + OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); + writer.write(responseJson.toString()); + writer.close(); + } } diff --git a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java index 3be7b261cd..9d5a371ab5 100644 --- a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java +++ b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java @@ -5,64 +5,34 @@ 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 name; - 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.name = request.getName(); + } - 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 getName() { + return name; + } - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } + public void setName(String name) { + this.name = name; + } } diff --git a/baeldung-pmd-rules.xml b/baeldung-pmd-rules.xml index 7625d68242..8175e80e19 100644 --- a/baeldung-pmd-rules.xml +++ b/baeldung-pmd-rules.xml @@ -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"> Baeldung custom PMD rules - + Test does not follow Baeldung naming convention 3 - \ No newline at end of file + diff --git a/cdi/README.md b/cdi/README.md index a27c35772a..0477ce85bd 100644 --- a/cdi/README.md +++ b/cdi/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [CDI Interceptor vs Spring AspectJ](http://www.baeldung.com/cdi-interceptor-vs-spring-aspectj) +- [An Introduction to CDI (Contexts and Dependency Injection) in Java](http://www.baeldung.com/java-ee-cdi) diff --git a/core-java-8/README.md b/core-java-8/README.md index aa6110b7b1..7993bd93d8 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -54,3 +54,5 @@ - [An Introduction to Java.util.Hashtable Class](http://www.baeldung.com/java-hash-table) - [Method Parameter Reflection in Java](http://www.baeldung.com/java-parameter-reflection) - [Java 8 Unsigned Arithmetic Support](http://www.baeldung.com/java-unsigned-arithmetic) +- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end) +- [Generalized Target-Type Inference in Java](http://www.baeldung.com/java-generalized-target-type-inference) diff --git a/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java b/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java new file mode 100644 index 0000000000..d9636656b5 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java @@ -0,0 +1,54 @@ +package com.baeldung.datetime; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.lang3.time.DateUtils; + +public class AddHoursToDate { + + public Date addHoursToJavaUtilDate(Date date, int hours) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.HOUR_OF_DAY, hours); + return calendar.getTime(); + } + + public Date addHoursToDateUsingInstant(Date date, int hours) { + return Date.from(date.toInstant() + .plus(Duration.ofHours(hours))); + } + + public LocalDateTime addHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.plusHours(hours); + } + + public LocalDateTime subtractHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.minusHours(hours); + } + + public ZonedDateTime addHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.plusHours(hours); + } + + public ZonedDateTime subtractHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.minusHours(hours); + } + + public Instant addHoursToInstant(Instant instant, int hours) { + return instant.plus(hours, ChronoUnit.HOURS); + } + + public Instant subtractHoursToInstant(Instant instant, int hours) { + return instant.minus(hours, ChronoUnit.HOURS); + } + + public Date addHoursWithApacheCommons(Date date, int hours) { + return DateUtils.addHours(date, hours); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java b/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java new file mode 100644 index 0000000000..aa34367f30 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java @@ -0,0 +1,116 @@ +package com.baeldung.datetime; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junit.Test; + +public class AddHoursToDateUnitTest { + + private final AddHoursToDate addHoursToDateObj = new AddHoursToDate(); + + @Test + public void givenJavaUtilDate_whenPositiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenNegativeHours_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndPostiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndNegativeHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenLocalDateTime_whenUsingAddHoursToLocalDateTime_thenAddHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 7, 0); + + assertThat(addHoursToDateObj.addHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenLocalDateTime_whenUsingMinusHoursToLocalDateTime_thenMinusHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 3, 0); + + assertThat(addHoursToDateObj.subtractHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingAddHoursToZonedDateTime_thenAddHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 7, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.addHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingMinusHoursToZonedDateTime_thenMinusHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 3, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.subtractHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenJavaUtilDate_whenUsingPositiveHrsAndAddHoursWithApacheCommons_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingNegativeHrsAndAddHoursWithApacheCommons_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() { + Instant actualValue = Instant.parse("2018-06-25T05:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z"); + + assertThat(addHoursToDateObj.addHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + + @Test + public void givenInstant_whenUsingSubtractHoursToInstant_thenMinusHours() { + Instant actualValue = Instant.parse("2018-06-25T07:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T05:12:35Z"); + + assertThat(addHoursToDateObj.subtractHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java new file mode 100644 index 0000000000..eef21a98c9 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.fileToBase64StringConversion; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Base64; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; + +public class FileToBase64StringConversionUnitTest { + + private String inputFilePath = "test_image.jpg"; + private String outputFilePath = "test_image_copy.jpg"; + + @Test + public void fileToBase64StringConversion() throws IOException { + //load file from /src/test/resources + ClassLoader classLoader = getClass().getClassLoader(); + File inputFile = new File(classLoader + .getResource(inputFilePath) + .getFile()); + + byte[] fileContent = FileUtils.readFileToByteArray(inputFile); + String encodedString = Base64 + .getEncoder() + .encodeToString(fileContent); + + //create output file + File outputFile = new File(inputFile + .getParentFile() + .getAbsolutePath() + File.pathSeparator + outputFilePath); + + // decode the string and write to file + byte[] decodedBytes = Base64 + .getDecoder() + .decode(encodedString); + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); + + assertTrue(FileUtils.contentEquals(inputFile, outputFile)); + } +} diff --git a/core-java-8/src/test/resources/test_image.jpg b/core-java-8/src/test/resources/test_image.jpg new file mode 100644 index 0000000000..d0db1627c9 Binary files /dev/null and b/core-java-8/src/test/resources/test_image.jpg differ diff --git a/core-java-collections/src/main/java/com/baeldung/java/list/ReverseIterator.java b/core-java-collections/src/main/java/com/baeldung/java/list/ReverseIterator.java new file mode 100644 index 0000000000..42dd543ed4 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/list/ReverseIterator.java @@ -0,0 +1,80 @@ +package com.baeldung.java.list; + +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; + +import org.apache.commons.collections4.iterators.ReverseListIterator; + +import com.google.common.collect.Lists; + +/** + * Provides methods for iterating backward over a list. + */ +public class ReverseIterator { + + /** + * Iterate using the for loop. + * + * @param list the list + */ + public void iterateUsingForLoop(final List list) { + + for (int i = list.size(); i-- > 0; ) { + System.out.println(list.get(i)); + } + } + + /** + * Iterate using the Java {@link ListIterator}. + * + * @param list the list + */ + public void iterateUsingListIterator(final List list) { + + final ListIterator listIterator = list.listIterator(list.size()); + while (listIterator.hasPrevious()) { + System.out.println(listIterator.previous()); + } + } + + /** + * Iterate using Java {@link Collections} API. + * + * @param list the list + */ + public void iterateUsingCollections(final List list) { + + Collections.reverse(list); + for (final String item : list) { + System.out.println(item); + } + } + + /** + * Iterate using Apache Commons {@link ReverseListIterator}. + * + * @param list the list + */ + public void iterateUsingApacheReverseListIterator(final List list) { + + final ReverseListIterator listIterator = new ReverseListIterator(list); + while (listIterator.hasNext()) { + System.out.println(listIterator.next()); + } + } + + /** + * Iterate using Guava {@link Lists} API. + * + * @param list the list + */ + public void iterateUsingGuava(final List list) { + + final List reversedList = Lists.reverse(list); + for (final String item : reversedList) { + System.out.println(item); + } + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/list/ReverseIteratorUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/list/ReverseIteratorUnitTest.java new file mode 100644 index 0000000000..172a2fe417 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/list/ReverseIteratorUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.java.list; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; + +import org.apache.commons.collections4.iterators.ReverseListIterator; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; + +public class ReverseIteratorUnitTest { + + private final ReverseIterator reverseIterator = new ReverseIterator(); + + private List list; + + private final String originalString = "ABCDE"; + + @BeforeEach + void setUp() { + + list = Lists.newArrayList("A", "B", "C", "D", "E"); + } + + @Test + void whenIteratingUsingForLoop_thenCorrect() { + + String reverseString = ""; + for (int i = list.size(); i-- > 0; ) { + reverseString += list.get(i); + } + assertEquals(reverseString, StringUtils.reverse(originalString)); + } + + @Test + void whenIteratingUsingListIterator_thenCorrect() { + + String reverseString = ""; + final ListIterator listIterator = list.listIterator(list.size()); + while (listIterator.hasPrevious()) { + reverseString += listIterator.previous(); + } + assertEquals(reverseString, StringUtils.reverse(originalString)); + } + + @Test + void whenIteratingUsingCollections_thenCorrect() { + + String reverseString = ""; + Collections.reverse(list); + for (final String item : list) { + reverseString += item; + } + assertEquals(reverseString, StringUtils.reverse(originalString)); + + assertEquals("E", list.get(0)); + } + + @Test + void whenIteratingUsingApacheReverseListIterator_thenCorrect() { + + String reverseString = ""; + final ReverseListIterator listIterator = new ReverseListIterator(list); + while (listIterator.hasNext()) { + reverseString += listIterator.next(); + } + assertEquals(reverseString, StringUtils.reverse(originalString)); + } + + @Test + void whenIteratingUsingGuava_thenCorrect() { + + String reverseString = ""; + final List reversedList = Lists.reverse(list); + for (final String item : reversedList) { + reverseString += item; + } + assertEquals(reverseString, StringUtils.reverse(originalString)); + + assertEquals("A", list.get(0)); + } +} \ No newline at end of file diff --git a/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java b/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java new file mode 100644 index 0000000000..63ee0f14b1 --- /dev/null +++ b/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java @@ -0,0 +1,54 @@ +package com.baeldung.symlink; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import static java.nio.file.StandardOpenOption.*; +import java.util.stream.IntStream; + +public class SymLinkExample { + + public void createSymbolicLink(Path link, Path target) throws IOException { + if (Files.exists(link)) { + Files.delete(link); + } + Files.createSymbolicLink(link, target); + } + + public void createHardLink(Path link, Path target) throws IOException { + if (Files.exists(link)) { + Files.delete(link); + } + Files.createLink(link, target); + } + + public Path createTextFile() throws IOException { + byte[] content = IntStream.range(0, 10000) + .mapToObj(i -> i + System.lineSeparator()) + .reduce("", String::concat) + .getBytes(StandardCharsets.UTF_8); + Path filePath = Paths.get(".", "target_link.txt"); + Files.write(filePath, content, CREATE, TRUNCATE_EXISTING); + return filePath; + } + + public void printLinkFiles(Path path) throws IOException { + try (DirectoryStream stream = Files.newDirectoryStream(path)) { + for (Path file : stream) { + if (Files.isDirectory(file)) { + printLinkFiles(file); + } else if (Files.isSymbolicLink(file)) { + System.out.format("File link '%s' with target '%s'%n", file, Files.readSymbolicLink(file)); + } + } + } + } + + public static void main(String[] args) throws IOException { + new SymLinkExample().printLinkFiles(Paths.get(".")); + } + +} diff --git a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java new file mode 100644 index 0000000000..803d8881b4 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.symlink; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.Test; + +public class SymLinkExampleUnitTest { + + @Test + public void whenUsingFiles_thenCreateSymbolicLink() throws IOException { + SymLinkExample example = new SymLinkExample(); + Path filePath = example.createTextFile(); + Path linkPath = Paths.get(".", "symbolic_link.txt"); + example.createSymbolicLink(linkPath, filePath); + assertTrue(Files.isSymbolicLink(linkPath)); + } + + @Test + public void whenUsingFiles_thenCreateHardLink() throws IOException { + SymLinkExample example = new SymLinkExample(); + Path filePath = example.createTextFile(); + Path linkPath = Paths.get(".", "hard_link.txt"); + example.createHardLink(linkPath, filePath); + assertFalse(Files.isSymbolicLink(linkPath)); + assertEquals(filePath.toFile() + .length(), + linkPath.toFile() + .length()); + } + +} diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java index f1bea1eefb..c49681efb8 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java @@ -14,8 +14,10 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Scanner; +import java.util.UUID; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.equalTo; @@ -111,6 +113,19 @@ public class JavaInputStreamToXUnitTest { assertThat(writer.toString(), equalTo(originalString)); } + + @Test + public final void givenUsingTempFile_whenConvertingAnInputStreamToAString_thenCorrect() throws IOException { + final String originalString = randomAlphabetic(DEFAULT_SIZE); + final InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); + + // When + Path tempFile = java.nio.file.Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp"); + java.nio.file.Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); + String result = new String(java.nio.file.Files.readAllBytes(tempFile)); + + assertThat(result, equalTo(originalString)); + } // tests - InputStream to byte[] diff --git a/core-java/README.md b/core-java/README.md index fa2d7e4cf0..16378bc169 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -160,3 +160,10 @@ - [Guide to the super Java Keyword](http://www.baeldung.com/java-super) - [Guide to the this Java Keyword](http://www.baeldung.com/java-this) - [Jagged Arrays In Java](http://www.baeldung.com/java-jagged-arrays) +- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class) +- [Extracting Year, Month and Day from Date in Java](http://www.baeldung.com/java-year-month-day) +- [Get Date Without Time in Java](http://www.baeldung.com/java-date-without-time) +- [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case) +- [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension) +- [Immutable Objects in Java](http://www.baeldung.com/java-immutable-object) +- [Console I/O in Java](http://www.baeldung.com/java-console-input-output) diff --git a/core-java/pom.xml b/core-java/pom.xml index cce714451e..cad458596b 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -10,8 +10,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -197,12 +197,7 @@ javax.mail mail ${javax.mail.version} - - - javax.mail - mail - 1.5.0-b01 - + com.ibm.icu icu4j @@ -255,6 +250,7 @@ org.apache.maven.plugins maven-jar-plugin + ${maven-jar-plugin.version} @@ -293,6 +289,7 @@ org.apache.maven.plugins maven-shade-plugin + ${maven-shade-plugin.version} @@ -314,6 +311,7 @@ com.jolira onejar-maven-plugin + ${onejar-maven-plugin.version} @@ -331,6 +329,7 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} @@ -478,6 +477,10 @@ 3.0.0-M1 1.6.0 1.5.0-b01 + 3.0.2 + 1.4.4 + 3.1.1 + 2.0.3.RELEASE 61.1 diff --git a/core-java/src/main/java/com/baeldung/console/ConsoleConsoleClass.java b/core-java/src/main/java/com/baeldung/console/ConsoleConsoleClass.java new file mode 100644 index 0000000000..a5c704345f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/console/ConsoleConsoleClass.java @@ -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."); + + } +} diff --git a/core-java/src/main/java/com/baeldung/console/ConsoleScannerClass.java b/core-java/src/main/java/com/baeldung/console/ConsoleScannerClass.java new file mode 100644 index 0000000000..7b7a7a4ade --- /dev/null +++ b/core-java/src/main/java/com/baeldung/console/ConsoleScannerClass.java @@ -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(); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/customexception/FileManager.java b/core-java/src/main/java/com/baeldung/customexception/FileManager.java new file mode 100644 index 0000000000..b6f4d960aa --- /dev/null +++ b/core-java/src/main/java/com/baeldung/customexception/FileManager.java @@ -0,0 +1,43 @@ +package com.baeldung.customexception; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; + +public class FileManager { + + public static String getFirstLine(String fileName) throws IncorrectFileNameException { + try (Scanner file = new Scanner(new File(fileName))) { + if (file.hasNextLine()) { + return file.nextLine(); + } else { + throw new IllegalArgumentException("Non readable file"); + } + } catch (FileNotFoundException err) { + if (!isCorrectFileName(fileName)) { + throw new IncorrectFileNameException("Incorrect filename : " + fileName, err); + } + // Logging etc + } catch (IllegalArgumentException err) { + if (!containsExtension(fileName)) { + throw new IncorrectFileExtensionException("Filename does not contain extension : " + fileName, err); + } + // Other error cases and logging + } + return "Default First Line"; + } + + private static boolean containsExtension(String fileName) { + if (fileName.contains(".txt") || fileName.contains(".doc")) + return true; + return false; + } + + private static boolean isCorrectFileName(String fileName) { + if (fileName.equals("wrongFileName.txt")) + return false; + else + return true; + } + +} diff --git a/core-java/src/main/java/com/baeldung/customexception/IncorrectFileExtensionException.java b/core-java/src/main/java/com/baeldung/customexception/IncorrectFileExtensionException.java new file mode 100644 index 0000000000..c6dc6d6964 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/customexception/IncorrectFileExtensionException.java @@ -0,0 +1,9 @@ +package com.baeldung.customexception; + +public class IncorrectFileExtensionException extends RuntimeException{ + private static final long serialVersionUID = 1L; + + public IncorrectFileExtensionException(String errorMessage, Throwable err) { + super(errorMessage, err); + } +} diff --git a/core-java/src/main/java/com/baeldung/customexception/IncorrectFileNameException.java b/core-java/src/main/java/com/baeldung/customexception/IncorrectFileNameException.java new file mode 100644 index 0000000000..a804cadb84 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/customexception/IncorrectFileNameException.java @@ -0,0 +1,9 @@ +package com.baeldung.customexception; + +public class IncorrectFileNameException extends Exception { + private static final long serialVersionUID = 1L; + + public IncorrectFileNameException(String errorMessage, Throwable err) { + super(errorMessage, err); + } +} diff --git a/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java new file mode 100644 index 0000000000..b557ccf31a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java @@ -0,0 +1,60 @@ +package com.baeldung.encrypt; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import java.io.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +class FileEncrypterDecrypter { + + private SecretKey secretKey; + private Cipher cipher; + + FileEncrypterDecrypter(SecretKey secretKey, String cipher) throws NoSuchPaddingException, NoSuchAlgorithmException { + this.secretKey = secretKey; + this.cipher = Cipher.getInstance(cipher); + } + + void encrypt(String content, String fileName) throws InvalidKeyException, IOException { + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] iv = cipher.getIV(); + + try ( + FileOutputStream fileOut = new FileOutputStream(fileName); + CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher) + ) { + fileOut.write(iv); + cipherOut.write(content.getBytes()); + } + + } + + String decrypt(String fileName) throws InvalidAlgorithmParameterException, InvalidKeyException, IOException { + + String content; + + try (FileInputStream fileIn = new FileInputStream(fileName)) { + byte[] fileIv = new byte[16]; + fileIn.read(fileIv); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(fileIv)); + + try ( + CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher); + InputStreamReader inputReader = new InputStreamReader(cipherIn); + BufferedReader reader = new BufferedReader(inputReader) + ) { + + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + content = sb.toString(); + } + + } + return content; + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java new file mode 100644 index 0000000000..138916ec60 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java @@ -0,0 +1,20 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Arithmetic { + + private static Logger LOGGER = LoggerFactory.getLogger(Arithmetic.class); + + public static void main(String[] args) { + + try { + int result = 30 / 0; // Trying to divide by zero + } catch (ArithmeticException e) { + LOGGER.error("ArithmeticException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java new file mode 100644 index 0000000000..93b53f284c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java @@ -0,0 +1,24 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ArrayIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(ArrayIndexOutOfBounds.class); + + public static void main(String[] args) { + + int[] nums = new int[] { 1, 2, 3 }; + + try { + int numFromNegativeIndex = nums[-1]; // Trying to access at negative index + int numFromGreaterIndex = nums[4]; // Trying to access at greater index + int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array + } catch (ArrayIndexOutOfBoundsException e) { + LOGGER.error("ArrayIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java new file mode 100644 index 0000000000..183f8f54a3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class Animal { + +} + +class Dog extends Animal { + +} + +class Lion extends Animal { + +} + +public class ClassCast { + + private static Logger LOGGER = LoggerFactory.getLogger(ClassCast.class); + + public static void main(String[] args) { + + try { + Animal animalOne = new Dog(); // At runtime the instance is dog + Dog bruno = (Dog) animalOne; // Downcasting + + Animal animalTwo = new Lion(); // At runtime the instance is animal + Dog tommy = (Dog) animalTwo; // Downcasting + } catch (ClassCastException e) { + LOGGER.error("ClassCastException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java new file mode 100644 index 0000000000..bb9e0bf4ac --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileNotFound { + + private static Logger LOGGER = LoggerFactory.getLogger(FileNotFound.class); + + public static void main(String[] args) { + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(new File("/invalid/file/location"))); + } catch (FileNotFoundException e) { + LOGGER.error("FileNotFoundException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000000..ab46c83da4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GlobalExceptionHandler { + + public static void main(String[] args) { + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + new GlobalExceptionHandler().performArithmeticOperation(10, 0); + } + + public int performArithmeticOperation(int num1, int num2) { + return num1/num2; + } + +} + +class Handler implements Thread.UncaughtExceptionHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(Handler.class); + + public void uncaughtException(Thread t, Throwable e) { + LOGGER.info("Unhandled exception caught!"); + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java new file mode 100644 index 0000000000..801536cb2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java @@ -0,0 +1,18 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalArgument { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalArgument.class); + + public static void main(String[] args) { + try { + Thread.sleep(-1000); + } catch (InterruptedException e) { + LOGGER.error("IllegalArgumentException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java new file mode 100644 index 0000000000..e8ddcea3c2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java @@ -0,0 +1,32 @@ +package com.baeldung.exceptions; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalState { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalState.class); + + public static void main(String[] args) { + + List intList = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + intList.add(i); + } + + Iterator intListIterator = intList.iterator(); // Initialized with index at -1 + + try { + intListIterator.remove(); // IllegalStateException + } catch (IllegalStateException e) { + LOGGER.error("IllegalStateException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java new file mode 100644 index 0000000000..319fd33591 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ChildThread extends Thread { + + private static Logger LOGGER = LoggerFactory.getLogger(ChildThread.class); + + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + LOGGER.error("InterruptedException caught!"); + } + } + +} + +public class InterruptedExceptionExample { + + public static void main(String[] args) throws InterruptedException { + ChildThread childThread = new ChildThread(); + childThread.start(); + childThread.interrupt(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java new file mode 100644 index 0000000000..57fcddf76b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MalformedURL { + + private static Logger LOGGER = LoggerFactory.getLogger(MalformedURL.class); + + public static void main(String[] args) { + + URL baeldungURL = null; + + try { + baeldungURL = new URL("malformedurl"); + } catch (MalformedURLException e) { + LOGGER.error("MalformedURLException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java new file mode 100644 index 0000000000..2402a786a9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NullPointer { + + private static Logger LOGGER = LoggerFactory.getLogger(NullPointer.class); + + public static void main(String[] args) { + + Person personObj = null; + + try { + String name = personObj.personName; // Accessing the field of a null object + personObj.personName = "Jon Doe"; // Modifying the field of a null object + } catch (NullPointerException e) { + LOGGER.error("NullPointerException caught!"); + } + + } +} + +class Person { + + public String personName; + + public String getPersonName() { + return personName; + } + + public void setPersonName(String personName) { + this.personName = personName; + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java new file mode 100644 index 0000000000..7050e70aee --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NumberFormat { + + private static Logger LOGGER = LoggerFactory.getLogger(NumberFormat.class); + + public static void main(String[] args) { + + String str1 = "100ABCD"; + + try { + int x = Integer.parseInt(str1); // Converting string with inappropriate format + int y = Integer.valueOf(str1); + } catch (NumberFormatException e) { + LOGGER.error("NumberFormatException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java new file mode 100644 index 0000000000..f7fb4c91e4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ParseExceptionExample { + + private static Logger LOGGER = LoggerFactory.getLogger(ParseExceptionExample.class); + + public static void main(String[] args) { + + DateFormat format = new SimpleDateFormat("MM, dd, yyyy"); + + try { + format.parse("01, , 2010"); + } catch (ParseException e) { + LOGGER.error("ParseException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java new file mode 100644 index 0000000000..bc297be498 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(StringIndexOutOfBounds.class); + + public static void main(String[] args) { + + String str = "Hello World"; + + try { + char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index + char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string + } catch (StringIndexOutOfBoundsException e) { + LOGGER.error("StringIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java b/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java new file mode 100644 index 0000000000..d8018cefd5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java @@ -0,0 +1,69 @@ +package com.baeldung.gregorian.calendar; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +public class GregorianCalendarExample { + + + public Date setMonth(GregorianCalendar calendar, int amount) { + calendar.set(Calendar.MONTH, amount); + return calendar.getTime(); + } + + + public Date rollAdd(GregorianCalendar calendar, int amount) { + calendar.roll(GregorianCalendar.MONTH, amount); + return calendar.getTime(); + } + + public boolean isLeapYearExample(int year) { + GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(); + return cal.isLeapYear(year); + } + + + + public Date subtractDays(GregorianCalendar calendar, int daysToSubtract) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, -daysToSubtract); + return cal.getTime(); + } + + public Date addDays(GregorianCalendar calendar, int daysToAdd) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, daysToAdd); + return cal.getTime(); + } + + public XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) throws DatatypeConfigurationException { + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + return datatypeFactory.newXMLGregorianCalendar(calendar); + } + + public Date toDate(XMLGregorianCalendar calendar) { + return calendar.toGregorianCalendar() + .getTime(); + } + + public int compareDates(GregorianCalendar firstDate, GregorianCalendar secondDate) { + return firstDate.compareTo(secondDate); + } + + public String formatDate(GregorianCalendar calendar) { + return calendar.toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + } + +} diff --git a/core-java/src/test/java/com/baeldung/customexception/IncorrectFileExtensionExceptionUnitTest.java b/core-java/src/test/java/com/baeldung/customexception/IncorrectFileExtensionExceptionUnitTest.java new file mode 100644 index 0000000000..230698f719 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/customexception/IncorrectFileExtensionExceptionUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.customexception; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; + +import org.junit.Test; + +public class IncorrectFileExtensionExceptionUnitTest { + + @Test + public void testWhenCorrectFileExtensionGiven_ReceivesNoException() throws IncorrectFileNameException { + assertThat(FileManager.getFirstLine("correctFileNameWithProperExtension.txt")).isEqualTo("Default First Line"); + } + + @Test(expected = IncorrectFileExtensionException.class) + public void testWhenCorrectFileNameExceptionThrown_ReceivesNoException() throws IncorrectFileNameException { + StringBuffer sBuffer = new StringBuffer(); + sBuffer.append("src"); + sBuffer.append(File.separator); + sBuffer.append("test"); + sBuffer.append(File.separator); + sBuffer.append("resources"); + sBuffer.append(File.separator); + sBuffer.append("correctFileNameWithoutProperExtension"); + FileManager.getFirstLine(sBuffer.toString()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/customexception/IncorrectFileNameExceptionUnitTest.java b/core-java/src/test/java/com/baeldung/customexception/IncorrectFileNameExceptionUnitTest.java new file mode 100644 index 0000000000..acb05eb763 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/customexception/IncorrectFileNameExceptionUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.customexception; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class IncorrectFileNameExceptionUnitTest { + + @Test(expected = IncorrectFileNameException.class) + public void testWhenIncorrectFileNameExceptionThrown_ReceivesIncorrectFileNameException() throws IncorrectFileNameException { + FileManager.getFirstLine("wrongFileName.txt"); + } + + @Test + public void testWhenCorrectFileNameExceptionThrown_ReceivesNoException() throws IncorrectFileNameException { + assertThat(FileManager.getFirstLine("correctFileName.txt")).isEqualTo("Default First Line"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java new file mode 100644 index 0000000000..b767a24b16 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.encrypt; + +import org.junit.Test; + +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import java.io.File; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class FileEncrypterDecrypterIntegrationTest { + + @Test + public void givenStringAndFilename_whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException { + String originalContent = "foobar"; + SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey(); + + FileEncrypterDecrypter fileEncrypterDecrypter = new FileEncrypterDecrypter(secretKey, "AES/CBC/PKCS5Padding"); + fileEncrypterDecrypter.encrypt(originalContent, "baz.enc"); + + String decryptedContent = fileEncrypterDecrypter.decrypt("baz.enc"); + assertThat(decryptedContent, is(originalContent)); + + new File("baz.enc").delete(); // cleanup + } +} diff --git a/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java new file mode 100644 index 0000000000..394de9c576 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.exceptions; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class GlobalExceptionHandlerUnitTest { + + @Mock + private Appender mockAppender; + + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void whenArithmeticException_thenUseUncaughtExceptionHandler() throws InterruptedException { + + Thread globalExceptionHandlerThread = new Thread() { + public void run() { + GlobalExceptionHandler globalExceptionHandlerObj = new GlobalExceptionHandler(); + globalExceptionHandlerObj.performArithmeticOperation(99, 0); + } + }; + + globalExceptionHandlerThread.start(); + globalExceptionHandlerThread.join(); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel()).isEqualTo(Level.INFO); + assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unhandled exception caught!"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java b/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java new file mode 100644 index 0000000000..a1d084cf9a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java @@ -0,0 +1,228 @@ +package com.baeldung.gregorian.calendar; + +import static org.junit.Assert.*; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.Test; + +import com.baeldung.gregorian.calendar.GregorianCalendarExample; + +public class GregorianCalendarTester { + + @Test + public void test_Calendar_Return_Type_Valid() { + Calendar calendar = Calendar.getInstance(); + assert ("gregory".equals(calendar.getCalendarType())); + } + + @Test + public void test_Calendar_Return_Type_InValid() { + Calendar calendar = Calendar.getInstance(); + assertNotEquals("gregorys", calendar.getCalendarType()); + } + + @Test(expected = ClassCastException.class) + public void test_Class_Cast_Exception() { + TimeZone tz = TimeZone.getTimeZone("GMT+9:00"); + Locale loc = new Locale("ja", "JP", "JP"); + Calendar calendar = Calendar.getInstance(loc); + GregorianCalendar gc = (GregorianCalendar) calendar; + } + + @Test + public void test_Getting_Calendar_information() { + GregorianCalendar calendar = new GregorianCalendar(2018, 5, 28); + assertTrue(false == calendar.isLeapYear(calendar.YEAR)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + assertTrue(2018 == calendar.getWeekYear()); + assertTrue(30 == calendar.getActualMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getActualMinimum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getGreatestMinimum(calendar.DAY_OF_MONTH)); + assertTrue(28 == calendar.getLeastMaximum(calendar.DAY_OF_MONTH)); + assertTrue(31 == calendar.getMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getMinimum(calendar.DAY_OF_MONTH)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + } + + @Test + public void test_Compare_Date_FirstDate_Greater_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 5, 28); + assertTrue(1 == firstDate.compareTo(secondDate)); + } + + + @Test + public void test_Compare_Date_FirstDate_Smaller_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 5, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(-1 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_Compare_Date_Both_Dates_Equal() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(0 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_date_format() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendar = new GregorianCalendar(2018, 6, 28); + assertEquals("28 Jul 2018", calendarDemo.formatDate(calendar)); + } + + @Test + public void test_dateFormatdMMMuuuu() { + String expectedDate = new GregorianCalendar(2018, 6, 28).toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + assertEquals("28 Jul 2018", expectedDate); + } + + @Test + public void test_addDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, 1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.addDays(calendarActual, 1)); + } + + @Test + public void test_whenAddOneDay_thenMonthIsChanged() { + final int finalDay1 = 1; + final int finalMonthJul = 6; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 30); + calendarExpected.add(Calendar.DATE, 1); + System.out.println(calendarExpected.getTime()); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay1); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthJul); + } + + @Test + public void test_whenSubtractOneDay_thenMonthIsChanged() { + final int finalDay31 = 31; + final int finalMonthMay = 4; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 1); + calendarExpected.add(Calendar.DATE, -1); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay31); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthMay); + } + + @Test + public void test_subDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, -1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.subtractDays(calendarActual, 1)); + } + + @Test + public void test_rollAdd() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, 8)); + } + + @Test + public void test_whenRollUpOneMonth_thenYearIsUnchanged() { + final int rolledUpMonthJuly = 7, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledUpMonthJuly); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_whenRollDownOneMonth_thenYearIsUnchanged() { + final int rolledDownMonthJune = 5, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledDownMonthJune); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_rollSubtract() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, -8)); + } + + @Test + public void test_setMonth() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.setMonth(calendarActual, 3)); + } + + @Test + public void test_setMonthApril() { + final int setMonthApril = 3, orginalYear2018 = 2018, originalDate28 = 28; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + assertEquals(calendarExpected.get(Calendar.MONTH), setMonthApril); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + assertEquals(calendarExpected.get(Calendar.DATE), originalDate28); + } + + @Test + public void test_toXMLGregorianCalendar() throws DatatypeConfigurationException { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarExpected); + assertEquals(expectedXMLGregorianCalendar, + calendarDemo.toXMLGregorianCalendar(calendarActual)); + } + + @Test + public void test_isLeapYear_True() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(true, calendarDemo.isLeapYearExample(2016)); + + } + + @Test + public void test_isLeapYear_False() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(false, calendarDemo.isLeapYearExample(2018)); + + } + + @Test + public void test_toDate() throws DatatypeConfigurationException { + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarActual); + expectedXMLGregorianCalendar.toGregorianCalendar().getTime(); + assertEquals(calendarActual.getTime(), + expectedXMLGregorianCalendar.toGregorianCalendar().getTime() ); + } +} diff --git a/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java b/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java new file mode 100644 index 0000000000..85cff51eb3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.thread.join; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.logging.Logger; + +import org.junit.Ignore; +import org.junit.Test; + +/** + * Demonstrates Thread.join behavior. + * + */ +public class ThreadJoinUnitTest { + + final static Logger LOGGER = Logger.getLogger(ThreadJoinUnitTest.class.getName()); + + class SampleThread extends Thread { + public int processingCount = 0; + + SampleThread(int processingCount) { + this.processingCount = processingCount; + LOGGER.info("Thread " + this.getName() + " created"); + } + + @Override + public void run() { + LOGGER.info("Thread " + this.getName() + " started"); + while (processingCount > 0) { + try { + Thread.sleep(1000); // Simulate some work being done by thread + } catch (InterruptedException e) { + LOGGER.info("Thread " + this.getName() + " interrupted."); + } + processingCount--; + LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount); + } + LOGGER.info("Thread " + this.getName() + " exiting"); + } + } + + @Test + public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException { + Thread t1 = new SampleThread(0); + LOGGER.info("Invoking join."); + t1.join(); + LOGGER.info("Returned from join"); + LOGGER.info("Thread state is" + t1.getState()); + assertFalse(t1.isAlive()); + } + + @Test + public void givenStartedThread_whenJoinCalled_waitsTillCompletion() + throws InterruptedException { + Thread t2 = new SampleThread(1); + t2.start(); + LOGGER.info("Invoking join."); + t2.join(); + LOGGER.info("Returned from join"); + assertFalse(t2.isAlive()); + } + + @Test + public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() + throws InterruptedException { + Thread t3 = new SampleThread(10); + t3.start(); + t3.join(1000); + assertTrue(t3.isAlive()); + } + + @Test + @Ignore + public void givenThreadTerminated_checkForEffect_notGuaranteed() + throws InterruptedException { + SampleThread t4 = new SampleThread(10); + t4.start(); + //not guaranteed to stop even if t4 finishes. + do { + + } while (t4.processingCount > 0); + } + + @Test + public void givenJoinWithTerminatedThread_checkForEffect_guaranteed() + throws InterruptedException { + SampleThread t4 = new SampleThread(10); + t4.start(); + do { + t4.join(100); + } while (t4.processingCount > 0); + } + +} \ No newline at end of file diff --git a/core-java/src/test/resources/correctFileNameWithoutProperExtension b/core-java/src/test/resources/correctFileNameWithoutProperExtension new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-kotlin/.gitignore b/core-kotlin/.gitignore index ae3c172604..0c017e8f8c 100644 --- a/core-kotlin/.gitignore +++ b/core-kotlin/.gitignore @@ -1 +1,14 @@ /bin/ + +#ignore gradle +.gradle/ + + +#ignore build and generated files +build/ +node/ +out/ + +#ignore installed node modules and package lock file +node_modules/ +package-lock.json diff --git a/core-kotlin/README.md b/core-kotlin/README.md index 7fcdc68429..4695d12a06 100644 --- a/core-kotlin/README.md +++ b/core-kotlin/README.md @@ -30,3 +30,6 @@ - [Lambda Expressions in Kotlin](http://www.baeldung.com/kotlin-lambda-expressions) - [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek) - [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson) +- [Kotlin String Templates](http://www.baeldung.com/kotlin-string-template) +- [Java EE 8 Security API](http://www.baeldung.com/java-ee-8-security) +- [Kotlin with Ktor](http://www.baeldung.com/kotlin-ktor) diff --git a/core-kotlin/build.gradle b/core-kotlin/build.gradle new file mode 100755 index 0000000000..6c1e06aa25 --- /dev/null +++ b/core-kotlin/build.gradle @@ -0,0 +1,57 @@ + + +group 'com.baeldung.ktor' +version '1.0-SNAPSHOT' + + +buildscript { + ext.kotlin_version = '1.2.41' + ext.ktor_version = '0.9.2' + + repositories { + mavenCentral() + } + dependencies { + + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName = 'APIServer.kt' + +sourceCompatibility = 1.8 +compileKotlin { kotlinOptions.jvmTarget = "1.8" } +compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } + +kotlin { experimental { coroutines "enable" } } + +repositories { + mavenCentral() + jcenter() + maven { url "https://dl.bintray.com/kotlin/ktor" } +} +sourceSets { + main{ + kotlin{ + srcDirs 'com/baeldung/ktor' + } + } + +} + +dependencies { + compile "io.ktor:ktor-server-netty:$ktor_version" + compile "ch.qos.logback:logback-classic:1.2.1" + compile "io.ktor:ktor-gson:$ktor_version" + testCompile group: 'junit', name: 'junit', version: '4.12' + implementation 'com.beust:klaxon:3.0.1' + +} +task runServer(type: JavaExec) { + main = 'APIServer' + classpath = sourceSets.main.runtimeClasspath +} \ No newline at end of file diff --git a/kotlin-ktor/gradle/wrapper/gradle-wrapper.jar b/core-kotlin/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from kotlin-ktor/gradle/wrapper/gradle-wrapper.jar rename to core-kotlin/gradle/wrapper/gradle-wrapper.jar diff --git a/kotlin-ktor/gradle/wrapper/gradle-wrapper.properties b/core-kotlin/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from kotlin-ktor/gradle/wrapper/gradle-wrapper.properties rename to core-kotlin/gradle/wrapper/gradle-wrapper.properties diff --git a/kotlin-ktor/gradlew b/core-kotlin/gradlew similarity index 100% rename from kotlin-ktor/gradlew rename to core-kotlin/gradlew diff --git a/kotlin-ktor/gradlew.bat b/core-kotlin/gradlew.bat similarity index 100% rename from kotlin-ktor/gradlew.bat rename to core-kotlin/gradlew.bat diff --git a/kotlin-ktor/.gitignore b/core-kotlin/kotlin-ktor/.gitignore similarity index 100% rename from kotlin-ktor/.gitignore rename to core-kotlin/kotlin-ktor/.gitignore diff --git a/kotlin-ktor/build.gradle b/core-kotlin/kotlin-ktor/build.gradle similarity index 92% rename from kotlin-ktor/build.gradle rename to core-kotlin/kotlin-ktor/build.gradle index 11aef74857..5c8f523cf1 100755 --- a/kotlin-ktor/build.gradle +++ b/core-kotlin/kotlin-ktor/build.gradle @@ -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 { diff --git a/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.jar b/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.jar new file mode 100755 index 0000000000..01b8bf6b1f Binary files /dev/null and b/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.jar differ diff --git a/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.properties b/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000000..0b83b5a3e3 --- /dev/null +++ b/core-kotlin/kotlin-ktor/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip diff --git a/core-kotlin/kotlin-ktor/gradlew b/core-kotlin/kotlin-ktor/gradlew new file mode 100755 index 0000000000..cccdd3d517 --- /dev/null +++ b/core-kotlin/kotlin-ktor/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/core-kotlin/kotlin-ktor/gradlew.bat b/core-kotlin/kotlin-ktor/gradlew.bat new file mode 100755 index 0000000000..e95643d6a2 --- /dev/null +++ b/core-kotlin/kotlin-ktor/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/kotlin-ktor/resources/logback.xml b/core-kotlin/kotlin-ktor/resources/logback.xml similarity index 100% rename from kotlin-ktor/resources/logback.xml rename to core-kotlin/kotlin-ktor/resources/logback.xml diff --git a/kotlin-ktor/settings.gradle b/core-kotlin/kotlin-ktor/settings.gradle similarity index 100% rename from kotlin-ktor/settings.gradle rename to core-kotlin/kotlin-ktor/settings.gradle diff --git a/kotlin-ktor/src/main/kotlin/APIServer.kt b/core-kotlin/kotlin-ktor/src/main/kotlin/APIServer.kt similarity index 52% rename from kotlin-ktor/src/main/kotlin/APIServer.kt rename to core-kotlin/kotlin-ktor/src/main/kotlin/APIServer.kt index e67609e8b2..a12182ccc8 100755 --- a/kotlin-ktor/src/main/kotlin/APIServer.kt +++ b/core-kotlin/kotlin-ktor/src/main/kotlin/APIServer.kt @@ -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) { + val toDoList = ArrayList(); val jsonResponse = """{ "id": 1, "task": "Pay waterbill", @@ -33,7 +33,7 @@ fun main(args: Array) { header("X-Developer", "Baeldung") } install(CallLogging) { - level = Level.INFO + level = Level.DEBUG filter { call -> call.request.path().startsWith("/todo") } filter { call -> call.request.path().startsWith("/author") } } @@ -42,15 +42,31 @@ fun main(args: Array) { 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.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) diff --git a/kotlin-ktor/webapp/WEB-INF/web.xml b/core-kotlin/kotlin-ktor/webapp/WEB-INF/web.xml similarity index 100% rename from kotlin-ktor/webapp/WEB-INF/web.xml rename to core-kotlin/kotlin-ktor/webapp/WEB-INF/web.xml diff --git a/core-kotlin/resources/logback.xml b/core-kotlin/resources/logback.xml new file mode 100755 index 0000000000..274cdcdb02 --- /dev/null +++ b/core-kotlin/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/core-kotlin/settings.gradle b/core-kotlin/settings.gradle new file mode 100755 index 0000000000..13bbce9583 --- /dev/null +++ b/core-kotlin/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'KtorWithKotlin' + diff --git a/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt b/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt new file mode 100755 index 0000000000..a12182ccc8 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt @@ -0,0 +1,73 @@ +@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.request.path +import io.ktor.request.receive +import io.ktor.response.respond +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) { + + val toDoList = ArrayList(); + val jsonResponse = """{ + "id": 1, + "task": "Pay waterbill", + "description": "Pay water bill today", + }""" + + + embeddedServer(Netty, 8080) { + install(DefaultHeaders) { + header("X-Developer", "Baeldung") + } + install(CallLogging) { + level = Level.DEBUG + filter { call -> call.request.path().startsWith("/todo") } + filter { call -> call.request.path().startsWith("/author") } + } + install(ContentNegotiation) { + gson { + setPrettyPrinting() + } + } + routing() { + route("/todo") { + post { + var toDo = call.receive(); + 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) +} \ No newline at end of file diff --git a/data-structures/src/main/java/com/baeldung/trie/Trie.java b/data-structures/src/main/java/com/baeldung/trie/Trie.java index dd51d97b2d..dac1a64733 100644 --- a/data-structures/src/main/java/com/baeldung/trie/Trie.java +++ b/data-structures/src/main/java/com/baeldung/trie/Trie.java @@ -1,13 +1,13 @@ package com.baeldung.trie; -public class Trie { +class Trie { private TrieNode root; Trie() { root = new TrieNode(); } - public void insert(String word) { + void insert(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -16,11 +16,11 @@ public class Trie { current.setEndOfWord(true); } - public boolean delete(String word) { + boolean delete(String word) { return delete(root, word, 0); } - public boolean containsNode(String word) { + boolean containsNode(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -34,7 +34,7 @@ public class Trie { return current.isEndOfWord(); } - public boolean isEmpty() { + boolean isEmpty() { return root == null; } @@ -51,7 +51,7 @@ public class Trie { if (node == null) { return false; } - boolean shouldDeleteCurrentNode = delete(node, word, index + 1); + boolean shouldDeleteCurrentNode = delete(node, word, index + 1) && !node.isEndOfWord(); if (shouldDeleteCurrentNode) { current.getChildren().remove(ch); diff --git a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java index 25dc753950..73dcdb63f5 100644 --- a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java +++ b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java @@ -4,28 +4,18 @@ import java.util.HashMap; import java.util.Map; class TrieNode { - private Map children; + private final Map children = new HashMap<>(); private boolean endOfWord; - public TrieNode() { - children = new HashMap<>(); - endOfWord = false; - } - - public Map getChildren() { + Map getChildren() { return children; } - public void setChildren(Map children) { - this.children = children; - } - - public boolean isEndOfWord() { + boolean isEndOfWord() { return endOfWord; } - public void setEndOfWord(boolean endOfWord) { + void setEndOfWord(boolean endOfWord) { this.endOfWord = endOfWord; } - } \ No newline at end of file diff --git a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java index be7e5575d8..6f7073651e 100644 --- a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java +++ b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java @@ -1,6 +1,7 @@ package com.baeldung.trie; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -53,6 +54,19 @@ public class TrieTest { assertFalse(trie.containsNode("Programming")); } + @Test + public void givenATrie_whenDeletingOverlappingElements_thenDontDeleteSubElement() { + + Trie trie1 = new Trie(); + + trie1.insert("pie"); + trie1.insert("pies"); + + trie1.delete("pies"); + + Assertions.assertTrue(trie1.containsNode("pie")); + } + private Trie createExampleTrie() { Trie trie = new Trie(); diff --git a/deltaspike/README.md b/deltaspike/README.md index ff12555376..c1ab0a9736 100644 --- a/deltaspike/README.md +++ b/deltaspike/README.md @@ -1 +1,3 @@ ## Relevant articles: + +- [A Guide to DeltaSpike Data Module](http://www.baeldung.com/deltaspike-data-module) diff --git a/ejb/wildfly/wildfly-mdb/pom.xml b/ejb/wildfly/wildfly-mdb/pom.xml new file mode 100644 index 0000000000..0b2ec7d5a3 --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + widlfly-mdb + + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + + + + + javax + javaee-api + ${javaee-api.version} + provided + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java new file mode 100644 index 0000000000..6997f92201 --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java @@ -0,0 +1,28 @@ +package com.baeldung.wildfly.mdb; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +/** + * Message-Driven Bean implementation class for: ReadMessageMDB + */ +@MessageDriven( + activationConfig = { + @ActivationConfigProperty(propertyName = "destination", propertyValue = "tutorialQueue"), + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") +}) +public class ReadMessageMDB implements MessageListener { + + public void onMessage(Message message) { + TextMessage textMessage = (TextMessage) message; + try { + System.out.println("Message received: " + textMessage.getText()); + } catch (JMSException e) { + System.out.println("Error while trying to consume messages: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java new file mode 100644 index 0000000000..7dcd04b43f --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java @@ -0,0 +1,52 @@ +package baeldung.com.example.servlet; + +import java.io.IOException; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@WebServlet("/SendMessageServlet") +public class SendMessageServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + String text = req.getParameter("text") != null ? req.getParameter("text") : "Hello World"; + + try ( + Context ic = new InitialContext(); + + ConnectionFactory cf = (ConnectionFactory) ic.lookup("/ConnectionFactory"); + Queue queue = (Queue) ic.lookup("queue/tutorialQueue"); + + Connection connection = cf.createConnection(); + ) { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer publisher = session.createProducer(queue); + + connection.start(); + + TextMessage message = session.createTextMessage(text); + publisher.send(message); + + } catch (NamingException | JMSException e) { + res.getWriter().println("Error while trying to send <" + text + "> message: " + e.getMessage()); + } + + res.getWriter().println("Message sent: " + text); + } + +} \ No newline at end of file diff --git a/ethereumj/.gitgnore b/ethereum/.gitgnore similarity index 100% rename from ethereumj/.gitgnore rename to ethereum/.gitgnore diff --git a/ethereumj/README.md b/ethereum/README.md similarity index 95% rename from ethereumj/README.md rename to ethereum/README.md index 320ae8c9f8..d06ca09636 100644 --- a/ethereumj/README.md +++ b/ethereum/README.md @@ -1,4 +1,4 @@ -## EthereumJ +## Ethereum ### Relevant Articles: - [Introduction to EthereumJ](http://www.baeldung.com/ethereumj) diff --git a/ethereum/pom.xml b/ethereum/pom.xml new file mode 100644 index 0000000000..f07ed2c6a0 --- /dev/null +++ b/ethereum/pom.xml @@ -0,0 +1,229 @@ + + 4.0.0 + com.baeldung.ethereum + ethereum + 0.0.1-SNAPSHOT + ethereum + + + parent-spring-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring.boot.version} + + + + + org.springframework + spring-core + ${springframework.version} + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + + + org.ethereum + ethereumj-core + ${ethereumj-core.version} + + + org.web3j + core + ${web3j.core.version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + + javax.servlet + jstl + ${jstl.version} + + + javax.servlet + javax.servlet-api + ${javax-servlet.version} + + + javax.servlet.jsp.jstl + jstl-api + ${jstl.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax-jsp.version} + + + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + org.springframework.boot + spring-boot-starter-test + test + ${spring.boot.version} + + + org.springframework + spring-context + ${springframework.version} + + + org.springframework + spring-test + ${springframework.version} + test + + + + + org.mockito + mockito-core + ${mockito.version} + + + org.hamcrest + hamcrest-core + + + test + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-core + + + + + org.hamcrest + hamcrest-library + ${hamcrest.version} + test + + + com.jayway.jsonpath + json-path + ${jsonpath.version} + + + + + ethereum + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + src/main/webapp + false + + + + + + + + Ethereum + Ethereum + https://dl.bintray.com/ethereum/maven/ + + + + + UTF-8 + 1.8 + 8.5.4 + 1.5.0-RELEASE + 3.3.1 + 5.0.5.RELEASE + 1.5.6.RELEASE + 1.10.19 + 2.5.0 + 1.3 + 2.9.3 + 2.3.1 + 3.1.0 + 2.4.0 + 1.2 + 4.12 + 1.2.3 + 1.7.25 + + + diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java b/ethereum/src/main/java/com/baeldung/ethereumj/ApplicationMain.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java rename to ethereum/src/main/java/com/baeldung/ethereumj/ApplicationMain.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java b/ethereum/src/main/java/com/baeldung/ethereumj/Constants.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java rename to ethereum/src/main/java/com/baeldung/ethereumj/Constants.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java b/ethereum/src/main/java/com/baeldung/ethereumj/beans/EthBean.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java rename to ethereum/src/main/java/com/baeldung/ethereumj/beans/EthBean.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java b/ethereum/src/main/java/com/baeldung/ethereumj/config/EthConfig.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java rename to ethereum/src/main/java/com/baeldung/ethereumj/config/EthConfig.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java b/ethereum/src/main/java/com/baeldung/ethereumj/controllers/EthController.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java rename to ethereum/src/main/java/com/baeldung/ethereumj/controllers/EthController.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java b/ethereum/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java rename to ethereum/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java b/ethereum/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java rename to ethereum/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java diff --git a/ethereumj/src/main/java/com/baeldung/web3j/Template.java b/ethereum/src/main/java/com/baeldung/web3j/Template.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/web3j/Template.java rename to ethereum/src/main/java/com/baeldung/web3j/Template.java diff --git a/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java b/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java new file mode 100644 index 0000000000..75ef948f7a --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java @@ -0,0 +1,68 @@ +package com.baeldung.web3j.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.PathResourceResolver; +import org.springframework.web.servlet.view.JstlView; +import org.springframework.web.servlet.view.UrlBasedViewResolver; + +import java.util.concurrent.Executor; + +@Configuration +@EnableWebMvc +@EnableAsync +@ComponentScan("com.baeldung.web3j") +public class AppConfig implements WebMvcConfigurer { + + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("index"); + } + + /** + * Static resource locations including themes + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**/*") + .addResourceLocations("/", "/resources/") + .setCachePeriod(3600) + .resourceChain(true) + .addResolver(new PathResourceResolver()); + } + + /** + * View resolver for JSP + */ + @Bean + public UrlBasedViewResolver viewResolver() { + UrlBasedViewResolver resolver = new UrlBasedViewResolver(); + resolver.setPrefix("/WEB-INF/jsp/"); + resolver.setSuffix(".jsp"); + resolver.setViewClass(JstlView.class); + return resolver; + } + + /** + * Configuration for async thread bean + * + * More: https://docs.spring.io/autorepo/docs/spring-framework/5.0.3.RELEASE/javadoc-api/org/springframework/scheduling/SchedulingTaskExecutor.html + */ + @Bean + public Executor asyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); + executor.setMaxPoolSize(2); + executor.setQueueCapacity(500); + executor.setThreadNamePrefix("CsvThread"); + executor.initialize(); + return executor; + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java b/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java new file mode 100644 index 0000000000..8a9a8cf8c1 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java @@ -0,0 +1,28 @@ +package com.baeldung.web3j.config; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + //AbstractDispatcherServletInitializer override DEFAULT_SERVLET_NAME + @Override + protected String getServletName() { + return "dispatcher"; + } + + @Override + protected Class[] getRootConfigClasses() { + return new Class[]{}; + } + + @Override + protected Class[] getServletConfigClasses() { + return new Class[]{AppConfig.class}; + } + + @Override + protected String[] getServletMappings() { + return new String[]{"/"}; + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java b/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java new file mode 100644 index 0000000000..005e4263cd --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java @@ -0,0 +1,18 @@ +package com.baeldung.web3j.constants; + +public class Constants { + + public static final String API_BLOCK = "/api/block"; + public static final String API_ACCOUNTS = "/api/accounts"; + public static final String API_TRANSACTIONS = "/api/transactions"; + public static final String API_BALANCE = "/api/balance"; + + public static final String GENERIC_EXCEPTION = "Exception encountered!"; + public static final String PLEASE_SUPPLY_REAL_DATA = "Please Supply Real Data!"; + + public static final String DEFAULT_ADDRESS = "0x281055afc982d96fab65b3a49cac8b878184cb16"; + public static final String DEFAULT_CONTRACT_ADDRESS = "00000000000000000000"; + + + +} diff --git a/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java b/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java new file mode 100644 index 0000000000..6909ca3e0c --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java @@ -0,0 +1,74 @@ +package com.baeldung.web3j.contracts; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.RemoteCall; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; + +/** + *

Auto generated code. + *

Do not modify! + *

Please use the web3j command line tools, + * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the + * codegen module to update. + * + *

Generated with web3j version 3.3.1. + */ +public class Example extends Contract { + private static final String BINARY = "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029"; + + protected static final HashMap _addresses; + + static { + _addresses = new HashMap<>(); + } + + protected Example(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + protected Example(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static RemoteCall deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(Example.class, web3j, credentials, gasPrice, gasLimit, BINARY, ""); + } + + public static RemoteCall deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(Example.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, ""); + } + + public RemoteCall ExampleFunction() { + final Function function = new Function( + "ExampleFunction", + Arrays.asList(), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public static Example load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new Example(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static Example load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new Example(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + protected String getStaticDeployedAddress(String networkId) { + return _addresses.get(networkId); + } + + public static String getPreviouslyDeployedAddress(String networkId) { + return _addresses.get(networkId); + } +} diff --git a/ethereumj/src/main/java/com/baeldung/web3j/contracts/Greeting.java b/ethereum/src/main/java/com/baeldung/web3j/contracts/Greeting.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/web3j/contracts/Greeting.java rename to ethereum/src/main/java/com/baeldung/web3j/contracts/Greeting.java diff --git a/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java b/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java new file mode 100644 index 0000000000..e05517bc79 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java @@ -0,0 +1,103 @@ +package com.baeldung.web3j.controllers; + +import com.baeldung.web3j.constants.Constants; +import com.baeldung.web3j.helpers.TimeHelper; +import com.baeldung.web3j.services.Web3Service; +import com.baeldung.web3j.transfers.ResponseTransfer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; + +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION; + +@RestController +public class EthereumRestController { + + @Autowired + Web3Service web3Service; + + @RequestMapping(value = Constants.API_BLOCK, method = RequestMethod.GET) + public Future getBlock() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getBlockNumber(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_ACCOUNTS, method = RequestMethod.GET) + public Future getAccounts() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getEthAccounts(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_TRANSACTIONS, method = RequestMethod.GET) + public Future getTransactions() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getTransactionCount(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_BALANCE, method = RequestMethod.GET) + public Future getBalance() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getEthBalance(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java b/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java new file mode 100644 index 0000000000..360fe088ba --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java @@ -0,0 +1,16 @@ +package com.baeldung.web3j.helpers; + +import java.time.Duration; +import java.time.Instant; + +public class TimeHelper { + + public static Instant start() { + return Instant.now(); + } + + public static Duration stop(Instant start) { + Instant end = Instant.now(); + return Duration.between(start, end); + } +} diff --git a/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java b/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java new file mode 100644 index 0000000000..c943ee4006 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java @@ -0,0 +1,151 @@ +package com.baeldung.web3j.services; + +import com.baeldung.web3j.contracts.Example; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.datatypes.Function; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.http.HttpService; +import org.web3j.tx.Contract; +import org.web3j.tx.ManagedTransaction; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static com.baeldung.web3j.constants.Constants.DEFAULT_ADDRESS; +import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION; +import static com.baeldung.web3j.constants.Constants.PLEASE_SUPPLY_REAL_DATA; + +@Service +public class Web3Service { + + private Web3j web3j = Web3j.build(new HttpService()); + + //Create and Init the default Web3J connection + public void customInit(String provider) { + this.web3j = Web3j.build(new HttpService(provider)); + } + + //Convert to and from supplied contract ABI bytecode + public static String toBinary(String bytecode) { + return bytecode.replaceFirst("^0x", ""); + } + + public static String toByteCode(String binary) { + return "0x" + binary; + } + + public CompletableFuture getBlockNumber() { + EthBlockNumber result = new EthBlockNumber(); + try { + result = this.web3j.ethBlockNumber().sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getEthAccounts() { + EthAccounts result = new EthAccounts(); + try { + result = this.web3j.ethAccounts().sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getTransactionCount() { + EthGetTransactionCount result = new EthGetTransactionCount(); + try { + result = this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getEthBalance() { + EthGetBalance result = new EthGetBalance(); + try { + result = this.web3j.ethGetBalance(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture fromScratchContractExample() { + + String contractAddress = ""; + + try { + //Create a wallet + WalletUtils.generateNewWalletFile("PASSWORD", new File("/path/to/destination"), true); + //Load the credentials from it + Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile"); + + //Deploy contract to address specified by wallet + Example contract = Example.deploy(this.web3j, + credentials, + ManagedTransaction.GAS_PRICE, + Contract.GAS_LIMIT).send(); + + //Het the address + contractAddress = contract.getContractAddress(); + + } catch (Exception ex) { + System.out.println(PLEASE_SUPPLY_REAL_DATA); + return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA); + } + return CompletableFuture.completedFuture(contractAddress); + } + + @Async + public CompletableFuture sendTx() { + String transactionHash = ""; + + try { + List inputParams = new ArrayList(); + List outputParams = new ArrayList(); + Function function = new Function("fuctionName", inputParams, outputParams); + + String encodedFunction = FunctionEncoder.encode(function); + + BigInteger nonce = BigInteger.valueOf(100); + BigInteger gasprice = BigInteger.valueOf(100); + BigInteger gaslimit = BigInteger.valueOf(100); + + Transaction transaction = Transaction.createFunctionCallTransaction("FROM_ADDRESS", nonce, gasprice, gaslimit, "TO_ADDRESS", encodedFunction); + + org.web3j.protocol.core.methods.response.EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get(); + transactionHash = transactionResponse.getTransactionHash(); + + } catch (Exception ex) { + System.out.println(PLEASE_SUPPLY_REAL_DATA); + return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA); + } + + return CompletableFuture.completedFuture(transactionHash); + } +} + + + + + + + + diff --git a/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java b/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java new file mode 100644 index 0000000000..9c5d1799ff --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java @@ -0,0 +1,28 @@ +package com.baeldung.web3j.transfers; + +import java.time.Duration; + +public class ResponseTransfer { + + public ResponseTransfer() {} + + private Duration performance; + private String message; + + public Duration getPerformance() { + return performance; + } + + public void setPerformance(Duration performance) { + this.performance = performance; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/ethereumj/src/main/resources/application.properties b/ethereum/src/main/resources/application.properties similarity index 100% rename from ethereumj/src/main/resources/application.properties rename to ethereum/src/main/resources/application.properties diff --git a/ethereum/src/main/resources/dev_ganache/README.md b/ethereum/src/main/resources/dev_ganache/README.md new file mode 100644 index 0000000000..2d3e645504 --- /dev/null +++ b/ethereum/src/main/resources/dev_ganache/README.md @@ -0,0 +1,23 @@ +# Ganache Readme + +TL:DR - To set up Ganache visit: http://truffleframework.com/ganache/ + +# Three Ways to Install Ganache + +Ganache is provided in three libraries or distributions: + +(1) Ganache - https://github.com/trufflesuite/ganache + +This is a pre-built and out-of-the-box solution. Easiest to set up. It provides an interface and server shell for Ganache CLI. + +(2) Ganache CLI - https://www.npmjs.com/package/ganache-cli + +Ganache CLI abstracts Ganache Core and supplies the default options and arguments used. + +(3) Ganache Core - https://www.npmjs.com/package/ganache-core + +Basically, only use Ganache Core if you need to build a totally customized option. + +# Use + +The default port is *8545* on *localhost* \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/README.md b/ethereum/src/main/resources/dev_truffle/README.md new file mode 100644 index 0000000000..b64e16d570 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/README.md @@ -0,0 +1,43 @@ +# Using Truffle + +Basic Truffle walkthrough readme. + +See also: http://truffleframework.com/docs/ + +# Bash + +Truffle install + +```bash + $ npm install truffle -g + $ truffle version +``` + +Truffle commands: + +```bash + $ truffle init + $ truffle compile + $ truffle migrate + $ truffle test +``` + +# Directory Structure + +The command `$ truffle init` will create a directory structure in the specified root according to the following: + +``` +root -| + |-build (Compiled Solc JSON Output Dir) + |-contracts (Solc Contracts to be Compiled and Migrated) + |-migrations (Specify the Order and Dependencies of Contracts to Be Deployed) + |-test (Truffle Tests) +``` + +# Compile + +Truffle will compile the smart contracts and expose their **JSON ABI's for use with Web3.js** or **Binary ABI's for use with Web3J**. + +# Migration + +Truffle will let you deploy your Solc contracts directly to a blockchin of your choice. \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json b/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json new file mode 100644 index 0000000000..977928c756 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json @@ -0,0 +1,455 @@ +{ + "contractName": "ConvertLib", + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "amount", + "type": "uint256" + }, + { + "name": "conversionRate", + "type": "uint256" + } + ], + "name": "convert", + "outputs": [ + { + "name": "convertedAmount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60d161002f600b82828239805160001a6073146000811461001f57610021565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029", + "sourceMap": "28:148:0:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24", + "deployedSourceMap": "28:148:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;50:123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109:20;154:14;145:6;:23;138:30;;50:123;;;;:::o", + "source": "pragma solidity ^0.4.17;\r\n\r\nlibrary ConvertLib{\r\n\tfunction convert(uint amount,uint conversionRate) returns (uint convertedAmount)\r\n\t{\r\n\t\treturn amount * conversionRate;\r\n\t}\r\n}\r\n", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\ConvertLib.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol", + "exportedSymbols": { + "ConvertLib": [ + 16 + ] + }, + "id": 17, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "id": 16, + "linearizedBaseContracts": [ + 16 + ], + "name": "ConvertLib", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 14, + "nodeType": "Block", + "src": "133:40:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 10, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "145:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "id": 11, + "name": "conversionRate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "154:14:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "145:23:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9, + "id": 13, + "nodeType": "Return", + "src": "138:30:0" + } + ] + }, + "documentation": null, + "id": 15, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "convert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 6, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "67:11:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "67:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "name": "conversionRate", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "79:19:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "79:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "66:33:0" + }, + "payable": false, + "returnParameters": { + "id": 9, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8, + "name": "convertedAmount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "109:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "109:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "108:22:0" + }, + "scope": 16, + "src": "50:123:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 17, + "src": "28:148:0" + } + ], + "src": "0:178:0" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol", + "exportedSymbols": { + "ConvertLib": [ + 16 + ] + }, + "id": 17, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "id": 16, + "linearizedBaseContracts": [ + 16 + ], + "name": "ConvertLib", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 14, + "nodeType": "Block", + "src": "133:40:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 10, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "145:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "id": 11, + "name": "conversionRate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "154:14:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "145:23:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9, + "id": 13, + "nodeType": "Return", + "src": "138:30:0" + } + ] + }, + "documentation": null, + "id": 15, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "convert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 6, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "67:11:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "67:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "name": "conversionRate", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "79:19:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "79:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "66:33:0" + }, + "payable": false, + "returnParameters": { + "id": 9, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8, + "name": "convertedAmount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "109:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "109:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "108:22:0" + }, + "scope": 16, + "src": "50:123:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 17, + "src": "28:148:0" + } + ], + "src": "0:178:0" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.678Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json b/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json new file mode 100644 index 0000000000..82111dab11 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json @@ -0,0 +1,251 @@ +{ + "contractName": "Example", + "abi": [ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": false, + "inputs": [], + "name": "ExampleFunction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029", + "deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029", + "sourceMap": "28:134:1:-;;;50:45;;;;;;;;28:134;;;;;;", + "deployedSourceMap": "28:134:1:-;;;;;;;;;;;;;;;;;;;;;;;;101:58;;;;;;;;;;;;;;;:::o", + "source": "pragma solidity ^0.4.17;\r\n\r\ncontract Example {\r\n function Example() {\r\n // constructor\r\n }\r\n\r\n function ExampleFunction() {\r\n // example function\r\n }\r\n}", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Example.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol", + "exportedSymbols": { + "Example": [ + 27 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 18, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:1" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": [ + 27 + ], + "name": "Example", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 21, + "nodeType": "Block", + "src": "69:26:1", + "statements": [] + }, + "documentation": null, + "id": 22, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Example", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "66:2:1" + }, + "payable": false, + "returnParameters": { + "id": 20, + "nodeType": "ParameterList", + "parameters": [], + "src": "69:0:1" + }, + "scope": 27, + "src": "50:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 25, + "nodeType": "Block", + "src": "128:31:1", + "statements": [] + }, + "documentation": null, + "id": 26, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "ExampleFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 23, + "nodeType": "ParameterList", + "parameters": [], + "src": "125:2:1" + }, + "payable": false, + "returnParameters": { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "128:0:1" + }, + "scope": 27, + "src": "101:58:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 28, + "src": "28:134:1" + } + ], + "src": "0:162:1" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol", + "exportedSymbols": { + "Example": [ + 27 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 18, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:1" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": [ + 27 + ], + "name": "Example", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 21, + "nodeType": "Block", + "src": "69:26:1", + "statements": [] + }, + "documentation": null, + "id": 22, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Example", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "66:2:1" + }, + "payable": false, + "returnParameters": { + "id": 20, + "nodeType": "ParameterList", + "parameters": [], + "src": "69:0:1" + }, + "scope": 27, + "src": "50:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 25, + "nodeType": "Block", + "src": "128:31:1", + "statements": [] + }, + "documentation": null, + "id": 26, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "ExampleFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 23, + "nodeType": "ParameterList", + "parameters": [], + "src": "125:2:1" + }, + "payable": false, + "returnParameters": { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "128:0:1" + }, + "scope": 27, + "src": "101:58:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 28, + "src": "28:134:1" + } + ], + "src": "0:162:1" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.710Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json b/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json new file mode 100644 index 0000000000..55f2c7ad69 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json @@ -0,0 +1,1380 @@ +{ + "contractName": "Migrations", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "last_completed_migration", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": false, + "inputs": [ + { + "name": "completed", + "type": "uint256" + } + ], + "name": "setCompleted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "new_address", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102d78061005e6000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610220565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc610226565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024b565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561021c578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b5af1151561021857600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102a857806001819055505b505600a165627a7a72305820be5431ce1823a03470fc4376ec6fdfa9e54ca2bd2b05b6271c73eb54ad4e4b060029", + "deployedBytecode": "0x606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610220565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc610226565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024b565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561021c578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b5af1151561021857600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102a857806001819055505b505600a165627a7a72305820be5431ce1823a03470fc4376ec6fdfa9e54ca2bd2b05b6271c73eb54ad4e4b060029", + "sourceMap": "26:488:2:-;;;178:58;;;;;;;;221:10;213:5;;:18;;;;;;;;;;;;;;;;;;26:488;;;;;;", + "deployedSourceMap": "26:488:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;240:103;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;409:19;161:5;;;;;;;;;;;147:19;;:10;:19;;;143:26;;;442:11;409:45;;460:8;:21;;;482:24;;460:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143:26;347:165;;:::o;74:36::-;;;;:::o;50:20::-;;;;;;;;;;;;;:::o;240:103::-;161:5;;;;;;;;;;;147:19;;:10;:19;;;143:26;;;329:9;302:24;:36;;;;143:26;240:103;:::o", + "source": "pragma solidity ^0.4.17;\n\ncontract Migrations {\n address public owner;\n uint public last_completed_migration;\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n function Migrations() public {\n owner = msg.sender;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address new_address) public restricted {\n Migrations upgraded = Migrations(new_address);\n upgraded.setCompleted(last_completed_migration);\n }\n}\n", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Migrations.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 84 + ] + }, + "id": 85, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 29, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:2" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 84, + "linearizedBaseContracts": [ + 84 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 31, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "50:20:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 30, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "50:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 33, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "74:36:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 32, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "74:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 41, + "nodeType": "Block", + "src": "137:37:2", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 35, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "147:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 36, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "147:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 37, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "161:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "147:19:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 40, + "nodeType": "IfStatement", + "src": "143:26:2", + "trueBody": { + "id": 39, + "nodeType": "PlaceholderStatement", + "src": "168:1:2" + } + } + ] + }, + "documentation": null, + "id": 42, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 34, + "nodeType": "ParameterList", + "parameters": [], + "src": "134:2:2" + }, + "src": "115:59:2", + "visibility": "internal" + }, + { + "body": { + "id": 50, + "nodeType": "Block", + "src": "207:29:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 45, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "213:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 46, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "221:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "221:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "213:18:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 49, + "nodeType": "ExpressionStatement", + "src": "213:18:2" + } + ] + }, + "documentation": null, + "id": 51, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Migrations", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 43, + "nodeType": "ParameterList", + "parameters": [], + "src": "197:2:2" + }, + "payable": false, + "returnParameters": { + "id": 44, + "nodeType": "ParameterList", + "parameters": [], + "src": "207:0:2" + }, + "scope": 84, + "src": "178:58:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 62, + "nodeType": "Block", + "src": "296:47:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 60, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 58, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "302:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 59, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "329:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "302:36:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 61, + "nodeType": "ExpressionStatement", + "src": "302:36:2" + } + ] + }, + "documentation": null, + "id": 63, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 56, + "modifierName": { + "argumentTypes": null, + "id": 55, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "285:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "285:10:2" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 54, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 53, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 63, + "src": "262:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 52, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "262:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "261:16:2" + }, + "payable": false, + "returnParameters": { + "id": 57, + "nodeType": "ParameterList", + "parameters": [], + "src": "296:0:2" + }, + "scope": 84, + "src": "240:103:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 82, + "nodeType": "Block", + "src": "403:109:2", + "statements": [ + { + "assignments": [ + 71 + ], + "declarations": [ + { + "constant": false, + "id": 71, + "name": "upgraded", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "409:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + }, + "typeName": { + "contractScope": null, + "id": 70, + "name": "Migrations", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 84, + "src": "409:10:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 75, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 73, + "name": "new_address", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 65, + "src": "442:11:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 72, + "name": "Migrations", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 84, + "src": "431:10:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Migrations_$84_$", + "typeString": "type(contract Migrations)" + } + }, + "id": 74, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "431:23:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "409:45:2" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 79, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "482:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 76, + "name": "upgraded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 71, + "src": "460:8:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "id": 78, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setCompleted", + "nodeType": "MemberAccess", + "referencedDeclaration": 63, + "src": "460:21:2", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256) external" + } + }, + "id": 80, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "460:47:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 81, + "nodeType": "ExpressionStatement", + "src": "460:47:2" + } + ] + }, + "documentation": null, + "id": 83, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 68, + "modifierName": { + "argumentTypes": null, + "id": 67, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "392:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "392:10:2" + } + ], + "name": "upgrade", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 66, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 65, + "name": "new_address", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "364:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 64, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "364:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "363:21:2" + }, + "payable": false, + "returnParameters": { + "id": 69, + "nodeType": "ParameterList", + "parameters": [], + "src": "403:0:2" + }, + "scope": 84, + "src": "347:165:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 85, + "src": "26:488:2" + } + ], + "src": "0:515:2" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 84 + ] + }, + "id": 85, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 29, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:2" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 84, + "linearizedBaseContracts": [ + 84 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 31, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "50:20:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 30, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "50:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 33, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "74:36:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 32, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "74:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 41, + "nodeType": "Block", + "src": "137:37:2", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 35, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "147:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 36, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "147:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 37, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "161:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "147:19:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 40, + "nodeType": "IfStatement", + "src": "143:26:2", + "trueBody": { + "id": 39, + "nodeType": "PlaceholderStatement", + "src": "168:1:2" + } + } + ] + }, + "documentation": null, + "id": 42, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 34, + "nodeType": "ParameterList", + "parameters": [], + "src": "134:2:2" + }, + "src": "115:59:2", + "visibility": "internal" + }, + { + "body": { + "id": 50, + "nodeType": "Block", + "src": "207:29:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 45, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "213:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 46, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "221:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "221:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "213:18:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 49, + "nodeType": "ExpressionStatement", + "src": "213:18:2" + } + ] + }, + "documentation": null, + "id": 51, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Migrations", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 43, + "nodeType": "ParameterList", + "parameters": [], + "src": "197:2:2" + }, + "payable": false, + "returnParameters": { + "id": 44, + "nodeType": "ParameterList", + "parameters": [], + "src": "207:0:2" + }, + "scope": 84, + "src": "178:58:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 62, + "nodeType": "Block", + "src": "296:47:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 60, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 58, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "302:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 59, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "329:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "302:36:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 61, + "nodeType": "ExpressionStatement", + "src": "302:36:2" + } + ] + }, + "documentation": null, + "id": 63, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 56, + "modifierName": { + "argumentTypes": null, + "id": 55, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "285:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "285:10:2" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 54, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 53, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 63, + "src": "262:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 52, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "262:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "261:16:2" + }, + "payable": false, + "returnParameters": { + "id": 57, + "nodeType": "ParameterList", + "parameters": [], + "src": "296:0:2" + }, + "scope": 84, + "src": "240:103:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 82, + "nodeType": "Block", + "src": "403:109:2", + "statements": [ + { + "assignments": [ + 71 + ], + "declarations": [ + { + "constant": false, + "id": 71, + "name": "upgraded", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "409:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + }, + "typeName": { + "contractScope": null, + "id": 70, + "name": "Migrations", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 84, + "src": "409:10:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 75, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 73, + "name": "new_address", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 65, + "src": "442:11:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 72, + "name": "Migrations", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 84, + "src": "431:10:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Migrations_$84_$", + "typeString": "type(contract Migrations)" + } + }, + "id": 74, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "431:23:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "409:45:2" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 79, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "482:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 76, + "name": "upgraded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 71, + "src": "460:8:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "id": 78, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setCompleted", + "nodeType": "MemberAccess", + "referencedDeclaration": 63, + "src": "460:21:2", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256) external" + } + }, + "id": 80, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "460:47:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 81, + "nodeType": "ExpressionStatement", + "src": "460:47:2" + } + ] + }, + "documentation": null, + "id": 83, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 68, + "modifierName": { + "argumentTypes": null, + "id": 67, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "392:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "392:10:2" + } + ], + "name": "upgrade", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 66, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 65, + "name": "new_address", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "364:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 64, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "364:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "363:21:2" + }, + "payable": false, + "returnParameters": { + "id": 69, + "nodeType": "ParameterList", + "parameters": [], + "src": "403:0:2" + }, + "scope": 84, + "src": "347:165:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 85, + "src": "26:488:2" + } + ], + "src": "0:515:2" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.710Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol b/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol new file mode 100644 index 0000000000..ec0576fc3f --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol @@ -0,0 +1,8 @@ +pragma solidity ^0.4.17; + +library ConvertLib{ + function convert(uint amount,uint conversionRate) returns (uint convertedAmount) + { + return amount * conversionRate; + } +} diff --git a/ethereum/src/main/resources/dev_truffle/contracts/Example.sol b/ethereum/src/main/resources/dev_truffle/contracts/Example.sol new file mode 100644 index 0000000000..c09c54843c --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/Example.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.17; + +contract Example { + function Example() { + // constructor + } + + function ExampleFunction() { + // example function + } +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol b/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol new file mode 100644 index 0000000000..f170cb4fa7 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity ^0.4.17; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + modifier restricted() { + if (msg.sender == owner) _; + } + + function Migrations() public { + owner = msg.sender; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js b/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js new file mode 100644 index 0000000000..269ad95867 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js @@ -0,0 +1,3 @@ +module.exports = deployer => { + deployer.deploy(artifacts.require("./Migrations.sol")); +}; diff --git a/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js b/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js new file mode 100644 index 0000000000..b6f30176ae --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js @@ -0,0 +1,8 @@ +const Example = artifacts.require("./Example.sol"), + ConvertLib = artifacts.require("./ConvertLib.sol"); + +module.exports = deployer => { + deployer.deploy(ConvertLib); + deployer.link(ConvertLib, Example); + deployer.deploy(Example); +}; diff --git a/ethereum/src/main/resources/dev_truffle/truffle.js b/ethereum/src/main/resources/dev_truffle/truffle.js new file mode 100644 index 0000000000..8110fdad45 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/truffle.js @@ -0,0 +1,20 @@ +module.exports = { + contracts_build_directory: "./build/contracts", + networks: { + live: { + network_id: 1, // Ethereum public network + host: 'localhost', + port: 8545 + }, + testnet: { + network_id: 3, // Official Ethereum test network (Ropsten) + host: 'localhost', + port: 8545 + }, + development: { + host: 'localhost', + port: 8545, + network_id: '*' + } + } +} diff --git a/ethereumj/src/main/resources/solidity/Greeting.sol b/ethereum/src/main/resources/solidity/Greeting.sol similarity index 100% rename from ethereumj/src/main/resources/solidity/Greeting.sol rename to ethereum/src/main/resources/solidity/Greeting.sol diff --git a/ethereumj/src/main/resources/solidity/build/Greeting.abi b/ethereum/src/main/resources/solidity/build/Greeting.abi similarity index 100% rename from ethereumj/src/main/resources/solidity/build/Greeting.abi rename to ethereum/src/main/resources/solidity/build/Greeting.abi diff --git a/ethereumj/src/main/resources/solidity/build/Greeting.bin b/ethereum/src/main/resources/solidity/build/Greeting.bin similarity index 100% rename from ethereumj/src/main/resources/solidity/build/Greeting.bin rename to ethereum/src/main/resources/solidity/build/Greeting.bin diff --git a/ethereum/src/main/webapp/WEB-INF/.gitkeep b/ethereum/src/main/webapp/WEB-INF/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ethereum/src/main/webapp/resources/.gitkeep b/ethereum/src/main/webapp/resources/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java b/ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java similarity index 99% rename from ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java rename to ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java index f62d229261..7676b99224 100644 --- a/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java +++ b/ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java @@ -74,4 +74,4 @@ public class EthControllerLiveTest { assertTrue("Dynamic data returned?", a.hasBody()); System.out.println("Dynamic data returned?: " + a.hasBody()); } -} +} \ No newline at end of file diff --git a/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java new file mode 100644 index 0000000000..ee78ab17c2 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java @@ -0,0 +1,78 @@ +package com.baeldung.web3j.controllers; + + +import com.baeldung.web3j.config.AppConfig; +import com.baeldung.web3j.constants.Constants; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {AppConfig.class}) +@WebAppConfiguration +public class EthereumRestControllerIntegrationTest { + + private MockMvc mockMvc; + + private void constructAsyncTest(String endpoint) { + try { + MvcResult asyncResult = mockMvc + .perform(get(endpoint)) + .andReturn(); + + mockMvc.perform(asyncDispatch(asyncResult)) + .andDo(print()) + .andExpect(status().isOk()); + + } catch (Exception e) { + System.out.println("Exception: " + e); + } + } + + @Autowired + private WebApplicationContext wac; + + @Before + public void preTest() throws Exception { + mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void accounts() { + constructAsyncTest(Constants.API_ACCOUNTS); + } + + @Test + public void transactions() { + constructAsyncTest(Constants.API_TRANSACTIONS); + } + + @Test + public void block() { + constructAsyncTest(Constants.API_BLOCK); + } + + @Test + public void balance() { + constructAsyncTest(Constants.API_BALANCE); + } + + @After + public void postTest() { + mockMvc = null; + } +} \ No newline at end of file diff --git a/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java new file mode 100644 index 0000000000..4ceed870f8 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.web3j.controllers; + +import com.baeldung.web3j.constants.Constants; +import com.baeldung.web3j.services.Web3Service; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class EthereumRestControllerUnitTest { + + private MockMvc mockMvc; + + private void constructAsyncTest(String endpoint) { + try { + MvcResult asyncResult = mockMvc + .perform(get(endpoint)) + .andReturn(); + + mockMvc.perform(asyncDispatch(asyncResult)) + .andDo(print()) + .andExpect(status().isOk()); + + } catch (Exception e) { + System.out.println("Exception: " + e); + } + } + + @Mock + private Web3Service web3Service; + + @InjectMocks + private EthereumRestController ethereumRestController; + + @Before + public void preTest() { + MockitoAnnotations.initMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(ethereumRestController).build(); + } + + @Test + public void accounts() { + constructAsyncTest(Constants.API_ACCOUNTS); + } + + @Test + public void transactions() { + constructAsyncTest(Constants.API_TRANSACTIONS); + } + + @Test + public void block() { + constructAsyncTest(Constants.API_BLOCK); + } + + @Test + public void balance() { + constructAsyncTest(Constants.API_BALANCE); + } + + @After + public void postTest() { + mockMvc = null; + } + +} diff --git a/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java b/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java new file mode 100644 index 0000000000..382c96e985 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.web3j.services; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; + +public class EthereumContractUnitTest { + + private Web3Service web3Service; + + @Before + public void setup() { + web3Service = new Web3Service(); + } + + @Test + public void testContract() { + CompletableFuture result = web3Service.fromScratchContractExample(); + assert (result instanceof CompletableFuture); + } + + @Test + public void sendTx() { + CompletableFuture result = web3Service.sendTx(); + assert (result instanceof CompletableFuture); + } + + @After + public void cleanup() { + } +} diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml deleted file mode 100644 index 6917505f1b..0000000000 --- a/ethereumj/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - com.baeldung.ethereumj - ethereumj - war - 1.0.0 - ethereumj - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - - - - Ethereum - Ethereum - https://dl.bintray.com/ethereum/maven/ - - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.ethereum - ethereumj-core - ${ethereumj-core.version} - - - - org.web3j - core - ${web3j.core.version} - - - - javax.servlet - jstl - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - ethereumj - - - - UTF-8 - 1.8 - 8.5.4 - 1.5.0-RELEASE - 3.3.1 - 2.5.0 - - - \ No newline at end of file diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml new file mode 100644 index 0000000000..d96a589e32 --- /dev/null +++ b/google-web-toolkit/pom.xml @@ -0,0 +1,116 @@ + + + + + 4.0.0 + com.baeldung + google_web_toolkit + war + 1.0-SNAPSHOT + com.baeldung.Google_web_toolkit + + + + + 1.8 + 1.8 + + + UTF-8 + UTF-8 + + + + + + + com.google.gwt + gwt + 2.8.2 + pom + import + + + + + + + com.google.gwt + gwt-servlet + runtime + + + com.google.gwt + gwt-user + provided + + + com.google.gwt + gwt-dev + provided + + + junit + junit + 4.11 + test + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + + + + net.ltgt.gwt.maven + gwt-maven-plugin + 1.0-rc-8 + + + + compile + test + + + + + com.baeldung.Google_web_toolkit + Google_web_toolkit + true + + 1.8 + + + + -compileReport + -XcompilerMetrics + + + ${project.build.directory}/${project.build.finalName} + compile+runtime + + + Google_web_toolkit.html + + + + + + + maven-surefire-plugin + 2.17 + + true + + + + + + diff --git a/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml b/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml new file mode 100644 index 0000000000..1d8ca819d9 --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java b/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java new file mode 100644 index 0000000000..ae0ae7da38 --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java @@ -0,0 +1,108 @@ +package com.baeldung.client; + +import com.baeldung.shared.MessageService; +import com.baeldung.shared.MessageServiceAsync; +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * Entry point classes define onModuleLoad(). + */ +public class Google_web_toolkit implements EntryPoint { + private final MessageServiceAsync messageServiceAsync = GWT.create(MessageService.class); + + public void onModuleLoad() { + Button sendButton = new Button("Submit"); + TextBox nameField = new TextBox(); + nameField.setText("Hi there"); + + Label warningLabel = new Label(); + + sendButton.addStyleName("sendButton"); + + RootPanel.get("nameFieldContainer").add(nameField); + RootPanel.get("sendButtonContainer").add(sendButton); + RootPanel.get("errorLabelContainer").add(warningLabel); + + Button closeButton = new Button("Thanks"); + closeButton.getElement().setId("closeButton"); + + Label textToServerLabel = new Label(); + HTML serverResponseLabel = new HTML(); + VerticalPanel vPanel = new VerticalPanel(); + vPanel.addStyleName("vPanel"); + vPanel.add(new HTML("Sending message to the server:")); + vPanel.add(textToServerLabel); + vPanel.add(new HTML("
Server replies:")); + vPanel.add(serverResponseLabel); + vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT); + vPanel.add(closeButton); + vPanel.setVisible(false); + RootPanel.get("serverResponseContainer").add(vPanel); + + closeButton.addClickHandler(event -> { + sendButton.setEnabled(true); + sendButton.setFocus(true); + vPanel.setVisible(false); + }); + + class MyHandler implements ClickHandler, KeyUpHandler { + + public void onClick(ClickEvent event) { + sendMessageToServer(); + } + + public void onKeyUp(KeyUpEvent event) { + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + sendMessageToServer(); + } + } + + private void sendMessageToServer() { + + warningLabel.setText(""); + String textToServer = nameField.getText(); + if (textToServer == null || textToServer.isEmpty()) { + warningLabel.setText("Please enter the message"); + return; + } + + sendButton.setEnabled(false); + textToServerLabel.setText(textToServer); + serverResponseLabel.setText(""); + messageServiceAsync.sendMessage(textToServer, new AsyncCallback() { + public void onFailure(Throwable caught) { + serverResponseLabel.addStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML("server error occurred"); + closeButton.setFocus(true); + } + + public void onSuccess(String result) { + serverResponseLabel.removeStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML(result); + closeButton.setFocus(true); + vPanel.setVisible(true); + } + }); + } + } + + // Add a handler to send the name to the server + MyHandler handler = new MyHandler(); + sendButton.addClickHandler(handler); + nameField.addKeyUpHandler(handler); + } +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java b/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java new file mode 100644 index 0000000000..41e2a4725c --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java @@ -0,0 +1,22 @@ +package com.baeldung.server; + +import com.baeldung.shared.MessageService; +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import java.time.LocalDateTime; + +/** + * The server-side implementation of the RPC service. + */ +@SuppressWarnings("serial") +public class MessageServiceImpl extends RemoteServiceServlet implements MessageService { + + public String sendMessage(String message) throws IllegalArgumentException { + if (message == null) { + throw new IllegalArgumentException("message is null"); + } + + return "Hello, " + message + "!

Time received: " + LocalDateTime.now(); + } + +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java new file mode 100644 index 0000000000..2c74a5c00d --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java @@ -0,0 +1,12 @@ +package com.baeldung.shared; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +/** + * The client-side stub for the RPC service. + */ +@RemoteServiceRelativePath("greet") +public interface MessageService extends RemoteService { + String sendMessage(String message) throws IllegalArgumentException; +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java new file mode 100644 index 0000000000..49d4a29b7b --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java @@ -0,0 +1,10 @@ +package com.baeldung.shared; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +/** + * The async counterpart of MessageService. + */ +public interface MessageServiceAsync { + void sendMessage(String input, AsyncCallback callback) throws IllegalArgumentException; +} diff --git a/google-web-toolkit/src/main/webapp/Google_web_toolkit.css b/google-web-toolkit/src/main/webapp/Google_web_toolkit.css new file mode 100644 index 0000000000..b02f219589 --- /dev/null +++ b/google-web-toolkit/src/main/webapp/Google_web_toolkit.css @@ -0,0 +1,31 @@ +/** Add css rules here for your application. */ +h1 { + font-size: 2em; + font-weight: bold; + color: #777777; + margin: 40px 0px 70px; + text-align: center; +} + +.sendButton { + display: block; + font-size: 16pt; +} + +/** Most GWT widgets already have a style name defined */ +.gwt-DialogBox { + width: 400px; +} + +.vPanel { + margin: 5px; +} + +.serverResponseLabelError { + color: red; +} + +/** Set ids using widget.getElement().setId("idOfElement") */ +#closeButton { + margin: 15px 6px 6px; +} \ No newline at end of file diff --git a/google-web-toolkit/src/main/webapp/Google_web_toolkit.html b/google-web-toolkit/src/main/webapp/Google_web_toolkit.html new file mode 100644 index 0000000000..20bba68eff --- /dev/null +++ b/google-web-toolkit/src/main/webapp/Google_web_toolkit.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + Sample GWT Application + + + + + +

Sample GWT Application

+ + + + + + + + + + + + + + +
Please enter your message:
+ + \ No newline at end of file diff --git a/google-web-toolkit/src/main/webapp/WEB-INF/web.xml b/google-web-toolkit/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..820d3d9916 --- /dev/null +++ b/google-web-toolkit/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + + + greetServlet + com.baeldung.server.MessageServiceImpl + + + + greetServlet + /google_web_toolkit/greet + + + + + Google_web_toolkit.html + + + diff --git a/google-web-toolkit/src/main/webapp/favicon.ico b/google-web-toolkit/src/main/webapp/favicon.ico new file mode 100644 index 0000000000..858a707523 Binary files /dev/null and b/google-web-toolkit/src/main/webapp/favicon.ico differ diff --git a/hibernate5/README.md b/hibernate5/README.md index afba239919..1bce52bd5e 100644 --- a/hibernate5/README.md +++ b/hibernate5/README.md @@ -12,4 +12,4 @@ - [@Immutable in Hibernate](http://www.baeldung.com/hibernate-immutable) - [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) - [Bootstrapping JPA Programmatically in Java](http://www.baeldung.com/java-bootstrap-jpa) - +- [Optimistic Locking in JPA](http://www.baeldung.com/jpa-optimistic-locking) diff --git a/javax-servlets/README.md b/javax-servlets/README.md index 55ca1116aa..d39a0cca13 100644 --- a/javax-servlets/README.md +++ b/javax-servlets/README.md @@ -5,3 +5,4 @@ - [Uploading Files with Servlets and JSP](http://www.baeldung.com/upload-file-servlet) - [Example of Downloading File in a Servlet](http://www.baeldung.com/servlet-download-file) - [Returning a JSON Response from a Servlet](http://www.baeldung.com/servlet-json-response) +- [Java EE Servlet Exception Handling](http://www.baeldung.com/servlet-exceptions) diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml index f64ce67a1f..fadf0216ce 100644 --- a/javax-servlets/pom.xml +++ b/javax-servlets/pom.xml @@ -1,79 +1,104 @@ - - - 4.0.0 - javax-servlets - 1.0-SNAPSHOT - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - commons-fileupload - commons-fileupload - 1.3.3 - - - commons-io - commons-io - 2.6 - - - - - javax.servlet - javax.servlet-api - 4.0.1 - - - javax.servlet.jsp.jstl - jstl-api - 1.2 - - - javax.servlet.jsp - javax.servlet.jsp-api - 2.3.1 - - - javax.servlet - jstl - 1.2 - - - - org.apache.httpcomponents - httpclient - ${org.apache.httpcomponents.version} - test - - - commons-logging - commons-logging - - - - - com.google.code.gson - gson - ${gson.version} - - - org.springframework - spring-test - ${spring-test.version} - test - - - - - 4.5.3 - 5.0.5.RELEASE - 2.8.2 - - \ No newline at end of file + + + 4.0.0 + com.baeldung.javax-servlets + javax-servlets + 1.0-SNAPSHOT + war + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.9.1 + test + + + org.hamcrest + hamcrest-core + 1.3 + test + + + org.mockito + mockito-core + 2.18.3 + test + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + commons-io + commons-io + 2.6 + + + + + javax.servlet + javax.servlet-api + 4.0.1 + + + javax.servlet.jsp.jstl + jstl-api + 1.2 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.1 + + + javax.servlet + jstl + 1.2 + + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + com.google.code.gson + gson + ${gson.version} + + + org.springframework + spring-test + ${spring-test.version} + test + + + + 3.1.0 + 4.5.3 + 5.0.5.RELEASE + 2.8.2 + + diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java index 9bbf8f4095..b1a6621b24 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -15,21 +14,19 @@ public class DownloadServlet extends HttpServlet { private final int ARBITARY_SIZE = 1048; @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); resp.setHeader("Content-disposition", "attachment; filename=sample.txt"); - - OutputStream out = resp.getOutputStream(); - InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt"); - byte[] buffer = new byte[ARBITARY_SIZE]; - - int numBytesRead; - while ((numBytesRead = in.read(buffer)) > 0) { - out.write(buffer, 0, numBytesRead); + try (InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt"); + OutputStream out = resp.getOutputStream()) { + + byte[] buffer = new byte[ARBITARY_SIZE]; + + int numBytesRead; + while ((numBytesRead = in.read(buffer)) > 0) { + out.write(buffer, 0, numBytesRead); + } } - - in.close(); - out.flush(); } } diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java new file mode 100644 index 0000000000..269cee3922 --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java @@ -0,0 +1,49 @@ +package com.baeldung.servlets; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={ + @WebInitParam(name="name", value="Not provided"), + @WebInitParam(name="email", value="Not provided")}) +public class UserServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + forwardRequest(request, response, "/WEB-INF/jsp/result.jsp"); + } + + protected void processRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + request.setAttribute("name", getRequestParameter(request, "name")); + request.setAttribute("email", getRequestParameter(request, "email")); + request.setAttribute("province", getContextParameter("province")); + request.setAttribute("country", getContextParameter("country")); + } + + protected String getRequestParameter(HttpServletRequest request, String name) { + String param = request.getParameter(name); + return !param.isEmpty() ? param : getInitParameter(name); + } + + protected String getContextParameter(String name) { + return getServletContext().getInitParameter(name); + } + + protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path) + throws ServletException, IOException { + request.getRequestDispatcher(path).forward(request, response); + } +} \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp new file mode 100644 index 0000000000..01cc54858e --- /dev/null +++ b/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp @@ -0,0 +1,16 @@ +<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> +<%@ page contentType="text/html" pageEncoding="UTF-8"%> + + + + + User Data + + +

User Information

+

Name: ${name}

+

Email: ${email}

+

Province: ${province}

+

Country: ${country}

+ + diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml index c9a06ac52d..383be7ff25 100644 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ b/javax-servlets/src/main/webapp/WEB-INF/web.xml @@ -1,9 +1,17 @@ + - + + province + Mendoza + + + country + Argentina + 404 /error-404.html diff --git a/javax-servlets/src/main/webapp/user.jsp b/javax-servlets/src/main/webapp/user.jsp new file mode 100644 index 0000000000..c6e1bb69f9 --- /dev/null +++ b/javax-servlets/src/main/webapp/user.jsp @@ -0,0 +1,19 @@ +<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> +<%@ page contentType="text/html" pageEncoding="UTF-8"%> + + + + Context and Servlet Initialization Parameters + + + +

Please fill the form below:

+
+ + + + + +
+ + diff --git a/javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java b/javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java similarity index 100% rename from javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java rename to javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java diff --git a/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java new file mode 100644 index 0000000000..d4c93791d2 --- /dev/null +++ b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.servlets; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class UserServletUnitTest { + + private static HttpServletRequest request; + private static HttpServletResponse response; + + + @BeforeClass + public static void setUpHttpServletRequestMockInstance() { + request = mock(HttpServletRequest.class); + } + + @BeforeClass + public static void setUpHttpServletResponsetMockInstance() { + response = mock(HttpServletResponse.class); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() { + request.getParameter("name"); + verify(request, atLeast(1)).getParameter("name"); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() { + when(request.getParameter("name")).thenReturn("username"); + assertThat(request.getParameter("name")).isEqualTo("username"); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() { + response.getContentType(); + verify(response, atLeast(1)).getContentType(); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() { + when(response.getContentType()).thenReturn("text/html"); + assertThat(response.getContentType()).isEqualTo("text/html"); + } +} \ No newline at end of file diff --git a/json-path/README.md b/json-path/README.md index 3563dcf880..7a84ea7bde 100644 --- a/json-path/README.md +++ b/json-path/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [Introduction to JsonPath](http://www.baeldung.com/guide-to-jayway-jsonpath) +- [Count with JsonPath](http://www.baeldung.com/jsonpath-count) diff --git a/libraries-data/src/main/resources/db.sql b/libraries-data/src/main/resources/db.sql index 1dac59307b..e6a9ed3fc2 100644 --- a/libraries-data/src/main/resources/db.sql +++ b/libraries-data/src/main/resources/db.sql @@ -1,3 +1,7 @@ +drop table if exists emp; +drop table if exists dept; + + create table dept( deptno numeric, dname varchar(14), diff --git a/libraries/README.md b/libraries/README.md index 3ef6303c88..09ad4ffcdf 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -80,7 +80,11 @@ - [Apache Commons Collections MapUtils](http://www.baeldung.com/apache-commons-map-utils) - [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [Creating REST Microservices with Javalin](http://www.baeldung.com/javalin-rest-microservices) - +- [Introduction to JavaPoet](http://www.baeldung.com/java-poet) +- [Introduction to Joda-Time](http://www.baeldung.com/joda-time) +- [Implementing a FTP-Client in Java](http://www.baeldung.com/java-ftp-client) +- [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date) +- [Histograms with Apache Commons Frequency](http://www.baeldung.com/apache-commons-frequency) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/libraries/pom.xml b/libraries/pom.xml index e3a6656995..a7efd55f1d 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -206,6 +206,12 @@ serenity-core ${serenity.version} test + + + org.asciidoctor + asciidoctorj + +
net.serenity-bdd @@ -699,6 +705,37 @@ ${jctools.version} + + + io.github.resilience4j + resilience4j-circuitbreaker + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-ratelimiter + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-bulkhead + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-retry + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-cache + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-timelimiter + ${resilience4j.version} + org.apache.commons commons-math3 @@ -877,7 +914,7 @@ 1.23.0 0.1.0 0.7.0 - 3.2.4 + 3.2.7 3.6 1.1 1.9.3 @@ -901,10 +938,10 @@ 1.2.0 2.8.5 2.92 - 1.4.0 - 1.24.0 - 1.1.3-rc.5 - 1.4.0 + 1.9.26 + 1.41.0 + 1.9.0 + 1.9.27 1.1.0 4.1.20.Final 4.1 @@ -921,15 +958,14 @@ 0.6.5 0.9.0 15.2 - 2.9.9 1.5.1 2.3.0 - 2.9.9 + 2.10 1.5.1 - 1.14 + 1.15 1.0.3 1.0.0 - 3.8.4 + 3.10.2 2.5.5 1.23.0 v4-rev493-1.21.0 @@ -946,6 +982,7 @@ 0.9.4.0006L 2.1.2 2.5.11 + 0.12.1 3.6.1 3.5.2 3.6 diff --git a/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java b/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java rename to libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java index 2ba1086226..773e39b76a 100644 --- a/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java +++ b/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java @@ -10,7 +10,7 @@ import java.util.function.Function; import static org.junit.Assert.*; import static io.atlassian.fugue.Unit.Unit; -public class FugueTest { +public class FugueUnitTest { @Test public void whenSome_thenDefined() { diff --git a/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java b/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java rename to libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java index 9f670af03c..39384a7442 100644 --- a/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java +++ b/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java @@ -7,7 +7,7 @@ import org.apache.commons.collections4.queue.CircularFifoQueue; import org.junit.Assert; import org.junit.Test; -public class CircularFifoQueueTest { +public class CircularFifoQueueUnitTest { private static final int DEFAULT_SIZE = 32; diff --git a/libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java b/libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java rename to libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java index cd9a7baaf3..3d12662968 100644 --- a/libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java +++ b/libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import static com.baeldung.commons.chain.AtmConstants.*; -public class AtmChainTest { +public class AtmChainUnitTest { public static final int EXPECTED_TOTAL_AMOUNT_TO_BE_WITHDRAWN = 460; public static final int EXPECTED_AMOUNT_LEFT_TO_BE_WITHDRAWN = 0; diff --git a/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java b/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java rename to libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java index f34f431d8e..448c5b0729 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java @@ -18,7 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class CollectionUtilsGuideTest { +public class CollectionUtilsGuideUnitTest { Customer customer1 = new Customer(1, "Daniel", 123456l, "locality1", "city1", "1234"); Customer customer4 = new Customer(4, "Bob", 456789l, "locality4", "city4", "4567"); diff --git a/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java b/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java rename to libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java index 988335b7d1..bad4d823a0 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java @@ -17,7 +17,7 @@ import static org.hamcrest.collection.IsMapWithSize.anEmptyMap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -public class MapUtilsTest { +public class MapUtilsUnitTest { private String[][] color2DArray = new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } }; private String[] color1DArray = new String[] { "RED", "#FF0000", "GREEN", "#00FF00", "BLUE", "#0000FF" }; diff --git a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java b/libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java rename to libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java index 4408dcc195..ebad4093f0 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java +++ b/libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java @@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; -public class BagTests { +public class BagUnitTest { @Test public void givenMultipleCopies_whenAdded_theCountIsKept() { diff --git a/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java b/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java rename to libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java index 6210bb51a9..f93e59ed75 100644 --- a/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java +++ b/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java @@ -15,7 +15,7 @@ import java.util.Map; import static org.junit.Assert.assertEquals; -public class CSVReaderWriterTest { +public class CSVReaderWriterUnitTest { public static final Map AUTHOR_BOOK_MAP = Collections.unmodifiableMap(new LinkedHashMap() { { diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java rename to libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java index 29bcebeb2b..a10f92639c 100644 --- a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java +++ b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java @@ -32,7 +32,7 @@ import org.apache.commons.lang3.time.FastDateFormat; import org.junit.Assert; import org.junit.Test; -public class Lang3UtilsTest { +public class Lang3UtilsUnitTest { @Test public void test_to_Boolean_fromString() { diff --git a/libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java b/libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java rename to libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java index 7e047577e5..bb4dc53eec 100644 --- a/libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java @@ -6,7 +6,7 @@ import org.apache.commons.math3.analysis.integration.UnivariateIntegrator; import org.junit.Assert; import org.junit.Test; -public class IntegrationTest { +public class SimpsonIntegratorUnitTest { @Test public void whenUnivariateIntegratorIntegrate_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java b/libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/crdt/CRDTTest.java rename to libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java index 3d3c952863..840263e430 100644 --- a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java +++ b/libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -public class CRDTTest { +public class CRDTUnitTest { @Test public void givenGrowOnlySet_whenTwoReplicasDiverge_thenShouldMergeItWithoutAConflict() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java index ee369fc75b..b9790e37ea 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class AllSatisfyPatternTest { +public class AllSatisfyPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java index a3314ebee6..d5a736503e 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class AnySatisfyPatternTest { +public class AnySatisfyPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java index b1aaceb09b..ff111a6d72 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java @@ -6,7 +6,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.assertj.core.api.Assertions; import org.junit.Test; -public class CollectPatternTest { +public class CollectPatternUnitTest { @Test public void whenCollect_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java similarity index 92% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java index e279314034..cb2bc11dc0 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java @@ -5,7 +5,7 @@ import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Test; -public class ConvertContainerToAnotherTest { +public class ConvertContainerToAnotherUnitTest { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java index 4ef7348a0d..1479b06593 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class DetectPatternTest { +public class DetectPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java index 3091f90908..b0735267ae 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java @@ -10,7 +10,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; -public class FlatCollectTest { +public class FlatCollectUnitTest { MutableList addresses1; MutableList addresses2; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java index 8cea575222..38d95047ed 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.map.mutable.UnifiedMap; import org.eclipse.collections.impl.tuple.Tuples; import org.junit.Test; -public class ForEachPatternTest { +public class ForEachPatternUnitTest { @SuppressWarnings("unchecked") @Test diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java similarity index 92% rename from libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java index 01a8fcaef4..10448c4474 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java @@ -7,7 +7,7 @@ import java.util.List; import org.eclipse.collections.impl.factory.Lists; import org.junit.Test; -public class InjectIntoPatternTest { +public class InjectIntoPatternUnitTest { @Test public void whenInjectInto_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java index bcb816c34a..0c3418b7b2 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java @@ -6,7 +6,7 @@ import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.factory.Lists; import org.junit.Test; -public class LazyIterationTest { +public class LazyIterationUnitTest { @Test public void whenLazyIteration_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java index 8ef18004aa..e5c27179a9 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class PartitionPatternTest { +public class PartitionPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java index bd743d56e8..b455938b0b 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class RejectPatternTest { +public class RejectPatternUnitTest { MutableList list; MutableList expectedList; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java index 154be08f08..7735daff65 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class SelectPatternTest { +public class SelectPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java index 2b5aa06289..942cdf4595 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java @@ -9,7 +9,7 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; -public class ZipTest { +public class ZipUnitTest { MutableList> expectedPairs; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java index 724f693011..b297d1d1eb 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java @@ -9,7 +9,7 @@ import org.eclipse.collections.impl.tuple.Tuples; import org.junit.Before; import org.junit.Test; -public class ZipWithIndexTest { +public class ZipWithIndexUnitTest { MutableList> expectedPairs; diff --git a/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java rename to libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java index 33952c8669..d62a115abd 100644 --- a/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java +++ b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java @@ -11,7 +11,7 @@ import fj.data.Option; import fj.function.Characters; import fj.function.Integers; -public class FunctionalJavaTest { +public class FunctionalJavaUnitTest { public static final F isEven = i -> i % 2 == 0; diff --git a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java b/libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java rename to libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java index 9210b18f0c..2a9d430430 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java @@ -8,10 +8,12 @@ import org.infinispan.Cache; import org.infinispan.manager.DefaultCacheManager; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import java.util.function.Supplier; -public class ConfigurationTest { +@Ignore +public abstract class AbstractIntegrationTest { private DefaultCacheManager cacheManager; diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java index 0a2ace9ca0..75dae2b2fa 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java @@ -1,11 +1,11 @@ package com.baeldung.infinispan.service; -import com.baeldung.infinispan.ConfigurationTest; +import com.baeldung.infinispan.AbstractIntegrationTest; import org.junit.Test; import static org.assertj.core.api.Java6Assertions.assertThat; -public class HelloWorldServiceIntegrationTest extends ConfigurationTest { +public class HelloWorldServiceIntegrationTest extends AbstractIntegrationTest { @Test public void whenGetIsCalledTwoTimes_thenTheSecondShouldHitTheCache() { diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java index ace99eef36..800c6c2775 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java @@ -1,11 +1,11 @@ package com.baeldung.infinispan.service; -import com.baeldung.infinispan.ConfigurationTest; +import com.baeldung.infinispan.AbstractIntegrationTest; import org.junit.Test; import static org.assertj.core.api.Java6Assertions.assertThat; -public class TransactionalServiceIntegrationTest extends ConfigurationTest { +public class TransactionalServiceIntegrationTest extends AbstractIntegrationTest { @Test public void whenLockingAnEntry_thenItShouldBeInaccessible() throws InterruptedException { diff --git a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java b/libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/jdeffered/AppTest.java rename to libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java index 97b20cda57..80cd16bd53 100644 --- a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java +++ b/libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; -public class AppTest { +public class JDeferredUnitTest { @Test public void givenJob_expectPromise() { diff --git a/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java b/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java index 3cf4f739e8..c2340e9528 100644 --- a/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java +++ b/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java @@ -86,7 +86,6 @@ public class JodaTimeUnitTest { DateTimeUtils.setCurrentMillisFixed(currentTimestamp); LocalDateTime currentDateAndTime = LocalDateTime.now(); - assertEquals(currentTimestamp, currentDateAndTime.toDate().getTime()); assertEquals(new DateTime(currentTimestamp), currentDateAndTime.toDateTime()); assertEquals(new LocalDate(currentTimestamp), currentDateAndTime.toLocalDate()); assertEquals(new LocalTime(currentTimestamp), currentDateAndTime.toLocalTime()); @@ -182,9 +181,6 @@ public class JodaTimeUnitTest { DateTime convertedDateTime = localDateTimeInChicago.toDateTime(DateTimeZone.forID("Europe/Bucharest")); assertEquals("2018-06-21T15:26:23.288+03:00", convertedDateTime.toString()); - - Date convertedDate = localDateTimeInChicago.toDate(TimeZone.getTimeZone("Europe/Bucharest")); - assertEquals("Thu Jun 21 15:26:23 EEST 2018", convertedDate.toString()); } } diff --git a/libraries/src/test/java/com/baeldung/jool/JOOLTest.java b/libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/jool/JOOLTest.java rename to libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java index 2cb393abd3..153014e324 100644 --- a/libraries/src/test/java/com/baeldung/jool/JOOLTest.java +++ b/libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java @@ -21,7 +21,7 @@ import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.assertEquals; import static org.jooq.lambda.tuple.Tuple.tuple; -public class JOOLTest { +public class JOOLUnitTest { @Test public void givenSeq_whenCheckContains_shouldReturnTrue() { List concat = Seq.of(1, 2, 3).concat(Seq.of(4, 5, 6)).toList(); diff --git a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java rename to libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java index c8718aef8d..f9213d9ab5 100644 --- a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java +++ b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java @@ -9,7 +9,7 @@ import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; @RunWith(JUnitParamsRunner.class) -public class SafeAdditionUtilTest { +public class SafeAdditionUtilUnitTest { private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java index 0cab612a7b..903da00995 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java @@ -11,7 +11,7 @@ import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; -public class MBassadorAsyncDispatchTest { +public class MBassadorAsyncDispatchUnitTest { private MBassador dispatcher = new MBassador(); private String testString; diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java index 99ea1aab71..bf20645e2d 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertFalse; -public class MBassadorAsyncInvocationTest { +public class MBassadorAsyncInvocationUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java index 04f6272412..bd05d2888e 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -public class MBassadorBasicTest { +public class MBassadorBasicUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java index 9d9a58aee9..68cfff0014 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java @@ -12,7 +12,7 @@ import java.util.*; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.*; -public class MBassadorConfigurationTest implements IPublicationErrorHandler { +public class MBassadorConfigurationUnitTest implements IPublicationErrorHandler { private MBassador dispatcher; private String messageString; diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java index e90ae15d3d..0094140fee 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -public class MBassadorFilterTest { +public class MBassadorFilterUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java index be5c9d4897..6f1ca83f0a 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import static org.junit.Assert.*; -public class MBassadorHierarchyTest { +public class MBassadorHierarchyUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java b/libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java rename to libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java index b023ffe8d9..e23eea1714 100644 --- a/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java +++ b/libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java @@ -20,7 +20,7 @@ import tec.units.ri.quantity.Quantities; import tec.units.ri.unit.MetricPrefix; import static tec.units.ri.unit.Units.*; -public class WaterTankTests { +public class WaterTankUnitTest { @Test public void givenQuantity_whenGetUnitAndConvertValue_thenSuccess() { diff --git a/libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java b/libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java rename to libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java index 394b3fba4f..fca96684ad 100644 --- a/libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java +++ b/libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -public class OpenCsvTest { +public class OpenCsvIntegrationTest { private Object testReadCsv(Object result) { assert (result != null); diff --git a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java rename to libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java index e9d5b8ede5..871a8a1935 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -public class CollectorUtilsTests { +public class CollectorUtilsUnitTest { @Test public void givenIntegerStream_whenCollectOnMaxByProjection_shouldReturnOptionalMaxValue() { diff --git a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java rename to libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java index ccd43b7777..889641502e 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.toList; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -public class StreamUtilsTests { +public class StreamUtilsUnitTest { @Test public void givenStream_whenZipWithIndex_shouldReturnZippedStreamWithIndex() { @@ -174,7 +174,7 @@ public class StreamUtilsTests { public void givenLimit_withIndices_shouldReturnLongStreamUptoLimit() { LongStream indices = StreamUtils.indices().limit(500); - assertThat(indices.count(), equalTo(500)); + assertThat(indices.count(), equalTo(500L)); } } diff --git a/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java new file mode 100644 index 0000000000..ced95c99cb --- /dev/null +++ b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.resilience4j; + +import io.github.resilience4j.bulkhead.Bulkhead; +import io.github.resilience4j.bulkhead.BulkheadConfig; +import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import io.github.resilience4j.retry.RetryRegistry; +import io.github.resilience4j.timelimiter.TimeLimiter; +import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import org.junit.Before; +import org.junit.Test; + +import java.time.Duration; +import java.util.concurrent.*; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class Resilience4jUnitTest { + + interface RemoteService { + + int process(int i); + } + + private RemoteService service; + + @Before + public void setUp() { + service = mock(RemoteService.class); + } + + @Test + public void whenCircuitBreakerIsUsed_thenItWorksAsExpected() { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + // Percentage of failures to start short-circuit + .failureRateThreshold(20) + // Min number of call attempts + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + CircuitBreaker circuitBreaker = registry.circuitBreaker("my"); + Function decorated = CircuitBreaker.decorateFunction(circuitBreaker, service::process); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + + for (int i = 0; i < 10; i++) { + try { + decorated.apply(i); + } catch (Exception ignore) { + } + } + + verify(service, times(5)).process(any(Integer.class)); + } + + @Test + public void whenBulkheadIsUsed_thenItWorksAsExpected() throws InterruptedException { + BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(1).build(); + BulkheadRegistry registry = BulkheadRegistry.of(config); + Bulkhead bulkhead = registry.bulkhead("my"); + Function decorated = Bulkhead.decorateFunction(bulkhead, service::process); + + Future taskInProgress = callAndBlock(decorated); + try { + assertThat(bulkhead.isCallPermitted()).isFalse(); + } finally { + taskInProgress.cancel(true); + } + } + + private Future callAndBlock(Function decoratedService) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + when(service.process(anyInt())).thenAnswer(invocation -> { + latch.countDown(); + Thread.currentThread().join(); + return null; + }); + + ForkJoinTask result = ForkJoinPool.commonPool().submit(() -> { + decoratedService.apply(1); + }); + latch.await(); + return result; + } + + @Test + public void whenRetryIsUsed_thenItWorksAsExpected() { + RetryConfig config = RetryConfig.custom().maxAttempts(2).build(); + RetryRegistry registry = RetryRegistry.of(config); + Retry retry = registry.retry("my"); + Function decorated = Retry.decorateFunction(retry, (Integer s) -> { + service.process(s); + return null; + }); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + try { + decorated.apply(1); + fail("Expected an exception to be thrown if all retries failed"); + } catch (Exception e) { + verify(service, times(2)).process(any(Integer.class)); + } + } + + @SuppressWarnings("unchecked") + @Test + public void whenTimeLimiterIsUsed_thenItWorksAsExpected() throws Exception { + long ttl = 1; + TimeLimiterConfig config = TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(ttl)).build(); + TimeLimiter timeLimiter = TimeLimiter.of(config); + + Future futureMock = mock(Future.class); + Callable restrictedCall = TimeLimiter.decorateFutureSupplier(timeLimiter, () -> futureMock); + restrictedCall.call(); + + verify(futureMock).get(ttl, TimeUnit.MILLISECONDS); + } +} diff --git a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java index 4cda0b5940..31f3a04362 100644 --- a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java @@ -10,7 +10,7 @@ import java.util.stream.Stream; import static junit.framework.TestCase.assertEquals; -public class JoolMergeStreamsTest { +public class JoolMergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { Stream seq1 = Stream.of(1, 3, 5); diff --git a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java index b8748abe03..38ddb47d87 100644 --- a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -public class MergeStreamsTest { +public class MergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { diff --git a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java index e5392dff2a..220348bf36 100644 --- a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -public class StreamExMergeStreamsTest { +public class StreamExMergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { diff --git a/libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java b/libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java rename to libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java index 3ed797ccaa..5af914afea 100644 --- a/libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java +++ b/libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java @@ -16,7 +16,7 @@ import org.springframework.util.StreamUtils; import static com.baeldung.streamutils.CopyStream.getStringFromInputStream; -public class CopyStreamTest { +public class CopyStreamUnitTest { @Test public void whenCopyInputStreamToOutputStream_thenCorrect() throws IOException { diff --git a/libraries/src/test/java/com/baeldung/text/DiffTest.java b/libraries/src/test/java/com/baeldung/text/DiffUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/DiffTest.java rename to libraries/src/test/java/com/baeldung/text/DiffUnitTest.java index 932fc96f21..f8a5d6fc0c 100644 --- a/libraries/src/test/java/com/baeldung/text/DiffTest.java +++ b/libraries/src/test/java/com/baeldung/text/DiffUnitTest.java @@ -5,7 +5,7 @@ import org.apache.commons.text.diff.StringsComparator; import org.junit.Assert; import org.junit.Test; -public class DiffTest { +public class DiffUnitTest { @Test public void whenEditScript_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java b/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java rename to libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java index e0a00afd84..47cfda1863 100644 --- a/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java +++ b/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java @@ -5,7 +5,7 @@ import org.apache.commons.text.similarity.LongestCommonSubsequenceDistance; import org.junit.Assert; import org.junit.Test; -public class LongestCommonSubsequenceTest { +public class LongestCommonSubsequenceUnitTest { @Test public void whenCompare_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/StrBuilderTest.java b/libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/StrBuilderTest.java rename to libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java index 4ebf00e1ed..09bb7f9a3f 100644 --- a/libraries/src/test/java/com/baeldung/text/StrBuilderTest.java +++ b/libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java @@ -4,7 +4,7 @@ import org.apache.commons.text.StrBuilder; import org.junit.Assert; import org.junit.Test; -public class StrBuilderTest { +public class StrBuilderUnitTest { @Test public void whenReplaced_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java b/libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java rename to libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java index 24e6ff59c8..85f5084485 100644 --- a/libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java +++ b/libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java @@ -7,7 +7,7 @@ import org.apache.commons.text.StrSubstitutor; import org.junit.Assert; import org.junit.Test; -public class StrSubstitutorTest { +public class StrSubstitutorUnitTest { @Test public void whenSubstituted_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java b/libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java similarity index 90% rename from libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java rename to libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java index 5a52bfd0db..5614566949 100644 --- a/libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java +++ b/libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java @@ -4,7 +4,7 @@ import org.apache.commons.text.translate.UnicodeEscaper; import org.junit.Assert; import org.junit.Test; -public class UnicodeEscaperTest { +public class UnicodeEscaperUnitTest { @Test public void whenTranslate_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java b/libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java rename to libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java index 82093ad297..7d3bce5cfe 100644 --- a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java +++ b/libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java @@ -27,7 +27,7 @@ import com.mashape.unirest.http.Unirest; import com.mashape.unirest.http.async.Callback; import com.mashape.unirest.http.exceptions.UnirestException; -public class HttpClientTest { +public class HttpClientLiveTest { @BeforeClass public static void setup() { diff --git a/maven-java-kotlin/pom.xml b/maven-java-kotlin/pom.xml new file mode 100644 index 0000000000..c4011ec884 --- /dev/null +++ b/maven-java-kotlin/pom.xml @@ -0,0 +1,96 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + 4.0.0 + + maven-java-kotlin + jar + + + 1.8 + 1.2.51 + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + + + + default-compile + none + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + + \ No newline at end of file diff --git a/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java b/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java new file mode 100644 index 0000000000..e2cc0f1e01 --- /dev/null +++ b/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java @@ -0,0 +1,26 @@ +package com.baeldung.mavenjavakotlin; + +import com.baeldung.mavenjavakotlin.services.JavaService; +import com.baeldung.mavenjavakotlin.services.KotlinService; + +public class Application { + + private static final String JAVA = "java"; + private static final String KOTLIN = "kotlin"; + + public static void main(String[] args) { + String language = args[0]; + switch (language) { + case JAVA: + new JavaService().sayHello(); + break; + case KOTLIN: + new KotlinService().sayHello(); + break; + default: + // Do nothing + break; + } + } + +} diff --git a/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java b/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java new file mode 100644 index 0000000000..b767e761af --- /dev/null +++ b/maven-java-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java @@ -0,0 +1,9 @@ +package com.baeldung.mavenjavakotlin.services; + +public class JavaService { + + public void sayHello() { + System.out.println("Java says 'Hello World!'"); + } + +} diff --git a/maven-java-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt b/maven-java-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt new file mode 100644 index 0000000000..114b1c88df --- /dev/null +++ b/maven-java-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt @@ -0,0 +1,9 @@ +package com.baeldung.mavenjavakotlin.services + +class KotlinService { + + fun sayHello() { + System.out.println("Kotlin says 'Hello World!'") + } + +} \ No newline at end of file diff --git a/meecrowave/pom.xml b/meecrowave/pom.xml new file mode 100644 index 0000000000..cf13aa1c1b --- /dev/null +++ b/meecrowave/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + apache-meecrowave + 0.0.1 + apache-meecrowave + A sample REST API application with Meecrowave + + + 1.8 + 1.8 + + + + + org.apache.meecrowave + meecrowave-core + 1.2.1 + + + + org.apache.meecrowave + meecrowave-jpa + 1.2.1 + + + + com.squareup.okhttp3 + okhttp + 3.10.0 + + + org.apache.meecrowave + meecrowave-junit + 1.2.0 + test + + + + junit + junit + 4.10 + test + + + + + + + org.apache.meecrowave + meecrowave-maven-plugin + 1.2.1 + + + + \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java new file mode 100644 index 0000000000..7925e8ff99 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java @@ -0,0 +1,30 @@ +package com.baeldung.meecrowave; + +public class Article { + private String name; + private String author; + + public Article() { + } + + public Article(String name, String author) { + this.author = author; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java new file mode 100644 index 0000000000..6cb7012c64 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java @@ -0,0 +1,32 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@RequestScoped +@Path("article") +public class ArticleEndpoints { + + @Inject + ArticleService articleService; + + @GET + public Response getArticle() { + return Response.ok() + .entity(new Article("name", "author")) + .build(); + + } + + @POST + public Response createArticle(Article article) { + return Response.status(Status.CREATED) + .entity(articleService.createArticle(article)) + .build(); + } +} \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java new file mode 100644 index 0000000000..7bd6b87345 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ArticleService { + public Article createArticle(Article article) { + return article; + } +} diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java new file mode 100644 index 0000000000..2aa7d0556f --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java @@ -0,0 +1,16 @@ +package com.baeldung.meecrowave; + +import org.apache.meecrowave.Meecrowave; + +public class Server { + public static void main(String[] args) { + final Meecrowave.Builder builder = new Meecrowave.Builder(); + builder.setScanningPackageIncludes("com.baeldung.meecrowave"); + builder.setJaxrsMapping("/api/*"); + builder.setJsonpPrettify(true); + + try (Meecrowave meecrowave = new Meecrowave(builder)) { + meecrowave.bake().await(); + } + } +} diff --git a/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java b/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java new file mode 100644 index 0000000000..0dc9773490 --- /dev/null +++ b/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.meecrowave; + + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.meecrowave.Meecrowave; +import org.apache.meecrowave.junit.MonoMeecrowave; +import org.apache.meecrowave.testing.ConfigurationInject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@RunWith(MonoMeecrowave.Runner.class) +public class ArticleEndpointsTest { + + @ConfigurationInject + private Meecrowave.Builder config; + private static OkHttpClient client; + + @BeforeClass + public static void setup() { + client = new OkHttpClient(); + } + + @Test + public void whenRetunedArticle_thenCorrect() throws IOException { + final String base = "http://localhost:"+config.getHttpPort(); + + Request request = new Request.Builder() + .url(base+"/article") + .build(); + Response response = client.newCall(request).execute(); + assertEquals(200, response.code()); + } +} diff --git a/micronaut/hello-world/.mvn/jvm.config b/micronaut/hello-world/.mvn/jvm.config new file mode 100644 index 0000000000..4967c447ae --- /dev/null +++ b/micronaut/hello-world/.mvn/jvm.config @@ -0,0 +1 @@ +-noverify -XX:TieredStopAtLevel=1 \ No newline at end of file diff --git a/micronaut/hello-world/.mvn/wrapper/MavenWrapperDownloader.java b/micronaut/hello-world/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000000..d475a89ce1 --- /dev/null +++ b/micronaut/hello-world/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/micronaut/hello-world/.mvn/wrapper/maven-wrapper.jar b/micronaut/hello-world/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000..08ebbb67f0 Binary files /dev/null and b/micronaut/hello-world/.mvn/wrapper/maven-wrapper.jar differ diff --git a/micronaut/hello-world/.mvn/wrapper/maven-wrapper.properties b/micronaut/hello-world/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..42fa4da219 --- /dev/null +++ b/micronaut/hello-world/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip \ No newline at end of file diff --git a/micronaut/hello-world/Dockerfile b/micronaut/hello-world/Dockerfile new file mode 100644 index 0000000000..ed4be82e8e --- /dev/null +++ b/micronaut/hello-world/Dockerfile @@ -0,0 +1,4 @@ +FROM java:openjdk-8u111-alpine +RUN apk --no-cache add curl +COPY build/libs/*-all.jar hello-world-server.jar +CMD java ${JAVA_OPTS} -jar hello-world-server.jar \ No newline at end of file diff --git a/micronaut/hello-world/micronaut-cli.yml b/micronaut/hello-world/micronaut-cli.yml new file mode 100644 index 0000000000..fe56560074 --- /dev/null +++ b/micronaut/hello-world/micronaut-cli.yml @@ -0,0 +1,5 @@ +profile: service +defaultPackage: hello.world.server +--- +testFramework: junit +sourceLanguage: java \ No newline at end of file diff --git a/micronaut/hello-world/mvnw b/micronaut/hello-world/mvnw new file mode 100755 index 0000000000..961a825001 --- /dev/null +++ b/micronaut/hello-world/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/micronaut/hello-world/mvnw.cmd b/micronaut/hello-world/mvnw.cmd new file mode 100755 index 0000000000..03d90e960b --- /dev/null +++ b/micronaut/hello-world/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/micronaut/hello-world/pom.xml b/micronaut/hello-world/pom.xml new file mode 100644 index 0000000000..56d051e506 --- /dev/null +++ b/micronaut/hello-world/pom.xml @@ -0,0 +1,139 @@ + + 4.0.0 + com.baeldung.micronaut + hello-world + 0.1 + + com.baeldung.micronaut.helloworld.server.ServerApplication + 1.0.0.M2 + 9 + + + + jcenter.bintray.com + http://jcenter.bintray.com + + + + + + io.micronaut + bom + ${micronaut.version} + pom + import + + + + + + io.micronaut + http-client + compile + + + io.micronaut + http-server-netty + compile + + + io.micronaut + inject + compile + + + io.micronaut + runtime + compile + + + javax.annotation + javax.annotation-api + 1.3.2 + compile + + + io.micronaut + inject-java + provided + + + ch.qos.logback + logback-classic + 1.2.3 + runtime + + + junit + junit + 4.12 + test + + + io.projectreactor + reactor-core + 3.1.6.RELEASE + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + ${exec.mainClass} + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + + -classpath + + ${exec.mainClass} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${jdk.version} + ${jdk.version} + + -parameters + + + + io.micronaut + inject-java + ${micronaut.version} + + + + + + + + diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java new file mode 100644 index 0000000000..d4051cef52 --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java @@ -0,0 +1,28 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.Client; +import io.micronaut.http.client.RxHttpClient; +import io.reactivex.Single; + +import javax.inject.Singleton; + +@Singleton +public class ConcreteGreetingClient +{ + private RxHttpClient httpClient; + + public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) { + this.httpClient = httpClient; + } + + public String greet(String name) { + HttpRequest req = HttpRequest.GET("/greet/" + name); + return httpClient.retrieve(req).blockingFirst(); + } + + public Single greetAsync(String name) { + HttpRequest req = HttpRequest.GET("/async/greet/" + name); + return httpClient.retrieve(req).first("An error as occurred"); + } +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java new file mode 100644 index 0000000000..8a691d5b06 --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java @@ -0,0 +1,14 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.http.annotation.Get; +import io.micronaut.http.client.Client; +import io.micronaut.http.client.RxHttpClient; + +import javax.inject.Inject; + +@Client("/greet") +public interface GreetingClient { + + @Get("/{name}") + String greet(String name); +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java new file mode 100644 index 0000000000..c5936051dd --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java @@ -0,0 +1,10 @@ +package com.baeldung.micronaut.helloworld.server; + +import io.micronaut.runtime.Micronaut; + +public class ServerApplication { + + public static void main(String[] args) { + Micronaut.run(ServerApplication.class); + } +} \ No newline at end of file diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java new file mode 100644 index 0000000000..4d86b9dfed --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java @@ -0,0 +1,20 @@ +package com.baeldung.micronaut.helloworld.server.controller; + +import com.baeldung.micronaut.helloworld.server.service.GreetingService; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.reactivex.Single; + +import javax.inject.Inject; + +@Controller("/async/greet") +public class AsyncGreetController { + + @Inject + private GreetingService greetingService; + + @Get("/{name}") + public Single greet(String name) { + return Single.just(greetingService.getGreeting() + name); + } +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java new file mode 100644 index 0000000000..c890c037e4 --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java @@ -0,0 +1,28 @@ +package com.baeldung.micronaut.helloworld.server.controller; + +import com.baeldung.micronaut.helloworld.server.service.GreetingService; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.Body; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Post; + +import javax.inject.Inject; + +@Controller("/greet") +public class GreetController { + + @Inject + private GreetingService greetingService; + + @Get("/{name}") + public String greet(String name) { + return greetingService.getGreeting() + name; + } + + @Post(value = "/{name}", consumes = MediaType.TEXT_PLAIN) + public String setGreeting(@Body String name) + { + return greetingService.getGreeting() + name; + } +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java new file mode 100644 index 0000000000..8ea5172cf6 --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java @@ -0,0 +1,14 @@ +package com.baeldung.micronaut.helloworld.server.service; + +import io.micronaut.context.annotation.Primary; + +import javax.inject.Singleton; + +@Primary +@Singleton +public class EnglishGreetingService implements GreetingService { + @Override + public String getGreeting() { + return "Hello "; + } +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java new file mode 100644 index 0000000000..6e28baaebe --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java @@ -0,0 +1,6 @@ +package com.baeldung.micronaut.helloworld.server.service; + +public interface GreetingService { + + String getGreeting(); +} diff --git a/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java new file mode 100644 index 0000000000..1ec53d8b2d --- /dev/null +++ b/micronaut/hello-world/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java @@ -0,0 +1,11 @@ +package com.baeldung.micronaut.helloworld.server.service; + +import javax.inject.Singleton; + +@Singleton +public class SpanishGreetingService implements GreetingService { + @Override + public String getGreeting() { + return "Hola "; + } +} diff --git a/micronaut/hello-world/src/main/resources/application.yml b/micronaut/hello-world/src/main/resources/application.yml new file mode 100644 index 0000000000..4119026dd6 --- /dev/null +++ b/micronaut/hello-world/src/main/resources/application.yml @@ -0,0 +1,5 @@ +micronaut: + application: + name: hello-world-server + server: + port: 9080 \ No newline at end of file diff --git a/micronaut/hello-world/src/main/resources/logback.xml b/micronaut/hello-world/src/main/resources/logback.xml new file mode 100644 index 0000000000..afaebf8e17 --- /dev/null +++ b/micronaut/hello-world/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java b/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java new file mode 100644 index 0000000000..c8c1d6b12a --- /dev/null +++ b/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java @@ -0,0 +1,38 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.context.ApplicationContext; +import io.micronaut.runtime.server.EmbeddedServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class ConcreteGreetingClientTest +{ + private EmbeddedServer server; + private ConcreteGreetingClient client; + + @Before + public void setup() + { + server = ApplicationContext.run(EmbeddedServer.class); + client = server.getApplicationContext().getBean(ConcreteGreetingClient.class); + } + + @After + public void cleanup() + { + server.stop(); + } + + @Test + public void testGreeting() { + assertEquals(client.greet("Mike"), "Hello Mike"); + } + + @Test + public void testGreetingAsync() { + assertEquals(client.greetAsync("Mike").blockingGet(), "Hello Mike"); + } +} diff --git a/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java b/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java new file mode 100644 index 0000000000..0f2ca460ac --- /dev/null +++ b/micronaut/hello-world/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java @@ -0,0 +1,32 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.context.ApplicationContext; +import io.micronaut.runtime.server.EmbeddedServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class GreetingClientTest { + private EmbeddedServer server; + private GreetingClient client; + + @Before + public void setup() + { + server = ApplicationContext.run(EmbeddedServer.class); + client = server.getApplicationContext().getBean(GreetingClient.class); + } + + @After + public void cleanup() + { + server.stop(); + } + + @Test + public void testGreeting() { + assertEquals(client.greet("Mike"), "Hello Mike"); + } +} diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 87479d5e2f..84e1a29a0d 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -31,6 +31,7 @@ 5.0.6.RELEASE 5.0.2 + 2.9.6 \ No newline at end of file diff --git a/patterns/README.md b/patterns/README.md index df39b39224..7d58260cf0 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -4,4 +4,5 @@ - [Implementing the Template Method Pattern in Java](http://www.baeldung.com/java-template-method-pattern) - [Chain of Responsibility Design Pattern in Java](http://www.baeldung.com/chain-of-responsibility-pattern) - [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern) +- [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern) diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index 77ead0b317..8b9d7a8193 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -9,3 +9,4 @@ - [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) - [Composite Design Pattern in Java](http://www.baeldung.com/java-composite-pattern) - [Visitor Design Pattern in Java](http://www.baeldung.com/java-visitor-pattern) +- [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern) diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Context.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Context.java new file mode 100644 index 0000000000..f2416988ea --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Context.java @@ -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> tables = new HashMap<>(); + + static { + List 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 matchAnyString = s -> s.length() > 0; + private static final Function> matchAllColumns = Stream::of; + /** + * Varies based on setup in subclasses of {@link Expression} + */ + private Predicate whereFilter = matchAnyString; + private Function> columnMapper = matchAllColumns; + + void setColumn(String column) { + this.column = column; + setColumnMapper(); + } + + void setTable(String table) { + this.table = table; + } + + void setFilter(Predicate filter) { + whereFilter = filter; + } + + /** + * Clears the context to defaults. + * No filters, match all columns. + */ + void clear() { + column = ""; + columnMapper = matchAllColumns; + whereFilter = matchAnyString; + } + + List search() { + + List 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]); + } + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Expression.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Expression.java new file mode 100644 index 0000000000..7f0893e719 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Expression.java @@ -0,0 +1,7 @@ +package com.baeldung.interpreter; + +import java.util.List; + +interface Expression { + List interpret(Context ctx); +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/From.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/From.java new file mode 100644 index 0000000000..d0690e3e85 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/From.java @@ -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 interpret(Context ctx) { + ctx.setTable(table); + if (where == null) { + return ctx.search(); + } + return where.interpret(ctx); + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/InterpreterDemo.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/InterpreterDemo.java new file mode 100644 index 0000000000..9b37037bb9 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/InterpreterDemo.java @@ -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 result = query.interpret(ctx); + System.out.println(result); + + Expression query2 = new Select("*", new From("people")); + List result2 = query2.interpret(ctx); + System.out.println(result2); + + Expression query3 = new Select("name", new From("people", new Where(name -> name.toLowerCase().startsWith("d")))); + List result3 = query3.interpret(ctx); + System.out.println(result3); + } +} diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Row.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Row.java new file mode 100644 index 0000000000..00fd2d993a --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Row.java @@ -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; + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Select.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Select.java new file mode 100644 index 0000000000..f235ce2a87 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Select.java @@ -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 interpret(Context ctx) { + ctx.setColumn(column); + return from.interpret(ctx); + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Where.java b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Where.java new file mode 100644 index 0000000000..b31fa54cff --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/interpreter/Where.java @@ -0,0 +1,19 @@ +package com.baeldung.interpreter; + +import java.util.List; +import java.util.function.Predicate; + +class Where implements Expression { + + private Predicate filter; + + Where(Predicate filter) { + this.filter = filter; + } + + @Override + public List interpret(Context ctx) { + ctx.setFilter(filter); + return ctx.search(); + } +} \ No newline at end of file diff --git a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java similarity index 99% rename from persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java rename to persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java index 9eb00b3651..eda9ca15e4 100644 --- a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java +++ b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java @@ -16,7 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class ArticleRepositoryIntegrationTest { +public class ArticleRepositoryLiveTest { private static final String TABLE_NAME = "articles"; diff --git a/persistence-modules/java-jpa/src/main/resources/database.sql b/persistence-modules/java-jpa/src/main/resources/database.sql index 0c93dafdc7..bd2bb68599 100644 --- a/persistence-modules/java-jpa/src/main/resources/database.sql +++ b/persistence-modules/java-jpa/src/main/resources/database.sql @@ -14,4 +14,4 @@ CREATE TABLE SCHEDULE_DAYS INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (1, 'FRIDAY'); INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (2, 'SATURDAY'); INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'MONDAY'); -INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'FRIDAY'); \ No newline at end of file +INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'FRIDAY'); diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index b1b7c8237b..b19c3b9c93 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -5,8 +5,8 @@ spring-boot-dynamodb 0.0.1-SNAPSHOT jar - Spring Boot Actuator - This is simple boot application for Spring boot actuator test + spring-boot-dynamodb + This is simple boot application for Spring boot dynamodb test parent-boot-1 diff --git a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java index 271c1e29ab..9278c0a12e 100644 --- a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java +++ b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java @@ -1,14 +1,18 @@ package com.baeldung.spring.data.dynamodb.config; +import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; -import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; @Configuration @EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.data.dynamodb.repositories") @@ -22,6 +26,9 @@ public class DynamoDBConfig { @Value("${amazon.aws.secretkey}") private String amazonAWSSecretKey; + + @Autowired + private ApplicationContext context; @Bean public AmazonDynamoDB amazonDynamoDB() { @@ -37,4 +44,8 @@ public class DynamoDBConfig { return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey); } + @Bean(name = "mvcHandlerMappingIntrospector") + public HandlerMappingIntrospector mvcHandlerMappingIntrospector() { + return new HandlerMappingIntrospector(context); + } } diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index c5e0049e83..cef12f5be7 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -70,6 +70,11 @@ spring-data-commons ${spring-data-commons.version} + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} +
@@ -79,6 +84,7 @@ 2.9.0 0.10.0 2.0.3.RELEASE + 0.6 diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java index 4ea8bb4bc0..62a7886f46 100644 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java @@ -1,8 +1,10 @@ package com.baeldung.spring.data.redis.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; @@ -18,6 +20,7 @@ import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; @Configuration @ComponentScan("com.baeldung.spring.data.redis") @EnableRedisRepositories(basePackages = "com.baeldung.spring.data.redis.repo") +@PropertySource("classpath:application.properties") public class RedisConfig { @Bean diff --git a/persistence-modules/spring-data-redis/src/main/resources/application.properties b/persistence-modules/spring-data-redis/src/main/resources/application.properties new file mode 100644 index 0000000000..49886b3b70 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.redis.host=localhost +spring.redis.port=6379 \ No newline at end of file diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java index 01dbfcff4d..5bc70069c5 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java @@ -1,24 +1,44 @@ package com.baeldung.spring.data.redis; -import com.baeldung.spring.data.redis.config.RedisConfig; -import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; -import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import java.util.UUID; - import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.redis.config.RedisConfig; +import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class RedisMessageListenerIntegrationTest { + private static redis.embedded.RedisServer redisServer; + @Autowired private RedisMessagePublisher redisMessagePublisher; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void testOnMessage() throws Exception { diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java index 66ef3c21b2..48832a8de9 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java @@ -3,13 +3,17 @@ package com.baeldung.spring.data.redis.repo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -18,10 +22,24 @@ import com.baeldung.spring.data.redis.model.Student; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class StudentRepositoryIntegrationTest { @Autowired private StudentRepository studentRepository; + + private static redis.embedded.RedisServer redisServer; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void whenSavingStudent_thenAvailableOnRetrieval() throws Exception { diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml index 09314c67b1..263e902e7c 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml @@ -17,7 +17,7 @@ - + diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml index e7ef9ad765..f39817383b 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml @@ -5,7 +5,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" > - + diff --git a/pom.xml b/pom.xml index e1b85e27c0..d6c440a194 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ couchbase deltaspike dozer - ethereumj + ethereum feign flips @@ -54,6 +54,7 @@ geotools testing-modules/groovy-spock google-cloud + google-web-toolkit gson guava guava-modules/guava-18 @@ -91,7 +92,7 @@ jsoup testing-modules/junit-5 jws - + libraries libraries-data linkrest logging-modules/log-mdc @@ -145,8 +146,10 @@ spring-boot-bootstrap spring-boot-admin spring-boot-ops + spring-boot-persistence spring-boot-security spring-boot-mvc + spring-boot-logging-log4j2 spring-cloud-data-flow spring-cloud spring-core @@ -181,14 +184,12 @@ spring-katharsis spring-ldap spring-mockito - spring-mvc-email spring-mvc-forms-jsp spring-mvc-forms-thymeleaf spring-mvc-java spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - spring-mvc-simple spring-mvc-kotlin spring-security-openid spring-protobuf @@ -264,11 +265,13 @@ java-spi performance-tests twilio - spring-boot-ctx-fluent + spring-boot-ctx-fluent java-ee-8-security-api spring-webflux-amqp antlr - maven-archetype + maven-archetype + maven-java-kotlin + apache-meecrowave @@ -372,8 +375,8 @@ org.apache.maven.plugins maven-pmd-plugin - 3.9.0 - + 3.8 + org.baeldung.pmd custom-pmd @@ -392,6 +395,9 @@ ${tutorialsproject.basedir}/baeldung-pmd-rules.xml + + target/generated-sources + diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java new file mode 100644 index 0000000000..1d3e1b3f8a --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java @@ -0,0 +1,59 @@ +package com.baeldung.rxjava; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; + +public class MultipleSubscribersColdObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersColdObs.class); + + public static void main(String[] args) throws InterruptedException { + defaultBehaviour(); + // subscribeBeforeConnect(); + + } + + private static void defaultBehaviour() { + Observable obs = getObservable(); + + LOGGER.info("Subscribing"); + Subscription s1 = obs.subscribe(i -> LOGGER.info("subscriber#1 is printing " + i)); + Subscription s2 = obs.subscribe(i -> LOGGER.info("subscriber#2 is printing " + i)); + + s1.unsubscribe(); + s2.unsubscribe(); + } + + private static void subscribeBeforeConnect() throws InterruptedException { + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("Subscribing"); + obs.subscribe(i -> LOGGER.info("subscriber #1 is printing " + i)); + obs.subscribe(i -> LOGGER.info("subscriber #2 is printing " + i)); + Thread.sleep(1000); + LOGGER.info("Connecting"); + Subscription s = obs.connect(); + s.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + subscriber.onNext(gettingValue(1)); + subscriber.onNext(gettingValue(2)); + + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + })); + }); + } + + private static Integer gettingValue(int i) { + LOGGER.info("Getting " + i); + return i; + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java new file mode 100644 index 0000000000..686c230003 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java @@ -0,0 +1,152 @@ +package com.baeldung.rxjava; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.JFrame; +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MultipleSubscribersHotObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersHotObs.class); + private static JFrame frame; + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + defaultBehaviour(); + // subscribeBeforeConnect(); + // connectBeforeSubscribe(); + // autoConnectAndSubscribe(); + // refCountAndSubscribe(); + } + + private static void createAndShowGUI() { + frame = new JFrame("Hot Observable Demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setBackground(Color.GRAY); + frame.setPreferredSize(new Dimension(500, 500)); + frame.pack(); + frame.setVisible(true); + } + + public static void defaultBehaviour() throws InterruptedException { + Observable obs = getObservable(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + } + + public static void subscribeBeforeConnect() throws InterruptedException { + + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("unsubscribe connected"); + s.unsubscribe(); + + } + + public static void connectBeforeSubscribe() throws InterruptedException { + + ConnectableObservable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish(); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + s.unsubscribe(); + + } + + public static void autoConnectAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().autoConnect(); + + LOGGER.info("autoconnect()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription s1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription s2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe 1"); + s1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe 2"); + s2.unsubscribe(); + } + + public static void refCountAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().refCount(); + + LOGGER.info("refcount()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + frame.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + subscriber.onNext(e.getX()); + } + }); + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + for (MouseListener listener : frame.getListeners(MouseListener.class)) { + frame.removeMouseListener(listener); + } + })); + }); + } +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/Constants.java b/spring-5-mvc/src/main/java/com/baeldung/Constants.java new file mode 100644 index 0000000000..472f3280b7 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/Constants.java @@ -0,0 +1,21 @@ +package com.baeldung; + +public class Constants { + + public static final String GENERIC_EXCEPTION = "Exception encountered!"; + + /** + * API endpoints. + */ + public static final String API_RBE = "/rbe"; + public static final String API_SSE = "/sse"; + public static final String API_SRB = "/srb"; + + /** + * API Responses. + */ + public static final String API_RBE_MSG = "I Was Sent From a Response Body Emitter!"; + public static final String API_SSE_MSG = "I Was Sent From a Sse!"; + public static final String API_SRB_MSG = "I Was Sent From a Streaming Response Body!"; + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java index a9ffee14da..b06f50b742 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java +++ b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java @@ -49,8 +49,6 @@ public class Foo { this.name = name; } - // - @Override public int hashCode() { final int prime = 31; diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java index cf78977961..fa07555bba 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java +++ b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java @@ -16,8 +16,6 @@ public class DataSetupBean implements InitializingBean { @Autowired private FooRepository repo; - // - @Override public void afterPropertiesSet() throws Exception { IntStream.range(1, 5).forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java new file mode 100644 index 0000000000..4af8eb9bd3 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java @@ -0,0 +1,35 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; + +@Controller +public class ResponseBodyEmitterController { + + @GetMapping(Constants.API_RBE) + public ResponseEntity handleRbe() { + ResponseBodyEmitter emitter = new ResponseBodyEmitter(); + ExecutorService nonBlockingService = Executors.newSingleThreadExecutor(); + + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_RBE_MSG + " @ " + new Date(), MediaType.TEXT_PLAIN); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return new ResponseEntity(emitter, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java new file mode 100644 index 0000000000..390178aaef --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java @@ -0,0 +1,32 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@Controller +public class SseEmitterController { + + @GetMapping(Constants.API_SSE) + public SseEmitter handleSse() { + SseEmitter emitter = new SseEmitter(); + + ExecutorService nonBlockingService = Executors.newSingleThreadExecutor(); + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_SSE_MSG + " @ " + new Date()); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return emitter; + } + +} \ No newline at end of file diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java new file mode 100644 index 0000000000..1722ad85cd --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java @@ -0,0 +1,23 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +@Controller +public class StreamingResponseBodyController { + + @GetMapping(Constants.API_SRB) + public ResponseEntity handleRbe() { + StreamingResponseBody stream = out -> { + String msg = Constants.API_SRB_MSG + " @ " + new Date(); + out.write(msg.getBytes()); + }; + return new ResponseEntity(stream, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp new file mode 100644 index 0000000000..df5baf7adb --- /dev/null +++ b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp @@ -0,0 +1,86 @@ +<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> + + + + + + + Spring MVC Async + " rel="stylesheet"> + + +
+

Spring MVC Async

+
+
+
+
+ + + diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java new file mode 100644 index 0000000000..a50651ced7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java @@ -0,0 +1,55 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; + +@Component +public class GlobalErrorAttributes extends DefaultErrorAttributes{ + + private HttpStatus status = HttpStatus.BAD_REQUEST; + private String message = "please provide a name"; + + public GlobalErrorAttributes() { + super(false); + } + + @Override + public Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { + Map map = super.getErrorAttributes(request, includeStackTrace); + map.put("status", getStatus()); + map.put("message", getMessage()); + return map; + } + + /** + * @return the status + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + + /** + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * @param message the message to set + */ + public void setMessage(String message) { + this.message = message; + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java new file mode 100644 index 0000000000..09bccb0d5e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java @@ -0,0 +1,47 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +@Order(-2) +public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + + public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext, + ServerCodecConfigurer serverCodecConfigurer) { + super(g, new ResourceProperties(), applicationContext); + super.setMessageWriters(serverCodecConfigurer.getWriters()); + super.setMessageReaders(serverCodecConfigurer.getReaders()); + } + + @Override + protected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + private Mono renderErrorResponse(final ServerRequest request) { + + final Map errorPropertiesMap = getErrorAttributes(request, false); + + return ServerResponse.status(HttpStatus.BAD_REQUEST) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(BodyInserters.fromObject(errorPropertiesMap)); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java new file mode 100644 index 0000000000..38d35544a7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java @@ -0,0 +1,12 @@ + +package com.baeldung.reactive.errorhandling; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class NameRequiredException extends ResponseStatusException { + + public NameRequiredException(HttpStatus status, String message, Throwable e) { + super(status, message, e); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java new file mode 100644 index 0000000000..87b78a4654 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java @@ -0,0 +1,29 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler1 { + + public Mono handleRequest1(ServerRequest request) { + return sayHello(request).onErrorReturn("Hello, Stranger") + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java new file mode 100644 index 0000000000..12172a0f54 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java @@ -0,0 +1,38 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler2 { + +public Mono handleRequest2(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> sayHelloFallback() + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + + private Mono sayHelloFallback() { + return Mono.just("Hello, Stranger"); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java new file mode 100644 index 0000000000..e95b039cce --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java @@ -0,0 +1,34 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler3 { + + public Mono handleRequest3(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + + e.getMessage())).flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java new file mode 100644 index 0000000000..3d6ef258d3 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java @@ -0,0 +1,30 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import com.baeldung.reactive.errorhandling.NameRequiredException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler4 { + +public Mono handleRequest4(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request) + .onErrorResume(e -> + Mono.error(new NameRequiredException( + HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name").get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java new file mode 100644 index 0000000000..41605b355b --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler5 { + + public Mono handleRequest5(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request), String.class); + + } + + private Mono sayHello(ServerRequest request) { + return Mono.just("Hello, " + request.queryParam("name").get()); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java new file mode 100644 index 0000000000..91be24571c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler1; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router1 { + + @Bean + public RouterFunction routeRequest1(Handler1 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java new file mode 100644 index 0000000000..bc7831f494 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler2; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router2 { + + @Bean + public RouterFunction routeRequest2(Handler2 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java new file mode 100644 index 0000000000..461e6fe9e7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler3; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router3 { + + @Bean + public RouterFunction routeRequest3(Handler3 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java new file mode 100644 index 0000000000..9dccc6858f --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler4; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router4 { + + @Bean + public RouterFunction routeRequest4(Handler4 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java new file mode 100644 index 0000000000..59fd587fc8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler5; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router5 { + + @Bean + public RouterFunction routeRequest5(Handler5 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..5220ea2f4c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive.responseheaders.controllers; + +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/response-header") +public class ResponseHeaderController { + + @GetMapping("/response-entity") + public Mono> usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return Mono.just(ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody)); + } + + @GetMapping("/server-http-response") + public Mono usingServerHttpResponse(ServerHttpResponse response) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ServerHttpResponse"; + String responseBody = "Response with header using ServerHttpResponse"; + + response.getHeaders().add(responseHeaderKey, responseHeaderValue); + return Mono.just(responseBody); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java new file mode 100644 index 0000000000..8d8484f5cd --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.filter; + +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import reactor.core.publisher.Mono; + +@Component +public class AddResponseHeaderWebFilter implements WebFilter { + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + exchange.getResponse() + .getHeaders() + .add("Baeldung-Example-Filter-Header", "Value-Filter"); + return chain.filter(exchange); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java new file mode 100644 index 0000000000..20f76d3b6e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java @@ -0,0 +1,21 @@ +package com.baeldung.reactive.responseheaders.functional.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + +@Component +public class ResponseHeaderHandler { + + public Mono useHandler(final ServerRequest request) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-Handler"; + String responseBody = "Response with header using Handler"; + + return ServerResponse.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(Mono.just(responseBody),String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java new file mode 100644 index 0000000000..63f7c7f036 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.reactive.responseheaders.functional.handlers.ResponseHeaderHandler; + +@Configuration +public class ResponseHeadersRouterFunctions { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired ResponseHeaderHandler handler) { + return RouterFunctions.route(RequestPredicates.GET("/functional-response-header/single-handler"), handler::useHandler); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java new file mode 100644 index 0000000000..bea2eaa75f --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java @@ -0,0 +1,168 @@ +package com.baeldung.reactive.errorhandling; + +import java.io.IOException; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) +public class ErrorHandlingIntegrationTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + public void givenErrorReturn_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + + } + + @Test + public void givenErrorReturn_whenNoUsername_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + } + + @Test + public void givenResumeFallback_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint2?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeFallback_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint2") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + + } + + @Test + public void givenResumeDynamicValue_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint3?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeDynamicValue_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint3") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hi, I looked around for your name but found: No value present", s); + } + + @Test + public void givenResumeRethrow_whenUsernamePresent_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint4?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeRethrow_whenNoUsername_thenOk() throws IOException { + + webTestClient.get() + .uri("/api/endpoint4") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + } + + @Test + public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint5?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenGlobalErrorHandling_whenNoUsername_thenOk() throws IOException { + webTestClient.get() + .uri("/api/endpoint5") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + + } + +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..db563e27d1 --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,63 @@ +package com.baeldung.reactive.responseheaders; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8080"; + private static final String ANNOTATION_BASE_URL = BASE_URL + "/response-header"; + private static final String FUNCTIONAL_BASE_URL = BASE_URL + "/functional-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER_VALUE = "Value-Filter"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + } + + @Test + public void whenUsingResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeaders() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/response-entity") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ResponseEntityBuilder") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingServerHttpResponseRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/server-http-response") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ServerHttpResponse") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingFunctionalHandlerRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(FUNCTIONAL_BASE_URL + "/single-handler") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-Handler") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } +} diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java new file mode 100644 index 0000000000..edb9b7cfa5 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java @@ -0,0 +1,172 @@ +package org.baeldung.batchscheduler; + +import java.util.Date; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.baeldung.batchscheduler.model.Book; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; +import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.ScheduledMethodRunnable; + +@Configuration +@EnableBatchProcessing +@EnableScheduling +public class SpringBatchScheduler { + + private final Logger logger = LoggerFactory.getLogger(SpringBatchScheduler.class); + + private AtomicBoolean enabled = new AtomicBoolean(true); + + private Date currentLaunchDate; + + private final Map> scheduledTasks = new IdentityHashMap<>(); + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @Scheduled(fixedRate = 2000) + public void launchJob() throws Exception { + Date date = new Date(); + logger.debug("scheduler starts at " + date); + if (enabled.get()) { + currentLaunchDate = date; + JobExecution jobExecution = jobLauncher().run(job(), new JobParametersBuilder().addDate("launchDate", currentLaunchDate) + .toJobParameters()); + logger.debug("Batch job ends with status as " + jobExecution.getStatus()); + } + logger.debug("scheduler ends "); + } + + public Date getCurrentLaunchDate() { + return currentLaunchDate; + } + + public void stop() { + enabled.set(false); + } + + public void start() { + enabled.set(true); + } + + @Bean + public TaskScheduler poolScheduler() { + return new CustomTaskScheduler(); + } + + private class CustomTaskScheduler extends ThreadPoolTaskScheduler { + + private static final long serialVersionUID = -7142624085505040603L; + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + ScheduledFuture future = super.scheduleAtFixedRate(task, period); + + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task; + scheduledTasks.put(runnable.getTarget(), future); + + return future; + } + + } + + public void cancelFutureSchedulerTasks() { + scheduledTasks.forEach((k, v) -> { + if (k instanceof SpringBatchScheduler) { + v.cancel(false); + } + }); + } + + @Bean + public Job job() { + return jobBuilderFactory.get("job") + .start(readBooks()) + .build(); + } + + @Bean + public JobLauncher jobLauncher() throws Exception { + SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); + jobLauncher.setJobRepository(jobRepository()); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } + + @Bean + public JobRepository jobRepository() throws Exception { + MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); + factory.setTransactionManager(new ResourcelessTransactionManager()); + return (JobRepository) factory.getObject(); + } + + @Bean + protected Step readBooks() { + return stepBuilderFactory.get("readBooks") + . chunk(2) + .reader(reader()) + .writer(writer()) + .build(); + } + + @Bean + public FlatFileItemReader reader() { + return new FlatFileItemReaderBuilder().name("bookItemReader") + .resource(new ClassPathResource("books.csv")) + .delimited() + .names(new String[] { "id", "name" }) + .fieldSetMapper(new BeanWrapperFieldSetMapper() { + { + setTargetType(Book.class); + } + }) + .build(); + } + + @Bean + public ItemWriter writer() { + return new ItemWriter() { + + @Override + public void write(List items) throws Exception { + logger.debug("writer..." + items.size()); + for (Book item : items) { + logger.debug(item.toString()); + } + + } + }; + } + +} diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java new file mode 100644 index 0000000000..f992bde20e --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java @@ -0,0 +1,35 @@ +package org.baeldung.batchscheduler.model; + +public class Book { + private int id; + private String name; + + public Book() {} + + public Book(int id, String name) { + super(); + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String toString() { + return "Book [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/spring-batch/src/main/resources/books.csv b/spring-batch/src/main/resources/books.csv new file mode 100644 index 0000000000..af68e986a2 --- /dev/null +++ b/spring-batch/src/main/resources/books.csv @@ -0,0 +1,4 @@ +1,SHARP OBJECTS (MOVIE TIE-IN): A NOVEL +2,ARTEMIS: A NOVEL +3,HER PRETTY FACE +4,ALL WE EVER WANTED \ No newline at end of file diff --git a/spring-batch/src/main/resources/logback.xml b/spring-batch/src/main/resources/logback.xml index b110d1c226..0313fb5008 100644 --- a/spring-batch/src/main/resources/logback.xml +++ b/spring-batch/src/main/resources/logback.xml @@ -12,6 +12,10 @@ additivity="false"> + + + + diff --git a/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java new file mode 100644 index 0000000000..ef825b900f --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java @@ -0,0 +1,60 @@ +package org.baeldung.batchscheduler; + +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = SpringBatchScheduler.class) +public class SpringBatchSchedulerIntegrationTest { + + private static final int TIMER = 3000; + + @Autowired + private ApplicationContext context; + + @Test + public void stopJobsWhenSchedulerDisabled() throws Exception { + Thread.sleep(TIMER); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + schedulerBean.stop(); + Thread.sleep(TIMER); + Date lastLaunchDate = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchDate, schedulerBean.getCurrentLaunchDate()); + } + + @Test + public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception { + Thread.sleep(TIMER); + ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler"); + Thread.sleep(TIMER); + Date lastLaunchTime = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchTime, schedulerBean.getCurrentLaunchDate()); + + } + + @Test + public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception { + Thread.sleep(TIMER); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + schedulerBean.cancelFutureSchedulerTasks(); + Thread.sleep(TIMER); + Date lastLaunchTime = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchTime, schedulerBean.getCurrentLaunchDate()); + + } + +} diff --git a/spring-boot-compare-embedded/.gitignore b/spring-boot-compare-embedded/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-compare-embedded/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.jar b/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000..9cc84ea9b4 Binary files /dev/null and b/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.jar differ diff --git a/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.properties b/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..9dda3b659b --- /dev/null +++ b/spring-boot-compare-embedded/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip diff --git a/spring-boot-compare-embedded/README.MD b/spring-boot-compare-embedded/README.MD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-compare-embedded/mvnw b/spring-boot-compare-embedded/mvnw new file mode 100644 index 0000000000..5bf251c077 --- /dev/null +++ b/spring-boot-compare-embedded/mvnw @@ -0,0 +1,225 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +echo $MAVEN_PROJECTBASEDIR +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/spring-boot-compare-embedded/mvnw.cmd b/spring-boot-compare-embedded/mvnw.cmd new file mode 100644 index 0000000000..019bd74d76 --- /dev/null +++ b/spring-boot-compare-embedded/mvnw.cmd @@ -0,0 +1,143 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/spring-boot-compare-embedded/pom.xml b/spring-boot-compare-embedded/pom.xml new file mode 100644 index 0000000000..af2c4ad5c6 --- /dev/null +++ b/spring-boot-compare-embedded/pom.xml @@ -0,0 +1,107 @@ + + + 4.0.0 + com.baeldung + spring-boot-compare-embedded + 0.0.1 + jar + spring-boot-compare-embedded + This is a simple application with used to compare embedded servlet containers. + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.openjdk.jmh + jmh-core + 1.21 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.21 + test + + + com.jayway.jsonpath + json-path + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + UTF-8 + UTF-8 + + + diff --git a/spring-boot-compare-embedded/src/main/java/com/baeldung/embedded/ComparisonApplication.java b/spring-boot-compare-embedded/src/main/java/com/baeldung/embedded/ComparisonApplication.java new file mode 100644 index 0000000000..b7c5d81388 --- /dev/null +++ b/spring-boot-compare-embedded/src/main/java/com/baeldung/embedded/ComparisonApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.embedded; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ComparisonApplication { + + public static void main(String[] args) { + SpringApplication.run(ComparisonApplication.class, args); + } +} diff --git a/spring-boot-compare-embedded/src/main/resources/META-INF/BenchmarkList b/spring-boot-compare-embedded/src/main/resources/META-INF/BenchmarkList new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-compare-embedded/src/main/resources/application.properties b/spring-boot-compare-embedded/src/main/resources/application.properties new file mode 100644 index 0000000000..a86bd3052e --- /dev/null +++ b/spring-boot-compare-embedded/src/main/resources/application.properties @@ -0,0 +1,3 @@ +management.endpoints.web.exposure.include=* +management.metrics.enable.root=true +management.metrics.enable.jvm=true \ No newline at end of file diff --git a/spring-boot-compare-embedded/src/test/java/com/baeldung/embedded/ComparisonBenchmarkTest.java b/spring-boot-compare-embedded/src/test/java/com/baeldung/embedded/ComparisonBenchmarkTest.java new file mode 100644 index 0000000000..23d51a5c94 --- /dev/null +++ b/spring-boot-compare-embedded/src/test/java/com/baeldung/embedded/ComparisonBenchmarkTest.java @@ -0,0 +1,119 @@ +package com.baeldung.embedded; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.assertj.core.util.Lists; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import com.jayway.jsonpath.JsonPath; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) +public class ComparisonBenchmarkTest { + + private static final String BASE_URL = "http://localhost:8080/actuator/metrics"; + + @Before + public void getAndPrintActuatorMetrics() { + RestTemplate restTemplate = new RestTemplate(); + for (MetricConfiguration c : getMetricConfigs()) { + getAndPrintActuatorMetric(restTemplate, c); + } + System.out.println(""); + } + + @Test + public void launchBenchmark() throws Exception { + Options opt = new OptionsBuilder() + .include(this.getClass().getName() + ".*") + .mode(Mode.Throughput) + .timeUnit(TimeUnit.SECONDS) + .warmupIterations(3) + .warmupTime(TimeValue.seconds(10)) + .measurementIterations(3) + .measurementTime(TimeValue.minutes(1)) + .threads(5) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .build(); + new Runner(opt).run(); + } + + @Benchmark + public void benchmark() throws Exception { + RestTemplate template = new RestTemplate(); + for (int i = 0; i < 10; i++) { + MetricNames metricNames = template.getForObject(BASE_URL, MetricNames.class); + metricNames.getNames().stream().forEach(n -> { + template.getForObject(BASE_URL + "/" + n, String.class); + }); + } + } + + static class MetricNames { + private String[] names; + + public List getNames() { + return Arrays.asList(this.names); + } + } + + static class MetricConfiguration { + + private String label; + private String metric; + private Class type; + private String jsonPath; + + public MetricConfiguration(String label, String metric, Class type, String path) { + this.label = label; + this.metric = metric; + this.type = type; + this.jsonPath = path; + } + + public String getLabel() { + return label; + } + + public Class getType() { + return type; + } + + public String getJsonPath() { + return jsonPath; + } + + public String getMetric() { + return metric; + } + } + + private List getMetricConfigs() { + return Lists.newArrayList( + new MetricConfiguration("jvm.memory.used", "jvm.memory.used", Integer.class, "$.measurements[0].value"), + new MetricConfiguration("jvm.classes.loaded", "jvm.classes.loaded", Integer.class, "$.measurements[0].value"), + new MetricConfiguration("jvm.threads.live", "jvm.threads.live", Integer.class, "$.measurements[0].value")); + } + + private void getAndPrintActuatorMetric(RestTemplate restTemplate, MetricConfiguration c) { + String response = restTemplate.getForObject(BASE_URL + "/" + c.getMetric(), String.class); + String value = (JsonPath.parse(response).read(c.getJsonPath(), c.getType())).toString(); + System.out.println("Startup Metric >>> " + c.getLabel() + "=" + value); + } +} diff --git a/spring-boot-compare-embedded/src/test/resources/logback-test.xml b/spring-boot-compare-embedded/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..ca894df791 --- /dev/null +++ b/spring-boot-compare-embedded/src/test/resources/logback-test.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/spring-boot-custom-starter/README.md b/spring-boot-custom-starter/README.md index 5b05394d6e..f983441ca0 100644 --- a/spring-boot-custom-starter/README.md +++ b/spring-boot-custom-starter/README.md @@ -1,2 +1,12 @@ ### Relevant Articles: - [Creating a Custom Starter with Spring Boot](http://www.baeldung.com/spring-boot-custom-starter) + +- **greeter-library**: The sample library that we're creating the starter for. + +- **greeter-spring-boot-autoconfigure**: The project containing the auto-configuration for the library. + +- **greeter-spring-boot-starter**: The custom starter for the library. + +- **greeter-spring-boot-sample-app**: The sample project that uses the custom starter. + +- [Multi-Module Project With Spring Boot](http://www.baeldung.com/spring-boot-multiple-modules) diff --git a/spring-boot-custom-starter/greeter/README.md b/spring-boot-custom-starter/greeter-library/README.md similarity index 100% rename from spring-boot-custom-starter/greeter/README.md rename to spring-boot-custom-starter/greeter-library/README.md diff --git a/spring-boot-custom-starter/greeter/pom.xml b/spring-boot-custom-starter/greeter-library/pom.xml similarity index 71% rename from spring-boot-custom-starter/greeter/pom.xml rename to spring-boot-custom-starter/greeter-library/pom.xml index aa45b8e6a4..3717ba005c 100644 --- a/spring-boot-custom-starter/greeter/pom.xml +++ b/spring-boot-custom-starter/greeter-library/pom.xml @@ -3,12 +3,12 @@ 4.0.0 com.baeldung - greeter + greeter-library 0.0.1-SNAPSHOT - parent-boot-1 + spring-boot-custom-starter com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../spring-boot-custom-starter \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java similarity index 90% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java index 970561d1fd..50fb31ddcb 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java @@ -1,6 +1,6 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import java.time.LocalDateTime; diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java similarity index 90% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java index fa30b0f312..14cef3e92d 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java @@ -1,4 +1,4 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; public class GreeterConfigParams { diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java similarity index 80% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java index fbbe11cf4f..23d4ac0a0d 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; import java.util.Properties; diff --git a/spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java b/spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java similarity index 92% rename from spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java rename to spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java index 787f795480..2b09ecc615 100644 --- a/spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java +++ b/spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java @@ -1,10 +1,12 @@ package com.baeldung.greeter; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import static org.junit.Assert.assertEquals; import java.time.LocalDateTime; +import com.baeldung.greeter.library.Greeter; +import com.baeldung.greeter.library.GreetingConfig; import org.junit.BeforeClass; import org.junit.Test; diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml index 96647ea0f1..d70f176c20 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -5,12 +5,14 @@ com.baeldung greeter-spring-boot-autoconfigure 0.0.1-SNAPSHOT + - parent-boot-1 + spring-boot-custom-starter com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../spring-boot-custom-starter + UTF-8 1.5.2.RELEASE @@ -40,7 +42,7 @@ com.baeldung - greeter + greeter-library ${greeter.version} true diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java index 4cf078aa00..ae3f88f9ff 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java @@ -1,6 +1,6 @@ package com.baeldung.greeter.autoconfigure; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -9,8 +9,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.baeldung.greeter.Greeter; -import com.baeldung.greeter.GreetingConfig; +import com.baeldung.greeter.library.Greeter; +import com.baeldung.greeter.library.GreetingConfig; @Configuration @ConditionalOnClass(Greeter.class) diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java index 3c87524648..5aa3ac7015 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java @@ -5,7 +5,7 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import com.baeldung.greeter.Greeter; +import com.baeldung.greeter.library.Greeter; @SpringBootApplication public class GreeterSampleApplication implements CommandLineRunner { diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java index a4816cf319..50193ccd60 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.baeldung.greeter.Greeter; +import com.baeldung.greeter.library.Greeter; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = GreeterSampleApplication.class) diff --git a/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml b/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml index 7bf13eebc8..af1a77d138 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml @@ -5,12 +5,14 @@ com.baeldung greeter-spring-boot-starter 0.0.1-SNAPSHOT + - parent-boot-1 + spring-boot-custom-starter com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../spring-boot-custom-starter + UTF-8 0.0.1-SNAPSHOT @@ -33,7 +35,7 @@ com.baeldung - greeter + greeter-library ${greeter.version} diff --git a/spring-boot-custom-starter/pom.xml b/spring-boot-custom-starter/pom.xml index 1bc0e14d8e..def089e9a9 100644 --- a/spring-boot-custom-starter/pom.xml +++ b/spring-boot-custom-starter/pom.xml @@ -13,7 +13,7 @@ - greeter + greeter-library greeter-spring-boot-autoconfigure greeter-spring-boot-starter greeter-spring-boot-sample-app diff --git a/spring-boot-gradle/README.md b/spring-boot-gradle/README.md index f96aa9ccf8..76b82dce02 100644 --- a/spring-boot-gradle/README.md +++ b/spring-boot-gradle/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Spring Boot: Configuring a Main Class](http://www.baeldung.com/spring-boot-main-class) +- [Thin JARs with Spring Boot](http://www.baeldung.com/spring-boot-thin-jar) diff --git a/spring-boot-logging-log4j2/.gitignore b/spring-boot-logging-log4j2/.gitignore new file mode 100644 index 0000000000..d129c74ec9 --- /dev/null +++ b/spring-boot-logging-log4j2/.gitignore @@ -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 diff --git a/spring-boot-logging-log4j2/README.md b/spring-boot-logging-log4j2/README.md new file mode 100644 index 0000000000..7676bd1919 --- /dev/null +++ b/spring-boot-logging-log4j2/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Logging in Spring Boot](http://www.baeldung.com/spring-boot-logging) diff --git a/spring-boot-logging-log4j2/pom.xml b/spring-boot-logging-log4j2/pom.xml new file mode 100644 index 0000000000..c07c157eee --- /dev/null +++ b/spring-boot-logging-log4j2/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + com.baeldung + spring-boot-logging-log4j2 + 0.0.1-SNAPSHOT + jar + Demo project for Spring Boot Logging with Log4J2 + + + org.springframework.boot + spring-boot-starter-parent + 2.0.3.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/LoggingController.java b/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/LoggingController.java new file mode 100644 index 0000000000..07763c8c3b --- /dev/null +++ b/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/LoggingController.java @@ -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..."; + } +} diff --git a/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java b/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java new file mode 100644 index 0000000000..336997a81e --- /dev/null +++ b/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java @@ -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); + } +} diff --git a/spring-boot-logging-log4j2/src/main/resources/application.properties b/spring-boot-logging-log4j2/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-logging-log4j2/src/main/resources/log4j2-spring.xml b/spring-boot-logging-log4j2/src/main/resources/log4j2-spring.xml new file mode 100644 index 0000000000..b08cd2d22d --- /dev/null +++ b/spring-boot-logging-log4j2/src/main/resources/log4j2-spring.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + %d %p %C{1.} [%t] %m%n + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoggingController.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoggingController.java new file mode 100644 index 0000000000..819ee589fe --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoggingController.java @@ -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..."; + } +} diff --git a/spring-boot-ops/README.md b/spring-boot-ops/README.md deleted file mode 100644 index 7eca307924..0000000000 --- a/spring-boot-ops/README.md +++ /dev/null @@ -1,10 +0,0 @@ -### Relevant Articles: - -- [Deploy a Spring Boot WAR into a Tomcat Server](http://www.baeldung.com/spring-boot-war-tomcat-deploy) -- [Spring Boot Dependency Management with a Custom Parent](http://www.baeldung.com/spring-boot-dependency-management-custom-parent) -- [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder) -- [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot) -- [Introduction to WebJars](http://www.baeldung.com/maven-webjars) -- [Intro to Spring Boot Starters](http://www.baeldung.com/spring-boot-starters) -- [A Quick Guide to Maven Wrapper](http://www.baeldung.com/maven-wrapper) -- [Shutdown a Spring Boot Application](http://www.baeldung.com/spring-boot-shutdown) diff --git a/spring-boot-ops/src/main/java/com/baeldung/springbootnonwebapp/SpringBootConsoleApplication.java b/spring-boot-ops/src/main/java/com/baeldung/springbootnonwebapp/SpringBootConsoleApplication.java new file mode 100644 index 0000000000..9faa463378 --- /dev/null +++ b/spring-boot-ops/src/main/java/com/baeldung/springbootnonwebapp/SpringBootConsoleApplication.java @@ -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]); + } + } +} diff --git a/spring-boot-persistence/.gitignore b/spring-boot-persistence/.gitignore new file mode 100644 index 0000000000..88e3308e9d --- /dev/null +++ b/spring-boot-persistence/.gitignore @@ -0,0 +1,5 @@ +/target/ +.settings/ +.classpath +.project + diff --git a/spring-boot-persistence/.mvn/wrapper/maven-wrapper.properties b/spring-boot-persistence/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a447c9fa81 --- /dev/null +++ b/spring-boot-persistence/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/spring-boot-persistence/README.MD b/spring-boot-persistence/README.MD new file mode 100644 index 0000000000..71cd226b3a --- /dev/null +++ b/spring-boot-persistence/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Spring Boot with multiple SQL import files](http://www.baeldung.com/spring-Boot-with-multiple-SQL-import-files) \ No newline at end of file diff --git a/spring-boot-persistence/mvnw b/spring-boot-persistence/mvnw new file mode 100755 index 0000000000..e96ccd5fbb --- /dev/null +++ b/spring-boot-persistence/mvnw @@ -0,0 +1,227 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/spring-boot-persistence/mvnw.cmd b/spring-boot-persistence/mvnw.cmd new file mode 100755 index 0000000000..4f0b068a03 --- /dev/null +++ b/spring-boot-persistence/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/spring-boot-persistence/pom.xml b/spring-boot-persistence/pom.xml new file mode 100644 index 0000000000..af0d7ea505 --- /dev/null +++ b/spring-boot-persistence/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + com.baeldung + spring-boot-persistence + 0.0.1-SNAPSHOT + jar + spring-boot-persistence + This is a simple Spring Data Repositories test + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter + + + + + spring-boot-persistence + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-war-plugin + + + pl.project13.maven + git-commit-id-plugin + + + + + \ No newline at end of file diff --git a/spring-boot-persistence/src/main/java/com/baeldung/Application.java b/spring-boot-persistence/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..43888c2d67 --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/Application.java @@ -0,0 +1,14 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +@SpringBootApplication +public class Application { + private static ApplicationContext applicationContext; + + public static void main(String[] args) { + applicationContext = SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/boot/domain/User.java b/spring-boot-persistence/src/main/java/com/baeldung/domain/User.java similarity index 96% rename from spring-boot/src/main/java/org/baeldung/boot/domain/User.java rename to spring-boot-persistence/src/main/java/com/baeldung/domain/User.java index b6d68b8c3c..9d1fc4c8ad 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/domain/User.java +++ b/spring-boot-persistence/src/main/java/com/baeldung/domain/User.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java b/spring-boot-persistence/src/main/java/com/baeldung/repository/UserRepository.java similarity index 97% rename from spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java rename to spring-boot-persistence/src/main/java/com/baeldung/repository/UserRepository.java index 2463a416d2..bdc1e0af33 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java +++ b/spring-boot-persistence/src/main/java/com/baeldung/repository/UserRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.repository; +package com.baeldung.repository; -import org.baeldung.boot.domain.User; +import com.baeldung.domain.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; diff --git a/spring-boot-persistence/src/main/resources/application.properties b/spring-boot-persistence/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryDataJpaIntegrationTest.java b/spring-boot-persistence/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java similarity index 77% rename from spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryDataJpaIntegrationTest.java rename to spring-boot-persistence/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java index dc4c6eedcf..af5abc22d7 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryDataJpaIntegrationTest.java +++ b/spring-boot-persistence/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.repository; +package com.baeldung.repository; -import org.baeldung.boot.domain.User; +import com.baeldung.domain.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -16,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ @RunWith(SpringRunner.class) @DataJpaTest -public class UserRepositoryDataJpaIntegrationTest { +public class UserRepositoryIntegrationTest { @Autowired private UserRepository userRepository; @@ -24,7 +24,7 @@ public class UserRepositoryDataJpaIntegrationTest { public void givenTwoImportFilesWhenFindAllShouldReturnSixUsers() { Collection users = userRepository.findAll(); - assertThat(users.size()).isEqualTo(6); + assertThat(users.size()).isEqualTo(9); } } diff --git a/spring-boot-persistence/src/test/resources/application.properties b/spring-boot-persistence/src/test/resources/application.properties new file mode 100644 index 0000000000..a5c1d983cf --- /dev/null +++ b/spring-boot-persistence/src/test/resources/application.properties @@ -0,0 +1,16 @@ +# spring.datasource.x +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.username=sa +spring.datasource.password=sa + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +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 + +spring.jpa.properties.hibernate.hbm2ddl.import_files=migrated_users.sql +spring.datasource.data=import_*_users.sql \ No newline at end of file diff --git a/spring-boot/src/test/resources/import_active_users.sql b/spring-boot-persistence/src/test/resources/import_active_users.sql similarity index 67% rename from spring-boot/src/test/resources/import_active_users.sql rename to spring-boot-persistence/src/test/resources/import_active_users.sql index e1bdfef5a8..0ec3161d91 100644 --- a/spring-boot/src/test/resources/import_active_users.sql +++ b/spring-boot-persistence/src/test/resources/import_active_users.sql @@ -1,3 +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); \ No newline at end of file +insert into USERS(name, status, id) values('Ed', 1, 3); diff --git a/spring-boot/src/test/resources/import_inactive_users.sql b/spring-boot-persistence/src/test/resources/import_inactive_users.sql similarity index 100% rename from spring-boot/src/test/resources/import_inactive_users.sql rename to spring-boot-persistence/src/test/resources/import_inactive_users.sql diff --git a/spring-boot-persistence/src/test/resources/migrated_users.sql b/spring-boot-persistence/src/test/resources/migrated_users.sql new file mode 100644 index 0000000000..11d1a69110 --- /dev/null +++ b/spring-boot-persistence/src/test/resources/migrated_users.sql @@ -0,0 +1,3 @@ +insert into USERS(name, status, id) values('Peter', 1, 7); +insert into USERS(name, status, id) values('David', 1, 8); +insert into USERS(name, status, id) values('Ed', 1, 9); diff --git a/spring-boot/.factorypath b/spring-boot/.factorypath index 68b2514aab..01b84b761a 100644 --- a/spring-boot/.factorypath +++ b/spring-boot/.factorypath @@ -1,4 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -16,7 +38,6 @@ - @@ -32,9 +53,7 @@ - - @@ -48,7 +67,6 @@ - @@ -85,6 +103,9 @@ + + + @@ -136,7 +157,6 @@ - diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 595e13cd9f..66e7c923c9 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -33,3 +33,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [How to Change the Default Port in Spring Boot](http://www.baeldung.com/spring-boot-change-port) - [Spring Boot Exit Codes](http://www.baeldung.com/spring-boot-exit-codes) - [Guide to the Favicon in Spring Boot](http://www.baeldung.com/spring-boot-favicon) +- [Spring Shutdown Callbacks](http://www.baeldung.com/spring-shutdown-callbacks) diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index d8ee3cc2d9..70c3bb4c6b 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung spring-boot @@ -16,6 +16,35 @@ + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + test + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + org.springframework.boot spring-boot-starter-thymeleaf @@ -55,11 +84,6 @@ test - - io.dropwizard.metrics metrics-core @@ -170,7 +194,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/AutoconfigurationTest.java diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java b/spring-boot/src/main/java/com/baeldung/mongodb/Application.java similarity index 60% rename from spring-mvc-email/src/main/java/com/baeldung/spring/Application.java rename to spring-boot/src/main/java/com/baeldung/mongodb/Application.java index bc5d6b3151..092ce3352b 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java +++ b/spring-boot/src/main/java/com/baeldung/mongodb/Application.java @@ -1,12 +1,10 @@ -package com.baeldung.spring; +package com.baeldung.mongodb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; - @SpringBootApplication -public class Application extends SpringBootServletInitializer { +public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } diff --git a/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java b/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java index 790584644f..34b50a2c0a 100644 --- a/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java +++ b/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java @@ -3,7 +3,7 @@ package org.baeldung.endpoints.info; import java.util.HashMap; import java.util.Map; -import org.baeldung.boot.repository.UserRepository; +import org.baeldung.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.info.Info; import org.springframework.boot.actuate.info.InfoContributor; diff --git a/spring-boot/src/main/java/org/baeldung/model/User.java b/spring-boot/src/main/java/org/baeldung/model/User.java new file mode 100644 index 0000000000..eb886338a0 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/model/User.java @@ -0,0 +1,49 @@ +package org.baeldung.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue + private Integer id; + private String name; + private Integer status; + + public User() { + } + + public User(String name, Integer status) { + this.name = name; + this.status = status; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java new file mode 100644 index 0000000000..cba504b6c6 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java @@ -0,0 +1,82 @@ +package org.baeldung.repository; + +import org.baeldung.model.User; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Repository; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; + +@Repository("userRepository") +public interface UserRepository extends JpaRepository { + + int countByStatus(int status); + + Optional findOneByName(String name); + + Stream findAllByName(String name); + + @Async + CompletableFuture findOneByStatus(Integer status); + + @Query("SELECT u FROM User u WHERE u.status = 1") + Collection findAllActiveUsers(); + + @Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true) + Collection findAllActiveUsersNative(); + + @Query("SELECT u FROM User u WHERE u.status = ?1") + User findUserByStatus(Integer status); + + @Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true) + User findUserByStatusNative(Integer status); + + @Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2") + User findUserByStatusAndName(Integer status, String name); + + @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") + User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name); + + @Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true) + User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name); + + @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") + User findUserByUserStatusAndUserName(@Param("status") Integer userStatus, @Param("name") String userName); + + @Query("SELECT u FROM User u WHERE u.name like ?1%") + User findUserByNameLike(String name); + + @Query("SELECT u FROM User u WHERE u.name like :name%") + User findUserByNameLikeNamedParam(@Param("name") String name); + + @Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true) + User findUserByNameLikeNative(String name); + + @Query(value = "SELECT u FROM User u") + List findAllUsers(Sort sort); + + @Query(value = "SELECT u FROM User u ORDER BY id") + Page findAllUsersWithPagination(Pageable pageable); + + @Query(value = "SELECT * FROM Users ORDER BY id \n-- #pageable\n", countQuery = "SELECT count(*) FROM Users", nativeQuery = true) + Page findAllUsersWithPaginationNative(Pageable pageable); + + @Modifying + @Query("update User u set u.status = :status where u.name = :name") + int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name); + + @Modifying + @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true) + int updateUserSetStatusForNameNative(Integer status, String name); + +} diff --git a/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java new file mode 100644 index 0000000000..30a4d61fbd --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java @@ -0,0 +1,62 @@ +package com.baeldung.mongodb; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.data.mongodb.core.MongoTemplate; + +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.IMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +class ManualEmbeddedMongoDbIntegrationTest { + private MongodExecutable mongodExecutable; + private MongoTemplate mongoTemplate; + + @AfterEach + void clean() { + mongodExecutable.stop(); + } + + @BeforeEach + void setup() throws Exception { + String ip = "localhost"; + int port = 27017; + + IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION) + .net(new Net(ip, port, Network.localhostIsIPv6())) + .build(); + + MongodStarter starter = MongodStarter.getDefaultInstance(); + mongodExecutable = starter.prepare(mongodConfig); + mongodExecutable.start(); + mongoTemplate = new MongoTemplate(new MongoClient(ip, port), "test"); + } + + @DisplayName("Given object When save object using MongoDB template Then object can be found") + @Test + void test() throws Exception { + // given + DBObject objectToSave = BasicDBObjectBuilder.start() + .add("key", "value") + .get(); + + // when + mongoTemplate.save(objectToSave, "collection"); + + // then + assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") + .containsOnly("value"); + } +} diff --git a/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java new file mode 100644 index 0000000000..5431217c3e --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.mongodb; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; + +@ContextConfiguration(classes = Application.class) +@DataMongoTest +@ExtendWith(SpringExtension.class) +public class MongoDbSpringIntegrationTest { + @DisplayName("Given object When save object using MongoDB template Then object can be found") + @Test + public void test(@Autowired MongoTemplate mongoTemplate) { + // given + DBObject objectToSave = BasicDBObjectBuilder.start() + .add("key", "value") + .get(); + + // when + mongoTemplate.save(objectToSave, "collection"); + + // then + assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") + .containsOnly("value"); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java similarity index 95% rename from spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java index a0f3a7a80f..72d204820e 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/UserRepositoryIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java @@ -1,7 +1,7 @@ -package org.baeldung.boot.repository; +package org.baeldung.repository; import org.baeldung.boot.config.H2JpaConfig; -import org.baeldung.boot.domain.User; +import org.baeldung.model.User; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,7 +27,8 @@ 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() { diff --git a/spring-boot/src/test/resources/application-integrationtest.properties b/spring-boot/src/test/resources/application-integrationtest.properties index 1a5bd502dd..bcd03226d3 100644 --- a/spring-boot/src/test/resources/application-integrationtest.properties +++ b/spring-boot/src/test/resources/application-integrationtest.properties @@ -2,5 +2,3 @@ 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 diff --git a/spring-boot/src/test/resources/application.properties b/spring-boot/src/test/resources/application.properties index fef16d556e..85e4e6e66f 100644 --- a/spring-boot/src/test/resources/application.properties +++ b/spring-boot/src/test/resources/application.properties @@ -16,6 +16,4 @@ 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 - -spring.jpa.properties.hibernate.hbm2ddl.import_files=import_active_users.sql,import_inactive_users.sql \ No newline at end of file +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory \ No newline at end of file diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java index f717f0f644..30f6ff6897 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java @@ -1,12 +1,10 @@ package org.baeldung.spring.cloud; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.task.configuration.EnableTask; @EnableTask -@EnableBatchProcessing @SpringBootApplication public class BatchJobApplication { diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java index dc6a5e2827..7ce867b60a 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java @@ -2,9 +2,9 @@ package org.baeldung.spring.cloud; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.batch.core.Job; import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.scope.context.ChunkContext; @@ -15,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@EnableBatchProcessing public class JobConfiguration { private static final Log logger = LogFactory.getLog(JobConfiguration.class); diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java index f8dfdec197..1f77351acc 100644 --- a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java @@ -3,10 +3,12 @@ package org.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest +@ContextConfiguration(classes = JobConfiguration.class) public class BatchJobApplicationIntegrationTest { @Test diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml index f3ce213540..e510a687cc 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml @@ -52,7 +52,7 @@ - Camden.SR4 + Edgware.SR4 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java index e077c42a96..14597d5c2f 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -11,5 +18,25 @@ public class SpringCloudRestServerIntegrationTest { @Test public void contextLoads() { } + + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } -} + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml index 27e327110a..cbd495908a 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml @@ -18,6 +18,7 @@ 3.0.1 + 0.6 @@ -57,6 +58,11 @@ org.springframework.boot spring-boot-starter-data-redis + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java index d25e0bee20..98cda102e9 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java @@ -1,13 +1,33 @@ package org.baeldung; +import java.io.IOException; + +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import redis.embedded.RedisServer; @RunWith(SpringRunner.class) @SpringBootTest public class BookReviewsApiIntegrationTest { + + private static RedisServer redisServer; + private static int port; + + @BeforeClass + public static void setUp() throws IOException { + + redisServer = new RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void destroy() { + redisServer.stop(); + } @Test public void contextLoads() { diff --git a/spring-core/README.md b/spring-core/README.md index 3684c7f6e9..adc21ffdaf 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -16,3 +16,5 @@ - [@Lookup Annotation in Spring](http://www.baeldung.com/spring-lookup) - [BeanNameAware and BeanFactoryAware Interfaces in Spring](http://www.baeldung.com/spring-bean-name-factory-aware) - [Spring – Injecting Collections](http://www.baeldung.com/spring-injecting-collections) +- [Access a File from the Classpath in a Spring Application](http://www.baeldung.com/spring-classpath-file-access) +- [Controlling Bean Creation Order with @DependsOn Annotation](http://www.baeldung.com/spring-depends-on) diff --git a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java index 11d9daf3bf..5de53192df 100644 --- a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java +++ b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; @@ -30,7 +29,7 @@ public class FileProcessorIntegrationTest { assertTrue(file.getText().endsWith("processed")); } - @Test(expected=NoSuchBeanDefinitionException.class) + @Test(expected=BeanCreationException.class) public void whenDependentBeanNotAvailable_ThrowsNoSuchBeanDefinitionException(){ context.getBean("dummyFileProcessor"); } diff --git a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java index 56eb810c09..f48ab410ca 100644 --- a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java @@ -1,10 +1,11 @@ package com.baeldung; +import org.junit.runner.RunWith; + import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; -import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions(features = "src/test/resources") -public class CucumberIntegrationTest { +public class CucumberIntegrationTest extends SpringIntegrationTest{ } \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java index f4d47d7871..8655a02469 100644 --- a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java @@ -5,16 +5,17 @@ import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; //@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = SpringDemoApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDemoApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@ContextConfiguration public class SpringIntegrationTest { static ResponseResults latestResponse = null; diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml index 0e525474e3..b3d2b0e359 100644 --- a/spring-data-rest/pom.xml +++ b/spring-data-rest/pom.xml @@ -10,10 +10,10 @@ Intro to Spring Data REST - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../parent-boot-2 diff --git a/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java b/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java index 82cb936348..e5748f2f55 100644 --- a/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java +++ b/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java @@ -3,17 +3,14 @@ package com.baeldung.config; import com.baeldung.events.AuthorEventHandler; import com.baeldung.events.BookEventHandler; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc -public class MvcConfig extends WebMvcConfigurerAdapter{ +public class MvcConfig implements WebMvcConfigurer { public MvcConfig(){ super(); diff --git a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java similarity index 97% rename from spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java rename to spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java index 4091fdf154..702c1521da 100644 --- a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java @@ -25,7 +25,7 @@ import com.baeldung.repositories.BookRepository; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) -public class SpringDataProjectionIntegrationTest { +public class SpringDataProjectionLiveTest { private static final String BOOK_ENDPOINT = "http://localhost:8080/books"; private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors"; @@ -38,7 +38,7 @@ public class SpringDataProjectionIntegrationTest { @Before public void setup(){ - if(bookRepo.findOne(1L) == null){ + if(bookRepo.findById(1L) == null){ Book book = new Book("Animal Farm"); book.setIsbn("978-1943138425"); book = bookRepo.save(book); diff --git a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java index e3fe60d487..196dc18d9e 100644 --- a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java @@ -1,15 +1,14 @@ package com.baeldung.relationships; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.Address; -import com.baeldung.models.Author; -import com.baeldung.models.Book; -import com.baeldung.models.Library; +import static org.junit.Assert.assertEquals; + import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -18,21 +17,27 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; -import org.json.JSONException; -import static org.junit.Assert.assertEquals; +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.Address; +import com.baeldung.models.Author; +import com.baeldung.models.Book; +import com.baeldung.models.Library; @RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class SpringDataRelationshipsIntegrationTest { @Autowired private TestRestTemplate template; + + @Value("${local.server.port}") + private int port; - private static final String BOOK_ENDPOINT = "http://localhost:8080/books/"; - private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors/"; - private static final String ADDRESS_ENDPOINT = "http://localhost:8080/addresses/"; - private static final String LIBRARY_ENDPOINT = "http://localhost:8080/libraries/"; + private static final String BOOK_ENDPOINT = "http://localhost:%s/books/"; + private static final String AUTHOR_ENDPOINT = "http://localhost:%s/authors/"; + private static final String ADDRESS_ENDPOINT = "http://localhost:%s/addresses/"; + private static final String LIBRARY_ENDPOINT = "http://localhost:%s/libraries/"; private static final String LIBRARY_NAME = "My Library"; private static final String AUTHOR_NAME = "George Orwell"; @@ -40,17 +45,17 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveOneToOneRelationship_thenCorrect() throws JSONException { Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); + template.postForEntity(String.format(LIBRARY_ENDPOINT, port), library, Library.class); Address address = new Address("Main street, nr 1"); - template.postForEntity(ADDRESS_ENDPOINT, address, Address.class); + template.postForEntity(String.format(ADDRESS_ENDPOINT, port), address, Address.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(ADDRESS_ENDPOINT + "/1", requestHeaders); - template.exchange(LIBRARY_ENDPOINT + "/1/libraryAddress", HttpMethod.PUT, httpEntity, String.class); + HttpEntity httpEntity = new HttpEntity<>(String.format(ADDRESS_ENDPOINT, port) + "/1", requestHeaders); + template.exchange(String.format(LIBRARY_ENDPOINT, port) + "/1/libraryAddress", HttpMethod.PUT, httpEntity, String.class); - ResponseEntity libraryGetResponse = template.getForEntity(ADDRESS_ENDPOINT + "/1/library", Library.class); + ResponseEntity libraryGetResponse = template.getForEntity(String.format(ADDRESS_ENDPOINT, port) + "/1/library", Library.class); assertEquals("library is incorrect", libraryGetResponse.getBody() .getName(), LIBRARY_NAME); } @@ -58,21 +63,21 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveOneToManyRelationship_thenCorrect() throws JSONException{ Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); + template.postForEntity(String.format(LIBRARY_ENDPOINT, port), library, Library.class); Book book1 = new Book("Dune"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book1, Book.class); Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book2, Book.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity bookHttpEntity = new HttpEntity<>(LIBRARY_ENDPOINT + "/1", requestHeaders); - template.exchange(BOOK_ENDPOINT + "/1/library", HttpMethod.PUT, bookHttpEntity, String.class); - template.exchange(BOOK_ENDPOINT + "/2/library", HttpMethod.PUT, bookHttpEntity, String.class); + HttpEntity bookHttpEntity = new HttpEntity<>(String.format(LIBRARY_ENDPOINT, port) + "/1", requestHeaders); + template.exchange(String.format(BOOK_ENDPOINT, port) + "/1/library", HttpMethod.PUT, bookHttpEntity, String.class); + template.exchange(String.format(BOOK_ENDPOINT, port) + "/2/library", HttpMethod.PUT, bookHttpEntity, String.class); - ResponseEntity libraryGetResponse = template.getForEntity(BOOK_ENDPOINT + "/1/library", Library.class); + ResponseEntity libraryGetResponse = template.getForEntity(String.format(BOOK_ENDPOINT, port) + "/1/library", Library.class); assertEquals("library is incorrect", libraryGetResponse.getBody() .getName(), LIBRARY_NAME); } @@ -80,20 +85,20 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveManyToManyRelationship_thenCorrect() throws JSONException{ Author author1 = new Author(AUTHOR_NAME); - template.postForEntity(AUTHOR_ENDPOINT, author1, Author.class); + template.postForEntity(String.format(AUTHOR_ENDPOINT, port), author1, Author.class); Book book1 = new Book("Animal Farm"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book1, Book.class); Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book2, Book.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(BOOK_ENDPOINT + "/1\n" + BOOK_ENDPOINT + "/2", requestHeaders); - template.exchange(AUTHOR_ENDPOINT + "/1/books", HttpMethod.PUT, httpEntity, String.class); + HttpEntity httpEntity = new HttpEntity<>(String.format(BOOK_ENDPOINT, port) + "/1\n" + String.format(BOOK_ENDPOINT, port) + "/2", requestHeaders); + template.exchange(String.format(AUTHOR_ENDPOINT, port) + "/1/books", HttpMethod.PUT, httpEntity, String.class); - String jsonResponse = template.getForObject(BOOK_ENDPOINT + "/1/authors", String.class); + String jsonResponse = template.getForObject(String.format(BOOK_ENDPOINT, port) + "/1/authors", String.class); JSONObject jsonObj = new JSONObject(jsonResponse).getJSONObject("_embedded"); JSONArray jsonArray = jsonObj.getJSONArray("authors"); assertEquals("author is incorrect", jsonArray.getJSONObject(0) diff --git a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java index bc321bc686..4c936ffc1c 100644 --- a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java @@ -1,31 +1,33 @@ package com.baeldung.validator; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.WebsiteUser; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.web.context.WebApplicationContext; - import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.WebsiteUser; +import com.fasterxml.jackson.databind.ObjectMapper; + @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc public class SpringDataRestValidatorIntegrationTest { public static final String URL = "http://localhost"; + @Autowired private MockMvc mockMvc; @Autowired diff --git a/spring-dispatcher-servlet/pom.xml b/spring-dispatcher-servlet/pom.xml index 9dfd3c0f39..35c6b1ad33 100644 --- a/spring-dispatcher-servlet/pom.xml +++ b/spring-dispatcher-servlet/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-spring-4 + parent-spring-5 0.0.1-SNAPSHOT - ../parent-spring-4 + ../parent-spring-5 diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java index f5ad032e84..c8a6cf06a6 100644 --- a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java @@ -17,7 +17,7 @@ import java.io.IOException; @Configuration @EnableWebMvc @ComponentScan("com.baeldung.springdispatcherservlet") -public class AppConfig extends WebMvcConfigurerAdapter { +public class AppConfig implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 9c3b6f14ed..bbc07a4091 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -29,6 +29,12 @@ spring-boot-starter-test test + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${de.flapdoodle.embed.mongo.version} + test + @@ -73,6 +79,7 @@ UTF-8 1.8 2.17 + 2.0.0 diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java index 092ebb93fd..477a7d2adb 100644 --- a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertNotEquals; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest +@SpringBootTest(classes = {SpringJenkinsPipelineApplication.class, TestMongoConfig.class }) public class SomeIntegrationTest { @Autowired private StudentRepository studentRepository; diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java new file mode 100644 index 0000000000..a85491cf7e --- /dev/null +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class }) +public class TestMongoConfig { + +} \ No newline at end of file diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml index bd8bc6f404..a2ca229031 100644 --- a/spring-jooq/pom.xml +++ b/spring-jooq/pom.xml @@ -5,9 +5,10 @@ 0.0.1-SNAPSHOT - com.baeldung - parent-modules - 1.0.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 1.4.4.RELEASE + @@ -55,6 +56,10 @@ org.springframework.boot spring-boot-starter-jooq + + org.springframework.boot + spring-boot-starter-test + diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java index 25317309ee..5e76fb3c93 100644 --- a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java +++ b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java @@ -12,14 +12,16 @@ import org.jooq.impl.DSL; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.DataAccessException; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -@Transactional("transactionManager") +import com.baeldung.jooq.introduction.PersistenceContextIntegrationTest; + +@ContextConfiguration(classes = PersistenceContextIntegrationTest.class) +@Transactional(transactionManager = "transactionManager") +@RunWith(SpringJUnit4ClassRunner.class) public class SpringBootIntegrationTest { @Autowired diff --git a/spring-ldap/pom.xml b/spring-ldap/pom.xml index 41683d32a1..ab5f557736 100644 --- a/spring-ldap/pom.xml +++ b/spring-ldap/pom.xml @@ -118,6 +118,7 @@ org.apache.maven.plugins maven-surefire-plugin + ${maven-surefire-plugin.version} integration-test diff --git a/spring-mvc-email/README.md b/spring-mvc-email/README.md deleted file mode 100644 index aa880188d7..0000000000 --- a/spring-mvc-email/README.md +++ /dev/null @@ -1,17 +0,0 @@ -## Relevant articles: - -- [Guide to Spring Email](http://www.baeldung.com/spring-email) - -## Spring MVC Email - -Example Spring MVC project to send email from web form. - -### Installing and Running - -Just run the Spring Boot application. -Type http://localhost:8080 in your browser to open the application. - - -### Sending test emails - -Follow UI links to send simple email, email using template or email with attachment. diff --git a/spring-mvc-email/pom.xml b/spring-mvc-email/pom.xml deleted file mode 100644 index 40d83046ef..0000000000 --- a/spring-mvc-email/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - - org.baeldung.spring - spring-mvc-email - 1.0 - spring-mvc-email - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - org.springframework.boot - spring-boot-starter-mail - - - - javax.servlet - jstl - - - - diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java b/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java deleted file mode 100644 index 9078d44764..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.spring.app.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.springframework.web.servlet.view.UrlBasedViewResolver; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Configuration -@ComponentScan("com.baeldung.spring") -@EnableWebMvc //tha same as -public class AppConfig extends WebMvcConfigurerAdapter { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } - - @Bean - public UrlBasedViewResolver urlBasedViewResolver() { - UrlBasedViewResolver resolver = new UrlBasedViewResolver(); - resolver.setOrder(0); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setCache(false); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public InternalResourceViewResolver internalResourceViewResolver() { - InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setOrder(1); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public SimpleMailMessage templateSimpleMessage() { - SimpleMailMessage message = new SimpleMailMessage(); - message.setText("This is the test email template for your email:\n%s\n"); - return message; - } -} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java b/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java deleted file mode 100644 index 656e237a9e..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.spring.controllers; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Controller -@RequestMapping({"/","/home"}) -public class HomeController { - - @RequestMapping(method = RequestMethod.GET) - public String showHomePage() { - return "home"; - } -} diff --git a/spring-mvc-email/src/main/resources/META-INF/application.xml b/spring-mvc-email/src/main/resources/META-INF/application.xml deleted file mode 100644 index 759a312bd4..0000000000 --- a/spring-mvc-email/src/main/resources/META-INF/application.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - SpringMVCEmail.war - SpringMVCEmail - - - - - web.war - SpringMVCEmailWeb - - - \ No newline at end of file diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml b/spring-mvc-email/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 4cd41216d9..0000000000 --- a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - simpleweb - org.springframework.web.servlet.DispatcherServlet - - contextClass - - org.springframework.web.context.support.AnnotationConfigWebApplicationContext - - - - contextConfigLocation - com.baeldung.spring.app.config.AppConfig - - 1 - - - - simpleweb - / - - - diff --git a/spring-mvc-forms-jsp/README.md b/spring-mvc-forms-jsp/README.md index 44786d5ec7..588828c9cf 100644 --- a/spring-mvc-forms-jsp/README.md +++ b/spring-mvc-forms-jsp/README.md @@ -4,5 +4,4 @@ - [MaxUploadSizeExceededException in Spring](http://www.baeldung.com/spring-maxuploadsizeexceeded) - [Getting Started with Forms in Spring MVC](http://www.baeldung.com/spring-mvc-form-tutorial) - [Form Validation with AngularJS and Spring MVC](http://www.baeldung.com/validation-angularjs-spring-mvc) -- [Guide to JSTL](http://www.baeldung.com/guide-to-jstl) - [A Guide to the JSTL Library](http://www.baeldung.com/jstl) diff --git a/spring-mvc-forms-jsp/pom.xml b/spring-mvc-forms-jsp/pom.xml index 359e186f52..3c18403c71 100644 --- a/spring-mvc-forms-jsp/pom.xml +++ b/spring-mvc-forms-jsp/pom.xml @@ -13,15 +13,16 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 org.springframework spring-webmvc - ${springframework.version} + ${spring.version} commons-logging @@ -65,11 +66,10 @@ commons-fileupload ${fileupload.version} - com.fasterxml.jackson.core jackson-databind - ${jackson.version} + ${jackson-databind.version} @@ -104,24 +104,14 @@ - - - 1 - jstl - https://mvnrepository.com/artifact/javax.servlet/jstl - - - - 4.3.7.RELEASE 2.6 1.2 2.3.1 3.1.0 - 5.4.0.Final + 6.0.10.Final server default deploy directory - 1.3.2 - 2.8.7 + 1.3.3 5.2.5.Final 5.1.40 diff --git a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java index 93fab9caf8..b8b36df84e 100644 --- a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java +++ b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java @@ -8,14 +8,13 @@ import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc @ComponentScan(basePackages = {"com.baeldung.springmvcforms", "com.baeldung.jstl"}) -class ApplicationConfiguration extends WebMvcConfigurerAdapter { +class ApplicationConfiguration implements WebMvcConfigurer { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { diff --git a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java index 49f006f422..9e0e7c99be 100644 --- a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java +++ b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java @@ -1,13 +1,12 @@ package com.baeldung.springmvcforms.domain; import javax.validation.constraints.Digits; +import javax.validation.constraints.Email; import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import org.hibernate.validator.constraints.Email; -import org.hibernate.validator.constraints.NotBlank; - public class User { @NotNull diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java index d4c15aead9..4b55bcc00f 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java @@ -1,23 +1,19 @@ package com.baeldung.web.controller; -import com.google.gson.Gson; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.handler.annotation.MessageExceptionHandler; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.simp.SimpMessageSendingOperations; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.stereotype.Controller; - import java.security.Principal; import java.util.Map; +import org.springframework.messaging.handler.annotation.MessageExceptionHandler; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.stereotype.Controller; + +import com.google.gson.Gson; + @Controller public class WebsocketSendToUserController { - @Autowired - private SimpMessageSendingOperations messagingTemplate; - private Gson gson = new Gson(); @MessageMapping("/message") diff --git a/spring-mvc-simple/README.md b/spring-mvc-simple/README.md index 3505fb8009..39053534fa 100644 --- a/spring-mvc-simple/README.md +++ b/spring-mvc-simple/README.md @@ -5,3 +5,4 @@ - [Spring 5 and Servlet 4 – The PushBuilder](http://www.baeldung.com/spring-5-push) - [Servlet Redirect vs Forward](http://www.baeldung.com/servlet-redirect-forward) - [Apache Tiles Integration with Spring MVC](http://www.baeldung.com/spring-mvc-apache-tiles) +- [Guide to Spring Email](http://www.baeldung.com/spring-email) diff --git a/spring-mvc-simple/pom.xml b/spring-mvc-simple/pom.xml index 08eab59540..ac112f7e29 100644 --- a/spring-mvc-simple/pom.xml +++ b/spring-mvc-simple/pom.xml @@ -20,6 +20,15 @@ spring-oxm ${spring-oxm.version} + + org.springframework + spring-context-support + + + com.sun.mail + javax.mail + 1.6.1 + javax.servlet javax.servlet-api @@ -122,6 +131,14 @@ json ${json.version} + + org.apache.maven.surefire + surefire-logger-api + ${maven-surefire-plugin.version} + + test + true + @@ -171,7 +188,7 @@ 1.2 2.3.2-b02 4.0.0 - 5.4.1.Final + 6.0.10.Final enter-location-of-server 1.3.2 1.8 diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java index c28ee02eef..284be6c212 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java @@ -8,6 +8,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.feed.RssChannelHttpMessageConverter; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @@ -20,10 +23,11 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; import java.util.ArrayList; import java.util.List; +import java.util.Properties; @Configuration @EnableWebMvc -@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator" }) +@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator", "com.baeldung.spring.mail" }) public class ApplicationConfiguration implements WebMvcConfigurer { @Override @@ -60,4 +64,29 @@ public class ApplicationConfiguration implements WebMvcConfigurer { converters.add(new RssChannelHttpMessageConverter()); converters.add(new JsonChannelHttpMessageConverter()); } + + @Bean + public SimpleMailMessage templateSimpleMessage() { + SimpleMailMessage message = new SimpleMailMessage(); + message.setText("This is the test email template for your email:\n%s\n"); + return message; + } + + @Bean + public JavaMailSender getJavaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost("smtp.gmail.com"); + mailSender.setPort(587); + + mailSender.setUsername("my.gmail@gmail.com"); + mailSender.setPassword("password"); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.debug", "true"); + + return mailSender; + } } diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java similarity index 95% rename from spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java index ff828ca9ec..16d1202eef 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java @@ -1,9 +1,8 @@ -package com.baeldung.spring.controllers; +package com.baeldung.spring.controller; import com.baeldung.spring.mail.EmailServiceImpl; -import com.baeldung.spring.web.dto.MailObject; +import com.baeldung.spring.domain.MailObject; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Controller; @@ -62,6 +61,11 @@ public class MailController { props.put("additionalInfo", "To make sure that you send an attachment with this email, change the value for the 'attachment.invoice' in the application.properties file to the path to the attachment."); labels.put("sendAttachment", props); } + + @RequestMapping(method = RequestMethod.GET) + public String showEmailsPage() { + return "emails"; + } @RequestMapping(value = {"/send", "/sendTemplate", "/sendAttachment"}, method = RequestMethod.GET) public String createMail(Model model, diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java similarity index 89% rename from spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java index 9623ff5d78..aceaf685fa 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java @@ -1,7 +1,6 @@ -package com.baeldung.spring.web.dto; - -import org.hibernate.validator.constraints.Email; +package com.baeldung.spring.domain; +import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java similarity index 100% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java similarity index 99% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java index ca418a7d90..039b970d8e 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java @@ -8,9 +8,10 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; +import java.io.File; + import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; -import java.io.File; /** * Created by Olga on 7/15/2016. diff --git a/spring-mvc-email/src/main/resources/application.properties b/spring-mvc-simple/src/main/resources/application.properties similarity index 87% rename from spring-mvc-email/src/main/resources/application.properties rename to spring-mvc-simple/src/main/resources/application.properties index 61a42050e5..9a804c07d8 100644 --- a/spring-mvc-email/src/main/resources/application.properties +++ b/spring-mvc-simple/src/main/resources/application.properties @@ -1,3 +1,5 @@ +#this property file will have to be loaded explicitly as this is not a Spring Boot project + # Gmail SMTP spring.mail.host=smtp.gmail.com spring.mail.port=587 diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp diff --git a/spring-mvc-webflow/pom.xml b/spring-mvc-webflow/pom.xml index f0a991912a..ec6ccc8ede 100644 --- a/spring-mvc-webflow/pom.xml +++ b/spring-mvc-webflow/pom.xml @@ -83,10 +83,10 @@ - 4.3.4.RELEASE + 5.0.1.RELEASE - 2.4.4.RELEASE + 2.5.0.RELEASE 3.1.0 1.2 @@ -94,8 +94,6 @@ 4.4.5 4.5.2 - 2.9.0 - 2.6 2.7 diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java index 434f49615b..46bf322f1d 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java @@ -2,12 +2,10 @@ package org.baeldung.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter; @@ -15,7 +13,7 @@ import org.springframework.webflow.mvc.servlet.FlowHandlerMapping; @EnableWebMvc @Configuration -public class WebMvcConfig extends WebMvcConfigurerAdapter { +public class WebMvcConfig implements WebMvcConfigurer { @Autowired private WebFlowConfig webFlowConfig; diff --git a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml index ab9eb1a9b7..bad5c5f78c 100644 --- a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml +++ b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml @@ -2,7 +2,7 @@ + http://www.springframework.org/schema/webflow/spring-webflow.xsd"> diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md index 6333b20e11..442a533d1b 100644 --- a/spring-mvc-xml/README.md +++ b/spring-mvc-xml/README.md @@ -10,7 +10,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](http://www.baeldung.com/spring-mvc-tutorial) - [Servlet Session Timeout](http://www.baeldung.com/servlet-session-timeout) -- [Basic Forms with Spring MVC](http://www.baeldung.com/spring-mvc-form-tutorial) - [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data) - [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind) - [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp) diff --git a/spring-mvc-xml/pom.xml b/spring-mvc-xml/pom.xml index 8ec2ff10e5..6979894f6f 100644 --- a/spring-mvc-xml/pom.xml +++ b/spring-mvc-xml/pom.xml @@ -37,13 +37,6 @@ - - com.fasterxml.jackson.core - jackson-databind - 2.9.2 - - - javax.servlet javax.servlet-api @@ -127,10 +120,8 @@ 5.0.2.RELEASE - 4.2.0.RELEASE - 5.2.5.Final 5.1.40 @@ -138,10 +129,10 @@ 4.5.2 - 5.3.3.Final + 6.0.10.Final 1.2 3.1.0 - 2.8.5 + 2.9.6 19.0 @@ -149,9 +140,6 @@ 2.5 2.8.0 - - 2.9.0 - 2.6 1.6.1 diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java index b5238b04d5..9752526963 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java @@ -2,11 +2,11 @@ package com.baeldung.spring; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @ImportResource("classpath:webMvcConfig.xml") @Configuration -public class ClientWebConfig extends WebMvcConfigurerAdapter { +public class ClientWebConfig implements WebMvcConfigurer { public ClientWebConfig() { super(); diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java index f299c46dbc..7925fa451d 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java @@ -9,13 +9,13 @@ import org.springframework.context.support.MessageSourceResourceBundle; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; //@EnableWebMvc //@Configuration -public class ClientWebConfigJava extends WebMvcConfigurerAdapter { +public class ClientWebConfigJava implements WebMvcConfigurer { public ClientWebConfigJava() { super(); @@ -38,8 +38,6 @@ public class ClientWebConfigJava extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/sample.html"); } diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java deleted file mode 100644 index fa76933f8f..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.spring.controller; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.ModelAndView; - -import com.baeldung.spring.form.Employee; - -@Controller -public class EmployeeController { - - Map employeeMap = new HashMap<>(); - - @RequestMapping(value = "/employee", method = RequestMethod.GET) - public ModelAndView showForm() { - return new ModelAndView("employeeHome", "employee", new Employee()); - } - - @RequestMapping(value = "/employee/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET) - public @ResponseBody Employee getEmployeeById(@PathVariable final long Id) { - return employeeMap.get(Id); - } - - @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) - public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) { - if (result.hasErrors()) { - return "error"; - } - model.addAttribute("name", employee.getName()); - model.addAttribute("contactNumber", employee.getContactNumber()); - model.addAttribute("id", employee.getId()); - employeeMap.put(employee.getId(), employee); - return "employeeView"; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java index eeaddcf8e0..0e2fe48160 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java @@ -11,7 +11,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import com.baeldung.spring.form.GeoIP; import com.baeldung.spring.service.RawDBDemoGeoIPLocationService; -@Controller +//@Controller +//add db file and uncomment to see the working example public class GeoIPTestController { private RawDBDemoGeoIPLocationService locationService; diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java deleted file mode 100644 index 66b2e9f185..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.spring.form; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class Employee { - - private long id; - - @NotNull - @Size(min = 1) - private String name; - @NotNull - @Size(min = 1) - private String contactNumber; - - public Employee() { - super(); - } - - // - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public long getId() { - return id; - } - - public void setId(final long id) { - this.id = id; - } - - public String getContactNumber() { - return contactNumber; - } - - public void setContactNumber(final String contactNumber) { - this.contactNumber = contactNumber; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java index 01638fbe76..307a36b10f 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java @@ -2,7 +2,8 @@ package com.baeldung.spring.form; import java.util.List; -import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.NotEmpty; + import org.springframework.web.multipart.MultipartFile; public class Person { diff --git a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml index 75d5c1ecd6..8a0671ca87 100644 --- a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml @@ -4,11 +4,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> + http://www.springframework.org/schema/mvc/spring-mvc.xsd"> diff --git a/spring-mvc-xml/src/main/resources/webMvcConfig.xml b/spring-mvc-xml/src/main/resources/webMvcConfig.xml index 37aebe1d1d..4bdb405237 100644 --- a/spring-mvc-xml/src/main/resources/webMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/webMvcConfig.xml @@ -3,11 +3,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd" + http://www.springframework.org/schema/mvc/spring-mvc.xsd" > diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp deleted file mode 100644 index 588678cdcf..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp +++ /dev/null @@ -1,33 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> - - - -Form Example - Register an Employee - - -

Welcome, Enter The Employee Details

- - - - - - - - - - - - - - - - - - -
Name
Id
Contact Number
-
- - - - \ No newline at end of file diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp deleted file mode 100644 index 1457bc5fc8..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp +++ /dev/null @@ -1,24 +0,0 @@ -<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> - - -Spring MVC Form Handling - - - -

Submitted Employee Information

- - - - - - - - - - - - - -
Name :${name}
ID :${id}
Contact Number :${contactNumber}
- - \ No newline at end of file diff --git a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java index 0e957f3400..0aa23842b1 100644 --- a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java +++ b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java @@ -14,10 +14,12 @@ public class GeoIpIntegrationTest { @Test public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception { - File database = new File("your-path-to-db-file"); + + ClassLoader classLoader = getClass().getClassLoader(); + File database = new File(classLoader.getResource("GeoLite2-City.mmdb").getFile()); DatabaseReader dbReader = new DatabaseReader.Builder(database).build(); - InetAddress ipAddress = InetAddress.getByName("your-public-ip"); + InetAddress ipAddress = InetAddress.getByName("google.com"); CityResponse response = dbReader.city(ipAddress); String countryName = response.getCountry().getName(); diff --git a/spring-mvc-xml/src/test/resources/.gitignore b/spring-mvc-xml/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/spring-mvc-xml/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb new file mode 100644 index 0000000000..6de839a7ed Binary files /dev/null and b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb differ diff --git a/spring-rest/README.md b/spring-rest/README.md index d1dcf554a5..b717a5001d 100644 --- a/spring-rest/README.md +++ b/spring-rest/README.md @@ -23,4 +23,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Custom Property Editor](http://www.baeldung.com/spring-mvc-custom-property-editor) - [Using the Spring RestTemplate Interceptor](http://www.baeldung.com/spring-rest-template-interceptor) - [Configure a RestTemplate with RestTemplateBuilder](http://www.baeldung.com/spring-rest-template-builder) - +- [Get and Post Lists of Objects with RestTemplate](http://www.baeldung.com/spring-rest-template-list) diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java new file mode 100644 index 0000000000..ebc18a130b --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.responseheaders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; + +@ServletComponentScan +@SpringBootApplication +public class ResponseHeadersApplication { + + public static void main(String[] args) { + SpringApplication.run(ResponseHeadersApplication.class, args); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java new file mode 100644 index 0000000000..c92d4afafd --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java @@ -0,0 +1,24 @@ +package com.baeldung.responseheaders.controllers; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/filter-response-header") +public class FilterResponseHeaderController { + + @GetMapping("/no-extra-header") + public String FilterHeaderResponseWithNoExtraHeader() { + return "Response body with Filter header and no extra header"; + } + + @GetMapping("/extra-header") + public String FilterHeaderResponseWithExtraHeader(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-ExtraHeader"); + return "Response body with Filter header and one extra header"; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..d93964b815 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,70 @@ +package com.baeldung.responseheaders.controllers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/single-response-header") +public class ResponseHeaderController { + + @GetMapping("/http-servlet-response") + public String usingHttpServletResponse(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-HttpServletResponse"); + return "Response with header using HttpServletResponse"; + } + + @GetMapping("/response-entity-constructor") + public ResponseEntity usingResponseEntityConstructor() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityContructor"); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-contructor-multiple-headers") + public ResponseEntity usingResponseEntityConstructorAndMultipleHeaders() { + List acceptableMediaTypes = new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON)); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityConstructorAndHeaders"); + responseHeaders.setAccept(acceptableMediaTypes); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-builder") + public ResponseEntity usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody); + } + + @GetMapping("/response-entity-builder-with-http-headers") + public ResponseEntity usingResponseEntityBuilderAndHttpHeaders() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityBuilderWithHttpHeaders"); + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .headers(responseHeaders) + .body(responseBody); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java new file mode 100644 index 0000000000..7d4ffb1391 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java @@ -0,0 +1,41 @@ +package com.baeldung.responseheaders.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@WebFilter("/filter-response-header/*") +public class AddResponseHeaderFilter implements Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(AddResponseHeaderFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // add special initialization requirements here + LOGGER.trace("Initializing filter..."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.setHeader("Baeldung-Example-Filter-Header", "Value-Filter"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // clean up any resource being held by the filter here + LOGGER.trace("Destroying filter..."); + } + +} diff --git a/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..bed0de55bd --- /dev/null +++ b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,103 @@ +package com.baeldung.responseheaders; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8082/spring-rest"; + private static final String SINGLE_BASE_URL = BASE_URL + "/single-response-header"; + private static final String FILTER_BASE_URL = BASE_URL + "/filter-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + + @Autowired + private TestRestTemplate template; + + @Test + public void whenHttpServletResponseRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/http-servlet-response"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-HttpServletResponse")); + } + + @Test + public void whenResponseEntityConstructorRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-constructor"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityContructor")); + } + + @Test + public void whenResponseEntityConstructorAndMultipleHeadersRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/response-entity-contructor-multiple-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityConstructorAndHeaders")); + assertThat(responseHeaders).containsEntry("Accept", Arrays.asList(MediaType.APPLICATION_JSON.toString())); + } + + @Test + public void whenResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilder")); + } + + @Test + public void whenResponseEntityBuilderAndHttpHeadersRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder-with-http-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilderWithHttpHeaders")); + } + + @Test + public void whenFilterWithNoExtraHeaderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/no-extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + } + + @Test + public void whenFilterWithExtraHeaderRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ExtraHeader")); + } + +} diff --git a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java similarity index 97% rename from spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java rename to spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java index e0c24c32b1..4f00bebdf4 100644 --- a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java +++ b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java @@ -21,7 +21,7 @@ import com.baeldung.transfer.LoginForm; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RestClientConfig.class) -public class RestTemplateIntegrationTest { +public class RestTemplateLiveTest { @Autowired RestTemplate restTemplate; diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java b/spring-security-mvc-custom/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java index 19f1ca76a6..19f49ea59d 100644 --- a/spring-security-mvc-custom/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java @@ -21,7 +21,7 @@ public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSu private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); - protected MySimpleUrlAuthenticationSuccessHandler() { + public MySimpleUrlAuthenticationSuccessHandler() { super(); } diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/spring-security-mvc-custom/src/main/java/org/baeldung/spring/SecSecurityConfig.java index e9d5bc4f70..ebe23950a7 100644 --- a/spring-security-mvc-custom/src/main/java/org/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -1,16 +1,70 @@ package org.baeldung.spring; +import org.baeldung.security.MySimpleUrlAuthenticationSuccessHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; @Configuration -@ImportResource({ "classpath:webSecurityConfig.xml" }) -public class SecSecurityConfig { +//@ImportResource({ "classpath:webSecurityConfig.xml" }) +@EnableWebSecurity +public class SecSecurityConfig extends WebSecurityConfigurerAdapter { - - public SecSecurityConfig() { super(); } + @Bean("authenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth.inMemoryAuthentication() + .withUser("user1").password("{noop}user1Pass").roles("USER") + .and() + .withUser("admin1").password("{noop}admin1Pass").roles("ADMIN"); + // @formatter:on + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers("/anonymous*").anonymous() + .antMatchers("/login*").permitAll() + .anyRequest().authenticated() + + .and() + .formLogin() + .loginPage("/login.html") + .loginProcessingUrl("/login") + .successHandler(myAuthenticationSuccessHandler()) + .failureUrl("/login.html?error=true") + + .and() + .logout().deleteCookies("JSESSIONID") + + .and() + .rememberMe().key("uniqueAndSecret").tokenValiditySeconds(86400) + + .and() + .csrf().disable() + ; + // @formatter:on + } + + @Bean + public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){ + return new MySimpleUrlAuthenticationSuccessHandler(); + } } diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml index f68b9addac..764e899640 100644 --- a/spring-security-sso/pom.xml +++ b/spring-security-sso/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../parent-boot-2 @@ -22,7 +22,9 @@ - 3.0.1 - - + 3.1.0 + 2.3.3.RELEASE + 2.0.1.RELEASE +
+ \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/pom.xml b/spring-security-sso/spring-security-sso-auth-server/pom.xml index 0d0086beb0..f506deccf7 100644 --- a/spring-security-sso/spring-security-sso-auth-server/pom.xml +++ b/spring-security-sso/spring-security-sso-auth-server/pom.xml @@ -21,6 +21,7 @@ org.springframework.security.oauth spring-security-oauth2 + ${oauth.version} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java index 20cde21073..56229d4d38 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java @@ -2,19 +2,20 @@ package org.baeldung.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { - @Autowired - private AuthenticationManager authenticationManager; - + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + @Override public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("permitAll()") @@ -25,17 +26,14 @@ public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("SampleClientId") - .secret("secret") + .secret(passwordEncoder.encode("secret")) .authorizedGrantTypes("authorization_code") .scopes("user_info") .autoApprove(true) + .redirectUris("http://localhost:8082/ui/login","http://localhost:8083/ui2/login") // .accessTokenValiditySeconds(3600) ; // 1 hour } - @Override - public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.authenticationManager(authenticationManager); - } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java index 5b0b39b444..b74d2f144c 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java index a568c22eec..5cebf4f4d2 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java @@ -1,18 +1,17 @@ package org.baeldung.config; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration +@Order(1) public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private AuthenticationManager authenticationManager; - + @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.requestMatchers() @@ -28,11 +27,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off - auth.parentAuthenticationManager(authenticationManager) - .inMemoryAuthentication() + auth.inMemoryAuthentication() .withUser("john") - .password("123") + .password(passwordEncoder().encode("123")) .roles("USER"); } // @formatter:on + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties index 32a0993b04..066123118f 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties @@ -1,4 +1,3 @@ server.port=8081 -server.context-path=/auth -security.basic.enabled=false +server.servlet.context-path=/auth #logging.level.org.springframework=DEBUG \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/pom.xml b/spring-security-sso/spring-security-sso-ui-2/pom.xml index a2323a044d..c38c855a30 100644 --- a/spring-security-sso/spring-security-sso-ui-2/pom.xml +++ b/spring-security-sso/spring-security-sso-ui-2/pom.xml @@ -25,8 +25,9 @@
- org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java index a222224c59..0c20853aed 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml index 6b0d3db5ad..97c8de7839 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8083 - context-path: /ui2 + servlet: + context-path: /ui2 session: cookie: name: UI2SESSION diff --git a/spring-security-sso/spring-security-sso-ui/pom.xml b/spring-security-sso/spring-security-sso-ui/pom.xml index dbb167b61c..6a0b630502 100644 --- a/spring-security-sso/spring-security-sso-ui/pom.xml +++ b/spring-security-sso/spring-security-sso-ui/pom.xml @@ -23,11 +23,13 @@ org.springframework.boot spring-boot-starter-security - + - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} + org.springframework.boot diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java index e186046e83..07d875d805 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml index bb4bd92033..d1d9ea6ebc 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8082 - context-path: /ui + servlet: + context-path: /ui session: cookie: name: UISESSION diff --git a/spring-security-thymeleaf/README.MD b/spring-security-thymeleaf/README.MD index 36007bce62..c5deeb9946 100644 --- a/spring-security-thymeleaf/README.MD +++ b/spring-security-thymeleaf/README.MD @@ -4,3 +4,4 @@ Jira BAEL-1556 ### Relevant Articles: - [Spring Security with Thymeleaf](http://www.baeldung.com/spring-security-thymeleaf) +- [Working with Select and Option in Thymeleaf](http://www.baeldung.com/thymeleaf-select-option) diff --git a/spring-session/pom.xml b/spring-session/pom.xml index 4c256663b0..277b033f43 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -30,6 +30,15 @@ org.springframework.boot spring-boot-starter-web + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + + + + 0.6 + \ No newline at end of file diff --git a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java b/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java index 84dd2bc139..f739aeb3ab 100644 --- a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java +++ b/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java @@ -1,27 +1,55 @@ package com.baeldung.spring.session; -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; -import redis.clients.jedis.Jedis; - -import java.util.Set; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.Set; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import redis.clients.jedis.Jedis; +import redis.embedded.RedisServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SessionWebApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) public class SessionControllerIntegrationTest { private Jedis jedis; + private static RedisServer redisServer; private TestRestTemplate testRestTemplate; private TestRestTemplate testRestTemplateWithAuth; private String testUrl = "http://localhost:8080/"; + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } + @Before public void clearRedisData() { + testRestTemplate = new TestRestTemplate(); - testRestTemplateWithAuth = new TestRestTemplate("admin", "password", null); + testRestTemplateWithAuth = new TestRestTemplate("admin", "password"); jedis = new Jedis("localhost", 6379); jedis.flushAll(); diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index 27af6c077a..99f46c2f39 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -15,6 +15,7 @@ - [Conditionals in Thymeleaf](http://www.baeldung.com/spring-thymeleaf-conditionals) - [Iteration in Thymeleaf](http://www.baeldung.com/thymeleaf-iteration) - [Working With Arrays in Thymeleaf](http://www.baeldung.com/thymeleaf-arrays) +- [Spring with Thymeleaf Pagination for a List](http://www.baeldung.com/spring-thymeleaf-pagination) ### Build the Project diff --git a/spring-thymeleaf/pom.xml b/spring-thymeleaf/pom.xml index 61d41e5f20..2c3740f1e8 100644 --- a/spring-thymeleaf/pom.xml +++ b/spring-thymeleaf/pom.xml @@ -98,6 +98,19 @@ ${springframework-security.version} test + + @@ -105,6 +118,7 @@ spring-data-commons ${springFramework-data.version} + @@ -117,6 +131,7 @@ false + org.codehaus.cargo cargo-maven2-plugin @@ -136,6 +151,7 @@ + org.apache.tomcat.maven tomcat7-maven-plugin diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java new file mode 100644 index 0000000000..bce0660fda --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java @@ -0,0 +1,12 @@ +// package com.baeldung.thymeleaf; + +// import org.springframework.boot.SpringApplication; +// import org.springframework.boot.autoconfigure.SpringBootApplication; + +// @SpringBootApplication +// public class WorkingWithArraysInThymeleafApplication { + +// public static void main(String[] args) { +// SpringApplication.run(WorkingWithArraysInThymeleafApplication.class, args); +// } +// } diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java new file mode 100644 index 0000000000..8276cc4376 --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java @@ -0,0 +1,17 @@ +package com.baeldung.thymeleaf.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ThymeleafArrayController { + @GetMapping("/arrays") + public String arrayController(Model model) { + String[] continents = {"Africa", "Antarctica", "Asia", "Australia", "Europe", "North America", "Sourth America"}; + + model.addAttribute("continents", continents); + + return "continents"; + } +} diff --git a/spring-thymeleaf/src/main/resources/templates/continents.html b/spring-thymeleaf/src/main/resources/templates/continents.html new file mode 100644 index 0000000000..0e7ffa3f58 --- /dev/null +++ b/spring-thymeleaf/src/main/resources/templates/continents.html @@ -0,0 +1,49 @@ + + + + Arrays in Thymeleaf + + + + + +

THE CONTINENTS

+

+ We have a total of + continents in this world. Following is a list showing their order + based on the number of population in each of them. +

+ +
    +
  1. +
  2. +
  3. +
  4. +
  5. +
  6. +
  7. +
+ +
    +
  • +
+ +

+ +

+ The greatest + continents. +

+ +

+ Europe is a continent: . +

+ +

+ Array of continents is empty . +

+ + + diff --git a/spring-userservice/pom.xml b/spring-userservice/pom.xml index c372beaa3c..a6acfe3fc6 100644 --- a/spring-userservice/pom.xml +++ b/spring-userservice/pom.xml @@ -217,11 +217,11 @@ 4.2.6.RELEASE - 1.4.2.RELEASE + 1.5.14.RELEASE 3.21.0-GA - 5.2.5.Final + 5.2.10.Final 5.1.40 1.10.5.RELEASE 1.4.193 diff --git a/spring-userservice/src/main/resources/persistence-derby.properties b/spring-userservice/src/main/resources/persistence-derby.properties index e808fdc288..b76c5de12f 100644 --- a/spring-userservice/src/main/resources/persistence-derby.properties +++ b/spring-userservice/src/main/resources/persistence-derby.properties @@ -7,6 +7,6 @@ jdbc.pass=tutorialpass # hibernate.X hibernate.dialect=org.hibernate.dialect.DerbyDialect hibernate.show_sql=false -hibernate.hbm2ddl.auto=create +hibernate.hbm2ddl.auto=update hibernate.cache.use_second_level_cache=false hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java index f46a3a070f..1cd38228b8 100644 --- a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java +++ b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java @@ -1,5 +1,10 @@ package org.baeldung.userservice; +import static org.junit.Assert.assertEquals; + +import java.util.logging.Level; +import java.util.logging.Logger; + import org.baeldung.custom.config.MvcConfig; import org.baeldung.custom.config.PersistenceDerbyJPAConfig; import org.baeldung.custom.config.SecSecurityConfig; @@ -8,22 +13,16 @@ import org.baeldung.web.MyUserDto; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.dao.DuplicateKeyException; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; -import static org.junit.Assert.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) @WebAppConfiguration public class CustomUserDetailsServiceIntegrationTest { diff --git a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java index eb3b858ddc..30614e7ee6 100755 --- a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java +++ b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java @@ -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> 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 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> 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 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; - } - } diff --git a/testing-modules/README.md b/testing-modules/README.md index d83970f96a..b269f547ec 100644 --- a/testing-modules/README.md +++ b/testing-modules/README.md @@ -12,4 +12,4 @@ - [Hamcrest Object Matchers](http://www.baeldung.com/hamcrest-object-matchers) - [Headers, Cookies and Parameters with REST-assured](http://www.baeldung.com/rest-assured-header-cookie-parameter) - [JSON Schema Validation with REST-assured](http://www.baeldung.com/rest-assured-json-schema) - +- [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) diff --git a/testing-modules/mockito/pom.xml b/testing-modules/mockito/pom.xml index c2e5b4bf31..45ce288fa9 100644 --- a/testing-modules/mockito/pom.xml +++ b/testing-modules/mockito/pom.xml @@ -46,6 +46,38 @@ ${hamcrest.version} + + org.springframework.boot + spring-boot-starter + LATEST + test + + + org.springframework.boot + spring-boot-starter-test + LATEST + test + + + org.springframework + spring-core + LATEST + + + org.springframework + spring-context + LATEST + + + org.eclipse.persistence + javax.persistence + 2.1.1 + + + org.springframework.data + spring-data-jpa + LATEST + @@ -67,7 +99,6 @@ 1.7.0 2.0.0.0 - \ No newline at end of file diff --git a/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/User.java b/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/User.java new file mode 100644 index 0000000000..28cd4f9fb0 --- /dev/null +++ b/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/User.java @@ -0,0 +1,49 @@ +package org.baeldung.mockito.repository; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue + private Integer id; + private String name; + private Integer status; + + public User() { + } + + public User(String name, Integer status) { + this.name = name; + this.status = status; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } +} \ No newline at end of file diff --git a/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/UserRepository.java b/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/UserRepository.java new file mode 100644 index 0000000000..3f1952a5e7 --- /dev/null +++ b/testing-modules/mockito/src/main/java/org/baeldung/mockito/repository/UserRepository.java @@ -0,0 +1,9 @@ +package org.baeldung.mockito.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository("userRepository") +public interface UserRepository extends JpaRepository { + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java new file mode 100644 index 0000000000..5d565fea88 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java @@ -0,0 +1,33 @@ +package org.baeldung.mockito; + +import org.baeldung.mockito.repository.UserRepository; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MockAnnotationUnitTest { + + @Mock + UserRepository mockRepository; + + @Test + public void testMockAnnotation() { + Mockito.when(mockRepository.count()).thenReturn(123L); + long userCount = mockRepository.count(); + Assert.assertEquals(123L, userCount); + Mockito.verify(mockRepository).count(); + } + + @Test + public void testMockitoMockMethod() { + UserRepository localMockRepository = Mockito.mock(UserRepository.class); + Mockito.when(localMockRepository.count()).thenReturn(111L); + long userCount = localMockRepository.count(); + Assert.assertEquals(111L, userCount); + Mockito.verify(localMockRepository).count(); + } +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java new file mode 100644 index 0000000000..008e674696 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java @@ -0,0 +1,30 @@ +package org.baeldung.mockito; + +import org.baeldung.mockito.repository.UserRepository; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +public class MockBeanAnnotationIntegrationTest { + + @MockBean + UserRepository mockRepository; + + @Autowired + ApplicationContext context; + + @Test + public void testMockBean() { + Mockito.when(mockRepository.count()).thenReturn(123L); + UserRepository userRepoFromContext = context.getBean(UserRepository.class); + long userCount = userRepoFromContext.count(); + Assert.assertEquals(123L, userCount); + Mockito.verify(mockRepository).count(); + } +} diff --git a/testing-modules/test-containers/README.md b/testing-modules/test-containers/README.md index 160893581d..f4f424194f 100644 --- a/testing-modules/test-containers/README.md +++ b/testing-modules/test-containers/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Docker Test Containers in Java Tests](TODO link to be added.) +- [Docker Test Containers in Java Tests](http://www.baeldung.com/docker-test-containers) diff --git a/xml/pom.xml b/xml/pom.xml index c417ceb15d..8c578cdad9 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -289,4 +289,3 @@
-