Merge remote-tracking branch 'origin/master'

This commit is contained in:
slavisa-baeldung 2017-04-27 13:55:36 +01:00
commit 52d32336e0
9 changed files with 478 additions and 250 deletions

View File

@ -0,0 +1,21 @@
package com.baeldung.concurrent.skiplist;
import java.time.ZonedDateTime;
public class Event {
private final ZonedDateTime eventTime;
private final String content;
public Event(ZonedDateTime eventTime, String content) {
this.eventTime = eventTime;
this.content = content;
}
public ZonedDateTime getEventTime() {
return eventTime;
}
public String getContent() {
return content;
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.concurrent.skiplist;
import java.time.ZonedDateTime;
import java.util.Comparator;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.ToLongFunction;
public class EventWindowSort {
private final ConcurrentSkipListMap<ZonedDateTime, String> events = new ConcurrentSkipListMap<>(Comparator.comparingLong(new ToLongFunction<ZonedDateTime>() {
@Override
public long applyAsLong(ZonedDateTime value) {
return value
.toInstant()
.toEpochMilli();
}
}));
public void acceptEvent(Event event) {
events.put(event.getEventTime(), event.getContent());
}
public ConcurrentNavigableMap<ZonedDateTime, String> getEventsFromLastMinute() {
return events.tailMap(ZonedDateTime
.now()
.minusMinutes(1));
}
public ConcurrentNavigableMap<ZonedDateTime, String> getEventsOlderThatOneMinute() {
return events.headMap(ZonedDateTime
.now()
.minusMinutes(1));
}
}

View File

@ -0,0 +1,120 @@
package com.baeldung.concurrent.skiplist;
import org.junit.Test;
import java.time.ZonedDateTime;
import java.util.UUID;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ConcurrentSkipListSetTest {
@Test
public void givenThreadsProducingEvents_whenGetForEventsFromLastMinute_thenReturnThoseEventsInTheLockFreeWay() throws InterruptedException {
//given
ExecutorService executorService = Executors.newFixedThreadPool(3);
EventWindowSort eventWindowSort = new EventWindowSort();
int numberOfThreads = 2;
//when
Runnable producer = () -> IntStream
.rangeClosed(0, 100)
.forEach(index -> eventWindowSort.acceptEvent(new Event(ZonedDateTime
.now()
.minusSeconds(index), UUID
.randomUUID()
.toString())));
for (int i = 0; i < numberOfThreads; i++) {
executorService.execute(producer);
}
Thread.sleep(500);
ConcurrentNavigableMap<ZonedDateTime, String> eventsFromLastMinute = eventWindowSort.getEventsFromLastMinute();
long eventsOlderThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isBefore(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
assertEquals(eventsOlderThanOneMinute, 0);
long eventYoungerThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isAfter(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
//then
assertTrue(eventYoungerThanOneMinute > 0);
executorService.awaitTermination(1, TimeUnit.SECONDS);
executorService.shutdown();
}
@Test
public void givenThreadsProducingEvents_whenGetForEventsOlderThanOneMinute_thenReturnThoseEventsInTheLockFreeWay() throws InterruptedException {
//given
ExecutorService executorService = Executors.newFixedThreadPool(3);
EventWindowSort eventWindowSort = new EventWindowSort();
int numberOfThreads = 2;
//when
Runnable producer = () -> IntStream
.rangeClosed(0, 100)
.forEach(index -> eventWindowSort.acceptEvent(new Event(ZonedDateTime
.now()
.minusSeconds(index), UUID
.randomUUID()
.toString())));
for (int i = 0; i < numberOfThreads; i++) {
executorService.execute(producer);
}
Thread.sleep(500);
ConcurrentNavigableMap<ZonedDateTime, String> eventsFromLastMinute = eventWindowSort.getEventsOlderThatOneMinute();
long eventsOlderThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isBefore(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
assertTrue(eventsOlderThanOneMinute > 0);
long eventYoungerThanOneMinute = eventsFromLastMinute
.entrySet()
.stream()
.filter(e -> e
.getKey()
.isAfter(ZonedDateTime
.now()
.minusMinutes(1)))
.count();
//then
assertEquals(eventYoungerThanOneMinute, 0);
executorService.awaitTermination(1, TimeUnit.SECONDS);
executorService.shutdown();
}
}

View File

@ -15,7 +15,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
@ -58,21 +58,22 @@
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.test.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
@ -91,6 +92,7 @@
<version>${junit.platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -107,6 +109,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
@ -171,10 +174,9 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<junit.platform.version>1.0.0-M3</junit.platform.version>
<junit.jupiter.version>5.0.0-M3</junit.jupiter.version>
<spring.test.version>4.3.7.RELEASE</spring.test.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
<junit.platform.version>1.0.0-M4</junit.platform.version>
<junit.jupiter.version>5.0.0-M4</junit.jupiter.version>
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
</properties>
</project>

View File

@ -56,49 +56,49 @@ public class Spring5ReactiveServerClientTest {
nettyContext.dispose();
}
@Test
public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception {
WebClient client = WebClient.create("http://localhost:8080");
Mono<String> result = client
.get()
.uri("/task")
.exchange()
.then(response -> response.bodyToMono(String.class));
// @Test
// public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception {
// WebClient client = WebClient.create("http://localhost:8080");
// Mono<String> result = client
// .get()
// .uri("/task")
// .exchange()
// .then(response -> response.bodyToMono(String.class));
//
// assertThat(result.block()).isInstanceOf(String.class);
// }
assertThat(result.block()).isInstanceOf(String.class);
}
// @Test
// public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception {
// URI uri = URI.create("http://localhost:8080/task/process");
// ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
// ClientRequest request = ClientRequest
// .method(HttpMethod.POST, uri)
// .body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
// .build();
//
// Flux<Task> taskResponse = exchange
// .exchange(request)
// .flatMap(response -> response.bodyToFlux(Task.class));
//
// assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class);
// }
@Test
public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception {
URI uri = URI.create("http://localhost:8080/task/process");
ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
ClientRequest request = ClientRequest
.method(HttpMethod.POST, uri)
.body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
.build();
Flux<Task> taskResponse = exchange
.exchange(request)
.flatMap(response -> response.bodyToFlux(Task.class));
assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class);
}
@Test
public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception {
URI uri = URI.create("http://localhost:8080/task");
ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
ClientRequest request = ClientRequest
.method(HttpMethod.GET, uri)
.body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
.build();
Flux<String> taskResponse = exchange
.exchange(request)
.flatMap(response -> response.bodyToFlux(String.class));
assertThat(taskResponse.blockFirst()).isInstanceOf(String.class);
}
// @Test
// public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception {
// URI uri = URI.create("http://localhost:8080/task");
// ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());
// ClientRequest request = ClientRequest
// .method(HttpMethod.GET, uri)
// .body(BodyInserters.fromPublisher(getLatLngs(), Task.class))
// .build();
//
// Flux<String> taskResponse = exchange
// .exchange(request)
// .flatMap(response -> response.bodyToFlux(String.class));
//
// assertThat(taskResponse.blockFirst()).isInstanceOf(String.class);
// }
private static Flux<Task> getLatLngs() {
return Flux

View File

@ -10,7 +10,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<version>1.4.6.RELEASE</version>
</parent>
<dependencies>

View File

@ -163,6 +163,30 @@ public class RestTemplateBasicLiveTest {
assertThat(foo.getName(), is(updatedInstance.getName()));
}
// PATCH
@Test
public void givenFooService_whenPatchExistingEntity_thenItIsUpdated() {
final RestTemplate template = new RestTemplate();
final HttpHeaders headers = prepareBasicAuthHeaders();
final HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"), headers);
// Create Resource
final ResponseEntity<Foo> createResponse = template.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);
// Update Resource
final Foo updatedResource = new Foo("newName");
updatedResource.setId(createResponse.getBody().getId());
final String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId();
final HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedResource, headers);
template.patchForObject(resourceUrl, requestUpdate, Void.class);
// Check that Resource was updated
final ResponseEntity<Foo> updateResponse = template.exchange(resourceUrl, HttpMethod.GET, new HttpEntity<>(headers), Foo.class);
final Foo foo = updateResponse.getBody();
assertThat(foo.getName(), is(updatedResource.getName()));
}
// DELETE
@Test

View File

@ -7,7 +7,7 @@ import org.testng.ITestListener;
import org.testng.ITestResult;
public class CustomisedListener implements ITestListener {
private static final Logger LOGGER = LoggerFactory.getLogger("TEST_REPORT");
private static final Logger LOGGER = LoggerFactory.getLogger("CUSTOM_LOGS");
@Override
public void onFinish(ITestContext context) {
@ -25,7 +25,8 @@ public class CustomisedListener implements ITestListener {
.forEach(result -> {
LOGGER.info(result.getName());
});
LOGGER.info("Test completed on: " + context.getEndDate().toString());
LOGGER.info("Test completed on: " + context.getEndDate()
.toString());
}
@Override
@ -54,13 +55,14 @@ public class CustomisedListener implements ITestListener {
@Override
public void onTestStart(ITestResult arg0) {
LOGGER.info("Testing: " + arg0.getName() + " " + arg0.getStartMillis());
LOGGER.info("Testing: " + arg0.getName());
}
@Override
public void onTestSuccess(ITestResult arg0) {
LOGGER.info("Tested: " + arg0.getName() + " " + arg0.getEndMillis());
long timeTaken = ((arg0.getEndMillis() - arg0.getStartMillis()));
LOGGER.info("Tested: " + arg0.getName() + " Time taken:" + timeTaken + " ms");
}

View File

@ -1,50 +1,73 @@
package com.baeldung.reports;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.IReporter;
import org.testng.IResultMap;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.xml.XmlSuite;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CustomisedReports implements IReporter {
private static final Logger LOGGER = LoggerFactory.getLogger("TEST_REPORT");
private PrintWriter reportWriter;
@Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
suites.stream()
.forEach(suite -> {
String suiteName = suite.getName();
new File(outputDirectory).mkdirs();
try {
reportWriter = new PrintWriter(new BufferedWriter(new FileWriter(new File(outputDirectory, "my-report.html"))));
} catch (IOException e) {
e.printStackTrace();
}
String resultRow = "<tr class=\"%s\"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>";
initReportTemplate();
for (ISuite suite : suites) {
Map<String, ISuiteResult> suiteResults = suite.getResults();
suiteResults.values()
.stream()
.forEach(result -> {
ITestContext context
= ((ISuiteResult) result).getTestContext();
LOGGER.info("Passed tests for suite '"
+ suiteName + "' is:"
+ context.getPassedTests()
.getAllResults()
.size());
LOGGER.info("Failed tests for suite '"
+ suiteName + "' is:"
+ context.getFailedTests()
.getAllResults()
.size());
LOGGER.info("Skipped tests for suite '"
+ suiteName + "' is:"
+ context.getSkippedTests()
.getAllResults()
.size());
});
});
for (String testName : suiteResults.keySet()) {
ISuiteResult suiteResult = suiteResults.get(testName);
ITestContext testContext = suiteResult.getTestContext();
IResultMap failedResult = testContext.getFailedTests();
Set<ITestResult> testsFailed = failedResult.getAllResults();
for (ITestResult testResult : testsFailed) {
reportWriter.println(String.format(resultRow, "danger", suite.getName(), testName, testResult.getName(), "FAILED", "NA"));
}
IResultMap passResult = testContext.getPassedTests();
Set<ITestResult> testsPassed = passResult.getAllResults();
for (ITestResult testResult : testsPassed) {
reportWriter.println(String.format(resultRow, "success", suite.getName(), testName, testResult.getName(), "PASSED", String.valueOf(testResult.getEndMillis() - testResult.getStartMillis())));
}
IResultMap skippedResult = testContext.getSkippedTests();
Set<ITestResult> testsSkipped = skippedResult.getAllResults();
for (ITestResult testResult : testsSkipped) {
reportWriter.println(String.format(resultRow, "warning", suite.getName(), testName, testResult.getName(), "SKIPPED", "NA"));
}
}
}
finishReportTemplate();
reportWriter.flush();
reportWriter.close();
}
private void initReportTemplate() {
reportWriter.println(
"<html>" + "<head>" + "<title>My Custom Report</title>" + "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" + "<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\">"
+ "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js\"></script>" + "<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"></script></head>" + "<body><div class=\"container\">");
reportWriter.println("<table class=\"table\"><thead><tr>" + "<th>Suite</th>" + "<th>Test</th>" + "<th>Method</th>" + "<th>Status</th>" + "<th>Execution Time(ms)</th>" + "</tr></thead> <tbody>");
}
private void finishReportTemplate() {
reportWriter.println(" </tbody></div></body></html>");
}
}