Merge remote-tracking branch 'origin/master' into sla-pr/1284-jesus
This commit is contained in:
commit
2665636c96
@ -1,3 +1,4 @@
|
|||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra)
|
- [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra)
|
||||||
|
- [Introduction to Cobertura](http://www.baeldung.com/cobertura)
|
||||||
|
4
apache-solrj/README.md
Normal file
4
apache-solrj/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
## Apache Solrj Tutorials Project
|
||||||
|
|
||||||
|
### Relevant Articles
|
||||||
|
- [Guide to Solr in Java with Apache Solrj](http://www.baeldung.com/apache-solrj)
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.solrjava;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.beans.Field;
|
||||||
|
|
||||||
|
public class ProductBean {
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
String price;
|
||||||
|
|
||||||
|
public ProductBean(String id, String name, String price) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field("id")
|
||||||
|
protected void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field("name")
|
||||||
|
protected void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field("price")
|
||||||
|
protected void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,12 @@ public class SolrJavaIntegration {
|
|||||||
solrClient.setParser(new XMLResponseParser());
|
solrClient.setParser(new XMLResponseParser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addProductBean(ProductBean pBean) throws IOException, SolrServerException {
|
||||||
|
|
||||||
|
solrClient.addBean(pBean);
|
||||||
|
solrClient.commit();
|
||||||
|
}
|
||||||
|
|
||||||
public void addSolrDocument(String documentId, String itemName, String itemPrice) throws SolrServerException, IOException {
|
public void addSolrDocument(String documentId, String itemName, String itemPrice) throws SolrServerException, IOException {
|
||||||
|
|
||||||
SolrInputDocument document = new SolrInputDocument();
|
SolrInputDocument document = new SolrInputDocument();
|
||||||
@ -27,12 +33,18 @@ public class SolrJavaIntegration {
|
|||||||
solrClient.commit();
|
solrClient.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteSolrDocument(String documentId) throws SolrServerException, IOException {
|
public void deleteSolrDocumentById(String documentId) throws SolrServerException, IOException {
|
||||||
|
|
||||||
solrClient.deleteById(documentId);
|
solrClient.deleteById(documentId);
|
||||||
solrClient.commit();
|
solrClient.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteSolrDocumentByQuery(String query) throws SolrServerException, IOException {
|
||||||
|
|
||||||
|
solrClient.deleteByQuery(query);
|
||||||
|
solrClient.commit();
|
||||||
|
}
|
||||||
|
|
||||||
protected HttpSolrClient getSolrClient() {
|
protected HttpSolrClient getSolrClient() {
|
||||||
return solrClient;
|
return solrClient;
|
||||||
}
|
}
|
||||||
@ -40,4 +52,5 @@ public class SolrJavaIntegration {
|
|||||||
protected void setSolrClient(HttpSolrClient solrClient) {
|
protected void setSolrClient(HttpSolrClient solrClient) {
|
||||||
this.solrClient = solrClient;
|
this.solrClient = solrClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class SolrJavaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAdd_thenVerifyAdded() throws SolrServerException, IOException {
|
public void whenAdd_thenVerifyAddedByQueryOnId() throws SolrServerException, IOException {
|
||||||
|
|
||||||
SolrQuery query = new SolrQuery();
|
SolrQuery query = new SolrQuery();
|
||||||
query.set("q", "id:123456");
|
query.set("q", "id:123456");
|
||||||
@ -33,18 +33,68 @@ public class SolrJavaIntegrationTest {
|
|||||||
response = solrJavaIntegration.getSolrClient().query(query);
|
response = solrJavaIntegration.getSolrClient().query(query);
|
||||||
|
|
||||||
SolrDocumentList docList = response.getResults();
|
SolrDocumentList docList = response.getResults();
|
||||||
assertEquals(docList.getNumFound(), 1);
|
assertEquals(1, docList.getNumFound());
|
||||||
|
|
||||||
for (SolrDocument doc : docList) {
|
for (SolrDocument doc : docList) {
|
||||||
assertEquals((String) doc.getFieldValue("id"), "123456");
|
assertEquals("Kenmore Dishwasher", (String) doc.getFieldValue("name"));
|
||||||
assertEquals((Double) doc.getFieldValue("price"), (Double) 599.99);
|
assertEquals((Double) 599.99, (Double) doc.getFieldValue("price"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenDelete_thenVerifyDeleted() throws SolrServerException, IOException {
|
public void whenAdd_thenVerifyAddedByQueryOnPrice() throws SolrServerException, IOException {
|
||||||
|
|
||||||
solrJavaIntegration.deleteSolrDocument("123456");
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.set("q", "price:599.99");
|
||||||
|
QueryResponse response = null;
|
||||||
|
|
||||||
|
response = solrJavaIntegration.getSolrClient().query(query);
|
||||||
|
|
||||||
|
SolrDocumentList docList = response.getResults();
|
||||||
|
assertEquals(1, docList.getNumFound());
|
||||||
|
|
||||||
|
for (SolrDocument doc : docList) {
|
||||||
|
assertEquals("123456", (String) doc.getFieldValue("id"));
|
||||||
|
assertEquals((Double) 599.99, (Double) doc.getFieldValue("price"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAdd_thenVerifyAddedByQuery() throws SolrServerException, IOException {
|
||||||
|
|
||||||
|
SolrDocument doc = solrJavaIntegration.getSolrClient().getById("123456");
|
||||||
|
assertEquals("Kenmore Dishwasher", (String) doc.getFieldValue("name"));
|
||||||
|
assertEquals((Double) 599.99, (Double) doc.getFieldValue("price"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddBean_thenVerifyAddedByQuery() throws SolrServerException, IOException {
|
||||||
|
|
||||||
|
ProductBean pBean = new ProductBean("888", "Apple iPhone 6s", "299.99");
|
||||||
|
solrJavaIntegration.addProductBean(pBean);
|
||||||
|
|
||||||
|
SolrDocument doc = solrJavaIntegration.getSolrClient().getById("888");
|
||||||
|
assertEquals("Apple iPhone 6s", (String) doc.getFieldValue("name"));
|
||||||
|
assertEquals((Double) 299.99, (Double) doc.getFieldValue("price"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteById_thenVerifyDeleted() throws SolrServerException, IOException {
|
||||||
|
|
||||||
|
solrJavaIntegration.deleteSolrDocumentById("123456");
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.set("q", "id:123456");
|
||||||
|
QueryResponse response = solrJavaIntegration.getSolrClient().query(query);
|
||||||
|
|
||||||
|
SolrDocumentList docList = response.getResults();
|
||||||
|
assertEquals(0, docList.getNumFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeleteByQuery_thenVerifyDeleted() throws SolrServerException, IOException {
|
||||||
|
|
||||||
|
solrJavaIntegration.deleteSolrDocumentByQuery("name:Kenmore Dishwasher");
|
||||||
|
|
||||||
SolrQuery query = new SolrQuery();
|
SolrQuery query = new SolrQuery();
|
||||||
query.set("q", "id:123456");
|
query.set("q", "id:123456");
|
||||||
@ -53,6 +103,6 @@ public class SolrJavaIntegrationTest {
|
|||||||
response = solrJavaIntegration.getSolrClient().query(query);
|
response = solrJavaIntegration.getSolrClient().query(query);
|
||||||
|
|
||||||
SolrDocumentList docList = response.getResults();
|
SolrDocumentList docList = response.getResults();
|
||||||
assertEquals(docList.getNumFound(), 0);
|
assertEquals(0, docList.getNumFound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
aws/pom.xml
25
aws/pom.xml
@ -7,17 +7,36 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>aws</name>
|
<name>aws</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<commons-io.version>2.5</commons-io.version>
|
||||||
|
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
||||||
|
<aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version>
|
||||||
|
<gson.version>2.8.0</gson.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.amazonaws</groupId>
|
<groupId>com.amazonaws</groupId>
|
||||||
<artifactId>aws-lambda-java-core</artifactId>
|
<artifactId>aws-lambda-java-core</artifactId>
|
||||||
<version>1.1.0</version>
|
<version>${aws-lambda-java-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.amazonaws</groupId>
|
||||||
|
<artifactId>aws-lambda-java-events</artifactId>
|
||||||
|
<version>${aws-lambda-java-events.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.5</version>
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>${gson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@ -26,7 +45,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.3</version>
|
<version>3.0.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.lambda.dynamodb;
|
||||||
|
|
||||||
|
import com.amazonaws.regions.Region;
|
||||||
|
import com.amazonaws.regions.Regions;
|
||||||
|
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
|
||||||
|
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
|
||||||
|
import com.amazonaws.services.dynamodbv2.document.Item;
|
||||||
|
import com.amazonaws.services.dynamodbv2.document.PutItemOutcome;
|
||||||
|
import com.amazonaws.services.dynamodbv2.document.spec.PutItemSpec;
|
||||||
|
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
|
||||||
|
import com.amazonaws.services.lambda.runtime.Context;
|
||||||
|
import com.amazonaws.services.lambda.runtime.RequestHandler;
|
||||||
|
import com.baeldung.lambda.dynamodb.bean.PersonRequest;
|
||||||
|
import com.baeldung.lambda.dynamodb.bean.PersonResponse;
|
||||||
|
|
||||||
|
public class SavePersonHandler implements RequestHandler<PersonRequest, PersonResponse> {
|
||||||
|
|
||||||
|
private DynamoDB dynamoDb;
|
||||||
|
|
||||||
|
private String DYNAMODB_TABLE_NAME = "Person";
|
||||||
|
private Regions REGION = Regions.US_WEST_2;
|
||||||
|
|
||||||
|
public PersonResponse handleRequest(PersonRequest personRequest, Context context) {
|
||||||
|
this.initDynamoDbClient();
|
||||||
|
|
||||||
|
persistData(personRequest);
|
||||||
|
|
||||||
|
PersonResponse personResponse = new PersonResponse();
|
||||||
|
personResponse.setMessage("Saved Successfully!!!");
|
||||||
|
return personResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PutItemOutcome persistData(PersonRequest personRequest) throws ConditionalCheckFailedException {
|
||||||
|
return this.dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||||
|
.putItem(
|
||||||
|
new PutItemSpec().withItem(new Item()
|
||||||
|
.withNumber("id", personRequest.getId())
|
||||||
|
.withString("firstName", personRequest.getFirstName())
|
||||||
|
.withString("lastName", personRequest.getLastName())
|
||||||
|
.withNumber("age", personRequest.getAge())
|
||||||
|
.withString("address", personRequest.getAddress())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDynamoDbClient() {
|
||||||
|
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
|
||||||
|
client.setRegion(Region.getRegion(REGION));
|
||||||
|
this.dynamoDb = new DynamoDB(client);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.baeldung.lambda.dynamodb.bean;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
public class PersonRequest {
|
||||||
|
private int id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private int age;
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
PersonRequest personRequest = new PersonRequest();
|
||||||
|
personRequest.setId(1);
|
||||||
|
personRequest.setFirstName("John");
|
||||||
|
personRequest.setLastName("Doe");
|
||||||
|
personRequest.setAge(30);
|
||||||
|
personRequest.setAddress("United States");
|
||||||
|
System.out.println(personRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
return gson.toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.lambda.dynamodb.bean;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class PersonResponse {
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
final Gson gson = new Gson();
|
||||||
|
return gson.toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,11 @@
|
|||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${ch.qos.logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
@ -76,9 +81,9 @@
|
|||||||
|
|
||||||
<!-- logging -->
|
<!-- logging -->
|
||||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||||
|
<ch.qos.logback.version>1.2.1</ch.qos.logback.version>
|
||||||
<!-- maven plugins -->
|
<!-- maven plugins -->
|
||||||
<maven-compiler-plugin.version>3.6-jigsaw-SNAPSHOT</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
package com.baeldung.java9.process;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sanaulla on 2/23/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ProcessAPIEnhancementsTest {
|
||||||
|
|
||||||
|
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
||||||
|
ProcessHandle processHandle = ProcessHandle.current();
|
||||||
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
|
assertNotNull(processHandle.getPid());
|
||||||
|
assertEquals(false, processInfo.arguments()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.command()
|
||||||
|
.isPresent());
|
||||||
|
assertTrue(processInfo.command()
|
||||||
|
.get()
|
||||||
|
.contains("java"));
|
||||||
|
|
||||||
|
assertEquals(true, processInfo.startInstant()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.totalCpuDuration()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.user()
|
||||||
|
.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSpawnProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
||||||
|
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd()
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version");
|
||||||
|
Process process = processBuilder.inheritIO()
|
||||||
|
.start();
|
||||||
|
ProcessHandle processHandle = process.toHandle();
|
||||||
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
|
assertNotNull(processHandle.getPid());
|
||||||
|
assertEquals(false, processInfo.arguments()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.command()
|
||||||
|
.isPresent());
|
||||||
|
assertTrue(processInfo.command()
|
||||||
|
.get()
|
||||||
|
.contains("java"));
|
||||||
|
assertEquals(true, processInfo.startInstant()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.totalCpuDuration()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, processInfo.user()
|
||||||
|
.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLiveProcesses_whenInvokeGetInfo_thenSuccess() {
|
||||||
|
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
||||||
|
liveProcesses.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> {
|
||||||
|
assertNotNull(ph.getPid());
|
||||||
|
assertEquals(true, ph.info()
|
||||||
|
.command()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, ph.info()
|
||||||
|
.startInstant()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, ph.info()
|
||||||
|
.totalCpuDuration()
|
||||||
|
.isPresent());
|
||||||
|
assertEquals(true, ph.info()
|
||||||
|
.user()
|
||||||
|
.isPresent());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenProcess_whenGetChildProcess_thenSuccess() throws IOException {
|
||||||
|
int childProcessCount = 5;
|
||||||
|
for (int i = 0; i < childProcessCount; i++) {
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd()
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder
|
||||||
|
= new ProcessBuilder(javaCmd, "-version");
|
||||||
|
processBuilder.inheritIO().start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<ProcessHandle> children = ProcessHandle.current()
|
||||||
|
.children();
|
||||||
|
children.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
||||||
|
.command()));
|
||||||
|
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
||||||
|
.descendants();
|
||||||
|
descendants.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
||||||
|
.command()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenProcess_whenAddExitCallback_thenSuccess() throws Exception {
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd()
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder
|
||||||
|
= new ProcessBuilder(javaCmd, "-version");
|
||||||
|
Process process = processBuilder.inheritIO()
|
||||||
|
.start();
|
||||||
|
ProcessHandle processHandle = process.toHandle();
|
||||||
|
|
||||||
|
log.info("PID: {} has started", processHandle.getPid());
|
||||||
|
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
||||||
|
onProcessExit.get();
|
||||||
|
assertEquals(false, processHandle.isAlive());
|
||||||
|
onProcessExit.thenAccept(ph -> {
|
||||||
|
log.info("PID: {} has stopped", ph.getPid());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,8 @@ package com.baeldung.algorithms;
|
|||||||
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import com.baeldung.algorithms.annealing.SimulatedAnnealing;
|
import com.baeldung.algorithms.ga.annealing.SimulatedAnnealing;
|
||||||
|
import com.baeldung.algorithms.ga.ant_colony.AntColonyOptimization;
|
||||||
import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm;
|
import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm;
|
||||||
import com.baeldung.algorithms.slope_one.SlopeOne;
|
import com.baeldung.algorithms.slope_one.SlopeOne;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ public class RunAlgorithm {
|
|||||||
System.out.println("1 - Simulated Annealing");
|
System.out.println("1 - Simulated Annealing");
|
||||||
System.out.println("2 - Slope One");
|
System.out.println("2 - Slope One");
|
||||||
System.out.println("3 - Simple Genetic Algorithm");
|
System.out.println("3 - Simple Genetic Algorithm");
|
||||||
|
System.out.println("4 - Ant Colony");
|
||||||
int decision = in.nextInt();
|
int decision = in.nextInt();
|
||||||
switch (decision) {
|
switch (decision) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -27,6 +29,10 @@ public class RunAlgorithm {
|
|||||||
SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm();
|
SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm();
|
||||||
ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111");
|
ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111");
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
AntColonyOptimization antColony = new AntColonyOptimization(21);
|
||||||
|
antColony.startAntOptimization();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Unknown option");
|
System.out.println("Unknown option");
|
||||||
break;
|
break;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.algorithms.annealing;
|
package com.baeldung.algorithms.ga.annealing;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.algorithms.annealing;
|
package com.baeldung.algorithms.ga.annealing;
|
||||||
|
|
||||||
public class SimulatedAnnealing {
|
public class SimulatedAnnealing {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.algorithms.annealing;
|
package com.baeldung.algorithms.ga.annealing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.algorithms.ga.ant_colony;
|
||||||
|
|
||||||
|
public class Ant {
|
||||||
|
|
||||||
|
protected int trailSize;
|
||||||
|
protected int trail[];
|
||||||
|
protected boolean visited[];
|
||||||
|
|
||||||
|
public Ant(int tourSize) {
|
||||||
|
this.trailSize = tourSize;
|
||||||
|
this.trail = new int[tourSize];
|
||||||
|
this.visited = new boolean[tourSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void visitCity(int currentIndex, int city) {
|
||||||
|
trail[currentIndex + 1] = city;
|
||||||
|
visited[city] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean visited(int i) {
|
||||||
|
return visited[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double trailLength(double graph[][]) {
|
||||||
|
double length = graph[trail[trailSize - 1]][trail[0]];
|
||||||
|
for (int i = 0; i < trailSize - 1; i++) {
|
||||||
|
length += graph[trail[i]][trail[i + 1]];
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void clear() {
|
||||||
|
for (int i = 0; i < trailSize; i++)
|
||||||
|
visited[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,212 @@
|
|||||||
|
package com.baeldung.algorithms.ga.ant_colony;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class AntColonyOptimization {
|
||||||
|
|
||||||
|
private double c = 1.0;
|
||||||
|
private double alpha = 1;
|
||||||
|
private double beta = 5;
|
||||||
|
private double evaporation = 0.5;
|
||||||
|
private double Q = 500;
|
||||||
|
private double antFactor = 0.8;
|
||||||
|
private double randomFactor = 0.01;
|
||||||
|
|
||||||
|
private int maxIterations = 1000;
|
||||||
|
|
||||||
|
public int numberOfCities;
|
||||||
|
public int numberOfAnts;
|
||||||
|
private double graph[][];
|
||||||
|
private double trails[][];
|
||||||
|
private Ant ants[];
|
||||||
|
private Random random = new Random();
|
||||||
|
private double probabilities[];
|
||||||
|
|
||||||
|
private int currentIndex;
|
||||||
|
|
||||||
|
public int[] bestTourOrder;
|
||||||
|
public double bestTourLength;
|
||||||
|
|
||||||
|
public AntColonyOptimization(int noOfCities) {
|
||||||
|
graph = generateRandomMatrix(noOfCities);
|
||||||
|
numberOfCities = graph.length;
|
||||||
|
numberOfAnts = (int) (numberOfCities * antFactor);
|
||||||
|
|
||||||
|
trails = new double[numberOfCities][numberOfCities];
|
||||||
|
probabilities = new double[numberOfCities];
|
||||||
|
ants = new Ant[numberOfAnts];
|
||||||
|
for (int j = 0; j < numberOfAnts; j++) {
|
||||||
|
ants[j] = new Ant(numberOfCities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate initial solution
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double[][] generateRandomMatrix(int n) {
|
||||||
|
double[][] randomMatrix = new double[n][n];
|
||||||
|
random.setSeed(System.currentTimeMillis());
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
Integer r = random.nextInt(100) + 1;
|
||||||
|
randomMatrix[i][j] = Math.abs(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return randomMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform ant optimization
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int[] startAntOptimization() {
|
||||||
|
int[] finalResult = null;
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
System.out.println("Attempt #" + i);
|
||||||
|
finalResult = solve();
|
||||||
|
}
|
||||||
|
return finalResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to run the main logic
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int[] solve() {
|
||||||
|
setupAnts();
|
||||||
|
clearTrails();
|
||||||
|
int iteration = 0;
|
||||||
|
while (iteration < maxIterations) {
|
||||||
|
moveAnts();
|
||||||
|
updateTrails();
|
||||||
|
updateBest();
|
||||||
|
iteration++;
|
||||||
|
}
|
||||||
|
System.out.println("Best tour length: " + (bestTourLength - numberOfCities));
|
||||||
|
System.out.println("Best tour order: " + Arrays.toString(bestTourOrder));
|
||||||
|
return bestTourOrder.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare ants for the simulation
|
||||||
|
*/
|
||||||
|
private void setupAnts() {
|
||||||
|
currentIndex = -1;
|
||||||
|
for (int i = 0; i < numberOfAnts; i++) {
|
||||||
|
ants[i].clear();
|
||||||
|
ants[i].visitCity(currentIndex, random.nextInt(numberOfCities));
|
||||||
|
}
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At each iteration, move ants
|
||||||
|
*/
|
||||||
|
private void moveAnts() {
|
||||||
|
while (currentIndex < numberOfCities - 1) {
|
||||||
|
for (Ant a : ants)
|
||||||
|
a.visitCity(currentIndex, selectNextCity(a));
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select next city for each ant
|
||||||
|
* @param ant
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int selectNextCity(Ant ant) {
|
||||||
|
if (random.nextDouble() < randomFactor) {
|
||||||
|
int t = random.nextInt(numberOfCities - currentIndex);
|
||||||
|
int j = -1;
|
||||||
|
for (int i = 0; i < numberOfCities; i++) {
|
||||||
|
if (!ant.visited(i)) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (j == t) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
calculateProbabilities(ant);
|
||||||
|
double r = random.nextDouble();
|
||||||
|
double total = 0;
|
||||||
|
for (int i = 0; i < numberOfCities; i++) {
|
||||||
|
total += probabilities[i];
|
||||||
|
if (total >= r) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("There are no other cities");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the next city picks probabilites
|
||||||
|
* @param ant
|
||||||
|
*/
|
||||||
|
private void calculateProbabilities(Ant ant) {
|
||||||
|
int i = ant.trail[currentIndex];
|
||||||
|
double pheromone = 0.0;
|
||||||
|
for (int l = 0; l < numberOfCities; l++) {
|
||||||
|
if (!ant.visited(l)) {
|
||||||
|
pheromone += Math.pow(trails[i][l], alpha) * Math.pow(1.0 / graph[i][l], beta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j < numberOfCities; j++) {
|
||||||
|
if (ant.visited(j)) {
|
||||||
|
probabilities[j] = 0.0;
|
||||||
|
} else {
|
||||||
|
double numerator = Math.pow(trails[i][j], alpha) * Math.pow(1.0 / graph[i][j], beta);
|
||||||
|
probabilities[j] = numerator / pheromone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update trails that ants used
|
||||||
|
*/
|
||||||
|
private void updateTrails() {
|
||||||
|
for (int i = 0; i < numberOfCities; i++) {
|
||||||
|
for (int j = 0; j < numberOfCities; j++) {
|
||||||
|
trails[i][j] *= evaporation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Ant a : ants) {
|
||||||
|
double contribution = Q / a.trailLength(graph);
|
||||||
|
for (int i = 0; i < numberOfCities - 1; i++) {
|
||||||
|
trails[a.trail[i]][a.trail[i + 1]] += contribution;
|
||||||
|
}
|
||||||
|
trails[a.trail[numberOfCities - 1]][a.trail[0]] += contribution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the best solution
|
||||||
|
*/
|
||||||
|
private void updateBest() {
|
||||||
|
if (bestTourOrder == null) {
|
||||||
|
bestTourOrder = ants[0].trail;
|
||||||
|
bestTourLength = ants[0].trailLength(graph);
|
||||||
|
}
|
||||||
|
for (Ant a : ants) {
|
||||||
|
if (a.trailLength(graph) < bestTourLength) {
|
||||||
|
bestTourLength = a.trailLength(graph);
|
||||||
|
bestTourOrder = a.trail.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear trails after simulation
|
||||||
|
*/
|
||||||
|
private void clearTrails() {
|
||||||
|
for (int i = 0; i < numberOfCities; i++)
|
||||||
|
for (int j = 0; j < numberOfCities; j++)
|
||||||
|
trails[i][j] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.locks.Condition;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
public class ReentrantLockWithCondition {
|
||||||
|
|
||||||
|
static Logger logger = LoggerFactory.getLogger(ReentrantLockWithCondition.class);
|
||||||
|
|
||||||
|
Stack<String> stack = new Stack<>();
|
||||||
|
int CAPACITY = 5;
|
||||||
|
|
||||||
|
ReentrantLock lock = new ReentrantLock();
|
||||||
|
Condition stackEmptyCondition = lock.newCondition();
|
||||||
|
Condition stackFullCondition = lock.newCondition();
|
||||||
|
|
||||||
|
public void pushToStack(String item) throws InterruptedException {
|
||||||
|
try {
|
||||||
|
lock.lock();
|
||||||
|
if (stack.size() == CAPACITY) {
|
||||||
|
logger.info(Thread.currentThread().getName() + " wait on stack full");
|
||||||
|
stackFullCondition.await();
|
||||||
|
}
|
||||||
|
logger.info("Pushing the item " + item);
|
||||||
|
stack.push(item);
|
||||||
|
stackEmptyCondition.signalAll();
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String popFromStack() throws InterruptedException {
|
||||||
|
try {
|
||||||
|
lock.lock();
|
||||||
|
if (stack.size() == 0) {
|
||||||
|
logger.info(Thread.currentThread().getName() + " wait on stack empty");
|
||||||
|
stackEmptyCondition.await();
|
||||||
|
}
|
||||||
|
return stack.pop();
|
||||||
|
} finally {
|
||||||
|
stackFullCondition.signalAll();
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final int threadCount = 2;
|
||||||
|
ReentrantLockWithCondition object = new ReentrantLockWithCondition();
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
service.execute(() -> {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
try {
|
||||||
|
object.pushToStack("Item " + i);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
service.execute(() -> {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
try {
|
||||||
|
logger.info("Item popped " + object.popFromStack());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
public class SharedObjectWithLock {
|
||||||
|
|
||||||
|
Logger logger = LoggerFactory.getLogger(SharedObjectWithLock.class);
|
||||||
|
|
||||||
|
ReentrantLock lock = new ReentrantLock(true);
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
public void perform() {
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||||
|
try {
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||||
|
counter++;
|
||||||
|
} catch (Exception exception) {
|
||||||
|
logger.error(" Interrupted Exception ", exception);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performTryLock() {
|
||||||
|
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " attempting to acquire the lock");
|
||||||
|
try {
|
||||||
|
boolean isLockAcquired = lock.tryLock(2, TimeUnit.SECONDS);
|
||||||
|
if (isLockAcquired) {
|
||||||
|
try {
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
|
||||||
|
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " processing");
|
||||||
|
sleep(1000);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException exception) {
|
||||||
|
logger.error(" Interrupted Exception ", exception);
|
||||||
|
}
|
||||||
|
logger.info("Thread - " + Thread.currentThread().getName() + " could not acquire the lock");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReentrantLock getLock() {
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isLocked() {
|
||||||
|
return lock.isLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasQueuedThreads() {
|
||||||
|
return lock.hasQueuedThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
final int threadCount = 2;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||||
|
|
||||||
|
service.execute(() -> {
|
||||||
|
object.perform();
|
||||||
|
});
|
||||||
|
service.execute(() -> {
|
||||||
|
object.performTryLock();
|
||||||
|
});
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.locks.StampedLock;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
public class StampedLockDemo {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
Logger logger = LoggerFactory.getLogger(StampedLockDemo.class);
|
||||||
|
|
||||||
|
private final StampedLock lock = new StampedLock();
|
||||||
|
|
||||||
|
public void put(String key, String value) throws InterruptedException {
|
||||||
|
long stamp = lock.writeLock();
|
||||||
|
|
||||||
|
try {
|
||||||
|
logger.info(Thread.currentThread().getName() + " acquired the write lock with stamp " + stamp);
|
||||||
|
map.put(key, value);
|
||||||
|
} finally {
|
||||||
|
lock.unlockWrite(stamp);
|
||||||
|
logger.info(Thread.currentThread().getName() + " unlocked the write lock with stamp " + stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get(String key) throws InterruptedException {
|
||||||
|
long stamp = lock.readLock();
|
||||||
|
logger.info(Thread.currentThread().getName() + " acquired the read lock with stamp " + stamp);
|
||||||
|
try {
|
||||||
|
sleep(5000);
|
||||||
|
return map.get(key);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
lock.unlockRead(stamp);
|
||||||
|
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readWithOptimisticLock(String key) throws InterruptedException {
|
||||||
|
long stamp = lock.tryOptimisticRead();
|
||||||
|
String value = map.get(key);
|
||||||
|
|
||||||
|
if (!lock.validate(stamp)) {
|
||||||
|
stamp = lock.readLock();
|
||||||
|
try {
|
||||||
|
sleep(5000);
|
||||||
|
return map.get(key);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
lock.unlock(stamp);
|
||||||
|
logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final int threadCount = 4;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
StampedLockDemo object = new StampedLockDemo();
|
||||||
|
|
||||||
|
Runnable writeTask = () -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
object.put("key1", "value1");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Runnable readTask = () -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
object.get("key1");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Runnable readOptimisticTask = () -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
object.readWithOptimisticLock("key1");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
service.submit(writeTask);
|
||||||
|
service.submit(writeTask);
|
||||||
|
service.submit(readTask);
|
||||||
|
service.submit(readOptimisticTask);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
public class SynchronizedHashMapWithRWLock {
|
||||||
|
|
||||||
|
static Map<String, String> syncHashMap = new HashMap<>();
|
||||||
|
Logger logger = LoggerFactory.getLogger(SynchronizedHashMapWithRWLock.class);
|
||||||
|
|
||||||
|
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
private final Lock readLock = lock.readLock();
|
||||||
|
private final Lock writeLock = lock.writeLock();
|
||||||
|
|
||||||
|
public void put(String key, String value) throws InterruptedException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
logger.info(Thread.currentThread().getName() + " writing");
|
||||||
|
syncHashMap.put(key, value);
|
||||||
|
sleep(1000);
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get(String key) {
|
||||||
|
try {
|
||||||
|
readLock.lock();
|
||||||
|
logger.info(Thread.currentThread().getName() + " reading");
|
||||||
|
return syncHashMap.get(key);
|
||||||
|
} finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String remove(String key) {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
return syncHashMap.remove(key);
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(String key) {
|
||||||
|
try {
|
||||||
|
readLock.lock();
|
||||||
|
return syncHashMap.containsKey(key);
|
||||||
|
} finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isReadLockAvailable() {
|
||||||
|
return readLock.tryLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
|
||||||
|
final int threadCount = 3;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
|
||||||
|
|
||||||
|
service.execute(new Thread(new Writer(object), "Writer"));
|
||||||
|
service.execute(new Thread(new Reader(object), "Reader1"));
|
||||||
|
service.execute(new Thread(new Reader(object), "Reader2"));
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Reader implements Runnable {
|
||||||
|
|
||||||
|
SynchronizedHashMapWithRWLock object;
|
||||||
|
|
||||||
|
public Reader(SynchronizedHashMapWithRWLock object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
object.get("key" + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Writer implements Runnable {
|
||||||
|
|
||||||
|
SynchronizedHashMapWithRWLock object;
|
||||||
|
|
||||||
|
public Writer(SynchronizedHashMapWithRWLock object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
try {
|
||||||
|
object.put("key" + i, "value" + i);
|
||||||
|
sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.list.listoflist;
|
||||||
|
|
||||||
|
public class Pen implements Stationery {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public Pen(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.list.listoflist;
|
||||||
|
|
||||||
|
public class Pencil implements Stationery{
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public Pencil(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.list.listoflist;
|
||||||
|
|
||||||
|
public class Rubber implements Stationery {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public Rubber(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.baeldung.list.listoflist;
|
||||||
|
|
||||||
|
public interface Stationery {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.algorithms;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.ga.ant_colony.AntColonyOptimization;
|
||||||
|
|
||||||
|
public class AntColonyOptimizationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateRandomMatrix() {
|
||||||
|
AntColonyOptimization antTSP = new AntColonyOptimization(5);
|
||||||
|
Assert.assertNotNull(antTSP.generateRandomMatrix(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartAntOptimization() {
|
||||||
|
AntColonyOptimization antTSP = new AntColonyOptimization(5);
|
||||||
|
Assert.assertNotNull(antTSP.startAntOptimization());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,7 +3,7 @@ package com.baeldung.algorithms;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.baeldung.algorithms.annealing.SimulatedAnnealing;
|
import com.baeldung.algorithms.ga.annealing.SimulatedAnnealing;
|
||||||
|
|
||||||
public class SimulatedAnnealingTest {
|
public class SimulatedAnnealingTest {
|
||||||
|
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class SharedObjectWithLockManualTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenLockAcquired_ThenLockedIsTrue() {
|
||||||
|
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||||
|
|
||||||
|
final int threadCount = 2;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
|
||||||
|
executeThreads(object, threadCount, service);
|
||||||
|
|
||||||
|
assertEquals(true, object.isLocked());
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenLocked_ThenQueuedThread() {
|
||||||
|
final int threadCount = 4;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||||
|
|
||||||
|
executeThreads(object, threadCount, service);
|
||||||
|
|
||||||
|
assertEquals(object.hasQueuedThreads(), true);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void whenTryLock_ThenQueuedThread() {
|
||||||
|
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||||
|
|
||||||
|
final int threadCount = 2;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
|
||||||
|
executeThreads(object, threadCount, service);
|
||||||
|
|
||||||
|
assertEquals(true, object.isLocked());
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetCount_ThenCorrectCount() throws InterruptedException {
|
||||||
|
final int threadCount = 4;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
final SharedObjectWithLock object = new SharedObjectWithLock();
|
||||||
|
|
||||||
|
executeThreads(object, threadCount, service);
|
||||||
|
Thread.sleep(1000);
|
||||||
|
assertEquals(object.getCounter(), 4);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeThreads(SharedObjectWithLock object, int threadCount, ExecutorService service) {
|
||||||
|
for (int i = 0; i < threadCount; i++) {
|
||||||
|
service.execute(() -> {
|
||||||
|
object.perform();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.baeldung.concurrent.locks;
|
||||||
|
|
||||||
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class SynchronizedHashMapWithRWLockManualTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWriting_ThenNoReading() {
|
||||||
|
SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
|
||||||
|
final int threadCount = 3;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
|
||||||
|
executeWriterThreads(object, threadCount, service);
|
||||||
|
|
||||||
|
assertEquals(object.isReadLockAvailable(), false);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenReading_ThenMultipleReadingAllowed() {
|
||||||
|
SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
|
||||||
|
final int threadCount = 5;
|
||||||
|
final ExecutorService service = Executors.newFixedThreadPool(threadCount);
|
||||||
|
|
||||||
|
executeReaderThreads(object, threadCount, service);
|
||||||
|
|
||||||
|
assertEquals(object.isReadLockAvailable(), true);
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeWriterThreads(SynchronizedHashMapWithRWLock object, int threadCount, ExecutorService service) {
|
||||||
|
for (int i = 0; i < threadCount; i++) {
|
||||||
|
service.execute(() -> {
|
||||||
|
try {
|
||||||
|
object.put("key" + threadCount, "value" + threadCount);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeReaderThreads(SynchronizedHashMapWithRWLock object, int threadCount, ExecutorService service) {
|
||||||
|
for (int i = 0; i < threadCount; i++)
|
||||||
|
service.execute(() -> {
|
||||||
|
object.get("key" + threadCount);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.baeldung.list.listoflist;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ListOfListsTest {
|
||||||
|
|
||||||
|
private List<ArrayList<? extends Stationery>> listOfLists = new ArrayList<ArrayList<? extends Stationery>>();
|
||||||
|
private ArrayList<Pen> penList = new ArrayList<>();
|
||||||
|
private ArrayList<Pencil> pencilList = new ArrayList<>();
|
||||||
|
private ArrayList<Rubber> rubberList = new ArrayList<>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
listOfLists.add(penList);
|
||||||
|
listOfLists.add(pencilList);
|
||||||
|
listOfLists.add(rubberList);
|
||||||
|
|
||||||
|
((ArrayList<Pen>) listOfLists.get(0)).add(new Pen("Pen 1"));
|
||||||
|
((ArrayList<Pencil>) listOfLists.get(1)).add(new Pencil("Pencil 1"));
|
||||||
|
((ArrayList<Rubber>) listOfLists.get(2)).add(new Rubber("Rubber 1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenListOfLists_thenCheckNames() {
|
||||||
|
assertEquals("Pen 1", ((Pen) listOfLists.get(0)
|
||||||
|
.get(0)).getName());
|
||||||
|
assertEquals("Pencil 1", ((Pencil) listOfLists.get(1)
|
||||||
|
.get(0)).getName());
|
||||||
|
assertEquals("Rubber 1", ((Rubber) listOfLists.get(2)
|
||||||
|
.get(0)).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void givenListOfLists_whenRemovingElements_thenCheckNames() {
|
||||||
|
|
||||||
|
((ArrayList<Pencil>) listOfLists.get(1)).remove(0);
|
||||||
|
listOfLists.remove(1);
|
||||||
|
assertEquals("Rubber 1", ((Rubber) listOfLists.get(1)
|
||||||
|
.get(0)).getName());
|
||||||
|
listOfLists.remove(0);
|
||||||
|
assertEquals("Rubber 1", ((Rubber) listOfLists.get(0)
|
||||||
|
.get(0)).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThreeList_whenCombineIntoOneList_thenCheckList() {
|
||||||
|
ArrayList<Pen> pens = new ArrayList<>();
|
||||||
|
pens.add(new Pen("Pen 1"));
|
||||||
|
pens.add(new Pen("Pen 2"));
|
||||||
|
ArrayList<Pencil> pencils = new ArrayList<>();
|
||||||
|
pencils.add(new Pencil("Pencil 1"));
|
||||||
|
pencils.add(new Pencil("Pencil 2"));
|
||||||
|
ArrayList<Rubber> rubbers = new ArrayList<>();
|
||||||
|
rubbers.add(new Rubber("Rubber 1"));
|
||||||
|
rubbers.add(new Rubber("Rubber 2"));
|
||||||
|
|
||||||
|
List<ArrayList<? extends Stationery>> list = new ArrayList<ArrayList<? extends Stationery>>();
|
||||||
|
list.add(pens);
|
||||||
|
list.add(pencils);
|
||||||
|
list.add(rubbers);
|
||||||
|
|
||||||
|
assertEquals("Pen 1", ((Pen) list.get(0)
|
||||||
|
.get(0)).getName());
|
||||||
|
assertEquals("Pencil 1", ((Pencil) list.get(1)
|
||||||
|
.get(0)).getName());
|
||||||
|
assertEquals("Rubber 1", ((Rubber) list.get(2)
|
||||||
|
.get(0)).getName());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
package org.baeldung.guava;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.reflect.Invokable;
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GuavaReflectionUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoGenericList_whenCheckIsAssignableFrom_thenReturnTrueDueToTypeErasure() {
|
||||||
|
//given
|
||||||
|
ArrayList<String> stringList = Lists.newArrayList();
|
||||||
|
ArrayList<Integer> intList = Lists.newArrayList();
|
||||||
|
|
||||||
|
//when
|
||||||
|
boolean result = stringList.getClass().isAssignableFrom(intList.getClass());
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTypeToken_whenResolveType_thenShouldResolveProperType() {
|
||||||
|
//given
|
||||||
|
TypeToken<List<String>> stringListToken = new TypeToken<List<String>>() {
|
||||||
|
};
|
||||||
|
TypeToken<List<Integer>> integerListToken = new TypeToken<List<Integer>>() {
|
||||||
|
};
|
||||||
|
TypeToken<List<? extends Number>> numberTypeToken = new TypeToken<List<? extends Number>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertFalse(stringListToken.isSubtypeOf(integerListToken));
|
||||||
|
assertFalse(numberTypeToken.isSubtypeOf(integerListToken));
|
||||||
|
assertTrue(integerListToken.isSubtypeOf(numberTypeToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCustomClass_whenCaptureGeneric_thenReturnTypeAtRuntime() {
|
||||||
|
//given
|
||||||
|
ParametrizedClass<String> parametrizedClass = new ParametrizedClass<String>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(parametrizedClass.type, TypeToken.of(String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenComplexType_whenGetTypeArgument_thenShouldReturnTypeAtRuntime() {
|
||||||
|
//given
|
||||||
|
TypeToken<Function<Integer, String>> funToken = new TypeToken<Function<Integer, String>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
//when
|
||||||
|
TypeToken<?> funResultToken = funToken.resolveType(Function.class.getTypeParameters()[1]);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(funResultToken, TypeToken.of(String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMapType_whenGetTypeArgumentOfEntry_thenShouldReturnTypeAtRuntime() throws NoSuchMethodException {
|
||||||
|
//given
|
||||||
|
TypeToken<Map<String, Integer>> mapToken = new TypeToken<Map<String, Integer>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
//when
|
||||||
|
TypeToken<?> entrySetToken = mapToken.resolveType(Map.class.getMethod("entrySet").getGenericReturnType());
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(entrySetToken, new TypeToken<Set<Map.Entry<String, Integer>>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInvokable_whenCheckPublicMethod_shouldReturnTrue() throws NoSuchMethodException {
|
||||||
|
//given
|
||||||
|
Method method = CustomClass.class.getMethod("somePublicMethod");
|
||||||
|
Invokable<CustomClass, ?> invokable = new TypeToken<CustomClass>() {
|
||||||
|
}.method(method);
|
||||||
|
|
||||||
|
//when
|
||||||
|
boolean isPublicStandradJava = Modifier.isPublic(method.getModifiers());
|
||||||
|
boolean isPublicGuava = invokable.isPublic();
|
||||||
|
//then
|
||||||
|
assertTrue(isPublicStandradJava);
|
||||||
|
assertTrue(isPublicGuava);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInvokable_whenCheckFinalMethod_shouldReturnFalseForIsOverridable() throws NoSuchMethodException {
|
||||||
|
//given
|
||||||
|
Method method = CustomClass.class.getMethod("notOverridablePublicMethod");
|
||||||
|
Invokable<CustomClass, ?> invokable = new TypeToken<CustomClass>() {
|
||||||
|
}.method(method);
|
||||||
|
|
||||||
|
//when
|
||||||
|
boolean isOverridableStandardJava = (!(Modifier.isFinal(method.getModifiers()) || Modifier.isPrivate(method.getModifiers())
|
||||||
|
|| Modifier.isStatic(method.getModifiers())
|
||||||
|
|| Modifier.isFinal(method.getDeclaringClass().getModifiers())));
|
||||||
|
boolean isOverridableFinalGauava = invokable.isOverridable();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertFalse(isOverridableStandardJava);
|
||||||
|
assertFalse(isOverridableFinalGauava);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenListOfType_whenGetReturnRype_shouldCaptureTypeAtRuntime() throws NoSuchMethodException {
|
||||||
|
//given
|
||||||
|
Method getMethod = List.class.getMethod("get", int.class);
|
||||||
|
|
||||||
|
//when
|
||||||
|
Invokable<List<Integer>, ?> invokable = new TypeToken<List<Integer>>() {
|
||||||
|
}.method(getMethod);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(TypeToken.of(Integer.class), invokable.getReturnType()); // Not Object.class!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract class ParametrizedClass<T> {
|
||||||
|
TypeToken<T> type = new TypeToken<T>(getClass()) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomClass {
|
||||||
|
public void somePublicMethod() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void notOverridablePublicMethod() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
guice-intro/pom.xml
Normal file
34
guice-intro/pom.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.examples.guice</groupId>
|
||||||
|
<artifactId>guice-intro</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.inject</groupId>
|
||||||
|
<artifactId>guice</artifactId>
|
||||||
|
<version>${guice.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<guice.version>4.1.0</guice.version>
|
||||||
|
</properties>
|
||||||
|
<name>guice-intro</name>
|
||||||
|
</project>
|
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
package com.baeldung.examples;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.Communication;
|
||||||
|
import com.baeldung.examples.guice.binding.AOPModule;
|
||||||
|
import com.baeldung.examples.guice.modules.BasicModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class RunGuice {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Injector injector = Guice.createInjector(new BasicModule(), new AOPModule());
|
||||||
|
Communication comms = injector.getInstance(Communication.class);
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
System.out.println("Enter your message to be sent; press Q to quit and P to print the message log");
|
||||||
|
while (true) {
|
||||||
|
String input = scanner.nextLine();
|
||||||
|
if (input.equalsIgnoreCase("q")) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
if (input.equalsIgnoreCase("p")) {
|
||||||
|
comms.print();
|
||||||
|
} else {
|
||||||
|
comms.sendMessage(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class Communication {
|
||||||
|
|
||||||
|
final Date start = new Date();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
private Queue<String> messageLog;
|
||||||
|
|
||||||
|
@Named("CommsUUID")
|
||||||
|
private String commsID;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DefaultCommunicator communicator;
|
||||||
|
|
||||||
|
public Communication(Boolean keepRecords) {
|
||||||
|
if (keepRecords) {
|
||||||
|
messageLog = new LinkedList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendMessage(String message) {
|
||||||
|
if (!message.isEmpty() && messageLog != null) {
|
||||||
|
messageLog.add(message);
|
||||||
|
}
|
||||||
|
return communicator.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void print() {
|
||||||
|
if (messageLog != null) {
|
||||||
|
for (String message : messageLog) {
|
||||||
|
logger.info(message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("Message logging wasn't enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultCommunicator getCommunicator() {
|
||||||
|
return this.communicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.constant.CommunicationModel;
|
||||||
|
|
||||||
|
public interface CommunicationMode {
|
||||||
|
|
||||||
|
public CommunicationModel getMode();
|
||||||
|
|
||||||
|
public boolean sendMessage(String message);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.marker.Communicator;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
|
||||||
|
public class DefaultCommunicator implements Communicator {
|
||||||
|
|
||||||
|
private CommunicationMode defaultCommsMode;
|
||||||
|
@Inject
|
||||||
|
@Named("SMSComms")
|
||||||
|
CommunicationMode smsCommsMode;
|
||||||
|
@Inject
|
||||||
|
@Named("EmailComms")
|
||||||
|
CommunicationMode emailCommsMode;
|
||||||
|
@Inject
|
||||||
|
@Named("IMComms")
|
||||||
|
CommunicationMode imCommsMode;
|
||||||
|
|
||||||
|
protected DefaultCommunicator(CommunicationMode defaultComms) {
|
||||||
|
this.defaultCommsMode = defaultComms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultCommunicator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendMessage(String message) {
|
||||||
|
boolean sent = false;
|
||||||
|
if (defaultCommsMode != null) {
|
||||||
|
sent = sendMessageByDefault(message);
|
||||||
|
} else {
|
||||||
|
sent = smsCommsMode.sendMessage(message);
|
||||||
|
}
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sendMessageByDefault(String message) {
|
||||||
|
boolean sent = false;
|
||||||
|
if (message != null && !message.trim().equals("")) {
|
||||||
|
return defaultCommsMode.sendMessage(message);
|
||||||
|
}
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.aop.MessageSentLoggable;
|
||||||
|
import com.baeldung.examples.guice.constant.CommunicationModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baekdung
|
||||||
|
*/
|
||||||
|
public class EmailCommunicationMode implements CommunicationMode {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommunicationModel getMode() {
|
||||||
|
return CommunicationModel.EMAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@MessageSentLoggable
|
||||||
|
public boolean sendMessage(String Message) {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.aop.MessageSentLoggable;
|
||||||
|
import com.baeldung.examples.guice.constant.CommunicationModel;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class IMCommunicationMode implements CommunicationMode {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommunicationModel getMode() {
|
||||||
|
return CommunicationModel.IM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@MessageSentLoggable
|
||||||
|
public boolean sendMessage(String message) {
|
||||||
|
logger.info("IM Message Sent");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung.examples.guice;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.aop.MessageSentLoggable;
|
||||||
|
import com.baeldung.examples.guice.constant.CommunicationModel;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class SMSCommunicationMode implements CommunicationMode {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommunicationModel getMode() {
|
||||||
|
return CommunicationModel.SMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@MessageSentLoggable
|
||||||
|
public boolean sendMessage(String message) {
|
||||||
|
logger.info("SMS message sent");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.examples.guice.aop;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.aopalliance.intercept.MethodInterceptor;
|
||||||
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class MessageLogger implements MethodInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||||
|
Object[] objectArray = invocation.getArguments();
|
||||||
|
int i = 0;
|
||||||
|
for (Object object : objectArray) {
|
||||||
|
Logger.getAnonymousLogger().info("Sending message: " + object.toString());
|
||||||
|
}
|
||||||
|
return invocation.proceed();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.examples.guice.aop;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface MessageSentLoggable {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.examples.guice.binding;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.aop.MessageLogger;
|
||||||
|
import com.baeldung.examples.guice.aop.MessageSentLoggable;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.matcher.Matchers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class AOPModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindInterceptor(Matchers.any(),
|
||||||
|
Matchers.annotatedWith(MessageSentLoggable.class),
|
||||||
|
new MessageLogger()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.baeldung.examples.guice.binding;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.Communication;
|
||||||
|
import com.baeldung.examples.guice.CommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.DefaultCommunicator;
|
||||||
|
import com.baeldung.examples.guice.EmailCommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.IMCommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.SMSCommunicationMode;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class BasicModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
try {
|
||||||
|
bind(Communication.class).toConstructor(Communication.class.getConstructor(Boolean.TYPE));
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
Logger.getLogger(BasicModule.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Logger.getLogger(BasicModule.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
bind(DefaultCommunicator.class).annotatedWith(Names.named("AnotherCommunicator")).to(DefaultCommunicator.class).asEagerSingleton();
|
||||||
|
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("IMComms")).to(IMCommunicationMode.class);
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("EmailComms")).to(EmailCommunicationMode.class);
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("SMSComms")).to(SMSCommunicationMode.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.examples.guice.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public enum CommunicationModel {
|
||||||
|
|
||||||
|
EMAIL("Email"), SMS("SMS"), IM("IM"), PHONE("Phone");
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
CommunicationModel(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.examples.guice.marker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public interface Communicator {
|
||||||
|
|
||||||
|
public boolean sendMessage(String message);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.examples.guice.modules;
|
||||||
|
|
||||||
|
import com.baeldung.examples.guice.Communication;
|
||||||
|
import com.baeldung.examples.guice.CommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.DefaultCommunicator;
|
||||||
|
import com.baeldung.examples.guice.EmailCommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.IMCommunicationMode;
|
||||||
|
import com.baeldung.examples.guice.SMSCommunicationMode;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Baeldung
|
||||||
|
*/
|
||||||
|
public class BasicModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
try {
|
||||||
|
bind(Communication.class).toConstructor(Communication.class.getConstructor(Boolean.class));
|
||||||
|
bind(Boolean.class).toInstance(true);
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
Logger.getLogger(com.baeldung.examples.guice.binding.BasicModule.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Logger.getLogger(com.baeldung.examples.guice.binding.BasicModule.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
bind(DefaultCommunicator.class).annotatedWith(Names.named("AnotherCommunicator")).to(DefaultCommunicator.class).asEagerSingleton();
|
||||||
|
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("IMComms")).to(IMCommunicationMode.class);
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("EmailComms")).to(EmailCommunicationMode.class);
|
||||||
|
bind(CommunicationMode.class).annotatedWith(Names.named("SMSComms")).to(SMSCommunicationMode.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
jooq/pom.xml
Normal file
46
jooq/pom.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>jooq</artifactId>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jooq</groupId>
|
||||||
|
<artifactId>jool</artifactId>
|
||||||
|
<version>${jool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jool.version>0.9.12</jool.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
243
jooq/src/test/java/com/baeldung/JOOLTest.java
Normal file
243
jooq/src/test/java/com/baeldung/JOOLTest.java
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.jooq.lambda.Seq;
|
||||||
|
import org.jooq.lambda.Unchecked;
|
||||||
|
import org.jooq.lambda.function.Function1;
|
||||||
|
import org.jooq.lambda.function.Function2;
|
||||||
|
import org.jooq.lambda.tuple.Tuple;
|
||||||
|
import org.jooq.lambda.tuple.Tuple2;
|
||||||
|
import org.jooq.lambda.tuple.Tuple3;
|
||||||
|
import org.jooq.lambda.tuple.Tuple4;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static org.jooq.lambda.tuple.Tuple.tuple;
|
||||||
|
|
||||||
|
public class JOOLTest {
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenCheckContains_shouldReturnTrue() {
|
||||||
|
List<Integer> concat = Seq.of(1, 2, 3).concat(Seq.of(4, 5, 6)).toList();
|
||||||
|
|
||||||
|
assertEquals(concat, Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue(Seq.of(1, 2, 3, 4).contains(2));
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue(Seq.of(1, 2, 3, 4).containsAll(2, 3));
|
||||||
|
|
||||||
|
|
||||||
|
assertTrue(Seq.of(1, 2, 3, 4).containsAny(2, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStreams_whenJoin_shouldHaveElementsFromTwoStreams() {
|
||||||
|
//given
|
||||||
|
Stream<Integer> left = Stream.of(1, 2, 4);
|
||||||
|
Stream<Integer> right = Stream.of(1, 2, 3);
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Integer> rightCollected = right.collect(Collectors.toList());
|
||||||
|
List<Integer> collect = left.filter(rightCollected::contains).collect(Collectors.toList());
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(collect, Arrays.asList(1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenJoin_shouldHaveElementsFromBothSeq() {
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 4).innerJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
|
||||||
|
Arrays.asList(tuple(1, 1), tuple(2, 2))
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 4).leftOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
|
||||||
|
Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(4, null))
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 4).rightOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
|
||||||
|
Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(null, 3))
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2).crossJoin(Seq.of("A", "B")).toList(),
|
||||||
|
Arrays.asList(tuple(1, "A"), tuple(1, "B"), tuple(2, "A"), tuple(2, "B"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenManipulateSeq_seqShouldHaveNewElementsInIt() {
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3).cycle().limit(9).toList(),
|
||||||
|
Arrays.asList(1, 2, 3, 1, 2, 3, 1, 2, 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3).duplicate().map((first, second) -> tuple(first.toList(), second.toList())),
|
||||||
|
tuple(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3))
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4).intersperse(0).toList(),
|
||||||
|
Arrays.asList(1, 0, 2, 0, 3, 0, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4, 5).shuffle().toList().size(),
|
||||||
|
5
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4).partition(i -> i > 2).map((first, second) -> tuple(first.toList(), second.toList())),
|
||||||
|
tuple(Arrays.asList(3, 4), Arrays.asList(1, 2))
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4).reverse().toList(),
|
||||||
|
Arrays.asList(4, 3, 2, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenGroupByAndFold_shouldReturnProperSeq() {
|
||||||
|
|
||||||
|
Map<Integer, List<Integer>> expectedAfterGroupBy = new HashMap<>();
|
||||||
|
expectedAfterGroupBy.put(1, Arrays.asList(1, 3));
|
||||||
|
expectedAfterGroupBy.put(0, Arrays.asList(2, 4));
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4).groupBy(i -> i % 2),
|
||||||
|
expectedAfterGroupBy
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of("a", "b", "c").foldLeft("!", (u, t) -> u + t),
|
||||||
|
"!abc"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of("a", "b", "c").foldRight("!", (t, u) -> t + u),
|
||||||
|
"abc!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenUsingSeqWhile_shouldBehaveAsWhileLoop() {
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4, 5).skipWhile(i -> i < 3).toList(),
|
||||||
|
Arrays.asList(3, 4, 5)
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3, 4, 5).skipUntil(i -> i == 3).toList(),
|
||||||
|
Arrays.asList(3, 4, 5)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeq_whenZip_shouldHaveZippedSeq() {
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c")).toList(),
|
||||||
|
Arrays.asList(tuple(1, "a"), tuple(2, "b"), tuple(3, "c"))
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c"), (x, y) -> x + ":" + y).toList(),
|
||||||
|
Arrays.asList("1:a", "2:b", "3:c")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Seq.of("a", "b", "c").zipWithIndex().toList(),
|
||||||
|
Arrays.asList(tuple("a", 0L), tuple("b", 1L), tuple("c", 2L))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Integer methodThatThrowsChecked(String arg) throws Exception {
|
||||||
|
return arg.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOperationThatThrowsCheckedException_whenExecuteAndNeedToWrapCheckedIntoUnchecked_shouldPass() {
|
||||||
|
//when
|
||||||
|
List<Integer> collect = Stream.of("a", "b", "c").map(elem -> {
|
||||||
|
try {
|
||||||
|
return methodThatThrowsChecked(elem);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(
|
||||||
|
collect,
|
||||||
|
Arrays.asList(1, 1, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOperationThatThrowsCheckedException_whenExecuteUsingUncheckedFuction_shouldPass() {
|
||||||
|
//when
|
||||||
|
List<Integer> collect = Stream.of("a", "b", "c")
|
||||||
|
.map(Unchecked.function(elem -> methodThatThrowsChecked(elem)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(
|
||||||
|
collect,
|
||||||
|
Arrays.asList(1, 1, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFunction_whenAppliedPartially_shouldAddNumberToPartialArgument() {
|
||||||
|
//given
|
||||||
|
Function2<Integer, Integer, Integer> addTwoNumbers = (v1, v2) -> v1 + v2;
|
||||||
|
addTwoNumbers.toBiFunction();
|
||||||
|
Function1<Integer, Integer> addToTwo = addTwoNumbers.applyPartially(2);
|
||||||
|
|
||||||
|
//when
|
||||||
|
Integer result = addToTwo.apply(5);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(result, (Integer) 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSeqOfTuples_whenTransformToLowerNumberOfTuples_shouldHaveProperResult() {
|
||||||
|
//given
|
||||||
|
Seq<Tuple3<String, String, Integer>> personDetails = Seq.of(tuple("michael", "similar", 49), tuple("jodie", "variable", 43));
|
||||||
|
Tuple2<String, String> tuple = tuple("winter", "summer");
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Tuple4<String, String, String, String>> result = personDetails.map(t -> t.limit2().concat(tuple)).toList();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(
|
||||||
|
result,
|
||||||
|
Arrays.asList(tuple("michael", "similar", "winter", "summer"), tuple("jodie", "variable", "winter", "summer"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
libraries/pom.xml
Normal file
48
libraries/pom.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>libraries</artifactId>
|
||||||
|
<name>libraries</name>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cglib</groupId>
|
||||||
|
<artifactId>cglib</artifactId>
|
||||||
|
<version>${cglib.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<cglib.version>3.2.4</cglib.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.cglib.mixin;
|
||||||
|
|
||||||
|
public class Class1 implements Interface1 {
|
||||||
|
@Override
|
||||||
|
public String first() {
|
||||||
|
return "first behaviour";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.cglib.mixin;
|
||||||
|
|
||||||
|
public class Class2 implements Interface2 {
|
||||||
|
@Override
|
||||||
|
public String second() {
|
||||||
|
return "second behaviour";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.baeldung.cglib.mixin;
|
||||||
|
|
||||||
|
public interface Interface1 {
|
||||||
|
String first();
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.baeldung.cglib.mixin;
|
||||||
|
|
||||||
|
public interface Interface2 {
|
||||||
|
String second();
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.baeldung.cglib.mixin;
|
||||||
|
|
||||||
|
public interface MixinInterface extends Interface1, Interface2 {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.cglib.proxy;
|
||||||
|
|
||||||
|
public class PersonService {
|
||||||
|
public String sayHello(String name) {
|
||||||
|
return "Hello " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer lengthOfName(String name) {
|
||||||
|
return name.length();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.cglib.proxy;
|
||||||
|
|
||||||
|
|
||||||
|
import net.sf.cglib.beans.BeanGenerator;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class BeanGeneratorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBeanCreator_whenAddProperty_thenClassShouldHaveFieldValue() throws Exception {
|
||||||
|
//given
|
||||||
|
BeanGenerator beanGenerator = new BeanGenerator();
|
||||||
|
|
||||||
|
//when
|
||||||
|
beanGenerator.addProperty("name", String.class);
|
||||||
|
Object myBean = beanGenerator.create();
|
||||||
|
Method setter = myBean
|
||||||
|
.getClass()
|
||||||
|
.getMethod("setName", String.class);
|
||||||
|
setter.invoke(myBean, "some string value set by a cglib");
|
||||||
|
|
||||||
|
//then
|
||||||
|
Method getter = myBean
|
||||||
|
.getClass()
|
||||||
|
.getMethod("getName");
|
||||||
|
assertEquals("some string value set by a cglib", getter.invoke(myBean));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.cglib.proxy;
|
||||||
|
|
||||||
|
import com.baeldung.cglib.mixin.*;
|
||||||
|
import net.sf.cglib.proxy.Mixin;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class MixinTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoClasses_whenMixedIntoOne_thenMixinShouldHaveMethodsFromBothClasses() throws Exception {
|
||||||
|
//when
|
||||||
|
Mixin mixin = Mixin.create(
|
||||||
|
new Class[]{Interface1.class, Interface2.class, MixinInterface.class},
|
||||||
|
new Object[]{new Class1(), new Class2()}
|
||||||
|
);
|
||||||
|
MixinInterface mixinDelegate = (MixinInterface) mixin;
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals("first behaviour", mixinDelegate.first());
|
||||||
|
assertEquals("second behaviour", mixinDelegate.second());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.baeldung.cglib.proxy;
|
||||||
|
|
||||||
|
import net.sf.cglib.proxy.Enhancer;
|
||||||
|
import net.sf.cglib.proxy.FixedValue;
|
||||||
|
import net.sf.cglib.proxy.MethodInterceptor;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ProxyTest {
|
||||||
|
@Test
|
||||||
|
public void givenPersonService_whenSayHello_thenReturnResult() {
|
||||||
|
//given
|
||||||
|
PersonService personService = new PersonService();
|
||||||
|
|
||||||
|
//when
|
||||||
|
String res = personService.sayHello("Tom");
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(res, "Hello Tom");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEnhancerProxy_whenExtendPersonService_thenInterceptMethod() throws Exception {
|
||||||
|
//given
|
||||||
|
Enhancer enhancer = new Enhancer();
|
||||||
|
enhancer.setSuperclass(PersonService.class);
|
||||||
|
enhancer.setCallback((FixedValue) () -> "Hello Tom!");
|
||||||
|
PersonService proxy = (PersonService) enhancer.create();
|
||||||
|
|
||||||
|
//when
|
||||||
|
String res = proxy.sayHello(null);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals("Hello Tom!", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEnhancer_whenExecuteMethodOnProxy_thenInterceptOnlyStringReturnTypeMethod() throws Exception {
|
||||||
|
//given
|
||||||
|
Enhancer enhancer = new Enhancer();
|
||||||
|
enhancer.setSuperclass(PersonService.class);
|
||||||
|
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
|
||||||
|
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
|
||||||
|
return "Hello Tom!";
|
||||||
|
} else {
|
||||||
|
return proxy.invokeSuper(obj, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//when
|
||||||
|
PersonService proxy = (PersonService) enhancer.create();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals("Hello Tom!", proxy.sayHello(null));
|
||||||
|
int lengthOfName = proxy.lengthOfName("Mary");
|
||||||
|
assertEquals(4, lengthOfName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,78 +31,85 @@ public class CustomLoggingTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithDefaultConfig_shouldLogToConsole() throws Exception {
|
public void givenLoggerWithDefaultConfig_whenLogToConsole_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger(getClass());
|
Logger logger = LogManager.getLogger(getClass());
|
||||||
Exception e = new RuntimeException("This is only a test!");
|
Exception e = new RuntimeException("This is only a test!");
|
||||||
|
|
||||||
logger.info("This is a simple message at INFO level. " + "It will be hidden.");
|
logger.info("This is a simple message at INFO level. " + "It will be hidden.");
|
||||||
logger.error("This is a simple message at ERROR level. " + "This is the minimum visible level.", e);
|
logger.error("This is a simple message at ERROR level. " + "This is the minimum visible level.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithConsoleConfig_shouldLogToConsoleInColors() throws Exception {
|
public void givenLoggerWithConsoleConfig_whenLogToConsoleInColors_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
|
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
|
||||||
|
Exception e = new RuntimeException("This is only a test!");
|
||||||
|
|
||||||
logger.trace("This is a colored message at TRACE level.");
|
logger.trace("This is a colored message at TRACE level.");
|
||||||
logger.debug("This is a colored message at DEBUG level. " + "This is the minimum visible level.");
|
logger.debug("This is a colored message at DEBUG level. " + "This is the minimum visible level.");
|
||||||
logger.info("This is a colored message at INFO level.");
|
logger.info("This is a colored message at INFO level.");
|
||||||
logger.warn("This is a colored message at WARN level.");
|
logger.warn("This is a colored message at WARN level.");
|
||||||
Exception e = new RuntimeException("This is only a test!");
|
|
||||||
logger.error("This is a colored message at ERROR level.", e);
|
logger.error("This is a colored message at ERROR level.", e);
|
||||||
logger.fatal("This is a colored message at FATAL level.");
|
logger.fatal("This is a colored message at FATAL level.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithConsoleConfig_shouldFilterByMarker() throws Exception {
|
public void givenLoggerWithConsoleConfig_whenFilterByMarker_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
|
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
|
||||||
Marker appError = MarkerManager.getMarker("APP_ERROR");
|
Marker appError = MarkerManager.getMarker("APP_ERROR");
|
||||||
logger.error(appError, "This marker message at ERROR level should be hidden.");
|
|
||||||
Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE");
|
Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE");
|
||||||
|
|
||||||
|
logger.error(appError, "This marker message at ERROR level should be hidden.");
|
||||||
logger.trace(connectionTrace, "This is a marker message at TRACE level.");
|
logger.trace(connectionTrace, "This is a marker message at TRACE level.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithConsoleConfig_shouldFilterByThreadContext() throws Exception {
|
public void givenLoggerWithConsoleConfig_whenFilterByThreadContext_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT");
|
Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT");
|
||||||
ThreadContext.put("userId", "1000");
|
ThreadContext.put("userId", "1000");
|
||||||
logger.info("This is a log-visible user login. Maybe from an admin account?");
|
logger.info("This is a log-visible user login. Maybe from an admin account?");
|
||||||
ThreadContext.put("userId", "1001");
|
ThreadContext.put("userId", "1001");
|
||||||
logger.info("This is a log-invisible user login.");
|
logger.info("This is a log-invisible user login.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithAsyncConfig_shouldLogToJsonFile() throws Exception {
|
public void givenLoggerWithAsyncConfig_whenLogToJsonFile_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER");
|
Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER");
|
||||||
|
|
||||||
final int count = 88;
|
final int count = 88;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
logger.info("This is async JSON message #{} at INFO level.", count);
|
logger.info("This is async JSON message #{} at INFO level.", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
long logEventsCount = Files.lines(Paths.get("target/logfile.json"))
|
long logEventsCount = Files.lines(Paths.get("target/logfile.json"))
|
||||||
.count();
|
.count();
|
||||||
assertTrue(logEventsCount > 0 && logEventsCount <= count);
|
assertTrue(logEventsCount > 0 && logEventsCount <= count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithFailoverConfig_shouldLog() throws Exception {
|
public void givenLoggerWithFailoverConfig_whenLog_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER");
|
Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER");
|
||||||
|
Exception e = new RuntimeException("This is only a test!");
|
||||||
|
|
||||||
logger.trace("This is a syslog message at TRACE level.");
|
logger.trace("This is a syslog message at TRACE level.");
|
||||||
logger.debug("This is a syslog message at DEBUG level.");
|
logger.debug("This is a syslog message at DEBUG level.");
|
||||||
logger.info("This is a syslog message at INFO level. This is the minimum visible level.");
|
logger.info("This is a syslog message at INFO level. This is the minimum visible level.");
|
||||||
logger.warn("This is a syslog message at WARN level.");
|
logger.warn("This is a syslog message at WARN level.");
|
||||||
Exception e = new RuntimeException("This is only a test!");
|
|
||||||
logger.error("This is a syslog message at ERROR level.", e);
|
logger.error("This is a syslog message at ERROR level.", e);
|
||||||
logger.fatal("This is a syslog message at FATAL level.");
|
logger.fatal("This is a syslog message at FATAL level.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithJdbcConfig_shouldLogToDataSource() throws Exception {
|
public void givenLoggerWithJdbcConfig_whenLogToDataSource_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("JDBC_APPENDER");
|
Logger logger = LogManager.getLogger("JDBC_APPENDER");
|
||||||
|
|
||||||
final int count = 88;
|
final int count = 88;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
logger.info("This is JDBC message #{} at INFO level.", count);
|
logger.info("This is JDBC message #{} at INFO level.", count);
|
||||||
}
|
}
|
||||||
Connection connection = ConnectionFactory.getConnection();
|
Connection connection = ConnectionFactory.getConnection();
|
||||||
ResultSet resultSet = connection.createStatement()
|
ResultSet resultSet = connection.createStatement()
|
||||||
.executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs");
|
.executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs");
|
||||||
|
|
||||||
int logCount = 0;
|
int logCount = 0;
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
logCount = resultSet.getInt("ROW_COUNT");
|
logCount = resultSet.getInt("ROW_COUNT");
|
||||||
@ -111,8 +118,9 @@ public class CustomLoggingTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggerWithRollingFileConfig_shouldLogToXMLFile() throws Exception {
|
public void givenLoggerWithRollingFileConfig_whenLogToXMLFile_thanOK() throws Exception {
|
||||||
Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER");
|
Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER");
|
||||||
|
|
||||||
final int count = 88;
|
final int count = 88;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
logger.info("This is rolling file XML message #{} at INFO level.", i);
|
logger.info("This is rolling file XML message #{} at INFO level.", i);
|
||||||
|
@ -19,12 +19,14 @@
|
|||||||
<Async name="AsyncAppender" bufferSize="80">
|
<Async name="AsyncAppender" bufferSize="80">
|
||||||
<AppenderRef ref="JSONLogfileAppender" />
|
<AppenderRef ref="JSONLogfileAppender" />
|
||||||
</Async>
|
</Async>
|
||||||
<Syslog name="Syslog" format="RFC5424" host="localhost" port="514" protocol="TCP" facility="local3" connectTimeoutMillis="10000" reconnectionDelayMillis="5000" />
|
<!--
|
||||||
|
<Syslog name="Syslog" format="RFC5424" host="localhost" port="514" protocol="TCP" facility="local3" connectTimeoutMillis="10000" reconnectionDelayMillis="5000" mdcId="mdc" includeMDC="true" />
|
||||||
<Failover name="FailoverAppender" primary="Syslog">
|
<Failover name="FailoverAppender" primary="Syslog">
|
||||||
<Failovers>
|
<Failovers>
|
||||||
<AppenderRef ref="ConsoleAppender" />
|
<AppenderRef ref="ConsoleAppender" />
|
||||||
</Failovers>
|
</Failovers>
|
||||||
</Failover>
|
</Failover>
|
||||||
|
-->
|
||||||
<JDBC name="JDBCAppender" tableName="logs">
|
<JDBC name="JDBCAppender" tableName="logs">
|
||||||
<ConnectionFactory class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory" method="getConnection" />
|
<ConnectionFactory class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory" method="getConnection" />
|
||||||
<Column name="when" isEventTimestamp="true" />
|
<Column name="when" isEventTimestamp="true" />
|
||||||
@ -53,9 +55,11 @@
|
|||||||
<Logger name="ASYNC_JSON_FILE_APPENDER" level="INFO" additivity="false">
|
<Logger name="ASYNC_JSON_FILE_APPENDER" level="INFO" additivity="false">
|
||||||
<AppenderRef ref="AsyncAppender" />
|
<AppenderRef ref="AsyncAppender" />
|
||||||
</Logger>
|
</Logger>
|
||||||
|
<!--
|
||||||
<Logger name="FAIL_OVER_SYSLOG_APPENDER" level="INFO" additivity="false">
|
<Logger name="FAIL_OVER_SYSLOG_APPENDER" level="INFO" additivity="false">
|
||||||
<AppenderRef ref="FailoverAppender" />
|
<AppenderRef ref="FailoverAppender" />
|
||||||
</Logger>
|
</Logger>
|
||||||
|
-->
|
||||||
<Logger name="JDBC_APPENDER" level="INFO" additivity="false">
|
<Logger name="JDBC_APPENDER" level="INFO" additivity="false">
|
||||||
<AppenderRef ref="JDBCAppender" />
|
<AppenderRef ref="JDBCAppender" />
|
||||||
</Logger>
|
</Logger>
|
||||||
|
14
mockito2/.gitignore
vendored
Normal file
14
mockito2/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
.settings
|
||||||
|
.project
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
5
mockito2/README.md
Normal file
5
mockito2/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
## Mockito 2 and Java 8 Tips
|
||||||
|
|
||||||
|
Examples on how to leverage Java 8 new features with Mockito version 2
|
98
mockito2/pom.xml
Normal file
98
mockito2/pom.xml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>mockito2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>mockito-2-with-java8</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>integration</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mime>json</test.mime>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mockito.version>2.7.5</mockito.version>
|
||||||
|
|
||||||
|
<!-- maven plugins -->
|
||||||
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
public class JobPosition {
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public JobPosition() {}
|
||||||
|
|
||||||
|
public JobPosition(String title) {
|
||||||
|
super();
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public interface JobService {
|
||||||
|
Optional<JobPosition> findCurrentJobPosition(Person person);
|
||||||
|
|
||||||
|
default boolean assignJobPosition(Person person, JobPosition jobPosition) {
|
||||||
|
if (!findCurrentJobPosition(person).isPresent()) {
|
||||||
|
person.setCurrentJobPosition(jobPosition);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<JobPosition> listJobs(Person person);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
public class Person {
|
||||||
|
private String name;
|
||||||
|
private JobPosition currentJobPosition;
|
||||||
|
|
||||||
|
public Person() {}
|
||||||
|
|
||||||
|
public Person(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JobPosition getCurrentJobPosition() {
|
||||||
|
return currentJobPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentJobPosition(JobPosition currentJobPosition) {
|
||||||
|
this.currentJobPosition = currentJobPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface UnemploymentService {
|
||||||
|
|
||||||
|
boolean personIsEntitledToUnemploymentSupport(Person person);
|
||||||
|
|
||||||
|
Optional<JobPosition> searchJob(Person person, String searchString);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class UnemploymentServiceImpl implements UnemploymentService {
|
||||||
|
private final JobService jobService;
|
||||||
|
|
||||||
|
public UnemploymentServiceImpl(JobService jobService) {
|
||||||
|
this.jobService = jobService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean personIsEntitledToUnemploymentSupport(Person person) {
|
||||||
|
Optional<JobPosition> optional = jobService.findCurrentJobPosition(person);
|
||||||
|
|
||||||
|
return !optional.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<JobPosition> searchJob(Person person, String searchString) {
|
||||||
|
Stream<JobPosition> stream = jobService.listJobs(person);
|
||||||
|
|
||||||
|
return stream.filter((j) -> j.getTitle().contains(searchString)).findFirst();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
|
||||||
|
public class ArgumentMatcherWithLambdaUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private UnemploymentServiceImpl unemploymentService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithJob_thenIsNotEntitled() {
|
||||||
|
Person peter = new Person("Peter");
|
||||||
|
Person linda = new Person("Linda");
|
||||||
|
|
||||||
|
JobPosition teacher = new JobPosition("Teacher");
|
||||||
|
|
||||||
|
when(jobService.findCurrentJobPosition(
|
||||||
|
ArgumentMatchers.argThat((p) -> p.getName().equals("Peter")))
|
||||||
|
).thenReturn(Optional.of(teacher));
|
||||||
|
|
||||||
|
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
|
||||||
|
assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentMatchers;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.ArgumentMatcher;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
|
||||||
|
public class ArgumentMatcherWithoutLambdaUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private UnemploymentServiceImpl unemploymentService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithJob_thenIsNotEntitled() {
|
||||||
|
Person peter = new Person("Peter");
|
||||||
|
Person linda = new Person("Linda");
|
||||||
|
|
||||||
|
JobPosition teacher = new JobPosition("Teacher");
|
||||||
|
|
||||||
|
when(jobService.findCurrentJobPosition(
|
||||||
|
ArgumentMatchers.argThat(new PeterArgumentMatcher()))
|
||||||
|
).thenReturn(Optional.of(teacher));
|
||||||
|
|
||||||
|
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(linda));
|
||||||
|
assertFalse(unemploymentService.personIsEntitledToUnemploymentSupport(peter));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PeterArgumentMatcher implements ArgumentMatcher<Person> {
|
||||||
|
@Override
|
||||||
|
public boolean matches(Person p) {
|
||||||
|
|
||||||
|
if (p.getName().equals("Peter")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
public class CustomAnswerWithLambdaUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private UnemploymentServiceImpl unemploymentService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithJobHistory_thenSearchReturnsValue() {
|
||||||
|
Person peter = new Person("Peter");
|
||||||
|
|
||||||
|
assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
|
||||||
|
Person linda = new Person("Linda");
|
||||||
|
|
||||||
|
assertFalse(unemploymentService.searchJob(linda, "").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
when(jobService.listJobs(any(Person.class))).then((i) -> {
|
||||||
|
return ((Person) i.getArgument(0)).getName().equals("Peter") ? Stream.of(new JobPosition("Teacher")) : Stream.empty();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
|
||||||
|
public class CustomAnswerWithoutLambdaUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private UnemploymentServiceImpl unemploymentService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithJobHistory_thenSearchReturnsValue() {
|
||||||
|
Person peter = new Person("Peter");
|
||||||
|
|
||||||
|
assertEquals("Teacher", unemploymentService.searchJob(peter, "").get().getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonWithNoJobHistory_thenSearchReturnsEmpty() {
|
||||||
|
Person linda = new Person("Linda");
|
||||||
|
|
||||||
|
assertFalse(unemploymentService.searchJob(linda, "").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PersonAnswer implements Answer<Stream<JobPosition>> {
|
||||||
|
@Override
|
||||||
|
public Stream<JobPosition> answer(InvocationOnMock invocation) throws Throwable {
|
||||||
|
Person person = invocation.getArgument(0);
|
||||||
|
|
||||||
|
if(person.getName().equals("Peter")) {
|
||||||
|
return Stream.<JobPosition>builder().add(new JobPosition("Teacher")).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
when(jobService.listJobs(any(Person.class))).then(new PersonAnswer());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
public class JobServiceUnitTest {
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultMethod_whenCallRealMethod_thenNoExceptionIsRaised() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.of(new JobPosition()));
|
||||||
|
doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
|
||||||
|
|
||||||
|
assertFalse(jobService.assignJobPosition(person, new JobPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
when(jobService.findCurrentJobPosition(person)).thenReturn(Optional.empty());
|
||||||
|
doCallRealMethod().when(jobService).assignJobPosition(Mockito.any(Person.class), Mockito.any(JobPosition.class));
|
||||||
|
|
||||||
|
assertTrue(jobService.assignJobPosition(person, new JobPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.mockito.java8;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
public class UnemploymentServiceImplUnitTest {
|
||||||
|
@Mock
|
||||||
|
private JobService jobService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private UnemploymentServiceImpl unemploymentService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenReturnIsOfTypeOptional_whenMocked_thenValueIsEmpty() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
when(jobService.findCurrentJobPosition(any(Person.class))).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenReturnIsOfTypeOptional_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
// This will fail when Mockito 1 is used
|
||||||
|
assertTrue(unemploymentService.personIsEntitledToUnemploymentSupport(person));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenReturnIsOfTypeStream_whenMocked_thenValueIsEmpty() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
when(jobService.listJobs(any(Person.class))).thenReturn(Stream.empty());
|
||||||
|
|
||||||
|
assertFalse(unemploymentService.searchJob(person, "").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenReturnIsOfTypeStream_whenDefaultValueIsReturned_thenValueIsEmpty() {
|
||||||
|
Person person = new Person();
|
||||||
|
|
||||||
|
// This will fail when Mockito 1 is used
|
||||||
|
assertFalse(unemploymentService.searchJob(person, "").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
}
|
14
pom.xml
14
pom.xml
@ -8,7 +8,6 @@
|
|||||||
<name>parent-modules</name>
|
<name>parent-modules</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<gib.referenceBranch>refs/heads/master</gib.referenceBranch>
|
<gib.referenceBranch>refs/heads/master</gib.referenceBranch>
|
||||||
@ -47,6 +46,7 @@
|
|||||||
<module>guava</module>
|
<module>guava</module>
|
||||||
<module>guava18</module>
|
<module>guava18</module>
|
||||||
<module>guava19</module>
|
<module>guava19</module>
|
||||||
|
<module>guice-intro</module>
|
||||||
<module>disruptor</module>
|
<module>disruptor</module>
|
||||||
|
|
||||||
<module>handling-spring-static-resources</module>
|
<module>handling-spring-static-resources</module>
|
||||||
@ -65,6 +65,7 @@
|
|||||||
<module>jaxb</module>
|
<module>jaxb</module>
|
||||||
<module>jee7</module>
|
<module>jee7</module>
|
||||||
<module>jjwt</module>
|
<module>jjwt</module>
|
||||||
|
<module>jooq</module>
|
||||||
<module>jpa-storedprocedure</module>
|
<module>jpa-storedprocedure</module>
|
||||||
<module>jsf</module>
|
<module>jsf</module>
|
||||||
<module>json-path</module>
|
<module>json-path</module>
|
||||||
@ -74,6 +75,7 @@
|
|||||||
|
|
||||||
<module>kotlin</module>
|
<module>kotlin</module>
|
||||||
|
|
||||||
|
<module>libraries</module>
|
||||||
<module>log-mdc</module>
|
<module>log-mdc</module>
|
||||||
<module>log4j</module>
|
<module>log4j</module>
|
||||||
<module>log4j2</module>
|
<module>log4j2</module>
|
||||||
@ -83,6 +85,7 @@
|
|||||||
<module>metrics</module>
|
<module>metrics</module>
|
||||||
<module>mesos-marathon</module>
|
<module>mesos-marathon</module>
|
||||||
<module>mockito</module>
|
<module>mockito</module>
|
||||||
|
<module>mockito2</module>
|
||||||
<module>mocks</module>
|
<module>mocks</module>
|
||||||
|
|
||||||
<module>orika</module>
|
<module>orika</module>
|
||||||
@ -93,6 +96,7 @@
|
|||||||
<module>querydsl</module>
|
<module>querydsl</module>
|
||||||
|
|
||||||
<!-- <module>raml</module> -->
|
<!-- <module>raml</module> -->
|
||||||
|
<module>reactor-core</module>
|
||||||
<module>redis</module>
|
<module>redis</module>
|
||||||
<module>rest-assured</module>
|
<module>rest-assured</module>
|
||||||
<module>rest-testing</module>
|
<module>rest-testing</module>
|
||||||
@ -109,7 +113,6 @@
|
|||||||
<module>spring-autowire</module>
|
<module>spring-autowire</module>
|
||||||
<module>spring-batch</module>
|
<module>spring-batch</module>
|
||||||
<module>spring-boot</module>
|
<module>spring-boot</module>
|
||||||
<module>spring-boot-servlet</module>
|
|
||||||
<module>spring-cloud-data-flow</module>
|
<module>spring-cloud-data-flow</module>
|
||||||
<module>spring-cloud</module>
|
<module>spring-cloud</module>
|
||||||
<module>spring-core</module>
|
<module>spring-core</module>
|
||||||
@ -197,15 +200,18 @@
|
|||||||
<module>apache-velocity</module>
|
<module>apache-velocity</module>
|
||||||
<module>apache-solrj</module>
|
<module>apache-solrj</module>
|
||||||
|
|
||||||
|
<module>rabbitmq</module>
|
||||||
|
|
||||||
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<extensions>
|
<extensions>
|
||||||
<extension>
|
<!--<extension>
|
||||||
<groupId>com.vackosar.gitflowincrementalbuilder</groupId>
|
<groupId>com.vackosar.gitflowincrementalbuilder</groupId>
|
||||||
<artifactId>gitflow-incremental-builder</artifactId>
|
<artifactId>gitflow-incremental-builder</artifactId>
|
||||||
<version>3.1</version>
|
<version>3.1</version>
|
||||||
</extension>
|
</extension>-->
|
||||||
</extensions>
|
</extensions>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
43
rabbitmq/pom.xml
Normal file
43
rabbitmq/pom.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>rabbitmq</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>rabbitmq</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.rabbitmq</groupId>
|
||||||
|
<artifactId>amqp-client</artifactId>
|
||||||
|
<version>3.6.6</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
31
rabbitmq/src/main/java/com/baeldung/consumer/Receiver.java
Normal file
31
rabbitmq/src/main/java/com/baeldung/consumer/Receiver.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.consumer;
|
||||||
|
|
||||||
|
import com.rabbitmq.client.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
public class Receiver {
|
||||||
|
|
||||||
|
private static final String QUEUE_NAME = "products_queue";
|
||||||
|
|
||||||
|
public static void main (String[] args) throws IOException, TimeoutException {
|
||||||
|
ConnectionFactory factory = new ConnectionFactory();
|
||||||
|
factory.setHost("localhost");
|
||||||
|
Connection connection = factory.newConnection();
|
||||||
|
Channel channel = connection.createChannel();
|
||||||
|
|
||||||
|
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||||
|
|
||||||
|
Consumer consumer = new DefaultConsumer(channel) {
|
||||||
|
@Override
|
||||||
|
public void handleDelivery(String consumerTag,
|
||||||
|
Envelope envelope, AMQP.BasicProperties properties,
|
||||||
|
byte[] body) throws IOException {
|
||||||
|
String message = new String(body, "UTF-8");
|
||||||
|
System.out.println(" [x] Received '" + message + "'");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
channel.basicConsume(QUEUE_NAME, true, consumer);
|
||||||
|
}
|
||||||
|
}
|
27
rabbitmq/src/main/java/com/baeldung/producer/Publisher.java
Normal file
27
rabbitmq/src/main/java/com/baeldung/producer/Publisher.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.producer;
|
||||||
|
|
||||||
|
import com.rabbitmq.client.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
public class Publisher {
|
||||||
|
|
||||||
|
private final static String QUEUE_NAME = "products_queue";
|
||||||
|
|
||||||
|
public static void main(String[]args) throws IOException, TimeoutException {
|
||||||
|
ConnectionFactory factory = new ConnectionFactory();
|
||||||
|
factory.setHost("localhost");
|
||||||
|
Connection connection = factory.newConnection();
|
||||||
|
Channel channel = connection.createChannel();
|
||||||
|
|
||||||
|
String message = "product details";
|
||||||
|
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
|
||||||
|
|
||||||
|
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
|
||||||
|
System.out.println(" [x] Sent '" + message + "'");
|
||||||
|
|
||||||
|
channel.close();
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
}
|
59
reactor-core/pom.xml
Normal file
59
reactor-core/pom.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>reactor-core</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-core</artifactId>
|
||||||
|
<version>${reactor-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<reactor-core.version>3.0.4.RELEASE</reactor-core.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<logback.version>1.1.3</logback.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
122
reactor-core/src/test/java/com/baeldung/reactor/ReactorTest.java
Normal file
122
reactor-core/src/test/java/com/baeldung/reactor/ReactorTest.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package com.baeldung.reactor;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.reactivestreams.Subscriber;
|
||||||
|
import org.reactivestreams.Subscription;
|
||||||
|
import reactor.core.publisher.ConnectableFlux;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.scheduler.Schedulers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class ReactorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlux_whenSubscribing_thenStream() throws InterruptedException {
|
||||||
|
|
||||||
|
List<Integer> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
Flux.just(1, 2, 3, 4)
|
||||||
|
.log()
|
||||||
|
.map(i -> {
|
||||||
|
System.out.println(i + ":" + Thread.currentThread());
|
||||||
|
return i * 2;
|
||||||
|
})
|
||||||
|
.subscribe(elements::add);
|
||||||
|
|
||||||
|
assertThat(elements).containsExactly(2, 4, 6, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlux_whenZipping_thenCombine() {
|
||||||
|
List<String> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
Flux.just(1, 2, 3, 4)
|
||||||
|
.log()
|
||||||
|
.map(i -> i * 2)
|
||||||
|
.zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (two, one) -> String.format("First Flux: %d, Second Flux: %d", one, two))
|
||||||
|
.subscribe(elements::add);
|
||||||
|
|
||||||
|
assertThat(elements).containsExactly(
|
||||||
|
"First Flux: 0, Second Flux: 2",
|
||||||
|
"First Flux: 1, Second Flux: 4",
|
||||||
|
"First Flux: 2, Second Flux: 6",
|
||||||
|
"First Flux: 3, Second Flux: 8");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlux_whenApplyingBackPressure_thenPushElementsInBatches() throws InterruptedException {
|
||||||
|
|
||||||
|
List<Integer> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
Flux.just(1, 2, 3, 4)
|
||||||
|
.log()
|
||||||
|
.map(i -> i * 2)
|
||||||
|
.onBackpressureBuffer()
|
||||||
|
.subscribe(new Subscriber<Integer>() {
|
||||||
|
private Subscription s;
|
||||||
|
int onNextAmount;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(final Subscription s) {
|
||||||
|
this.s = s;
|
||||||
|
s.request(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(final Integer integer) {
|
||||||
|
elements.add(integer);
|
||||||
|
onNextAmount++;
|
||||||
|
if (onNextAmount % 2 == 0) {
|
||||||
|
s.request(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(final Throwable t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
int ham = 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertThat(elements).containsExactly(2, 4, 6, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlux_whenInParallel_thenSubscribeInDifferentThreads() throws InterruptedException {
|
||||||
|
List<String> threadNames = new ArrayList<>();
|
||||||
|
|
||||||
|
Flux.just(1, 2, 3, 4)
|
||||||
|
.log()
|
||||||
|
.map(i -> Thread.currentThread().getName())
|
||||||
|
.subscribeOn(Schedulers.parallel())
|
||||||
|
.subscribe(threadNames::add);
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
assertThat(threadNames).containsExactly("parallel-1", "parallel-1", "parallel-1", "parallel-1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenConnectableFlux_whenConnected_thenShouldStream() {
|
||||||
|
|
||||||
|
List<Integer> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
final ConnectableFlux<Integer> publish = Flux.just(1, 2, 3, 4).publish();
|
||||||
|
|
||||||
|
publish.subscribe(elements::add);
|
||||||
|
|
||||||
|
assertThat(elements).isEmpty();
|
||||||
|
|
||||||
|
publish.connect();
|
||||||
|
|
||||||
|
assertThat(elements).containsExactly(1, 2, 3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,7 +18,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.solr</groupId>
|
<groupId>org.apache.solr</groupId>
|
||||||
<artifactId>solr-solrj</artifactId>
|
<artifactId>solr-solrj</artifactId>
|
||||||
<version>6.1.0</version>
|
<version>6.4.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.baeldung.solr.fulltext.search.model;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.beans.Field;
|
||||||
|
|
||||||
|
public class Item {
|
||||||
|
|
||||||
|
@Field
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Field
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Field
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@Field
|
||||||
|
private float price;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(float price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.solr.fulltext.search.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
|
|
||||||
|
import com.baeldung.solr.fulltext.search.model.Item;
|
||||||
|
|
||||||
|
public interface ItemSearchService {
|
||||||
|
|
||||||
|
public void index(String id, String description, String category, float price) throws SolrServerException, IOException;
|
||||||
|
|
||||||
|
public void indexBean(Item item) throws IOException, SolrServerException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.solr.fulltext.search.service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.SolrClient;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
|
||||||
|
import com.baeldung.solr.fulltext.search.model.Item;
|
||||||
|
|
||||||
|
public class ItemSearchServiceImpl implements ItemSearchService {
|
||||||
|
|
||||||
|
private final SolrClient solrClient;
|
||||||
|
|
||||||
|
public ItemSearchServiceImpl(SolrClient solrClient) {
|
||||||
|
this.solrClient = solrClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void index(String id, String description, String category, float price) throws SolrServerException, IOException {
|
||||||
|
SolrInputDocument doc = new SolrInputDocument();
|
||||||
|
doc.addField("id", id);
|
||||||
|
doc.addField("description", description);
|
||||||
|
doc.addField("category", category);
|
||||||
|
doc.addField("price", price);
|
||||||
|
solrClient.add(doc);
|
||||||
|
solrClient.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void indexBean(Item item) throws IOException, SolrServerException {
|
||||||
|
solrClient.addBean(item);
|
||||||
|
solrClient.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,374 @@
|
|||||||
|
package com.baeldung.solr.fulltext.search.service;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.solr.client.solrj.SolrClient;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||||
|
import org.apache.solr.client.solrj.response.FacetField.Count;
|
||||||
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
|
import org.apache.solr.client.solrj.response.RangeFacet;
|
||||||
|
import org.apache.solr.client.solrj.response.SpellCheckResponse;
|
||||||
|
import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
|
||||||
|
import org.apache.solr.client.solrj.response.SuggesterResponse;
|
||||||
|
import org.apache.solr.common.SolrDocument;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.solr.fulltext.search.model.Item;
|
||||||
|
|
||||||
|
public class ItemSearchServiceIntegrationTest {
|
||||||
|
|
||||||
|
private static SolrClient solrClient;
|
||||||
|
private static ItemSearchService itemSearchService;
|
||||||
|
private static final String solrUrl = "http://localhost:8987/solr/item";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void initBeans() throws Exception {
|
||||||
|
solrClient = new HttpSolrClient.Builder(solrUrl).build();
|
||||||
|
itemSearchService = new ItemSearchServiceImpl(solrClient);
|
||||||
|
|
||||||
|
solrClient.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void clearSolrData() throws Exception {
|
||||||
|
solrClient.deleteByQuery("*:*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenIndexing_thenAvailableOnRetrieval() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Washing Machine", "Home Appliances", 450f);
|
||||||
|
final SolrDocument indexedDoc = solrClient.getById("hm0001");
|
||||||
|
assertEquals("hm0001", indexedDoc.get("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenIndexingBean_thenAvailableOnRetrieval() throws Exception {
|
||||||
|
Item item = new Item();
|
||||||
|
item.setId("hm0002");
|
||||||
|
item.setCategory("Televisions");
|
||||||
|
item.setDescription("LED TV 32");
|
||||||
|
item.setPrice(500);
|
||||||
|
itemSearchService.indexBean(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingByBasicQuery_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "LED TV 32", "Brand1 Home Appliances", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("brand1");
|
||||||
|
query.setStart(0);
|
||||||
|
query.setRows(10);
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(3, items.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithWildCard_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "LED TV 32", "Brand1 Home Appliances", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("*rand?");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(3, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithLogicalOperators_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 LED TV 32", "Washing Appliances", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("brand1 AND (Washing OR Refrigerator)");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(2, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithFields_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("0003", "Brand2 LED TV 32", "Brand1 Washing Home Appliances", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("description:Brand* AND category:*Washing*");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(1, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithPhrase_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Dishwasher", "Washing tools and equipment ", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("washing MachIne");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(2, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithRealPhrase_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Dishwasher", "Washing tools and equipment ", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("\"washing machine\"");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(1, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingPhraseWithProximity_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 450f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Dishwasher", "Washing tools and equipment ", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("\"Washing equipment\"~2");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(1, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithPriceRange_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Dishwasher", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing tools and equipment ", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("price:[100 TO 300]");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(3, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithPriceRangeInclusiveExclusive_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Dishwasher", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing tools and equipment ", 450f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("price:{100 TO 300]");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(2, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithFilterQuery_thenAllMatchingItemsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing tools and equipment ", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("price:[100 TO 300]");
|
||||||
|
query.addFilterQuery("description:Brand1", "category:Home Appliances");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Item> items = response.getBeans(Item.class);
|
||||||
|
|
||||||
|
assertEquals(2, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithFacetFields_thenAllMatchingFacetsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "CategoryA", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "CategoryA", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "CategoryB", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "CategoryB", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("*:*");
|
||||||
|
query.addFacetField("category");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<Count> facetResults = response.getFacetField("category").getValues();
|
||||||
|
|
||||||
|
assertEquals(2, facetResults.size());
|
||||||
|
|
||||||
|
for (Count count : facetResults) {
|
||||||
|
if ("categorya".equalsIgnoreCase(count.getName())) {
|
||||||
|
assertEquals(2, count.getCount());
|
||||||
|
} else if ("categoryb".equalsIgnoreCase(count.getName())) {
|
||||||
|
assertEquals(2, count.getCount());
|
||||||
|
} else {
|
||||||
|
fail("unexpected category");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithFacetQuery_thenAllMatchingFacetsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "CategoryA", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "CategoryA", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "CategoryB", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "CategoryB", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("*:*");
|
||||||
|
|
||||||
|
query.addFacetQuery("Washing OR Refrigerator");
|
||||||
|
query.addFacetQuery("Brand2");
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
Map<String, Integer> facetQueryMap = response.getFacetQuery();
|
||||||
|
|
||||||
|
assertEquals(2, facetQueryMap.size());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Integer> entry : facetQueryMap.entrySet()) {
|
||||||
|
String facetQuery = entry.getKey();
|
||||||
|
|
||||||
|
if ("Washing OR Refrigerator".equals(facetQuery)) {
|
||||||
|
assertEquals(Integer.valueOf(2), entry.getValue());
|
||||||
|
} else if ("Brand2".equals(facetQuery)) {
|
||||||
|
assertEquals(Integer.valueOf(2), entry.getValue());
|
||||||
|
} else {
|
||||||
|
fail("unexpected query");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithFacetRange_thenAllMatchingFacetsShouldAvialble() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "CategoryA", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "CategoryA", 125f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "CategoryB", 150f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "CategoryB", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("*:*");
|
||||||
|
|
||||||
|
query.addNumericRangeFacet("price", 100, 275, 25);
|
||||||
|
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
List<RangeFacet> rangeFacets = response.getFacetRanges().get(0).getCounts();
|
||||||
|
|
||||||
|
assertEquals(7, rangeFacets.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithHitHighlighting_thenKeywordsShouldBeHighlighted() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing equipments", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("Appliances");
|
||||||
|
query.setHighlight(true);
|
||||||
|
query.addHighlightField("category");
|
||||||
|
query.setHighlightSimplePre("<strong>");
|
||||||
|
query.setHighlightSimplePost("</strong>");
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
|
||||||
|
Map<String, Map<String, List<String>>> hitHighlightedMap = response.getHighlighting();
|
||||||
|
Map<String, List<String>> highlightedFieldMap = hitHighlightedMap.get("hm0001");
|
||||||
|
List<String> highlightedList = highlightedFieldMap.get("category");
|
||||||
|
String highLightedText = highlightedList.get(0);
|
||||||
|
|
||||||
|
assertEquals("Home <strong>Appliances</strong>", highLightedText);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithKeywordWithMistake_thenSpellingSuggestionsShouldBeReturned() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing equipments", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setQuery("hme");
|
||||||
|
query.set("spellcheck", "on");
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
|
||||||
|
SpellCheckResponse spellCheckResponse = response.getSpellCheckResponse();
|
||||||
|
|
||||||
|
assertEquals(false, spellCheckResponse.isCorrectlySpelled());
|
||||||
|
|
||||||
|
Suggestion suggestion = spellCheckResponse.getSuggestions().get(0);
|
||||||
|
|
||||||
|
assertEquals("hme", suggestion.getToken());
|
||||||
|
|
||||||
|
List<String> alternatives = suggestion.getAlternatives();
|
||||||
|
String alternative = alternatives.get(0);
|
||||||
|
|
||||||
|
assertEquals("home", alternative);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSearchingWithIncompleteKeyword_thenKeywordSuggestionsShouldBeReturned() throws Exception {
|
||||||
|
itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
|
||||||
|
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
|
||||||
|
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
|
||||||
|
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Home washing equipments", 250f);
|
||||||
|
|
||||||
|
SolrQuery query = new SolrQuery();
|
||||||
|
query.setRequestHandler("/suggest");
|
||||||
|
query.set("suggest", "true");
|
||||||
|
query.set("suggest.build", "true");
|
||||||
|
query.set("suggest.dictionary", "mySuggester");
|
||||||
|
query.set("suggest.q", "Hom");
|
||||||
|
QueryResponse response = solrClient.query(query);
|
||||||
|
|
||||||
|
SuggesterResponse suggesterResponse = response.getSuggesterResponse();
|
||||||
|
Map<String, List<String>> suggestedTerms = suggesterResponse.getSuggestedTerms();
|
||||||
|
List<String> suggestions = suggestedTerms.get("mySuggester");
|
||||||
|
|
||||||
|
assertEquals(2, suggestions.size());
|
||||||
|
|
||||||
|
for (String term : suggestions) {
|
||||||
|
if (!"Home Appliances".equals(term) && !"Home washing equipments".equals(term)) {
|
||||||
|
fail("Unexpected suggestions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
spring-5/.gitignore
vendored
Normal file
13
spring-5/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
6
spring-5/README.md
Normal file
6
spring-5/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
## Spring REST Example Project
|
||||||
|
|
||||||
|
###The Course
|
||||||
|
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
|
### Relevant Articles:
|
116
spring-5/pom.xml
Normal file
116
spring-5/pom.xml
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-5</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-5</name>
|
||||||
|
<description></description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- runtime and test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spring-snapshots</id>
|
||||||
|
<name>Spring Snapshots</name>
|
||||||
|
<url>https://repo.spring.io/snapshot</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>spring-milestones</id>
|
||||||
|
<name>Spring Milestones</name>
|
||||||
|
<url>https://repo.spring.io/milestone</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>spring-snapshots</id>
|
||||||
|
<name>Spring Snapshots</name>
|
||||||
|
<url>https://repo.spring.io/snapshot</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>spring-milestones</id>
|
||||||
|
<name>Spring Milestones</name>
|
||||||
|
<url>https://repo.spring.io/milestone</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
13
spring-5/src/main/java/com/baeldung/Spring5Application.java
Normal file
13
spring-5/src/main/java/com/baeldung/Spring5Application.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Spring5Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Spring5Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.persistence;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.baeldung.web.Foo;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DataSetupBean implements InitializingBean {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FooRepository repo;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
IntStream.range(1, 20).forEach(i -> repo.save(new Foo(randomAlphabetic(8))));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.persistence;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import com.baeldung.web.Foo;
|
||||||
|
|
||||||
|
public interface FooRepository extends JpaRepository<Foo, Long>, JpaSpecificationExecutor<Foo> {
|
||||||
|
|
||||||
|
}
|
84
spring-5/src/main/java/com/baeldung/web/Foo.java
Normal file
84
spring-5/src/main/java/com/baeldung/web/Foo.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package com.baeldung.web;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Foo {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Foo() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Foo(final String name) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Foo(final long id, final String name) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Foo other = (Foo) obj;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Foo [name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
spring-5/src/main/java/com/baeldung/web/FooController.java
Normal file
62
spring-5/src/main/java/com/baeldung/web/FooController.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.web;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.baeldung.persistence.FooRepository;
|
||||||
|
|
||||||
|
@RestController("/foos")
|
||||||
|
public class FooController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FooRepository repo;
|
||||||
|
|
||||||
|
// API - read
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/foos/{id}")
|
||||||
|
@ResponseBody
|
||||||
|
@Validated
|
||||||
|
public Foo findById(@PathVariable @Min(0) final long id) {
|
||||||
|
return repo.findOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
public List<Foo> findAll() {
|
||||||
|
return repo.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(params = { "page", "size" }, method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
@Validated
|
||||||
|
public List<Foo> findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) {
|
||||||
|
final Page<Foo> resultPage = repo.findAll(new PageRequest(page, size));
|
||||||
|
return resultPage.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API - write
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}")
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
@ResponseBody
|
||||||
|
public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
spring-5/src/main/resources/application.properties
Normal file
6
spring-5/src/main/resources/application.properties
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
server.port=8081
|
||||||
|
|
||||||
|
security.user.name=user
|
||||||
|
security.user.password=pass
|
||||||
|
|
||||||
|
logging.level.root=INFO
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class IntegrationTestExample1 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1a() {
|
||||||
|
block(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1b() {
|
||||||
|
block(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void block(long ms) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(ms);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.println("Thread interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class IntegrationTestExample2 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1a() {
|
||||||
|
block(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1b() {
|
||||||
|
block(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void block(long ms) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(ms);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.println("Thread Interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
spring-5/src/test/java/com/baeldung/ParallelTestExample.java
Normal file
24
spring-5/src/test/java/com/baeldung/ParallelTestExample.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.ParallelComputer;
|
||||||
|
import org.junit.runner.Computer;
|
||||||
|
import org.junit.runner.JUnitCore;
|
||||||
|
|
||||||
|
public class ParallelTestExample {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void runTests() {
|
||||||
|
final Class<?>[] classes = { IntegrationTestExample1.class, IntegrationTestExample2.class };
|
||||||
|
|
||||||
|
JUnitCore.runClasses(new Computer(), classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void runTestsInParallel() {
|
||||||
|
final Class<?>[] classes = { IntegrationTestExample1.class, IntegrationTestExample2.class };
|
||||||
|
|
||||||
|
JUnitCore.runClasses(new ParallelComputer(true, true), classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class Spring5ApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.baeldung.bean.config;
|
||||||
|
|
||||||
|
import org.baeldung.bean.injection.Helm;
|
||||||
|
import org.baeldung.bean.injection.Ship;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ConstructorBasedShipConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Ship ship() {
|
||||||
|
return new Ship(helm());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Helm helm() {
|
||||||
|
return new Helm();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.baeldung.bean.config;
|
||||||
|
|
||||||
|
import org.baeldung.bean.injection.Helm;
|
||||||
|
import org.baeldung.bean.injection.Ship;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
public class SetterBasedShipConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Ship ship() {
|
||||||
|
return new Ship();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Helm helm() {
|
||||||
|
return new Helm();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user