diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Operations.java b/core-java/src/main/java/com/baeldung/java/reflection/Operations.java index 754a93122f..dd11a9bcee 100644 --- a/core-java/src/main/java/com/baeldung/java/reflection/Operations.java +++ b/core-java/src/main/java/com/baeldung/java/reflection/Operations.java @@ -1,17 +1,21 @@ package com.baeldung.java.reflection; public class Operations { - + public double sum(int a, double b) { return a + b; } - - public static double multiply(float a, long b){ + + public static double multiply(float a, long b) { return a * b; } private boolean and(boolean a, boolean b) { return a && b; } - + + protected int max(int a, int b) { + return a > b ? a : b; + } + } diff --git a/core-java/src/test/java/com/baeldung/concurrent/adder/LongAdderTest.java b/core-java/src/test/java/com/baeldung/concurrent/adder/LongAdderTest.java index 854db5d9b9..77d1e9de27 100644 --- a/core-java/src/test/java/com/baeldung/concurrent/adder/LongAdderTest.java +++ b/core-java/src/test/java/com/baeldung/concurrent/adder/LongAdderTest.java @@ -8,6 +8,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.LongAdder; import java.util.stream.IntStream; +import static com.jayway.awaitility.Awaitility.await; import static junit.framework.TestCase.assertEquals; public class LongAdderTest { @@ -60,6 +61,7 @@ public class LongAdderTest { executorService.shutdown(); assertEquals(counter.sumThenReset(), numberOfIncrements * numberOfThreads); - assertEquals(counter.sum(), 0); + + await().until(() -> assertEquals(counter.sum(), 0)); } } diff --git a/core-java/src/test/java/com/baeldung/dateapi/JavaDurationTest.java b/core-java/src/test/java/com/baeldung/dateapi/JavaDurationTest.java new file mode 100644 index 0000000000..f4bfc0f55c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/dateapi/JavaDurationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.dateapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +import org.junit.Test; + +public class JavaDurationTest { + + @Test + public void test2() { + Instant start = Instant.parse("2017-10-03T10:15:30.00Z"); + Instant end = Instant.parse("2017-10-03T10:16:30.00Z"); + + Duration duration = Duration.between(start, end); + + assertFalse(duration.isNegative()); + + assertEquals(60, duration.getSeconds()); + assertEquals(1, duration.toMinutes()); + + Duration fromDays = Duration.ofDays(1); + assertEquals(86400, fromDays.getSeconds()); + + Duration fromMinutes = Duration.ofMinutes(60); + assertEquals(1, fromMinutes.toHours()); + + assertEquals(120, duration.plusSeconds(60).getSeconds()); + assertEquals(30, duration.minusSeconds(30).getSeconds()); + + assertEquals(120, duration.plus(60, ChronoUnit.SECONDS).getSeconds()); + assertEquals(30, duration.minus(30, ChronoUnit.SECONDS).getSeconds()); + + Duration fromChar1 = Duration.parse("P1DT1H10M10.5S"); + Duration fromChar2 = Duration.parse("PT10M"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/dateapi/JavaPeriodTest.java b/core-java/src/test/java/com/baeldung/dateapi/JavaPeriodTest.java new file mode 100644 index 0000000000..a0bede49b5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/dateapi/JavaPeriodTest.java @@ -0,0 +1,44 @@ +package com.baeldung.dateapi; + +import org.apache.log4j.Logger; +import org.junit.Test; + +import java.time.LocalDate; +import java.time.Period; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class JavaPeriodTest { + + private static final Logger LOG = Logger.getLogger(JavaPeriodTest.class); + + @Test + public void whenTestPeriod_thenOk() { + + LocalDate startDate = LocalDate.of(2015, 2, 15); + LocalDate endDate = LocalDate.of(2017, 1, 21); + + Period period = Period.between(startDate, endDate); + + LOG.info(String.format("Years:%d months:%d days:%d", period.getYears(), period.getMonths(), period.getDays())); + + assertFalse(period.isNegative()); + assertEquals(56, period.plusDays(50).getDays()); + assertEquals(9, period.minusMonths(2).getMonths()); + + Period fromUnits = Period.of(3, 10, 10); + Period fromDays = Period.ofDays(50); + Period fromMonths = Period.ofMonths(5); + Period fromYears = Period.ofYears(10); + Period fromWeeks = Period.ofWeeks(40); + + assertEquals(280, fromWeeks.getDays()); + + Period fromCharYears = Period.parse("P2Y"); + assertEquals(2, fromCharYears.getYears()); + Period fromCharUnits = Period.parse("P2Y3M5D"); + assertEquals(5, fromCharUnits.getDays()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/reflection/OperationsUnitTest.java b/core-java/src/test/java/com/baeldung/java/reflection/OperationsUnitTest.java index 4bd12047c6..71ee466afd 100644 --- a/core-java/src/test/java/com/baeldung/java/reflection/OperationsUnitTest.java +++ b/core-java/src/test/java/com/baeldung/java/reflection/OperationsUnitTest.java @@ -14,23 +14,23 @@ public class OperationsUnitTest { public OperationsUnitTest() { } - @Test(expected=IllegalAccessException.class) - public void givenObject_whenInvokePrivatedMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ - Method andInstanceMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class); + @Test(expected = IllegalAccessException.class) + public void givenObject_whenInvokePrivateMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method andPrivateMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class); Operations operationsInstance = new Operations(); - Boolean result = (Boolean)andInstanceMethod.invoke(operationsInstance, true, false); + Boolean result = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false); assertFalse(result); } @Test public void givenObject_whenInvokePrivateMethod_thenCorrect() throws Exception { - Method andInstanceMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class); - andInstanceMethod.setAccessible(true); + Method andPrivatedMethod = Operations.class.getDeclaredMethod("and", boolean.class, boolean.class); + andPrivatedMethod.setAccessible(true); Operations operationsInstance = new Operations(); - Boolean result = (Boolean)andInstanceMethod.invoke(operationsInstance, true, false); + Boolean result = (Boolean) andPrivatedMethod.invoke(operationsInstance, true, false); assertFalse(result); } @@ -40,17 +40,17 @@ public class OperationsUnitTest { Method sumInstanceMethod = Operations.class.getMethod("sum", int.class, double.class); Operations operationsInstance = new Operations(); - Double result = (Double)sumInstanceMethod.invoke(operationsInstance, 1, 3); - + Double result = (Double) sumInstanceMethod.invoke(operationsInstance, 1, 3); + assertThat(result, equalTo(4.0)); } - + @Test public void givenObject_whenInvokeStaticMethod_thenCorrect() throws Exception { - Method multiplyStaticMethod = Operations.class.getDeclaredMethod("multiply",float.class, long.class); + Method multiplyStaticMethod = Operations.class.getDeclaredMethod("multiply", float.class, long.class); + + Double result = (Double) multiplyStaticMethod.invoke(null, 3.5f, 2); - Double result = (Double)multiplyStaticMethod.invoke(null, 3.5f, 2); - assertThat(result, equalTo(7.0)); } diff --git a/core-java/src/test/java/com/baeldung/java/reflection/operations/MoreOperationsUnitTest.java b/core-java/src/test/java/com/baeldung/java/reflection/operations/MoreOperationsUnitTest.java new file mode 100644 index 0000000000..a7b5df01dd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/reflection/operations/MoreOperationsUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.java.reflection.operations; + +import com.baeldung.java.reflection.*; +import static org.hamcrest.CoreMatchers.equalTo; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.junit.Test; +import static org.junit.Assert.assertThat; + +public class MoreOperationsUnitTest { + + public MoreOperationsUnitTest() { + } + + @Test(expected = IllegalAccessException.class) + public void givenObject_whenInvokeProtectedMethod_thenFail() throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method maxProtectedMethod = Operations.class.getDeclaredMethod("max", int.class, int.class); + + Operations operationsInstance = new Operations(); + Integer result = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4); + System.out.println("result = " + result); + assertThat(result, equalTo(4)); + } + + @Test + public void givenObject_whenInvokeProtectedMethod_thenCorrect() throws Exception { + Method maxProtectedMethod = Operations.class.getDeclaredMethod("max", int.class, int.class); + maxProtectedMethod.setAccessible(true); + + Operations operationsInstance = new Operations(); + Integer result = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4); + + assertThat(result, equalTo(4)); + } + +} diff --git a/pom.xml b/pom.xml index 91af48f79f..58f1256b17 100644 --- a/pom.xml +++ b/pom.xml @@ -229,8 +229,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3 - true + **/*IntegrationTest.java **/*LongRunningUnitTest.java diff --git a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java b/spring-5/src/main/java/com/baeldung/functional/FormHandler.java index 5c3890d412..857d22a67f 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java +++ b/spring-5/src/main/java/com/baeldung/functional/FormHandler.java @@ -1,10 +1,12 @@ package com.baeldung.functional; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; +import java.util.List; import java.util.concurrent.atomic.AtomicLong; import static org.springframework.web.reactive.function.BodyExtractors.toDataBuffers; @@ -21,21 +23,22 @@ public class FormHandler { .filter(formData -> "baeldung".equals(formData.get("user"))) .filter(formData -> "you_know_what_to_do".equals(formData.get("token"))) .flatMap(formData -> ok().body(Mono.just("welcome back!"), String.class)) - .or(ServerResponse.badRequest().build()); + .switchIfEmpty(ServerResponse.badRequest().build()); } Mono handleUpload(ServerRequest request) { return request .body(toDataBuffers()) .collectList() - .flatMap(dataBuffers -> { - AtomicLong atomicLong = new AtomicLong(0); - dataBuffers.forEach(d -> atomicLong.addAndGet(d - .asByteBuffer() - .array().length)); + .flatMap(dataBuffers -> ok() + .body(fromObject(extractData(dataBuffers).toString()))); + } - return ok() - .body(fromObject(atomicLong.toString())); - }); + private AtomicLong extractData(List dataBuffers) { + AtomicLong atomicLong = new AtomicLong(0); + dataBuffers.forEach(d -> atomicLong.addAndGet(d + .asByteBuffer() + .array().length)); + return atomicLong; } } diff --git a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java index fe7f4b06ff..cf1029c12f 100644 --- a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java @@ -4,8 +4,18 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.boot.web.server.WebServer; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserters; + +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromResource; + public class FunctionalWebApplicationIntegrationTest { private static WebTestClient client; @@ -49,7 +59,7 @@ public class FunctionalWebApplicationIntegrationTest { .isEqualTo("helloworld"); } - /* @Test + @Test public void givenLoginForm_whenPostValidToken_thenSuccess() throws Exception { MultiValueMap formData = new LinkedMultiValueMap<>(1); formData.add("user", "baeldung"); @@ -59,15 +69,15 @@ public class FunctionalWebApplicationIntegrationTest { .post() .uri("/login") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .exchange(BodyInserters.fromFormData(formData)) + .body(BodyInserters.fromFormData(formData)) + .exchange() .expectStatus() .isOk() .expectBody(String.class) - .value() .isEqualTo("welcome back!"); - }*/ + } - /* @Test + @Test public void givenLoginForm_whenRequestWithInvalidToken_thenFail() throws Exception { MultiValueMap formData = new LinkedMultiValueMap<>(2); formData.add("user", "baeldung"); @@ -77,27 +87,28 @@ public class FunctionalWebApplicationIntegrationTest { .post() .uri("/login") .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .exchange(BodyInserters.fromFormData(formData)) + .body(BodyInserters.fromFormData(formData)) + .exchange() .expectStatus() .isBadRequest(); } -*/ - /* @Test + + @Test public void givenUploadForm_whenRequestWithMultipartData_thenSuccess() throws Exception { Resource resource = new ClassPathResource("/baeldung-weekly.png"); client .post() .uri("/upload") .contentType(MediaType.MULTIPART_FORM_DATA) - .exchange(fromResource(resource)) + .body(fromResource(resource)) + .exchange() .expectStatus() .isOk() .expectBody(String.class) - .value() .isEqualTo(String.valueOf(resource.contentLength())); } -*/ - /* @Test + + @Test public void givenActors_whenAddActor_thenAdded() throws Exception { client .get() @@ -105,14 +116,14 @@ public class FunctionalWebApplicationIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(Actor.class) - .list() + .expectBodyList(Actor.class) .hasSize(2); client .post() .uri("/actor") - .exchange(fromObject(new Actor("Clint", "Eastwood"))) + .body(fromObject(new Actor("Clint", "Eastwood"))) + .exchange() .expectStatus() .isOk(); @@ -122,10 +133,9 @@ public class FunctionalWebApplicationIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(Actor.class) - .list() + .expectBodyList(Actor.class) .hasSize(3); - }*/ + } @Test public void givenResources_whenAccess_thenGot() throws Exception { diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 7477c78b58..1c34dfa7ca 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -125,19 +125,31 @@ mysql-connector-java 6.0.6 - + + org.springframework + spring-websocket + ${spring.version} + + + + org.springframework + spring-messaging + ${spring.version} + + + org.togglz togglz-spring-boot-starter ${togglz.version} - - + + org.togglz togglz-spring-security ${togglz.version} - + org.apache.activemq artemis-server diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/Message.java b/spring-boot/src/main/java/org/baeldung/websocket/client/Message.java new file mode 100644 index 0000000000..bcab44870b --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/websocket/client/Message.java @@ -0,0 +1,25 @@ +package org.baeldung.websocket.client; + +public class Message { + + private String from; + private String text; + + public String getText() { + return text; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public void setText(String text) { + this.text = text; + } + + +} diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java b/spring-boot/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java new file mode 100644 index 0000000000..35bf1827ea --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java @@ -0,0 +1,58 @@ +package org.baeldung.websocket.client; + +import org.apache.log4j.Logger; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompHeaders; +import org.springframework.messaging.simp.stomp.StompSession; +import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; + +import java.lang.reflect.Type; + +/** + * This class is an implementation for StompSessionHandlerAdapter. + * Once a connection is established, We subscribe to /topic/messages and + * send a sample message to server. + * + * @author Kalyan + * + */ +public class MyStompSessionHandler extends StompSessionHandlerAdapter { + + private Logger logger = Logger.getLogger(MyStompSessionHandler.class); + + @Override + public void afterConnected(StompSession session, StompHeaders connectedHeaders) { + logger.info("New session established : "+session.getSessionId()); + session.subscribe("/topic/messages", this); + logger.info("Subscribed to /topic/messages"); + session.send("/app/chat", getSampleMessage()); + logger.info("Message sent to websocket server"); + } + + @Override + public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) { + logger.error("Got an exception", exception); + } + + @Override + public Type getPayloadType(StompHeaders headers) { + return Message.class; + } + + @Override + public void handleFrame(StompHeaders headers, Object payload) { + Message msg = (Message)payload; + logger.info("Received : "+ msg.getText()+ " from : "+msg.getFrom()); + } + + /** + * A sample message instance. + * @return instance of Message + */ + private Message getSampleMessage(){ + Message msg = new Message(); + msg.setFrom("Nicky"); + msg.setText("Howdy!!"); + return msg; + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/StompClient.java b/spring-boot/src/main/java/org/baeldung/websocket/client/StompClient.java new file mode 100644 index 0000000000..da2dbeac3d --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/websocket/client/StompClient.java @@ -0,0 +1,37 @@ +package org.baeldung.websocket.client; + +import java.util.Collections; +import java.util.List; +import java.util.Scanner; + +import org.springframework.messaging.converter.MappingJackson2MessageConverter; +import org.springframework.messaging.simp.stomp.StompSessionHandler; +import org.springframework.web.socket.client.standard.StandardWebSocketClient; +import org.springframework.web.socket.messaging.WebSocketStompClient; +import org.springframework.web.socket.sockjs.client.SockJsClient; +import org.springframework.web.socket.sockjs.client.Transport; +import org.springframework.web.socket.sockjs.client.WebSocketTransport; + +/** + * Stand alone WebSocketStompClient. + * @author Kalyan + * + */ +public class StompClient { + + private static String URL = "ws://localhost:8080/spring-mvc-java/chat"; + + public static void main(String[] args) { + Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient()); + List transports = Collections.singletonList(webSocketTransport); + SockJsClient sockJsClient = new SockJsClient(transports); + + WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient); + stompClient.setMessageConverter(new MappingJackson2MessageConverter()); + + StompSessionHandler sessionHandler = new MyStompSessionHandler(); + stompClient.connect(URL, sessionHandler); + + new Scanner(System.in).nextLine(); // Don't close immediately. + } +} diff --git a/spring-boot/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerTest.java b/spring-boot/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerTest.java new file mode 100644 index 0000000000..b8b1ec8c6c --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerTest.java @@ -0,0 +1,26 @@ +package com.baeldung.websocket.client; + +import org.baeldung.websocket.client.MyStompSessionHandler; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.messaging.simp.stomp.StompHeaders; +import org.springframework.messaging.simp.stomp.StompSession; + +/** + * Test class for MyStompSessionHandler + * @author Kalyan + * + */ +public class MyStompSessionHandlerTest { + + @Test + public void testAfterConnectedSuccessfull() { + StompSession mockSession = Mockito.mock(StompSession.class); + StompHeaders mockHeader = Mockito.mock(StompHeaders.class); + MyStompSessionHandler sessionHandler = new MyStompSessionHandler(); + sessionHandler.afterConnected(mockSession, mockHeader); + Mockito.verify(mockSession).subscribe("/topic/messages", sessionHandler); + Mockito.verify(mockSession).send(Mockito.anyString(), Mockito.anyObject()); + } +} + diff --git a/testng/src/test/java/com/baeldung/reports/CustomisedReports.java b/testng/src/test/java/com/baeldung/reports/CustomisedReports.java index 7e303035aa..58f9ff4e57 100644 --- a/testng/src/test/java/com/baeldung/reports/CustomisedReports.java +++ b/testng/src/test/java/com/baeldung/reports/CustomisedReports.java @@ -31,8 +31,7 @@ public class CustomisedReports implements IReporter { initReportTemplate(); for (ISuite suite : suites) { Map suiteResults = suite.getResults(); - for (String testName : suiteResults.keySet()) { - ISuiteResult suiteResult = suiteResults.get(testName); + suiteResults.forEach((testName, suiteResult) -> { ITestContext testContext = suiteResult.getTestContext(); IResultMap failedResult = testContext.getFailedTests(); @@ -52,8 +51,7 @@ public class CustomisedReports implements IReporter { for (ITestResult testResult : testsSkipped) { reportWriter.println(String.format(resultRow, "warning", suite.getName(), testName, testResult.getName(), "SKIPPED", "NA")); } - - } + }); } finishReportTemplate(); reportWriter.flush(); @@ -62,8 +60,8 @@ public class CustomisedReports implements IReporter { private void initReportTemplate() { reportWriter.println( - "" + "" + "My Custom Report" + "" + "" - + "" + "" + "
"); + "" + "" + "My Custom Report" + "" + "" + + "" + "" + "
"); reportWriter.println("" + "" + "" + "" + "" + "" + ""); }
SuiteTestMethodStatusExecution Time(ms)