From ac30817a2365e294a2d9fb2a453bd22182f73c45 Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Fri, 2 Apr 2021 12:51:43 +0200 Subject: [PATCH 01/31] Evaluation Article: A quick and practical example of Hexagonal Architecture in Java --- .../hexagonal/HexagonalSpringApplication.java | 20 +++ .../adapter/BookingPersistenceAdapter.java | 18 +++ .../adapter/RestAPIEndpointAdapter.java | 38 ++++++ .../adapter/TheatreServiceAdapter.java | 31 +++++ .../adapter/WalletServiceAdapter.java | 23 ++++ .../baeldung/hexagonal/domain/Booking.java | 84 +++++++++++++ .../service/CustomerWalletService.java | 8 ++ .../service/MockCustomerWalletService.java | 11 ++ .../external/service/MockTheatreService.java | 21 ++++ .../external/service/TheatreService.java | 24 ++++ .../port/BookingPersistencePort.java | 7 ++ .../hexagonal/port/BookingServicePort.java | 73 +++++++++++ .../hexagonal/port/TheatreServicePort.java | 9 ++ .../hexagonal/port/WalletServicePort.java | 5 + .../repository/BookingRepository.java | 8 ++ .../repository/MockBookingRepository.java | 11 ++ .../hexagonal/usecase/BookTicketUseCase.java | 67 ++++++++++ .../RestAPIEndpointAdapterUnitTest.java | 88 +++++++++++++ .../usecase/BookTicketUseCaseUnitTest.java | 119 ++++++++++++++++++ 19 files changed, 665 insertions(+) create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java create mode 100644 ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java create mode 100644 ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java diff --git a/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java b/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java new file mode 100644 index 0000000000..c679d459f0 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java @@ -0,0 +1,20 @@ +package com.baeldung.hexagonal; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; + + +@SpringBootApplication(exclude={ + CassandraAutoConfiguration.class, + MongoDataAutoConfiguration.class, + MongoAutoConfiguration.class +}) +public class HexagonalSpringApplication { + + public static void main(final String[] args) { + SpringApplication.run(HexagonalSpringApplication.class, args); + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java new file mode 100644 index 0000000000..e6d4dbbe36 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java @@ -0,0 +1,18 @@ +package com.baeldung.hexagonal.adapter; + +import com.baeldung.hexagonal.domain.Booking; +import com.baeldung.hexagonal.port.BookingPersistencePort; +import com.baeldung.hexagonal.repository.BookingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class BookingPersistenceAdapter implements BookingPersistencePort { + + @Autowired + private BookingRepository bookingRepository; + + public boolean persist(Booking booking) { + return bookingRepository.save(booking); + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java new file mode 100644 index 0000000000..7c35f302c0 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java @@ -0,0 +1,38 @@ +package com.baeldung.hexagonal.adapter; + +import com.baeldung.hexagonal.port.BookingServicePort; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import static com.baeldung.hexagonal.port.BookingServicePort.BookingRequest; +import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse; +import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; + +@RestController +public class RestAPIEndpointAdapter { + + private BookingServicePort bookingServicePort; + + @Autowired + public RestAPIEndpointAdapter(BookingServicePort bookingServicePort) { + this.bookingServicePort = bookingServicePort; + } + + @PostMapping(path = "/booking") + public ResponseEntity createBooking(@RequestBody BookingRequest request) { + BookingResponse response = bookingServicePort.book(request); + + if (response.getStatusCode() == SEAT_NOT_AVAILABLE + || response.getStatusCode() == PAYMENT_FAILED){ + return new ResponseEntity(response, HttpStatus.PRECONDITION_FAILED); + } else if (response.getStatusCode() == UNKNOWN_ERROR) { + return new ResponseEntity(response, HttpStatus.INTERNAL_SERVER_ERROR); + } + + return new ResponseEntity(response, HttpStatus.CREATED); + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java new file mode 100644 index 0000000000..d644f5eee0 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java @@ -0,0 +1,31 @@ +package com.baeldung.hexagonal.adapter; + +import com.baeldung.hexagonal.external.service.TheatreService; +import com.baeldung.hexagonal.port.TheatreServicePort; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import java.util.Optional; +import java.util.Set; + +@Component +public class TheatreServiceAdapter implements TheatreServicePort { + + @Autowired + private TheatreService theatreService; + + public Optional reserveSeats(String theatreId, String movieShowId, Set seats) { + ResponseEntity response = theatreService.postReservation(theatreId, movieShowId, seats); + if (response.getStatusCode() == HttpStatus.CREATED) { + return Optional.of(response.getBody().getId()); + } + return Optional.empty(); + } + + public boolean releaseSeats(String resrevationId) { + ResponseEntity response = theatreService.deleteReservation(resrevationId); + return response.getStatusCode() == HttpStatus.NO_CONTENT; + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java new file mode 100644 index 0000000000..930b9c1cf6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java @@ -0,0 +1,23 @@ +package com.baeldung.hexagonal.adapter; + +import com.baeldung.hexagonal.external.service.CustomerWalletService; +import com.baeldung.hexagonal.port.WalletServicePort; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +@Component +public class WalletServiceAdapter implements WalletServicePort { + + private final CustomerWalletService customerWalletService; + + @Autowired + public WalletServiceAdapter(CustomerWalletService customerWalletService) { + this.customerWalletService = customerWalletService; + } + + public boolean debit(String customerId, Double amount) { + HttpStatus response = customerWalletService.postDebit(customerId, amount); + return response == HttpStatus.CREATED; + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java b/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java new file mode 100644 index 0000000000..34e3f3b81b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java @@ -0,0 +1,84 @@ +package com.baeldung.hexagonal.domain; + +import java.util.Set; + +public class Booking { + private String bookingId; + private String movieShowId; + private String theatreId; + private String customerId; + private Set seats; + private Double amount; + private Status status; + + public enum Status { + INITIAL, SUCCESS, FAILURE + } + + public Booking( + String bookingId, String movieShowId, String theatreId, String customerId, Set seats, Double amount, Status status) { + this.bookingId = bookingId; + this.movieShowId = movieShowId; + this.theatreId = theatreId; + this.customerId = customerId; + this.seats = seats; + this.amount = amount; + this.status = Status.INITIAL; + } + + public String getMovieShowId() { + return movieShowId; + } + + public String getTheatreId() { + return theatreId; + } + + public Set getSeats() { + return seats; + } + + public String getCustomerId() { + return customerId; + } + + public String getBookingId() { + return bookingId; + } + + public Double getAmount() { + return amount; + } + + public Status getStatus() { + return status; + } + + public void setBookingId(String bookingId) { + this.bookingId = bookingId; + } + + public void setMovieShowId(String movieShowId) { + this.movieShowId = movieShowId; + } + + public void setTheatreId(String theatreId) { + this.theatreId = theatreId; + } + + public void setCustomerId(String customerId) { + this.customerId = customerId; + } + + public void setSeats(Set seats) { + this.seats = seats; + } + + public void setAmount(Double amount) { + this.amount = amount; + } + + public void setStatus(Status status) { + this.status = status; + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java new file mode 100644 index 0000000000..102cef788e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.external.service; + +import org.springframework.http.HttpStatus; + +public interface CustomerWalletService { + + HttpStatus postDebit(String customerId, Double amount); +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java new file mode 100644 index 0000000000..4a76368b19 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java @@ -0,0 +1,11 @@ +package com.baeldung.hexagonal.external.service; + +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +@Service +public class MockCustomerWalletService implements CustomerWalletService { + public HttpStatus postDebit(String customerId, Double amount) { + return HttpStatus.CREATED; + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java new file mode 100644 index 0000000000..333cbee889 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java @@ -0,0 +1,21 @@ +package com.baeldung.hexagonal.external.service; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.Set; +import java.util.UUID; + +@Service +public class MockTheatreService implements TheatreService { + + public ResponseEntity postReservation(String theatreId, String movieShowId, Set seats) { + return new ResponseEntity( + new Reservation(UUID.randomUUID().toString()), HttpStatus.CREATED); + } + + public ResponseEntity deleteReservation(String reservationId) { + return new ResponseEntity(HttpStatus.NO_CONTENT); + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java new file mode 100644 index 0000000000..48f0c5e15d --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java @@ -0,0 +1,24 @@ +package com.baeldung.hexagonal.external.service; + +import org.springframework.http.ResponseEntity; + +import java.util.Set; + +public interface TheatreService { + + ResponseEntity postReservation(String theatreId, String movieShowId, Set seats); + + ResponseEntity deleteReservation(String reservationId); + + class Reservation { + private final String id; + + public Reservation(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java new file mode 100644 index 0000000000..0deffb42e0 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java @@ -0,0 +1,7 @@ +package com.baeldung.hexagonal.port; + +import com.baeldung.hexagonal.domain.Booking; + +public interface BookingPersistencePort { + boolean persist(Booking booking); +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java new file mode 100644 index 0000000000..3b444df4f6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java @@ -0,0 +1,73 @@ +package com.baeldung.hexagonal.port; + +import java.util.Set; + +public interface BookingServicePort { + + BookingResponse book(BookingRequest request); + + class BookingRequest { + private String movieShowId; + private String customerId; + private String theatreId; + private Set seats; + private Double amount; + + public String getMovieShowId() { + return movieShowId; + } + + public void setMovieShowId(String movieShowId) { + this.movieShowId = movieShowId; + } + + public String getCustomerId() { + return customerId; + } + + public void setCustomerId(String customerId) { + this.customerId = customerId; + } + + public String getTheatreId() { + return theatreId; + } + + public void setTheatreId(String theatreId) { + this.theatreId = theatreId; + } + + public Set getSeats() { + return seats; + } + + public void setSeats(Set seats) { + this.seats = seats; + } + + public Double getAmount() { + return amount; + } + + public void setAmount(Double amount) { + this.amount = amount; + } + } + + class BookingResponse { + public static final int SUCCESS = 0; + public static final int SEAT_NOT_AVAILABLE = 1; + public static final int PAYMENT_FAILED = 2; + public static final int UNKNOWN_ERROR = 3; + + private final int statusCode; + + public BookingResponse(int statusCode) { + this.statusCode = statusCode; + } + + public int getStatusCode() { + return statusCode; + } + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java new file mode 100644 index 0000000000..dac517c724 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java @@ -0,0 +1,9 @@ +package com.baeldung.hexagonal.port; + +import java.util.Optional; +import java.util.Set; + +public interface TheatreServicePort { + Optional reserveSeats(String theatreId, String movieShowId, Set seats); + boolean releaseSeats(String resrevationId); +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java new file mode 100644 index 0000000000..102bb619e8 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java @@ -0,0 +1,5 @@ +package com.baeldung.hexagonal.port; + +public interface WalletServicePort { + boolean debit(String customerId, Double amount); +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java new file mode 100644 index 0000000000..c56ffe1308 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.repository; + +import com.baeldung.hexagonal.domain.Booking; + +public interface BookingRepository { + + boolean save(Booking booking); +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java new file mode 100644 index 0000000000..d378cff0af --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.hexagonal.repository; + +import com.baeldung.hexagonal.domain.Booking; +import org.springframework.stereotype.Repository; + +@Repository +public class MockBookingRepository implements BookingRepository { + public boolean save(Booking booking) { + return true; + } +} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java b/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java new file mode 100644 index 0000000000..7d9db9724e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java @@ -0,0 +1,67 @@ +package com.baeldung.hexagonal.usecase; + +import com.baeldung.hexagonal.domain.Booking; +import com.baeldung.hexagonal.port.BookingPersistencePort; +import com.baeldung.hexagonal.port.BookingServicePort; +import com.baeldung.hexagonal.port.TheatreServicePort; +import com.baeldung.hexagonal.port.WalletServicePort; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; +import java.util.UUID; + +import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; + +@Component +public class BookTicketUseCase implements BookingServicePort { + + private BookingPersistencePort bookingPersistencePort; + private TheatreServicePort theatreServicePort; + private WalletServicePort walletServicePort; + + @Autowired + public BookTicketUseCase(BookingPersistencePort bookingPersistencePort, TheatreServicePort theatreServicePort, WalletServicePort walletServicePort) { + this.bookingPersistencePort = bookingPersistencePort; + this.theatreServicePort = theatreServicePort; + this.walletServicePort = walletServicePort; + } + + public BookingResponse book(BookingRequest request) { + + Booking booking = new Booking( + UUID.randomUUID().toString(), + request.getMovieShowId(), + request.getTheatreId(), + request.getCustomerId(), + request.getSeats(), + request.getAmount(), + Booking.Status.INITIAL); + + if (!bookingPersistencePort.persist(booking)) { + return new BookingResponse(UNKNOWN_ERROR); + } + + Optional reservationIdOptional = theatreServicePort.reserveSeats( + booking.getTheatreId(), + booking.getMovieShowId(), + booking.getSeats()); + if (!reservationIdOptional.isPresent()) { + booking.setStatus(Booking.Status.FAILURE); + bookingPersistencePort.persist(booking); + return new BookingResponse(SEAT_NOT_AVAILABLE); + } + + if (!walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) { + reservationIdOptional.ifPresent(reservationId -> theatreServicePort.releaseSeats(reservationId)); + booking.setStatus(Booking.Status.FAILURE); + bookingPersistencePort.persist(booking); + return new BookingResponse(PAYMENT_FAILED); + } + + booking.setStatus(Booking.Status.SUCCESS); + bookingPersistencePort.persist(booking); + + return new BookingResponse(SUCCESS); + } +} diff --git a/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java new file mode 100644 index 0000000000..76d853fdda --- /dev/null +++ b/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java @@ -0,0 +1,88 @@ +package com.baeldung.hexagonal.adapter; + +import com.baeldung.hexagonal.port.BookingServicePort; +import com.baeldung.hexagonal.port.BookingServicePort.BookingRequest; +import com.baeldung.hexagonal.port.BookingServicePort.BookingResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.Arrays; +import java.util.HashSet; + +import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +class RestAPIEndpointAdapterUnitTest { + + private BookingServicePort bookingServicePort; + private RestAPIEndpointAdapter restAPIEndpointAdapter; + + @BeforeEach + void setUp() { + bookingServicePort = mock(BookingServicePort.class); + restAPIEndpointAdapter = new RestAPIEndpointAdapter(bookingServicePort); + } + + private BookingServicePort.BookingRequest getBookingRequest() { + BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); + request.setTheatreId("theatre-id"); + request.setMovieShowId("movie-show-id"); + request.setCustomerId("customer-id"); + request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); + request.setAmount(100.00); + return request; + } + + @Test + void whenBookingServicePortReturnsUnknownError_thenReturnInternalServerError() { + BookingServicePort.BookingRequest request = getBookingRequest(); + when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(UNKNOWN_ERROR)); + + ResponseEntity response = restAPIEndpointAdapter.createBooking(request); + + verify(bookingServicePort).book(any(BookingRequest.class)); + assertNotNull(response); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + } + + @Test + void whenBookingServicePortReturnsSeatUnavailable_thenReturnPreconditionFailed() { + BookingServicePort.BookingRequest request = getBookingRequest(); + when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(SEAT_NOT_AVAILABLE)); + + ResponseEntity response = restAPIEndpointAdapter.createBooking(request); + + verify(bookingServicePort).book(any(BookingRequest.class)); + assertNotNull(response); + assertEquals(HttpStatus.PRECONDITION_FAILED, response.getStatusCode()); + } + + @Test + void whenBookingServicePortReturnsPaymentFailed_thenReturnPreconditionFailed() { + BookingServicePort.BookingRequest request = getBookingRequest(); + when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(PAYMENT_FAILED)); + + ResponseEntity response = restAPIEndpointAdapter.createBooking(request); + + verify(bookingServicePort).book(any(BookingRequest.class)); + assertNotNull(response); + assertEquals(HttpStatus.PRECONDITION_FAILED, response.getStatusCode()); + } + + @Test + void whenBookingServicePortReturnsSuccess_thenReturnCreated() { + BookingServicePort.BookingRequest request = getBookingRequest(); + when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(SUCCESS)); + + ResponseEntity response = restAPIEndpointAdapter.createBooking(request); + + verify(bookingServicePort).book(any(BookingRequest.class)); + assertNotNull(response); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + } +} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java new file mode 100644 index 0000000000..eec2b65609 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java @@ -0,0 +1,119 @@ +package com.baeldung.hexagonal.usecase; + +import com.baeldung.hexagonal.domain.Booking; +import com.baeldung.hexagonal.port.BookingPersistencePort; +import com.baeldung.hexagonal.port.BookingServicePort; +import com.baeldung.hexagonal.port.TheatreServicePort; +import com.baeldung.hexagonal.port.WalletServicePort; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +class BookTicketUseCaseUnitTest { + + private BookingPersistencePort bookingPersistencePort; + private TheatreServicePort theatreServicePort; + private WalletServicePort walletServicePort; + private BookTicketUseCase bookTicketUseCase; + + @BeforeEach + void setUp() { + bookingPersistencePort = mock(BookingPersistencePort.class); + theatreServicePort = mock(TheatreServicePort.class); + walletServicePort = mock(WalletServicePort.class); + bookTicketUseCase = new BookTicketUseCase(bookingPersistencePort, theatreServicePort, walletServicePort); + } + + private BookingServicePort.BookingRequest getBookingRequest() { + BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); + request.setTheatreId("theatre-id"); + request.setMovieShowId("movie-show-id"); + request.setCustomerId("customer-id"); + request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); + request.setAmount(100.00); + return request; + } + + private Booking getBooking(BookingServicePort.BookingRequest request) { + return new Booking( + "booking-id", + request.getMovieShowId(), + request.getTheatreId(), + request.getCustomerId(), + request.getSeats(), + request.getAmount(), + Booking.Status.INITIAL); + } + + @Test + void whenErrorInInitialPersistence_thenReturnUnknownError() { + BookingServicePort.BookingRequest request = getBookingRequest(); + Booking booking = getBooking(request); + when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(false); + BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); + + verify(bookingPersistencePort, times(1)).persist(any(Booking.class)); + assertNotNull(response); + assertEquals(BookingServicePort.BookingResponse.UNKNOWN_ERROR, response.getStatusCode()); + } + + @Test + void whenErrorInReserveSeats_thenReturnSeatNotAvailable() { + BookingServicePort.BookingRequest request = getBookingRequest(); + Booking booking = getBooking(request); + when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); + when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + .thenReturn(Optional.empty()); + BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); + + verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); + verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + assertNotNull(response); + assertEquals(BookingServicePort.BookingResponse.SEAT_NOT_AVAILABLE, response.getStatusCode()); + } + + @Test + void whenErrorInWalletDebit_thenReturnPaymentFailed() { + BookingServicePort.BookingRequest request = getBookingRequest(); + Booking booking = getBooking(request); + when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); + when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + .thenReturn(Optional.of("reservation-id")); + when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) + .thenReturn(false); + BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); + + verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); + verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + verify(walletServicePort).debit(any(String.class), any(Double.class)); + verify(theatreServicePort).releaseSeats(any(String.class)); + assertNotNull(response); + assertEquals(BookingServicePort.BookingResponse.PAYMENT_FAILED, response.getStatusCode()); + } + + @Test + void whenNoErrorInAnyPorts_thenReturnSuccess() { + BookingServicePort.BookingRequest request = getBookingRequest(); + Booking booking = getBooking(request); + when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); + when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + .thenReturn(Optional.of("reservation-id")); + when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) + .thenReturn(true); + BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); + + verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); + verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + verify(walletServicePort).debit(any(String.class), any(Double.class)); + assertNotNull(response); + assertEquals(BookingServicePort.BookingResponse.SUCCESS, response.getStatusCode()); + } +} \ No newline at end of file From c5b651fca0334a707e3cd8cd443b52ec35b0011e Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Fri, 9 Apr 2021 20:31:53 +0200 Subject: [PATCH 02/31] Update code to be more compact --- .../adapter/BookingPersistenceAdapter.java | 4 ++ .../adapter/RestAPIEndpointAdapter.java | 16 +++----- .../adapter/TheatreServiceAdapter.java | 17 ++++---- .../adapter/WalletServiceAdapter.java | 12 ++---- .../baeldung/hexagonal/domain/Booking.java | 41 ++++++++++--------- .../external/service/MockTheatreService.java | 8 ++-- .../external/service/TheatreService.java | 4 +- .../port/BookingPersistencePort.java | 1 + .../hexagonal/port/BookingServicePort.java | 18 ++++---- .../hexagonal/port/TheatreServicePort.java | 2 +- .../repository/BookingRepository.java | 1 + .../repository/MockBookingRepository.java | 5 +++ .../hexagonal/usecase/BookTicketUseCase.java | 34 ++++++--------- .../RestAPIEndpointAdapterUnitTest.java | 7 ++-- .../usecase/BookTicketUseCaseUnitTest.java | 41 ++++++++----------- 15 files changed, 97 insertions(+), 114 deletions(-) diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java index e6d4dbbe36..1b191bde86 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java @@ -15,4 +15,8 @@ public class BookingPersistenceAdapter implements BookingPersistencePort { public boolean persist(Booking booking) { return bookingRepository.save(booking); } + + public boolean updateStatus(String bookingId, String status) { + return bookingRepository.updateStatus(bookingId, status); + } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java index 7c35f302c0..3e1b1fc90f 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java @@ -2,7 +2,6 @@ package com.baeldung.hexagonal.adapter; import com.baeldung.hexagonal.port.BookingServicePort; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -10,7 +9,9 @@ import org.springframework.web.bind.annotation.RestController; import static com.baeldung.hexagonal.port.BookingServicePort.BookingRequest; import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse; -import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; +import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.SUCCESS; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.FAILED_DEPENDENCY; @RestController public class RestAPIEndpointAdapter { @@ -25,14 +26,7 @@ public class RestAPIEndpointAdapter { @PostMapping(path = "/booking") public ResponseEntity createBooking(@RequestBody BookingRequest request) { BookingResponse response = bookingServicePort.book(request); - - if (response.getStatusCode() == SEAT_NOT_AVAILABLE - || response.getStatusCode() == PAYMENT_FAILED){ - return new ResponseEntity(response, HttpStatus.PRECONDITION_FAILED); - } else if (response.getStatusCode() == UNKNOWN_ERROR) { - return new ResponseEntity(response, HttpStatus.INTERNAL_SERVER_ERROR); - } - - return new ResponseEntity(response, HttpStatus.CREATED); + return new ResponseEntity<>(response, + response.getStatusCode() == SUCCESS ? CREATED : FAILED_DEPENDENCY); } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java index d644f5eee0..fa19483b13 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java @@ -3,29 +3,28 @@ package com.baeldung.hexagonal.adapter; import com.baeldung.hexagonal.external.service.TheatreService; import com.baeldung.hexagonal.port.TheatreServicePort; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import java.util.Optional; import java.util.Set; +import static com.baeldung.hexagonal.external.service.TheatreService.Reservation; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.NO_CONTENT; + @Component public class TheatreServiceAdapter implements TheatreServicePort { @Autowired private TheatreService theatreService; - public Optional reserveSeats(String theatreId, String movieShowId, Set seats) { - ResponseEntity response = theatreService.postReservation(theatreId, movieShowId, seats); - if (response.getStatusCode() == HttpStatus.CREATED) { - return Optional.of(response.getBody().getId()); - } - return Optional.empty(); + public Optional reserveSeats(String movieShowId, Set seats) { + ResponseEntity response = theatreService.postReservation(movieShowId, seats); + return response.getStatusCode() == CREATED ? Optional.of(response.getBody().getId()): Optional.empty(); } public boolean releaseSeats(String resrevationId) { - ResponseEntity response = theatreService.deleteReservation(resrevationId); - return response.getStatusCode() == HttpStatus.NO_CONTENT; + return theatreService.deleteReservation(resrevationId).getStatusCode() == NO_CONTENT; } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java index 930b9c1cf6..1d8db867b7 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java @@ -3,21 +3,17 @@ package com.baeldung.hexagonal.adapter; import com.baeldung.hexagonal.external.service.CustomerWalletService; import com.baeldung.hexagonal.port.WalletServicePort; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; +import static org.springframework.http.HttpStatus.CREATED; + @Component public class WalletServiceAdapter implements WalletServicePort { - private final CustomerWalletService customerWalletService; - @Autowired - public WalletServiceAdapter(CustomerWalletService customerWalletService) { - this.customerWalletService = customerWalletService; - } + private CustomerWalletService customerWalletService; public boolean debit(String customerId, Double amount) { - HttpStatus response = customerWalletService.postDebit(customerId, amount); - return response == HttpStatus.CREATED; + return customerWalletService.postDebit(customerId, amount) == CREATED; } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java b/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java index 34e3f3b81b..ed9b7281f2 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java @@ -1,39 +1,46 @@ package com.baeldung.hexagonal.domain; +import com.baeldung.hexagonal.port.BookingServicePort; + import java.util.Set; +import java.util.UUID; public class Booking { + + public static final String STATUS_INITIAL = "INITIAL"; + public static final String STATUS_SUCCESS = "SUCCESS"; + public static final String STATUS_FAILURE = "FAILED"; + private String bookingId; private String movieShowId; - private String theatreId; private String customerId; private Set seats; private Double amount; - private Status status; - - public enum Status { - INITIAL, SUCCESS, FAILURE - } + private String status; public Booking( - String bookingId, String movieShowId, String theatreId, String customerId, Set seats, Double amount, Status status) { + String bookingId, String movieShowId, String customerId, Set seats, Double amount, String status) { this.bookingId = bookingId; this.movieShowId = movieShowId; - this.theatreId = theatreId; this.customerId = customerId; this.seats = seats; this.amount = amount; - this.status = Status.INITIAL; + this.status = status; + } + + public Booking(BookingServicePort.BookingRequest request) { + this.bookingId = UUID.randomUUID().toString(); + this.movieShowId = request.getMovieShowId(); + this.customerId = request.getCustomerId(); + this.seats = request.getSeats(); + this.amount = request.getAmount(); + this.status = STATUS_INITIAL; } public String getMovieShowId() { return movieShowId; } - public String getTheatreId() { - return theatreId; - } - public Set getSeats() { return seats; } @@ -50,7 +57,7 @@ public class Booking { return amount; } - public Status getStatus() { + public String getStatus() { return status; } @@ -62,10 +69,6 @@ public class Booking { this.movieShowId = movieShowId; } - public void setTheatreId(String theatreId) { - this.theatreId = theatreId; - } - public void setCustomerId(String customerId) { this.customerId = customerId; } @@ -78,7 +81,7 @@ public class Booking { this.amount = amount; } - public void setStatus(Status status) { + public void setStatus(String status) { this.status = status; } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java index 333cbee889..eb018e69b2 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java @@ -10,12 +10,12 @@ import java.util.UUID; @Service public class MockTheatreService implements TheatreService { - public ResponseEntity postReservation(String theatreId, String movieShowId, Set seats) { - return new ResponseEntity( + public ResponseEntity postReservation(String movieShowId, Set seats) { + return new ResponseEntity<>( new Reservation(UUID.randomUUID().toString()), HttpStatus.CREATED); } - public ResponseEntity deleteReservation(String reservationId) { - return new ResponseEntity(HttpStatus.NO_CONTENT); + public ResponseEntity deleteReservation(String reservationId) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java index 48f0c5e15d..8107bfb418 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java @@ -6,9 +6,9 @@ import java.util.Set; public interface TheatreService { - ResponseEntity postReservation(String theatreId, String movieShowId, Set seats); + ResponseEntity postReservation(String movieShowId, Set seats); - ResponseEntity deleteReservation(String reservationId); + ResponseEntity deleteReservation(String reservationId); class Reservation { private final String id; diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java index 0deffb42e0..c1d1d73630 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java @@ -4,4 +4,5 @@ import com.baeldung.hexagonal.domain.Booking; public interface BookingPersistencePort { boolean persist(Booking booking); + public boolean updateStatus(String bookingId, String status); } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java index 3b444df4f6..12710a6014 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java @@ -9,7 +9,6 @@ public interface BookingServicePort { class BookingRequest { private String movieShowId; private String customerId; - private String theatreId; private Set seats; private Double amount; @@ -29,14 +28,6 @@ public interface BookingServicePort { this.customerId = customerId; } - public String getTheatreId() { - return theatreId; - } - - public void setTheatreId(String theatreId) { - this.theatreId = theatreId; - } - public Set getSeats() { return seats; } @@ -61,6 +52,12 @@ public interface BookingServicePort { public static final int UNKNOWN_ERROR = 3; private final int statusCode; + private String bookingId; + + public BookingResponse(String bookingId, int statusCode) { + this.bookingId = bookingId; + this.statusCode = statusCode; + } public BookingResponse(int statusCode) { this.statusCode = statusCode; @@ -69,5 +66,8 @@ public interface BookingServicePort { public int getStatusCode() { return statusCode; } + public String getBookingId() { + return bookingId; + } } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java index dac517c724..8e5fab8b46 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java @@ -4,6 +4,6 @@ import java.util.Optional; import java.util.Set; public interface TheatreServicePort { - Optional reserveSeats(String theatreId, String movieShowId, Set seats); + Optional reserveSeats(String movieShowId, Set seats); boolean releaseSeats(String resrevationId); } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java index c56ffe1308..7dd20290ba 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java @@ -5,4 +5,5 @@ import com.baeldung.hexagonal.domain.Booking; public interface BookingRepository { boolean save(Booking booking); + boolean updateStatus(String bookingId, String status); } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java index d378cff0af..1738e606d0 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java @@ -8,4 +8,9 @@ public class MockBookingRepository implements BookingRepository { public boolean save(Booking booking) { return true; } + + @Override + public boolean updateStatus(String bookingId, String status) { + return true; + } } diff --git a/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java b/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java index 7d9db9724e..8d3112bd37 100644 --- a/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java +++ b/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java @@ -9,8 +9,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Optional; -import java.util.UUID; +import static com.baeldung.hexagonal.domain.Booking.STATUS_FAILURE; +import static com.baeldung.hexagonal.domain.Booking.STATUS_SUCCESS; import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; @Component @@ -29,39 +30,28 @@ public class BookTicketUseCase implements BookingServicePort { public BookingResponse book(BookingRequest request) { - Booking booking = new Booking( - UUID.randomUUID().toString(), - request.getMovieShowId(), - request.getTheatreId(), - request.getCustomerId(), - request.getSeats(), - request.getAmount(), - Booking.Status.INITIAL); + Booking booking = new Booking(request); if (!bookingPersistencePort.persist(booking)) { return new BookingResponse(UNKNOWN_ERROR); } - Optional reservationIdOptional = theatreServicePort.reserveSeats( - booking.getTheatreId(), - booking.getMovieShowId(), - booking.getSeats()); + String bookingId = booking.getBookingId(); + + Optional reservationIdOptional = theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats()); if (!reservationIdOptional.isPresent()) { - booking.setStatus(Booking.Status.FAILURE); - bookingPersistencePort.persist(booking); - return new BookingResponse(SEAT_NOT_AVAILABLE); + bookingPersistencePort.updateStatus(bookingId, STATUS_FAILURE); + return new BookingResponse(bookingId, SEAT_NOT_AVAILABLE); } if (!walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) { reservationIdOptional.ifPresent(reservationId -> theatreServicePort.releaseSeats(reservationId)); - booking.setStatus(Booking.Status.FAILURE); - bookingPersistencePort.persist(booking); - return new BookingResponse(PAYMENT_FAILED); + bookingPersistencePort.updateStatus(bookingId, STATUS_FAILURE); + return new BookingResponse(bookingId, PAYMENT_FAILED); } - booking.setStatus(Booking.Status.SUCCESS); - bookingPersistencePort.persist(booking); + bookingPersistencePort.updateStatus(bookingId, STATUS_SUCCESS); - return new BookingResponse(SUCCESS); + return new BookingResponse(bookingId, SUCCESS); } } diff --git a/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java index 76d853fdda..cb22f5f37a 100644 --- a/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java +++ b/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java @@ -30,7 +30,6 @@ class RestAPIEndpointAdapterUnitTest { private BookingServicePort.BookingRequest getBookingRequest() { BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); - request.setTheatreId("theatre-id"); request.setMovieShowId("movie-show-id"); request.setCustomerId("customer-id"); request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); @@ -47,7 +46,7 @@ class RestAPIEndpointAdapterUnitTest { verify(bookingServicePort).book(any(BookingRequest.class)); assertNotNull(response); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); } @Test @@ -59,7 +58,7 @@ class RestAPIEndpointAdapterUnitTest { verify(bookingServicePort).book(any(BookingRequest.class)); assertNotNull(response); - assertEquals(HttpStatus.PRECONDITION_FAILED, response.getStatusCode()); + assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); } @Test @@ -71,7 +70,7 @@ class RestAPIEndpointAdapterUnitTest { verify(bookingServicePort).book(any(BookingRequest.class)); assertNotNull(response); - assertEquals(HttpStatus.PRECONDITION_FAILED, response.getStatusCode()); + assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); } @Test diff --git a/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java index eec2b65609..ffb4246f79 100644 --- a/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java +++ b/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java @@ -34,7 +34,6 @@ class BookTicketUseCaseUnitTest { private BookingServicePort.BookingRequest getBookingRequest() { BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); - request.setTheatreId("theatre-id"); request.setMovieShowId("movie-show-id"); request.setCustomerId("customer-id"); request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); @@ -42,21 +41,10 @@ class BookTicketUseCaseUnitTest { return request; } - private Booking getBooking(BookingServicePort.BookingRequest request) { - return new Booking( - "booking-id", - request.getMovieShowId(), - request.getTheatreId(), - request.getCustomerId(), - request.getSeats(), - request.getAmount(), - Booking.Status.INITIAL); - } - @Test void whenErrorInInitialPersistence_thenReturnUnknownError() { BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = getBooking(request); + Booking booking = new Booking(request); when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(false); BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); @@ -68,14 +56,15 @@ class BookTicketUseCaseUnitTest { @Test void whenErrorInReserveSeats_thenReturnSeatNotAvailable() { BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = getBooking(request); + Booking booking = new Booking(request); when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) .thenReturn(Optional.empty()); BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); - verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + verify(bookingPersistencePort).persist(any(Booking.class)); + verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); + verify(theatreServicePort).reserveSeats(any(String.class), any(HashSet.class)); assertNotNull(response); assertEquals(BookingServicePort.BookingResponse.SEAT_NOT_AVAILABLE, response.getStatusCode()); } @@ -83,16 +72,17 @@ class BookTicketUseCaseUnitTest { @Test void whenErrorInWalletDebit_thenReturnPaymentFailed() { BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = getBooking(request); + Booking booking = new Booking(request); when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) .thenReturn(Optional.of("reservation-id")); when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) .thenReturn(false); BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); - verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + verify(bookingPersistencePort).persist(any(Booking.class)); + verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); + verify(theatreServicePort).reserveSeats(any(String.class), any(HashSet.class)); verify(walletServicePort).debit(any(String.class), any(Double.class)); verify(theatreServicePort).releaseSeats(any(String.class)); assertNotNull(response); @@ -102,16 +92,17 @@ class BookTicketUseCaseUnitTest { @Test void whenNoErrorInAnyPorts_thenReturnSuccess() { BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = getBooking(request); + Booking booking = new Booking(request); when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getTheatreId(), booking.getMovieShowId(), booking.getSeats())) + when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) .thenReturn(Optional.of("reservation-id")); when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) .thenReturn(true); BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - verify(bookingPersistencePort, times(2)).persist(any(Booking.class)); - verify(theatreServicePort).reserveSeats(any(String.class), any(String.class), any(HashSet.class)); + verify(bookingPersistencePort).persist(any(Booking.class)); + verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); + verify(theatreServicePort).reserveSeats( any(String.class), any(HashSet.class)); verify(walletServicePort).debit(any(String.class), any(Double.class)); assertNotNull(response); assertEquals(BookingServicePort.BookingResponse.SUCCESS, response.getStatusCode()); From e2f8cdd817fb41f5cf9ece68e32151f4181139b0 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Fri, 15 Oct 2021 08:36:43 +0530 Subject: [PATCH 03/31] Serialization Validation initial commit Changes for Adding Tests Serialization Validation 1: Added utility Method. 2: Added Tests --- core-java-modules/core-java/pom.xml | 6 ++ .../com/baeldung/util/SerializationUtils.java | 29 +++++++ .../serialization/SerializationUnitTest.java | 79 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java create mode 100644 core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index db2b1edc70..00f26b0e0a 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -61,6 +61,11 @@ moneta ${javamoney.moneta.version} + + org.springframework + spring-core + ${spring.core.version} + @@ -187,6 +192,7 @@ 3.0.0-M1 1.8 1.8 + 4.3.20.RELEASE \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java new file mode 100644 index 0000000000..eb5eb6aac1 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java @@ -0,0 +1,29 @@ +package com.baeldung.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class SerializationUtils { + + public static byte[] serialize(T obj) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + public static T deserialize(byte[] b, Class cl) + throws IOException, ClassNotFoundException { + ByteArrayInputStream bais = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bais); + Object o = ois.readObject(); + return cl.cast(o); + } +} + diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java new file mode 100644 index 0000000000..9be174e42d --- /dev/null +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.serialization; + +import static org.junit.Assert.assertTrue; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import org.apache.commons.lang3.SerializationUtils; +import org.junit.Test; + +public class SerializationUnitTest { + + @Test(expected = NotSerializableException.class) + public void whenSerializing_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(address); + } + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingApacheCommons_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + SerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = SerializationUtils.serialize(p); + Person p2 = (Person) SerializationUtils.deserialize(serialize); + assertTrue(p2.getAge() == p.getAge()); + assertTrue(p2.getName().equals(p.getName())); + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + org.springframework.util.SerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = org.springframework.util.SerializationUtils.serialize(p); + Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize); + assertTrue(p2.getAge() == p.getAge()); + assertTrue(p2.getName().equals(p.getName())); + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + com.baeldung.util.SerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = com.baeldung.util.SerializationUtils.serialize(p); + Person p2 = com.baeldung.util.SerializationUtils.deserialize(serialize, Person.class); + assertTrue(p2.getAge() == p.getAge()); + assertTrue(p2.getName().equals(p.getName())); + } +} From e0ca51411858c19c761eb42d8abb68bce0d088b7 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Fri, 15 Oct 2021 09:13:02 +0530 Subject: [PATCH 04/31] Method for validation of Serializable Objects Method for validation of Serializable Objects --- .../main/java/com/baeldung/util/SerializationUtils.java | 4 ++++ .../com/baeldung/serialization/SerializationUnitTest.java | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java index eb5eb6aac1..da884d0b9b 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java @@ -25,5 +25,9 @@ public class SerializationUtils { Object o = ois.readObject(); return cl.cast(o); } + + public static boolean isSerializable(Class it) { + return it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + } } diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java index 9be174e42d..376bd370f5 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -1,6 +1,7 @@ package com.baeldung.serialization; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import java.io.FileOutputStream; import java.io.IOException; @@ -76,4 +77,11 @@ public class SerializationUnitTest { assertTrue(p2.getAge() == p.getAge()); assertTrue(p2.getName().equals(p.getName())); } + + @Test + public void whenSerializingUsingCustomSerializationUtils_ThanOk(){ + assertFalse(com.baeldung.util.SerializationUtils.isSerializable(Address.class)); + assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Person.class)); + assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Integer.class)); + } } From 98528e849ea5376b6beda828391306a01554ecc8 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Fri, 15 Oct 2021 09:26:11 +0530 Subject: [PATCH 05/31] Style Correction Style Correction --- .../com/baeldung/util/SerializationUtils.java | 38 +++++++++---------- .../serialization/SerializationUnitTest.java | 5 ++- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java index da884d0b9b..7ebff1a113 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java @@ -9,25 +9,23 @@ import java.io.Serializable; public class SerializationUtils { - public static byte[] serialize(T obj) - throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(obj); - oos.close(); - return baos.toByteArray(); + public static byte[] serialize(T obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); } - - public static T deserialize(byte[] b, Class cl) - throws IOException, ClassNotFoundException { - ByteArrayInputStream bais = new ByteArrayInputStream(b); - ObjectInputStream ois = new ObjectInputStream(bais); - Object o = ois.readObject(); - return cl.cast(o); - } - - public static boolean isSerializable(Class it) { - return it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); - } -} + public static T deserialize(byte[] b, Class cl) + throws IOException, ClassNotFoundException { + ByteArrayInputStream bais = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bais); + Object o = ois.readObject(); + return cl.cast(o); + } + + public static boolean isSerializable(Class it) { + return it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + } +} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java index 376bd370f5..b5795d362c 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -68,7 +68,8 @@ public class SerializationUnitTest { } @Test - public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() + throws IOException, ClassNotFoundException { Person p = new Person(); p.setAge(20); p.setName("Joe"); @@ -79,7 +80,7 @@ public class SerializationUnitTest { } @Test - public void whenSerializingUsingCustomSerializationUtils_ThanOk(){ + public void whenSerializingUsingCustomSerializationUtils_ThanOk() { assertFalse(com.baeldung.util.SerializationUtils.isSerializable(Address.class)); assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Person.class)); assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Integer.class)); From 008e340482d77a0a1329dd49b56c9e9acd199e40 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Fri, 15 Oct 2021 19:25:52 +0530 Subject: [PATCH 06/31] Update SerializationUtils.java Updating serialization Utils --- .../java/com/baeldung/util/SerializationUtils.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java index 7ebff1a113..429325eb43 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.lang.reflect.Field; public class SerializationUtils { @@ -26,6 +27,15 @@ public class SerializationUtils { } public static boolean isSerializable(Class it) { - return it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + if(!serializable) { + return serializable; + } + Field[] declaredFields = it.getDeclaredFields(); + for(Field field: declaredFields) { + Class fieldType = field.getType(); + return isSerializable(fieldType); + } + return serializable; } } From 2fa7ea1f22e41082f70350f39b436023e5a390f0 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Tue, 19 Oct 2021 07:24:07 +0530 Subject: [PATCH 07/31] Changes to PO Changes to add transition and volatile --- .../java/com/baeldung/util/SerializationUtils.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java index 429325eb43..2a9391965f 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java @@ -7,6 +7,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; public class SerializationUtils { @@ -28,11 +29,16 @@ public class SerializationUtils { public static boolean isSerializable(Class it) { boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); - if(!serializable) { + if (!serializable) { return serializable; } Field[] declaredFields = it.getDeclaredFields(); - for(Field field: declaredFields) { + for (Field field : declaredFields) { + if (Modifier.isVolatile(field.getModifiers()) + || Modifier.isTransient(field.getModifiers()) + || Modifier.isStatic(field.getModifiers())) { + continue; + } Class fieldType = field.getType(); return isSerializable(fieldType); } From 40c6b489d8a55ffa7f46448c5e3b8debfe34b357 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Sun, 24 Oct 2021 07:03:35 +0530 Subject: [PATCH 08/31] Update SerializationUnitTest.java Changes to add more tests. --- .../serialization/SerializationUnitTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java index b5795d362c..e0ee2bb654 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -3,9 +3,11 @@ package com.baeldung.serialization; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.NotSerializableException; +import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; @@ -23,6 +25,25 @@ public class SerializationUnitTest { objectOutputStream.writeObject(address); } } + + @Test + public void whenSerializingAndDeserializing_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + + FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(p); + } + + FileInputStream fileInputStream = new FileInputStream("yofile.txt"); + try ( ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) { + Person p2 = (Person) objectInputStream.readObject(); + assertTrue(p2.getAge() == p.getAge()); + assertTrue(p2.getName().equals(p.getName())); + } + } @Test(expected = ClassCastException.class) public void whenSerializingUsingApacheCommons_ThenThrowsError() { From c06df0225cff88ca3902c74f0c37b10602952567 Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Sat, 30 Oct 2021 01:18:37 +0200 Subject: [PATCH 09/31] BAEL-4546: sample app to show-case docker compose with the latest image --- docker/docker-sample-app/Dockerfile | 3 + docker/docker-sample-app/README.md | 3 + .../docker-compose-build-image.yaml | 8 + .../docker-compose-with-image.yaml | 9 + docker/docker-sample-app/mvnw | 310 ++++++++++++++++++ docker/docker-sample-app/mvnw.cmd | 182 ++++++++++ docker/docker-sample-app/pom.xml | 45 +++ .../personal/dockapp/DockAppApplication.java | 13 + .../dockapp/endpoint/MyController.java | 13 + .../src/main/resources/application.properties | 1 + .../dockapp/DockAppApplicationUnitTest.java | 13 + docker/pom.xml | 1 + 12 files changed, 601 insertions(+) create mode 100644 docker/docker-sample-app/Dockerfile create mode 100644 docker/docker-sample-app/README.md create mode 100644 docker/docker-sample-app/docker-compose-build-image.yaml create mode 100644 docker/docker-sample-app/docker-compose-with-image.yaml create mode 100755 docker/docker-sample-app/mvnw create mode 100644 docker/docker-sample-app/mvnw.cmd create mode 100644 docker/docker-sample-app/pom.xml create mode 100644 docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java create mode 100644 docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java create mode 100644 docker/docker-sample-app/src/main/resources/application.properties create mode 100644 docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java diff --git a/docker/docker-sample-app/Dockerfile b/docker/docker-sample-app/Dockerfile new file mode 100644 index 0000000000..71fc1a29d9 --- /dev/null +++ b/docker/docker-sample-app/Dockerfile @@ -0,0 +1,3 @@ +FROM openjdk:11 +COPY target/docker-sample-app-0.0.1.jar app.jar +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/docker/docker-sample-app/README.md b/docker/docker-sample-app/README.md new file mode 100644 index 0000000000..6aeaa1d2a3 --- /dev/null +++ b/docker/docker-sample-app/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- How to Get Docker-Compose to Always Use the Latest Image diff --git a/docker/docker-sample-app/docker-compose-build-image.yaml b/docker/docker-sample-app/docker-compose-build-image.yaml new file mode 100644 index 0000000000..27c1d8ee44 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-build-image.yaml @@ -0,0 +1,8 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + build: . + ports: + - "8080:8080" diff --git a/docker/docker-sample-app/docker-compose-with-image.yaml b/docker/docker-sample-app/docker-compose-with-image.yaml new file mode 100644 index 0000000000..9a8822f762 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-with-image.yaml @@ -0,0 +1,9 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + image: "eugen/test-app:latest" + ports: + - "8080:8080" + diff --git a/docker/docker-sample-app/mvnw b/docker/docker-sample-app/mvnw new file mode 100755 index 0000000000..a16b5431b4 --- /dev/null +++ b/docker/docker-sample-app/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/docker/docker-sample-app/mvnw.cmd b/docker/docker-sample-app/mvnw.cmd new file mode 100644 index 0000000000..c8d43372c9 --- /dev/null +++ b/docker/docker-sample-app/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml new file mode 100644 index 0000000000..416ec45b10 --- /dev/null +++ b/docker/docker-sample-app/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.baeldung.docker + docker + 0.0.1 + + + docker-sample-app + docker-sample-app + Demo project for Spring Boot and Docker + + + 11 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java b/docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java new file mode 100644 index 0000000000..b0f031d25a --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java @@ -0,0 +1,13 @@ +package com.personal.dockapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DockAppApplication { + + public static void main(String[] args) { + SpringApplication.run(DockAppApplication.class, args); + } + +} diff --git a/docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java b/docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java new file mode 100644 index 0000000000..bf2886f19d --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java @@ -0,0 +1,13 @@ +package com.personal.dockapp.endpoint; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MyController { + + @GetMapping + public String version() { + return "1.7"; + } +} diff --git a/docker/docker-sample-app/src/main/resources/application.properties b/docker/docker-sample-app/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/docker/docker-sample-app/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java b/docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java new file mode 100644 index 0000000000..2f8abafe70 --- /dev/null +++ b/docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java @@ -0,0 +1,13 @@ +package com.personal.dockapp; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DockAppApplicationUnitTest { + + @Test + void contextLoads() { + } + +} diff --git a/docker/pom.xml b/docker/pom.xml index 3fcc9ca94f..0a397dd966 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -25,6 +25,7 @@ docker-internal-dto docker-spring-boot + docker-sample-app From 1e9e55daf9adc04fd8f9d959da452017603742fb Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Sat, 30 Oct 2021 01:39:48 +0200 Subject: [PATCH 10/31] BAEL-4546: formatting changes --- .../docker/app}/DockAppApplication.java | 8 ++++---- .../docker/app}/endpoint/MyController.java | 2 +- .../docker/app}/DockAppApplicationUnitTest.java | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) rename docker/docker-sample-app/src/main/java/com/{personal/dockapp => baeldung/docker/app}/DockAppApplication.java (55%) rename docker/docker-sample-app/src/main/java/com/{personal/dockapp => baeldung/docker/app}/endpoint/MyController.java (85%) rename docker/docker-sample-app/src/test/java/com/{personal/dockapp => baeldung/docker/app}/DockAppApplicationUnitTest.java (67%) diff --git a/docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java similarity index 55% rename from docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java rename to docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java index b0f031d25a..e7ff52015c 100644 --- a/docker/docker-sample-app/src/main/java/com/personal/dockapp/DockAppApplication.java +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java @@ -1,4 +1,4 @@ -package com.personal.dockapp; +package com.baeldung.docker.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DockAppApplication { - public static void main(String[] args) { - SpringApplication.run(DockAppApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(DockAppApplication.class, args); + } } diff --git a/docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java similarity index 85% rename from docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java rename to docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java index bf2886f19d..d46c57e606 100644 --- a/docker/docker-sample-app/src/main/java/com/personal/dockapp/endpoint/MyController.java +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java @@ -1,4 +1,4 @@ -package com.personal.dockapp.endpoint; +package com.baeldung.docker.app.endpoint; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java similarity index 67% rename from docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java rename to docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java index 2f8abafe70..7220766988 100644 --- a/docker/docker-sample-app/src/test/java/com/personal/dockapp/DockAppApplicationUnitTest.java +++ b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java @@ -1,4 +1,4 @@ -package com.personal.dockapp; +package com.baeldung.docker.app; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -6,8 +6,8 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class DockAppApplicationUnitTest { - @Test - void contextLoads() { - } + @Test + void contextLoads() { + } } From e29cfda933ba0ecbc16d969dba0bb53b9ccd8683 Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Sat, 30 Oct 2021 02:01:47 +0200 Subject: [PATCH 11/31] BAEL-4546: Reverting evaluation article code --- .../hexagonal/HexagonalSpringApplication.java | 20 ---- .../adapter/BookingPersistenceAdapter.java | 22 ---- .../adapter/RestAPIEndpointAdapter.java | 32 ----- .../adapter/TheatreServiceAdapter.java | 30 ----- .../adapter/WalletServiceAdapter.java | 19 --- .../baeldung/hexagonal/domain/Booking.java | 87 -------------- .../service/CustomerWalletService.java | 8 -- .../service/MockCustomerWalletService.java | 11 -- .../external/service/MockTheatreService.java | 21 ---- .../external/service/TheatreService.java | 24 ---- .../port/BookingPersistencePort.java | 8 -- .../hexagonal/port/BookingServicePort.java | 73 ------------ .../hexagonal/port/TheatreServicePort.java | 9 -- .../hexagonal/port/WalletServicePort.java | 5 - .../repository/BookingRepository.java | 9 -- .../repository/MockBookingRepository.java | 16 --- .../hexagonal/usecase/BookTicketUseCase.java | 57 --------- .../RestAPIEndpointAdapterUnitTest.java | 87 -------------- .../usecase/BookTicketUseCaseUnitTest.java | 110 ------------------ 19 files changed, 648 deletions(-) delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java delete mode 100644 ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java delete mode 100644 ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java delete mode 100644 ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java diff --git a/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java b/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java deleted file mode 100644 index c679d459f0..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/HexagonalSpringApplication.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.hexagonal; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; - - -@SpringBootApplication(exclude={ - CassandraAutoConfiguration.class, - MongoDataAutoConfiguration.class, - MongoAutoConfiguration.class -}) -public class HexagonalSpringApplication { - - public static void main(final String[] args) { - SpringApplication.run(HexagonalSpringApplication.class, args); - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java deleted file mode 100644 index 1b191bde86..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/BookingPersistenceAdapter.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.baeldung.hexagonal.adapter; - -import com.baeldung.hexagonal.domain.Booking; -import com.baeldung.hexagonal.port.BookingPersistencePort; -import com.baeldung.hexagonal.repository.BookingRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class BookingPersistenceAdapter implements BookingPersistencePort { - - @Autowired - private BookingRepository bookingRepository; - - public boolean persist(Booking booking) { - return bookingRepository.save(booking); - } - - public boolean updateStatus(String bookingId, String status) { - return bookingRepository.updateStatus(bookingId, status); - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java deleted file mode 100644 index 3e1b1fc90f..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.hexagonal.adapter; - -import com.baeldung.hexagonal.port.BookingServicePort; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import static com.baeldung.hexagonal.port.BookingServicePort.BookingRequest; -import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse; -import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.SUCCESS; -import static org.springframework.http.HttpStatus.CREATED; -import static org.springframework.http.HttpStatus.FAILED_DEPENDENCY; - -@RestController -public class RestAPIEndpointAdapter { - - private BookingServicePort bookingServicePort; - - @Autowired - public RestAPIEndpointAdapter(BookingServicePort bookingServicePort) { - this.bookingServicePort = bookingServicePort; - } - - @PostMapping(path = "/booking") - public ResponseEntity createBooking(@RequestBody BookingRequest request) { - BookingResponse response = bookingServicePort.book(request); - return new ResponseEntity<>(response, - response.getStatusCode() == SUCCESS ? CREATED : FAILED_DEPENDENCY); - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java deleted file mode 100644 index fa19483b13..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/TheatreServiceAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.hexagonal.adapter; - -import com.baeldung.hexagonal.external.service.TheatreService; -import com.baeldung.hexagonal.port.TheatreServicePort; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import java.util.Optional; -import java.util.Set; - -import static com.baeldung.hexagonal.external.service.TheatreService.Reservation; -import static org.springframework.http.HttpStatus.CREATED; -import static org.springframework.http.HttpStatus.NO_CONTENT; - -@Component -public class TheatreServiceAdapter implements TheatreServicePort { - - @Autowired - private TheatreService theatreService; - - public Optional reserveSeats(String movieShowId, Set seats) { - ResponseEntity response = theatreService.postReservation(movieShowId, seats); - return response.getStatusCode() == CREATED ? Optional.of(response.getBody().getId()): Optional.empty(); - } - - public boolean releaseSeats(String resrevationId) { - return theatreService.deleteReservation(resrevationId).getStatusCode() == NO_CONTENT; - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java b/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java deleted file mode 100644 index 1d8db867b7..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/adapter/WalletServiceAdapter.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.hexagonal.adapter; - -import com.baeldung.hexagonal.external.service.CustomerWalletService; -import com.baeldung.hexagonal.port.WalletServicePort; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import static org.springframework.http.HttpStatus.CREATED; - -@Component -public class WalletServiceAdapter implements WalletServicePort { - - @Autowired - private CustomerWalletService customerWalletService; - - public boolean debit(String customerId, Double amount) { - return customerWalletService.postDebit(customerId, amount) == CREATED; - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java b/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java deleted file mode 100644 index ed9b7281f2..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/domain/Booking.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import com.baeldung.hexagonal.port.BookingServicePort; - -import java.util.Set; -import java.util.UUID; - -public class Booking { - - public static final String STATUS_INITIAL = "INITIAL"; - public static final String STATUS_SUCCESS = "SUCCESS"; - public static final String STATUS_FAILURE = "FAILED"; - - private String bookingId; - private String movieShowId; - private String customerId; - private Set seats; - private Double amount; - private String status; - - public Booking( - String bookingId, String movieShowId, String customerId, Set seats, Double amount, String status) { - this.bookingId = bookingId; - this.movieShowId = movieShowId; - this.customerId = customerId; - this.seats = seats; - this.amount = amount; - this.status = status; - } - - public Booking(BookingServicePort.BookingRequest request) { - this.bookingId = UUID.randomUUID().toString(); - this.movieShowId = request.getMovieShowId(); - this.customerId = request.getCustomerId(); - this.seats = request.getSeats(); - this.amount = request.getAmount(); - this.status = STATUS_INITIAL; - } - - public String getMovieShowId() { - return movieShowId; - } - - public Set getSeats() { - return seats; - } - - public String getCustomerId() { - return customerId; - } - - public String getBookingId() { - return bookingId; - } - - public Double getAmount() { - return amount; - } - - public String getStatus() { - return status; - } - - public void setBookingId(String bookingId) { - this.bookingId = bookingId; - } - - public void setMovieShowId(String movieShowId) { - this.movieShowId = movieShowId; - } - - public void setCustomerId(String customerId) { - this.customerId = customerId; - } - - public void setSeats(Set seats) { - this.seats = seats; - } - - public void setAmount(Double amount) { - this.amount = amount; - } - - public void setStatus(String status) { - this.status = status; - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java deleted file mode 100644 index 102cef788e..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/CustomerWalletService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.external.service; - -import org.springframework.http.HttpStatus; - -public interface CustomerWalletService { - - HttpStatus postDebit(String customerId, Double amount); -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java deleted file mode 100644 index 4a76368b19..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockCustomerWalletService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.hexagonal.external.service; - -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Service; - -@Service -public class MockCustomerWalletService implements CustomerWalletService { - public HttpStatus postDebit(String customerId, Double amount) { - return HttpStatus.CREATED; - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java deleted file mode 100644 index eb018e69b2..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/MockTheatreService.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.hexagonal.external.service; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; - -import java.util.Set; -import java.util.UUID; - -@Service -public class MockTheatreService implements TheatreService { - - public ResponseEntity postReservation(String movieShowId, Set seats) { - return new ResponseEntity<>( - new Reservation(UUID.randomUUID().toString()), HttpStatus.CREATED); - } - - public ResponseEntity deleteReservation(String reservationId) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java b/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java deleted file mode 100644 index 8107bfb418..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/external/service/TheatreService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.hexagonal.external.service; - -import org.springframework.http.ResponseEntity; - -import java.util.Set; - -public interface TheatreService { - - ResponseEntity postReservation(String movieShowId, Set seats); - - ResponseEntity deleteReservation(String reservationId); - - class Reservation { - private final String id; - - public Reservation(String id) { - this.id = id; - } - - public String getId() { - return id; - } - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java deleted file mode 100644 index c1d1d73630..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingPersistencePort.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.port; - -import com.baeldung.hexagonal.domain.Booking; - -public interface BookingPersistencePort { - boolean persist(Booking booking); - public boolean updateStatus(String bookingId, String status); -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java deleted file mode 100644 index 12710a6014..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/BookingServicePort.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.baeldung.hexagonal.port; - -import java.util.Set; - -public interface BookingServicePort { - - BookingResponse book(BookingRequest request); - - class BookingRequest { - private String movieShowId; - private String customerId; - private Set seats; - private Double amount; - - public String getMovieShowId() { - return movieShowId; - } - - public void setMovieShowId(String movieShowId) { - this.movieShowId = movieShowId; - } - - public String getCustomerId() { - return customerId; - } - - public void setCustomerId(String customerId) { - this.customerId = customerId; - } - - public Set getSeats() { - return seats; - } - - public void setSeats(Set seats) { - this.seats = seats; - } - - public Double getAmount() { - return amount; - } - - public void setAmount(Double amount) { - this.amount = amount; - } - } - - class BookingResponse { - public static final int SUCCESS = 0; - public static final int SEAT_NOT_AVAILABLE = 1; - public static final int PAYMENT_FAILED = 2; - public static final int UNKNOWN_ERROR = 3; - - private final int statusCode; - private String bookingId; - - public BookingResponse(String bookingId, int statusCode) { - this.bookingId = bookingId; - this.statusCode = statusCode; - } - - public BookingResponse(int statusCode) { - this.statusCode = statusCode; - } - - public int getStatusCode() { - return statusCode; - } - public String getBookingId() { - return bookingId; - } - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java deleted file mode 100644 index 8e5fab8b46..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/TheatreServicePort.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.hexagonal.port; - -import java.util.Optional; -import java.util.Set; - -public interface TheatreServicePort { - Optional reserveSeats(String movieShowId, Set seats); - boolean releaseSeats(String resrevationId); -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java b/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java deleted file mode 100644 index 102bb619e8..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/port/WalletServicePort.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.hexagonal.port; - -public interface WalletServicePort { - boolean debit(String customerId, Double amount); -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java deleted file mode 100644 index 7dd20290ba..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/repository/BookingRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.hexagonal.repository; - -import com.baeldung.hexagonal.domain.Booking; - -public interface BookingRepository { - - boolean save(Booking booking); - boolean updateStatus(String bookingId, String status); -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java b/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java deleted file mode 100644 index 1738e606d0..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/repository/MockBookingRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.hexagonal.repository; - -import com.baeldung.hexagonal.domain.Booking; -import org.springframework.stereotype.Repository; - -@Repository -public class MockBookingRepository implements BookingRepository { - public boolean save(Booking booking) { - return true; - } - - @Override - public boolean updateStatus(String bookingId, String status) { - return true; - } -} diff --git a/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java b/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java deleted file mode 100644 index 8d3112bd37..0000000000 --- a/ddd/src/main/java/com/baeldung/hexagonal/usecase/BookTicketUseCase.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.baeldung.hexagonal.usecase; - -import com.baeldung.hexagonal.domain.Booking; -import com.baeldung.hexagonal.port.BookingPersistencePort; -import com.baeldung.hexagonal.port.BookingServicePort; -import com.baeldung.hexagonal.port.TheatreServicePort; -import com.baeldung.hexagonal.port.WalletServicePort; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.Optional; - -import static com.baeldung.hexagonal.domain.Booking.STATUS_FAILURE; -import static com.baeldung.hexagonal.domain.Booking.STATUS_SUCCESS; -import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; - -@Component -public class BookTicketUseCase implements BookingServicePort { - - private BookingPersistencePort bookingPersistencePort; - private TheatreServicePort theatreServicePort; - private WalletServicePort walletServicePort; - - @Autowired - public BookTicketUseCase(BookingPersistencePort bookingPersistencePort, TheatreServicePort theatreServicePort, WalletServicePort walletServicePort) { - this.bookingPersistencePort = bookingPersistencePort; - this.theatreServicePort = theatreServicePort; - this.walletServicePort = walletServicePort; - } - - public BookingResponse book(BookingRequest request) { - - Booking booking = new Booking(request); - - if (!bookingPersistencePort.persist(booking)) { - return new BookingResponse(UNKNOWN_ERROR); - } - - String bookingId = booking.getBookingId(); - - Optional reservationIdOptional = theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats()); - if (!reservationIdOptional.isPresent()) { - bookingPersistencePort.updateStatus(bookingId, STATUS_FAILURE); - return new BookingResponse(bookingId, SEAT_NOT_AVAILABLE); - } - - if (!walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) { - reservationIdOptional.ifPresent(reservationId -> theatreServicePort.releaseSeats(reservationId)); - bookingPersistencePort.updateStatus(bookingId, STATUS_FAILURE); - return new BookingResponse(bookingId, PAYMENT_FAILED); - } - - bookingPersistencePort.updateStatus(bookingId, STATUS_SUCCESS); - - return new BookingResponse(bookingId, SUCCESS); - } -} diff --git a/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java deleted file mode 100644 index cb22f5f37a..0000000000 --- a/ddd/src/test/java/com/baeldung/hexagonal/adapter/RestAPIEndpointAdapterUnitTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.baeldung.hexagonal.adapter; - -import com.baeldung.hexagonal.port.BookingServicePort; -import com.baeldung.hexagonal.port.BookingServicePort.BookingRequest; -import com.baeldung.hexagonal.port.BookingServicePort.BookingResponse; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import java.util.Arrays; -import java.util.HashSet; - -import static com.baeldung.hexagonal.port.BookingServicePort.BookingResponse.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -class RestAPIEndpointAdapterUnitTest { - - private BookingServicePort bookingServicePort; - private RestAPIEndpointAdapter restAPIEndpointAdapter; - - @BeforeEach - void setUp() { - bookingServicePort = mock(BookingServicePort.class); - restAPIEndpointAdapter = new RestAPIEndpointAdapter(bookingServicePort); - } - - private BookingServicePort.BookingRequest getBookingRequest() { - BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); - request.setMovieShowId("movie-show-id"); - request.setCustomerId("customer-id"); - request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); - request.setAmount(100.00); - return request; - } - - @Test - void whenBookingServicePortReturnsUnknownError_thenReturnInternalServerError() { - BookingServicePort.BookingRequest request = getBookingRequest(); - when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(UNKNOWN_ERROR)); - - ResponseEntity response = restAPIEndpointAdapter.createBooking(request); - - verify(bookingServicePort).book(any(BookingRequest.class)); - assertNotNull(response); - assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); - } - - @Test - void whenBookingServicePortReturnsSeatUnavailable_thenReturnPreconditionFailed() { - BookingServicePort.BookingRequest request = getBookingRequest(); - when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(SEAT_NOT_AVAILABLE)); - - ResponseEntity response = restAPIEndpointAdapter.createBooking(request); - - verify(bookingServicePort).book(any(BookingRequest.class)); - assertNotNull(response); - assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); - } - - @Test - void whenBookingServicePortReturnsPaymentFailed_thenReturnPreconditionFailed() { - BookingServicePort.BookingRequest request = getBookingRequest(); - when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(PAYMENT_FAILED)); - - ResponseEntity response = restAPIEndpointAdapter.createBooking(request); - - verify(bookingServicePort).book(any(BookingRequest.class)); - assertNotNull(response); - assertEquals(HttpStatus.FAILED_DEPENDENCY, response.getStatusCode()); - } - - @Test - void whenBookingServicePortReturnsSuccess_thenReturnCreated() { - BookingServicePort.BookingRequest request = getBookingRequest(); - when(bookingServicePort.book(any(BookingRequest.class))).thenReturn(new BookingResponse(SUCCESS)); - - ResponseEntity response = restAPIEndpointAdapter.createBooking(request); - - verify(bookingServicePort).book(any(BookingRequest.class)); - assertNotNull(response); - assertEquals(HttpStatus.CREATED, response.getStatusCode()); - } -} \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java b/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java deleted file mode 100644 index ffb4246f79..0000000000 --- a/ddd/src/test/java/com/baeldung/hexagonal/usecase/BookTicketUseCaseUnitTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.baeldung.hexagonal.usecase; - -import com.baeldung.hexagonal.domain.Booking; -import com.baeldung.hexagonal.port.BookingPersistencePort; -import com.baeldung.hexagonal.port.BookingServicePort; -import com.baeldung.hexagonal.port.TheatreServicePort; -import com.baeldung.hexagonal.port.WalletServicePort; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -class BookTicketUseCaseUnitTest { - - private BookingPersistencePort bookingPersistencePort; - private TheatreServicePort theatreServicePort; - private WalletServicePort walletServicePort; - private BookTicketUseCase bookTicketUseCase; - - @BeforeEach - void setUp() { - bookingPersistencePort = mock(BookingPersistencePort.class); - theatreServicePort = mock(TheatreServicePort.class); - walletServicePort = mock(WalletServicePort.class); - bookTicketUseCase = new BookTicketUseCase(bookingPersistencePort, theatreServicePort, walletServicePort); - } - - private BookingServicePort.BookingRequest getBookingRequest() { - BookingServicePort.BookingRequest request = new BookingServicePort.BookingRequest(); - request.setMovieShowId("movie-show-id"); - request.setCustomerId("customer-id"); - request.setSeats(new HashSet<>(Arrays.asList("A1", "A2"))); - request.setAmount(100.00); - return request; - } - - @Test - void whenErrorInInitialPersistence_thenReturnUnknownError() { - BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = new Booking(request); - when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(false); - BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - - verify(bookingPersistencePort, times(1)).persist(any(Booking.class)); - assertNotNull(response); - assertEquals(BookingServicePort.BookingResponse.UNKNOWN_ERROR, response.getStatusCode()); - } - - @Test - void whenErrorInReserveSeats_thenReturnSeatNotAvailable() { - BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = new Booking(request); - when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) - .thenReturn(Optional.empty()); - BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - - verify(bookingPersistencePort).persist(any(Booking.class)); - verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); - verify(theatreServicePort).reserveSeats(any(String.class), any(HashSet.class)); - assertNotNull(response); - assertEquals(BookingServicePort.BookingResponse.SEAT_NOT_AVAILABLE, response.getStatusCode()); - } - - @Test - void whenErrorInWalletDebit_thenReturnPaymentFailed() { - BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = new Booking(request); - when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) - .thenReturn(Optional.of("reservation-id")); - when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) - .thenReturn(false); - BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - - verify(bookingPersistencePort).persist(any(Booking.class)); - verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); - verify(theatreServicePort).reserveSeats(any(String.class), any(HashSet.class)); - verify(walletServicePort).debit(any(String.class), any(Double.class)); - verify(theatreServicePort).releaseSeats(any(String.class)); - assertNotNull(response); - assertEquals(BookingServicePort.BookingResponse.PAYMENT_FAILED, response.getStatusCode()); - } - - @Test - void whenNoErrorInAnyPorts_thenReturnSuccess() { - BookingServicePort.BookingRequest request = getBookingRequest(); - Booking booking = new Booking(request); - when(bookingPersistencePort.persist(any(Booking.class))).thenReturn(true); - when(theatreServicePort.reserveSeats(booking.getMovieShowId(), booking.getSeats())) - .thenReturn(Optional.of("reservation-id")); - when(walletServicePort.debit(booking.getCustomerId(), booking.getAmount())) - .thenReturn(true); - BookingServicePort.BookingResponse response = bookTicketUseCase.book(request); - - verify(bookingPersistencePort).persist(any(Booking.class)); - verify(bookingPersistencePort).updateStatus(any(String.class), any(String.class)); - verify(theatreServicePort).reserveSeats( any(String.class), any(HashSet.class)); - verify(walletServicePort).debit(any(String.class), any(Double.class)); - assertNotNull(response); - assertEquals(BookingServicePort.BookingResponse.SUCCESS, response.getStatusCode()); - } -} \ No newline at end of file From 000ae20d5dcbc1786510439ea3b36afc00589544 Mon Sep 17 00:00:00 2001 From: Maciej Glowka Date: Sun, 3 Oct 2021 22:11:58 +0200 Subject: [PATCH 12/31] BAEL-5134: an example of constructor chaining, added unit tests --- .../constructorchaining/Customer.java | 34 +++++++++++++ .../baeldung/constructorchaining/Person.java | 51 +++++++++++++++++++ .../constructorchaining/CustomerUnitTest.java | 31 +++++++++++ .../constructorchaining/PersonUnitTest.java | 29 +++++++++++ 4 files changed, 145 insertions(+) create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java create mode 100644 core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java create mode 100644 core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java new file mode 100644 index 0000000000..62dbdef297 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java @@ -0,0 +1,34 @@ +package com.baeldung.constructorchaining; + +import java.util.Objects; + +public class Customer extends Person { + private final String loyaltyCardId; + + public Customer(String firstName, String lastName, int age, String loyaltyCardId) { + this(firstName, null, lastName, age, loyaltyCardId); + } + + public Customer(String firstName, String middleName, String lastName, int age, String loyaltyCardId) { + super(firstName, middleName, lastName, age); + this.loyaltyCardId = loyaltyCardId; + } + + public String getLoyaltyCardId() { + return loyaltyCardId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Customer customer = (Customer) o; + return Objects.equals(loyaltyCardId, customer.loyaltyCardId); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), loyaltyCardId); + } +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java new file mode 100644 index 0000000000..02ce2220ba --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java @@ -0,0 +1,51 @@ +package com.baeldung.constructorchaining; + +import java.util.Objects; + +public class Person { + private final String firstName; + private final String middleName; + private final String lastName; + private final int age; + + public Person(String firstName, String lastName, int age) { + this(firstName, null, lastName, age); + } + + + public Person(String firstName, String middleName, String lastName, int age) { + this.firstName = firstName; + this.middleName = middleName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public int getAge() { + return age; + } + + public String getMiddleName() { + return middleName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Person person = (Person) o; + return age == person.age && Objects.equals(firstName, person.firstName) && Objects.equals(middleName, person.middleName) && Objects.equals(lastName, person.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, middleName, lastName, age); + } +} diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java new file mode 100644 index 0000000000..ad00ea65b8 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.constructorchaining; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class CustomerUnitTest { + + @Test + public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() { + Customer mark = new Customer("Mark", "Johnson", 23, "abcd1234"); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Johnson", mark.getLastName()); + assertEquals("abcd1234", mark.getLoyaltyCardId()); + assertNull(mark.getMiddleName()); + } + + @Test + public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() { + Customer mark = new Customer("Mark", "Andrew", "Johnson", 23, "abcd1234"); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Andrew", mark.getMiddleName()); + assertEquals("Johnson", mark.getLastName()); + assertEquals("abcd1234", mark.getLoyaltyCardId()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java new file mode 100644 index 0000000000..8322917951 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.constructorchaining; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class PersonUnitTest { + + @Test + public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() { + Person mark = new Person("Mark", "Johnson", 23); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Johnson", mark.getLastName()); + assertNull(mark.getMiddleName()); + } + + @Test + public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() { + Person mark = new Person("Mark", "Andrew", "Johnson", 23); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Andrew", mark.getMiddleName()); + assertEquals("Johnson", mark.getLastName()); + } +} \ No newline at end of file From d01252575450f481f42b7797fbbac865519cfe0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matea=20Pej=C4=8Dinovi=C4=87?= Date: Wed, 3 Nov 2021 21:07:13 +0100 Subject: [PATCH 13/31] Modified the regex pattern --- .../MultipleDelimitersSplitUnitTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java index c8f8fc2d98..2da8955645 100644 --- a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java @@ -17,7 +17,7 @@ public class MultipleDelimitersSplitUnitTest { @Test public void givenString_whenSplittingByMultipleDelimitersWithRegEx_thenStringSplit() { String example = "Mary;Thomas:Jane-Kate"; - String[] names = example.split(";|:|-"); + String[] names = example.split("[;:-]"); String[] expectedNames = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Assertions.assertEquals(4, names.length); Assertions.assertArrayEquals(expectedNames, names); @@ -38,7 +38,7 @@ public class MultipleDelimitersSplitUnitTest { String example = "Mary;Thomas:Jane-Kate"; String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Iterable expected = Arrays.asList(expectedArray); - Iterable names = Splitter.on(Pattern.compile(";|:|-")).split(example); + Iterable names = Splitter.on(Pattern.compile("[;:-]")).split(example); Assertions.assertEquals(4, Iterators.size(names.iterator())); Assertions.assertIterableEquals(expected, names); } @@ -48,7 +48,7 @@ public class MultipleDelimitersSplitUnitTest { String example = "Mary;Thomas:Jane-Kate"; String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Iterable expected = Arrays.asList(expectedArray); - Iterable names = Splitter.onPattern(";|:|-").split(example); + Iterable names = Splitter.onPattern("[;:-]").split(example); Assertions.assertEquals(4, Iterators.size(names.iterator())); Assertions.assertIterableEquals(expected, names); } From d800af95b83ad9414d74827dde311b15729230e9 Mon Sep 17 00:00:00 2001 From: gjohnson Date: Wed, 3 Nov 2021 23:05:01 +0000 Subject: [PATCH 14/31] For 3rd PR (POM fixed) - [BAEL-4451] LDAP Authentication using Pure Java --- core-java-modules/core-java-jndi/pom.xml | 13 ++ .../ldap/auth/JndiLdapAuthManualTest.java | 165 ++++++++++++++++++ .../src/test/resources/logback.xml | 13 ++ .../src/test/resources/users.ldif | 20 +++ 4 files changed, 211 insertions(+) create mode 100644 core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java create mode 100644 core-java-modules/core-java-jndi/src/test/resources/logback.xml create mode 100644 core-java-modules/core-java-jndi/src/test/resources/users.ldif diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml index 1728c0b5d9..6b7c4e1359 100644 --- a/core-java-modules/core-java-jndi/pom.xml +++ b/core-java-modules/core-java-jndi/pom.xml @@ -41,6 +41,18 @@ h2 ${h2.version} + + org.apache.directory.server + apacheds-test-framework + ${apacheds.version} + test + + + org.assertj + assertj-core + 3.21.0 + test + @@ -59,6 +71,7 @@ 5.0.9.RELEASE 1.4.199 + 2.0.0.AM26 1.8 1.8 diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java new file mode 100644 index 0000000000..5a675c62c9 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java @@ -0,0 +1,165 @@ +package com.baeldung.jndi.ldap.auth; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.util.Hashtable; + +import javax.naming.AuthenticationException; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; + +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.CreatePartition; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(FrameworkRunner.class) +@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost", port = 10390)}) +@CreateDS( + allowAnonAccess = false, partitions = {@CreatePartition(name = "TestPartition", suffix = "dc=baeldung,dc=com")}) +@ApplyLdifFiles({"users.ldif"}) +// class marked as manual test, as it has to run independently from the other unit tests in the module +public class JndiLdapAuthManualTest extends AbstractLdapTestUnit { + + private static void authenticateUser(Hashtable environment) throws Exception { + DirContext context = new InitialDirContext(environment); + context.close(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception { + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + + environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + environment.put(Context.SECURITY_CREDENTIALS, "12345"); + + assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenAuthUserWithWrongPW_thenAuthFails() throws Exception { + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + + environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + environment.put(Context.SECURITY_CREDENTIALS, "wronguserpw"); + + assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment)); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception { + + // first authenticate against LDAP as admin to search up DN of user : Joe Simms + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); + environment.put(Context.SECURITY_CREDENTIALS, "secret"); + + DirContext adminContext = new InitialDirContext(environment); + + // define the search filter to find the person with CN : Joe Simms + String filter = "(&(objectClass=person)(cn=Joe Simms))"; + + // declare the attributes we want returned for the object being searched + String[] attrIDs = { "cn" }; + + // define the search controls + SearchControls searchControls = new SearchControls(); + searchControls.setReturningAttributes(attrIDs); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // search for User with filter cn=Joe Simms + NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls); + if (searchResults.hasMore()) { + + SearchResult result = (SearchResult) searchResults.next(); + Attributes attrs = result.getAttributes(); + + String distinguishedName = result.getNameInNamespace(); + assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + + String commonName = attrs.get("cn").toString(); + assertThat(commonName).isEqualTo("cn: Joe Simms"); + + // authenticate new context with DN for user Joe Simms, using correct password + + environment.put(Context.SECURITY_PRINCIPAL, distinguishedName); + environment.put(Context.SECURITY_CREDENTIALS, "12345"); + + assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException(); + } + + adminContext.close(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithWrongPW_thenAuthFails() throws Exception { + + // first authenticate against LDAP as admin to search up DN of user : Joe Simms + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); + environment.put(Context.SECURITY_CREDENTIALS, "secret"); + DirContext adminContext = new InitialDirContext(environment); + + // define the search filter to find the person with CN : Joe Simms + String filter = "(&(objectClass=person)(cn=Joe Simms))"; + + // declare the attributes we want returned for the object being searched + String[] attrIDs = { "cn" }; + + // define the search controls + SearchControls searchControls = new SearchControls(); + searchControls.setReturningAttributes(attrIDs); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // search for User with filter cn=Joe Simms + NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls); + if (searchResults.hasMore()) { + + SearchResult result = (SearchResult) searchResults.next(); + Attributes attrs = result.getAttributes(); + + String distinguishedName = result.getNameInNamespace(); + assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + + String commonName = attrs.get("cn").toString(); + assertThat(commonName).isEqualTo("cn: Joe Simms"); + + // authenticate new context with DN for user Joe Simms, using wrong password + + environment.put(Context.SECURITY_PRINCIPAL, distinguishedName); + environment.put(Context.SECURITY_CREDENTIALS, "wronguserpassword"); + + assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment)); + } + + adminContext.close(); + } +} diff --git a/core-java-modules/core-java-jndi/src/test/resources/logback.xml b/core-java-modules/core-java-jndi/src/test/resources/logback.xml new file mode 100644 index 0000000000..e55b365ba4 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/core-java-modules/core-java-jndi/src/test/resources/users.ldif b/core-java-modules/core-java-jndi/src/test/resources/users.ldif new file mode 100644 index 0000000000..c1996586d5 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/users.ldif @@ -0,0 +1,20 @@ +version: 1 +dn: dc=baeldung,dc=com +objectClass: domain +objectClass: top +dc: baeldung + +dn: ou=Users,dc=baeldung,dc=com +objectClass: organizationalUnit +objectClass: top +ou: Users + +dn: cn=Joe Simms,ou=Users,dc=baeldung,dc=com +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: Joe Simms +sn: Simms +uid: user1 +userPassword: 12345 From 04f000b4ba5704b52369207687520a2eda9fc0d7 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Thu, 4 Nov 2021 12:37:59 +0100 Subject: [PATCH 15/31] JAVA-8269: Temporarily disable spring-boot-keycloak --- spring-boot-modules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 1b2f6ffa06..0e4c2fe60b 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -46,7 +46,7 @@ spring-boot-groovy spring-boot-jasypt - spring-boot-keycloak + spring-boot-libraries spring-boot-libraries-2 spring-boot-logging-log4j2 From 502372a1decf519899eba83c5d0a7514b1e6cdd3 Mon Sep 17 00:00:00 2001 From: Benjamin Caure Date: Thu, 4 Nov 2021 21:13:22 +0100 Subject: [PATCH 16/31] BAEL-4792 Stateless REST API and CSRF (#11398) * Scan package for controller Migrate deprecated Spring config * BAEL-4792: enable CSRF + sample REST API request * Adjust CSRF logs --- .../java/com/baeldung/spring/MvcConfig.java | 10 ++--- .../com/baeldung/spring/RestController.java | 31 ++++++++++++++ .../baeldung/spring/SecSecurityConfig.java | 11 ++--- .../src/main/resources/logback.xml | 2 +- .../src/main/webapp/WEB-INF/view/homepage.jsp | 42 ++++++++++++++++++- .../webapp/WEB-INF/view/react/public/csrf.js | 3 ++ .../WEB-INF/view/react/public/index.html | 1 + .../webapp/WEB-INF/view/react/src/Form.js | 15 +++---- 8 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java create mode 100644 spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java index f8acdfe2ac..226459db75 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java @@ -1,18 +1,20 @@ package com.baeldung.spring; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { +@ComponentScan(basePackages = { "com.baeldung.spring" }) +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -22,8 +24,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/anonymous.html"); registry.addViewController("/login.html"); @@ -35,7 +35,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/view/react/build/static/"); - + registry.addResourceHandler("/*.js").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.json").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.ico").addResourceLocations("/WEB-INF/view/react/build/"); diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java new file mode 100644 index 0000000000..4084df9698 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/rest") +public class RestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class); + + @GetMapping + public ResponseEntity get(HttpServletRequest request) { + CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); + LOGGER.info("{}={}", token.getHeaderName(), token.getToken()); + return ResponseEntity.ok().build(); + } + + @PostMapping + public ResponseEntity post(HttpServletRequest request) { + // Same impl as GET for testing purpose + return this.get(request); + } +} diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java index 7b67028647..d560589cce 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration @EnableWebSecurity @@ -21,11 +22,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.inMemoryAuthentication() - .withUser("user1").password("user1Pass").roles("USER") + .withUser("user1").password("{noop}user1Pass").roles("USER") .and() - .withUser("user2").password("user2Pass").roles("USER") + .withUser("user2").password("{noop}user2Pass").roles("USER") .and() - .withUser("admin").password("admin0Pass").roles("ADMIN"); + .withUser("admin").password("{noop}admin0Pass").roles("ADMIN"); // @formatter:on } @@ -33,11 +34,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() + .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() - .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico").permitAll() + .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest").permitAll() .anyRequest().authenticated() .and() .formLogin() diff --git a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml index 25f3f36d1a..2cc702de59 100644 --- a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml +++ b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml @@ -12,7 +12,7 @@ - + diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp index c9d88cbc9b..d64f80a5cb 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp @@ -1,11 +1,30 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> - + + +

This is the body of the sample view

+
+

CSRF Testing

+
+ CSRF Token: + + +
+
+
+   + +
+
+
Request Result:

+
+ +

Roles

This text is only visible to a user

@@ -22,5 +41,26 @@ ">Logout + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js new file mode 100644 index 0000000000..657cc31f41 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js @@ -0,0 +1,3 @@ +window.getCsrfToken = () => { + return document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1'); +} diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html index 0c3f78d7b3..6d4894da42 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html @@ -6,6 +6,7 @@ + javax.transaction diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml index 1a49ced021..bcccc136a4 100644 --- a/google-web-toolkit/pom.xml +++ b/google-web-toolkit/pom.xml @@ -44,12 +44,6 @@ gwt-dev provided - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/grpc/pom.xml b/grpc/pom.xml index f034b2b517..6f0c3b5c91 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -37,12 +37,6 @@ ${io.grpc.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.annotation javax.annotation-api diff --git a/json-2/pom.xml b/json-2/pom.xml index 53d67320ba..b4301c41e5 100644 --- a/json-2/pom.xml +++ b/json-2/pom.xml @@ -24,12 +24,6 @@ jsoniter ${jsoniter.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/junit5/pom.xml b/junit5/pom.xml index b9804408a2..00b04ea292 100644 --- a/junit5/pom.xml +++ b/junit5/pom.xml @@ -8,8 +8,8 @@ junit5 - parent-modules com.baeldung + parent-modules 1.0.0-SNAPSHOT @@ -18,19 +18,4 @@ 8 - - - org.junit.jupiter - junit-jupiter-api - 5.8.1 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.8.1 - test - - - \ No newline at end of file diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 3db34709e7..dd48453a8c 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -14,12 +14,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.kafka kafka-streams @@ -92,6 +86,10 @@ commons-codec commons-codec + + junit + junit + @@ -104,6 +102,12 @@ flink-test-utils_2.11 ${flink.version} test + + + junit + junit + + org.slf4j diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index a9c340b319..954f666785 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -61,12 +61,6 @@ netty-all ${netty.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.tomcat diff --git a/libraries/pom.xml b/libraries/pom.xml index 4ecf82aa87..b2e429ff65 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -146,12 +146,6 @@ jmh-core ${jmh-core.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - info.debatty java-lsh diff --git a/maven-modules/maven-integration-test/pom.xml b/maven-modules/maven-integration-test/pom.xml index 4283baf63b..01be0ad1a4 100644 --- a/maven-modules/maven-integration-test/pom.xml +++ b/maven-modules/maven-integration-test/pom.xml @@ -26,12 +26,6 @@ jersey-hk2 ${jersey.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/maven-modules/maven-properties/pom.xml b/maven-modules/maven-properties/pom.xml index b3169a7fb0..88e13a0fb8 100644 --- a/maven-modules/maven-properties/pom.xml +++ b/maven-modules/maven-properties/pom.xml @@ -14,15 +14,6 @@ ../.. - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - diff --git a/micronaut/pom.xml b/micronaut/pom.xml index f36f565a94..019bd6ab29 100644 --- a/micronaut/pom.xml +++ b/micronaut/pom.xml @@ -64,12 +64,6 @@ ${logback.version} runtime - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - io.projectreactor reactor-core diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml index ad649d58d8..0eb4b8075d 100644 --- a/persistence-modules/java-jpa-3/pom.xml +++ b/persistence-modules/java-jpa-3/pom.xml @@ -68,12 +68,6 @@ ${assertj.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.testcontainers postgresql diff --git a/restx/pom.xml b/restx/pom.xml index ea9f927563..57736f60cd 100644 --- a/restx/pom.xml +++ b/restx/pom.xml @@ -113,12 +113,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 10bc6d3104..8a41da5448 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -80,12 +80,6 @@ arquillian-junit-container test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - joda-time diff --git a/tensorflow-java/pom.xml b/tensorflow-java/pom.xml index 2ac4d28a37..4dd86d45e3 100644 --- a/tensorflow-java/pom.xml +++ b/tensorflow-java/pom.xml @@ -21,18 +21,6 @@ tensorflow ${tensorflow.version} - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - diff --git a/xml/pom.xml b/xml/pom.xml index 6bae312452..f88f0f89b0 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -107,18 +107,6 @@ commons-lang ${commons-lang.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core From 0f8560ed36c7ff2586c0c580cfeb9311e8d70856 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Fri, 5 Nov 2021 16:04:59 +0530 Subject: [PATCH 19/31] JAVA-1672: removing redundant junit-platform-commons declarations --- algorithms-miscellaneous-5/pom.xml | 5 ----- algorithms-miscellaneous-6/pom.xml | 5 ----- testing-modules/spring-testing/pom.xml | 5 ----- testing-modules/test-containers/pom.xml | 6 ------ 4 files changed, 21 deletions(-) diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml index 32ecce58a6..c68ac96c38 100644 --- a/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-miscellaneous-5/pom.xml @@ -34,11 +34,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-miscellaneous-6/pom.xml index 6d5f211c8a..a9eb75cf1e 100644 --- a/algorithms-miscellaneous-6/pom.xml +++ b/algorithms-miscellaneous-6/pom.xml @@ -19,11 +19,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index ff5265eab8..08b56c9a1a 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -60,11 +60,6 @@ org.springframework.data spring-data-jpa - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.awaitility awaitility diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index aa2c85af21..687bc418ad 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -23,12 +23,6 @@ ${junit-platform.version} test - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - test - org.apache.logging.log4j log4j-core From 073e3c1771b9774e6c6f9de16e761bdb5728c601 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Fri, 5 Nov 2021 16:35:29 +0530 Subject: [PATCH 20/31] JAVA-1672: updating surefire version in main pom --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f2a53f38b7..855cf54f0a 100644 --- a/pom.xml +++ b/pom.xml @@ -1398,8 +1398,7 @@ 1.2.6 - - 2.21.0 + 2.22.2 3.8.1 3.0.0 1.8 From 15cae84104b9f76bbf13be815db4ff3d4e674a43 Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Fri, 5 Nov 2021 13:24:28 +0100 Subject: [PATCH 21/31] BAEL-4546 incorporate thee review comments --- docker/docker-sample-app/pom.xml | 72 ++++++++++++++++---------------- docker/pom.xml | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml index 416ec45b10..6841fabcee 100644 --- a/docker/docker-sample-app/pom.xml +++ b/docker/docker-sample-app/pom.xml @@ -1,45 +1,45 @@ - 4.0.0 - - com.baeldung.docker - docker - 0.0.1 - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + com.baeldung.docker + docker + 0.0.1 + - docker-sample-app - docker-sample-app - Demo project for Spring Boot and Docker + docker-sample-app + docker-sample-app + Demo project for Spring Boot and Docker - - 11 - + + 11 + - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-test - test - - + + org.springframework.boot + spring-boot-starter-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/docker/pom.xml b/docker/pom.xml index 0a397dd966..f481f1b8b7 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -25,7 +25,7 @@ docker-internal-dto docker-spring-boot - docker-sample-app + docker-sample-app From 7502addfafac08d5b86ff5117da77699b7ddbd0d Mon Sep 17 00:00:00 2001 From: Swapan Pramanick Date: Fri, 5 Nov 2021 14:40:16 +0100 Subject: [PATCH 22/31] BAEL-4546 incorporate thee review comments --- docker/docker-sample-app/mvnw | 310 ------------------------------ docker/docker-sample-app/mvnw.cmd | 182 ------------------ 2 files changed, 492 deletions(-) delete mode 100755 docker/docker-sample-app/mvnw delete mode 100644 docker/docker-sample-app/mvnw.cmd diff --git a/docker/docker-sample-app/mvnw b/docker/docker-sample-app/mvnw deleted file mode 100755 index a16b5431b4..0000000000 --- a/docker/docker-sample-app/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/docker/docker-sample-app/mvnw.cmd b/docker/docker-sample-app/mvnw.cmd deleted file mode 100644 index c8d43372c9..0000000000 --- a/docker/docker-sample-app/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% From 47ca31189a3adb3b192081d51bb8eae2bbfeb628 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Sat, 6 Nov 2021 05:53:22 +0530 Subject: [PATCH 23/31] Review comments updated Review comments updated --- core-java-modules/core-java/pom.xml | 8 +- .../baeldung/util/MySerializationUtils.java | 44 +++++ .../com/baeldung/util/SerializationUtils.java | 47 ------ .../serialization/SerializationUnitTest.java | 154 +++++++++--------- 4 files changed, 125 insertions(+), 128 deletions(-) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index 00f26b0e0a..42262be29a 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -62,10 +62,10 @@ ${javamoney.moneta.version} - org.springframework - spring-core - ${spring.core.version} - + org.springframework + spring-core + ${spring.core.version} + diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java new file mode 100644 index 0000000000..bfaa91313c --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java @@ -0,0 +1,44 @@ +package com.baeldung.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class MySerializationUtils { + + public static byte[] serialize(T obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + public static T deserialize(byte[] b, Class cl) throws IOException, ClassNotFoundException { + ByteArrayInputStream bais = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bais); + Object o = ois.readObject(); + return cl.cast(o); + } + + public static boolean isSerializable(Class it) { + boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + if (!serializable) { + return serializable; + } + Field[] declaredFields = it.getDeclaredFields(); + for (Field field : declaredFields) { + if (Modifier.isVolatile(field.getModifiers()) || Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) { + continue; + } + Class fieldType = field.getType(); + return isSerializable(fieldType); + } + return serializable; + } +} diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java deleted file mode 100644 index 2a9391965f..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/util/SerializationUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.baeldung.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - -public class SerializationUtils { - - public static byte[] serialize(T obj) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(obj); - oos.close(); - return baos.toByteArray(); - } - - public static T deserialize(byte[] b, Class cl) - throws IOException, ClassNotFoundException { - ByteArrayInputStream bais = new ByteArrayInputStream(b); - ObjectInputStream ois = new ObjectInputStream(bais); - Object o = ois.readObject(); - return cl.cast(o); - } - - public static boolean isSerializable(Class it) { - boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); - if (!serializable) { - return serializable; - } - Field[] declaredFields = it.getDeclaredFields(); - for (Field field : declaredFields) { - if (Modifier.isVolatile(field.getModifiers()) - || Modifier.isTransient(field.getModifiers()) - || Modifier.isStatic(field.getModifiers())) { - continue; - } - Class fieldType = field.getType(); - return isSerializable(fieldType); - } - return serializable; - } -} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java index e0ee2bb654..bc9cf04b86 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -1,7 +1,8 @@ package com.baeldung.serialization; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -16,94 +17,93 @@ import org.junit.Test; public class SerializationUnitTest { - @Test(expected = NotSerializableException.class) - public void whenSerializing_ThenThrowsError() throws IOException { - Address address = new Address(); - address.setHouseNumber(10); - FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); - try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { - objectOutputStream.writeObject(address); - } - } - - @Test + @Test(expected = NotSerializableException.class) + public void whenSerializing_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(address); + } + } + + @Test public void whenSerializingAndDeserializing_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { Person p = new Person(); p.setAge(20); p.setName("Joe"); FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); - try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { - objectOutputStream.writeObject(p); - } + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(p); + } - FileInputStream fileInputStream = new FileInputStream("yofile.txt"); - try ( ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) { - Person p2 = (Person) objectInputStream.readObject(); - assertTrue(p2.getAge() == p.getAge()); - assertTrue(p2.getName().equals(p.getName())); - } - } + FileInputStream fileInputStream = new FileInputStream("yofile.txt"); + try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) { + Person p2 = (Person) objectInputStream.readObject(); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } + } - @Test(expected = ClassCastException.class) - public void whenSerializingUsingApacheCommons_ThenThrowsError() { - Address address = new Address(); - address.setHouseNumber(10); - SerializationUtils.serialize((Serializable) address); - } + @Test(expected = ClassCastException.class) + public void whenSerializingUsingApacheCommons_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + SerializationUtils.serialize((Serializable) address); + } - @Test - public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() { - Person p = new Person(); - p.setAge(20); - p.setName("Joe"); - byte[] serialize = SerializationUtils.serialize(p); - Person p2 = (Person) SerializationUtils.deserialize(serialize); - assertTrue(p2.getAge() == p.getAge()); - assertTrue(p2.getName().equals(p.getName())); - } + @Test + public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = SerializationUtils.serialize(p); + Person p2 = (Person) SerializationUtils.deserialize(serialize); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } - @Test(expected = ClassCastException.class) - public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() { - Address address = new Address(); - address.setHouseNumber(10); - org.springframework.util.SerializationUtils.serialize((Serializable) address); - } + @Test(expected = ClassCastException.class) + public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + org.springframework.util.SerializationUtils.serialize((Serializable) address); + } - @Test - public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() { - Person p = new Person(); - p.setAge(20); - p.setName("Joe"); - byte[] serialize = org.springframework.util.SerializationUtils.serialize(p); - Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize); - assertTrue(p2.getAge() == p.getAge()); - assertTrue(p2.getName().equals(p.getName())); - } + @Test + public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = org.springframework.util.SerializationUtils.serialize(p); + Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } - @Test(expected = ClassCastException.class) - public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException { - Address address = new Address(); - address.setHouseNumber(10); - com.baeldung.util.SerializationUtils.serialize((Serializable) address); - } + @Test(expected = ClassCastException.class) + public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + com.baeldung.util.MySerializationUtils.serialize((Serializable) address); + } - @Test - public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() - throws IOException, ClassNotFoundException { - Person p = new Person(); - p.setAge(20); - p.setName("Joe"); - byte[] serialize = com.baeldung.util.SerializationUtils.serialize(p); - Person p2 = com.baeldung.util.SerializationUtils.deserialize(serialize, Person.class); - assertTrue(p2.getAge() == p.getAge()); - assertTrue(p2.getName().equals(p.getName())); - } + @Test + public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = com.baeldung.util.MySerializationUtils.serialize(p); + Person p2 = com.baeldung.util.MySerializationUtils.deserialize(serialize, Person.class); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } - @Test - public void whenSerializingUsingCustomSerializationUtils_ThanOk() { - assertFalse(com.baeldung.util.SerializationUtils.isSerializable(Address.class)); - assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Person.class)); - assertTrue(com.baeldung.util.SerializationUtils.isSerializable(Integer.class)); - } + @Test + public void whenSerializingUsingCustomSerializationUtils_ThanOk() { + assertFalse(com.baeldung.util.MySerializationUtils.isSerializable(Address.class)); + assertTrue(com.baeldung.util.MySerializationUtils.isSerializable(Person.class)); + assertTrue(com.baeldung.util.MySerializationUtils.isSerializable(Integer.class)); + } } From 9728ae73773aed0a06583b3a4ec50c1f4e5810fe Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Sat, 6 Nov 2021 06:09:48 +0530 Subject: [PATCH 24/31] Updated review comment --- .../serialization/SerializationUnitTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java index bc9cf04b86..a8c4009386 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -15,6 +15,8 @@ import java.io.Serializable; import org.apache.commons.lang3.SerializationUtils; import org.junit.Test; +import com.baeldung.util.MySerializationUtils; + public class SerializationUnitTest { @Test(expected = NotSerializableException.class) @@ -86,7 +88,7 @@ public class SerializationUnitTest { public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException { Address address = new Address(); address.setHouseNumber(10); - com.baeldung.util.MySerializationUtils.serialize((Serializable) address); + MySerializationUtils.serialize((Serializable) address); } @Test @@ -94,16 +96,16 @@ public class SerializationUnitTest { Person p = new Person(); p.setAge(20); p.setName("Joe"); - byte[] serialize = com.baeldung.util.MySerializationUtils.serialize(p); - Person p2 = com.baeldung.util.MySerializationUtils.deserialize(serialize, Person.class); + byte[] serialize = MySerializationUtils.serialize(p); + Person p2 = MySerializationUtils.deserialize(serialize, Person.class); assertEquals(p2.getAge(), p.getAge()); assertEquals(p2.getName(), p.getName()); } @Test public void whenSerializingUsingCustomSerializationUtils_ThanOk() { - assertFalse(com.baeldung.util.MySerializationUtils.isSerializable(Address.class)); - assertTrue(com.baeldung.util.MySerializationUtils.isSerializable(Person.class)); - assertTrue(com.baeldung.util.MySerializationUtils.isSerializable(Integer.class)); + assertFalse(MySerializationUtils.isSerializable(Address.class)); + assertTrue(MySerializationUtils.isSerializable(Person.class)); + assertTrue(MySerializationUtils.isSerializable(Integer.class)); } } From 91f5674d46c792c42128f1dbb55db6f1815b575d Mon Sep 17 00:00:00 2001 From: Thiago dos Santos Hora Date: Sun, 24 Oct 2021 18:42:53 +0200 Subject: [PATCH 25/31] [BAEL-5197] Add code samples and tests --- core-java-modules/core-java-17/README.md | 1 + core-java-modules/core-java-17/pom.xml | 84 +++++++++++++++++++ .../java/com/baeldung/features/JEP356.java | 20 +++++ .../java/com/baeldung/features/JEP406.java | 28 +++++++ .../java/com/baeldung/features/JEP409.java | 38 +++++++++ .../java/com/baeldung/features/JEP412.java | 56 +++++++++++++ .../java/com/baeldung/features/JEP414.java | 27 ++++++ .../src/main/java/module-info.java | 4 + .../src/main/resources/compile_c.sh | 9 ++ .../src/main/resources/print_name.c | 8 ++ .../com/baeldung/features/JEP356UnitTest.java | 19 +++++ .../com/baeldung/features/JEP406UnitTest.java | 33 ++++++++ .../com/baeldung/features/JEP409UnitTest.java | 39 +++++++++ .../com/baeldung/features/JEP412UnitTest.java | 17 ++++ .../com/baeldung/features/JEP414UnitTest.java | 38 +++++++++ 15 files changed, 421 insertions(+) create mode 100644 core-java-modules/core-java-17/README.md create mode 100644 core-java-modules/core-java-17/pom.xml create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java create mode 100644 core-java-modules/core-java-17/src/main/java/module-info.java create mode 100755 core-java-modules/core-java-17/src/main/resources/compile_c.sh create mode 100644 core-java-modules/core-java-17/src/main/resources/print_name.c create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java diff --git a/core-java-modules/core-java-17/README.md b/core-java-modules/core-java-17/README.md new file mode 100644 index 0000000000..37095551a1 --- /dev/null +++ b/core-java-modules/core-java-17/README.md @@ -0,0 +1 @@ +### Relevant articles: diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml new file mode 100644 index 0000000000..e422bd62bb --- /dev/null +++ b/core-java-modules/core-java-17/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + core-java-17 + 0.1.0-SNAPSHOT + core-java-17 + jar + http://maven.apache.org + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.release} + --enable-preview + ${maven.compiler.source.version} + ${maven.compiler.target.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.plugin.version} + + + --enable-preview + --enable-native-access=core.java + 1 + + + + + org.apache.maven.surefire + surefire-api + ${surefire.plugin.version} + + + + + + + + 17 + 17 + 17 + 3.8.1 + 3.0.0-M5 + 3.17.2 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java new file mode 100644 index 0000000000..0890b025be --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java @@ -0,0 +1,20 @@ +package com.baeldung.features; + +import java.util.random.RandomGeneratorFactory; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class JEP356 { + + public Stream getAllAlgorithms() { + return RandomGeneratorFactory.all().map(RandomGeneratorFactory::name); + } + + public IntStream getPseudoInts(String algorithm, int streamSize) { + // returns an IntStream with size @streamSize of random numbers generated using the @algorithm + // where the lower bound is 0 and the upper is 100 (exclusive) + return RandomGeneratorFactory.of(algorithm) + .create() + .ints(streamSize, 0,100); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java new file mode 100644 index 0000000000..2bc3a664d1 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java @@ -0,0 +1,28 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP409.Circle; +import com.baeldung.features.JEP409.Shape; +import com.baeldung.features.JEP409.Triangle; + +public class JEP406 { + + static record Human (String name, int age, String profession) {} + + public String checkObject(Object obj) { + return switch (obj) { + case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession()); + case Circle c -> "This is a circle"; + case Shape s -> "It is just a shape"; + case null -> "It is null"; + default -> "It is an object"; + }; + } + + public String checkShape(Shape shape) { + return switch (shape) { + case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle"; + case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle"; + default -> "Just a normal shape"; + }; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java new file mode 100644 index 0000000000..0fc3d6f467 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java @@ -0,0 +1,38 @@ +package com.baeldung.features; + +public class JEP409 { + + sealed interface Shape permits Rectangle, Circle, Square, Triangle { + int getNumberOfSides(); + } + + static final class Rectangle implements Shape { + @Override + public int getNumberOfSides() { + return 4; + } + } + + static final class Circle implements Shape { + @Override + public int getNumberOfSides() { + return 0; + } + } + + static final class Square implements Shape { + @Override + public int getNumberOfSides() { + return 4; + } + } + + static non-sealed class Triangle implements Shape { + + @Override + public int getNumberOfSides() { + return 3; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java new file mode 100644 index 0000000000..8c998629c9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java @@ -0,0 +1,56 @@ +package com.baeldung.features; + +import jdk.incubator.foreign.CLinker; +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.SymbolLookup; + +import java.io.IOException; +import java.lang.invoke.MethodType; + +import static jdk.incubator.foreign.ResourceScope.newImplicitScope; + +public class JEP412 { + + private static final SymbolLookup libLookup; + + static { + var resource = JEP412.class.getResource("/compile_c.sh"); + try { + var process = new ProcessBuilder("sh", resource.getPath()).start(); + while (process.isAlive()) {} + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + var path = JEP412.class.getResource("/print_name.so").getPath(); + System.load(path); + libLookup = SymbolLookup.loaderLookup(); + } + + public String getPrintNameFormat(String name){ + + var printMethod = libLookup.lookup("printName"); + + if (printMethod.isPresent()) { + var methodReference = CLinker.getInstance() + .downcallHandle( + printMethod.get(), + MethodType.methodType(MemoryAddress.class, MemoryAddress.class), + FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_POINTER) + ); + + try { + var nativeString = CLinker.toCString(name, newImplicitScope()); + var invokeReturn = methodReference.invoke(nativeString.address()); + var memoryAddress = (MemoryAddress) invokeReturn; + return CLinker.toJavaString(memoryAddress); + } catch (Throwable throwable) { + throw new RuntimeException(throwable); + } + } + throw new RuntimeException("printName function not found."); + } +} + + diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java new file mode 100644 index 0000000000..aaccc4a665 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java @@ -0,0 +1,27 @@ +package com.baeldung.features; + +import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.VectorSpecies; + +public class JEP414 { + + private static final VectorSpecies SPECIES = FloatVector.SPECIES_PREFERRED; + + + public void newVectorComputation(float[] a, float[] b, float[] c) { + for (var i = 0; i < a.length; i += SPECIES.length()) { + var m = SPECIES.indexInRange(i, a.length); + var va = FloatVector.fromArray(SPECIES, a, i, m); + var vb = FloatVector.fromArray(SPECIES, b, i, m); + var vc = va.mul(vb); + vc.intoArray(c, i, m); + } + } + + public void commonVectorComputation(float[] a, float[] b, float[] c) { + for (var i = 0; i < a.length; i ++) { + c[i] = a[i] * b[i]; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/module-info.java b/core-java-modules/core-java-17/src/main/java/module-info.java new file mode 100644 index 0000000000..b1ce62aa68 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module core.java { + requires jdk.incubator.vector; + requires jdk.incubator.foreign; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/compile_c.sh b/core-java-modules/core-java-17/src/main/resources/compile_c.sh new file mode 100755 index 0000000000..d2e0629cc5 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/compile_c.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +gcc -c -fPIC $SCRIPTPATH/print_name.c +gcc -shared -rdynamic -o print_name.so print_name.o + +mv print_name.so $SCRIPTPATH/ +mv print_name.o $SCRIPTPATH/ \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/print_name.c b/core-java-modules/core-java-17/src/main/resources/print_name.c new file mode 100644 index 0000000000..7bda12e352 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/print_name.c @@ -0,0 +1,8 @@ +#include +#include + +char* printName(char *name) { + char* newString = (char*)malloc((15 + sizeof(name))*sizeof(char)); + sprintf(newString, "Your name is %s", name); + return newString; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java new file mode 100644 index 0000000000..b4f61a6f24 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JEP356UnitTest { + + @Test + void getPseudoInts_whenUsingAlgorithmXoroshiro128PlusPlus_shouldReturnStreamOfRandomInteger() { + var algorithm = "Xoshiro256PlusPlus"; + var streamSize = 100; + + JEP356 jep356 = new JEP356(); + + jep356.getPseudoInts(algorithm, streamSize) + .forEach(value -> assertThat(value).isLessThanOrEqualTo(99)); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java new file mode 100644 index 0000000000..87e6f3bec6 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP406.Human; +import com.baeldung.features.JEP409.Square; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class JEP406UnitTest { + + @Test + void checkObject_shouldMatchWithHuman() { + var jep406 = new JEP406(); + + var human = new Human("John", 31, "Developer"); + + var checkResult = jep406.checkObject(human); + + assertEquals("Name: John, age: 31 and profession: Developer", checkResult); + } + + @Test + void checkShape_shouldMatchWithShape() { + var jep406 = new JEP406(); + + var square = new Square(); + + var checkResult = jep406.checkShape(square); + + assertEquals("Just a normal shape", checkResult); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java new file mode 100644 index 0000000000..41380ec2bb --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP409.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +class JEP409UnitTest { + + static class WeirdTriangle extends Triangle { + @Override public int getNumberOfSides() { + return 40; + } + } + + @Test + void testSealedClass_shouldInvokeRightClass() { + + Shape shape = spy(new WeirdTriangle()); + + int numberOfSides = getNumberOfSides(shape); + + assertEquals(40, numberOfSides); + verify(shape).getNumberOfSides(); + } + + int getNumberOfSides(Shape shape) { + return switch (shape) { + case WeirdTriangle t -> t.getNumberOfSides(); + case Circle c -> c.getNumberOfSides(); + case Triangle t -> t.getNumberOfSides(); + case Rectangle r -> r.getNumberOfSides(); + case Square s -> s.getNumberOfSides(); + }; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java new file mode 100644 index 0000000000..66e7d952c7 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JEP412UnitTest { + + @Test + void getPrintNameFormat_whenPassingAName_shouldReceiveItFormatted() { + var jep412 = new JEP412(); + + var formattedName = jep412.getPrintNameFormat("John"); + + assertEquals("Your name is John", formattedName); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java new file mode 100644 index 0000000000..459344d907 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JEP414UnitTest { + + @Test + void vectorComputation_shouldMultiplyVectors() { + var jep414 = new JEP414(); + + float[] a = initArray(100); + float[] b = initArray(100); + float[] c = new float[100]; + float[] d = new float[100]; + + jep414.newVectorComputation(a, b, c); + jep414.commonVectorComputation(a, b, d); + + for (int i = 0; i < a.length; i++) { + assertEquals(c[i], d[i]); + } + } + + private float[] initArray(int size) { + final var jep356 = new JEP356(); + final var values = new float[size]; + final var pseudoInts = jep356.getPseudoInts("Xoshiro256PlusPlus", size).mapToObj(Float::valueOf).collect(toList()); + + for (int i = 0; i < pseudoInts.size(); i++) { + values[i] = pseudoInts.get(i); + } + + return values; + } +} \ No newline at end of file From 683f3199bb8900860d9ac7fa4e919a1328885f45 Mon Sep 17 00:00:00 2001 From: thomasduxbury <68503838+thomasduxbury@users.noreply.github.com> Date: Sat, 6 Nov 2021 23:56:30 +0000 Subject: [PATCH 26/31] BAEL-5179: Introduction to HexFormat in Java 17 (#11387) --- .../ByteHexadecimalConversionUnitTest.java | 23 +++++++++++ ...tiveTypeHexadecimalConversionUnitTest.java | 22 ++++++++++ .../hexformat/StringFormattingUnitTest.java | 15 +++++++ .../UppercaseLowercaseOutputUnitTest.java | 40 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..29b6eb1bee --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ByteHexadecimalConversionUnitTest { + + private HexFormat hexFormat = HexFormat.of(); + + @Test + void givenInitialisedHexFormat_whenHexStringIsPassed_thenByteArrayRepresentationIsReturned() { + byte[] hexBytes = hexFormat.parseHex("ABCDEF0123456789"); + assertArrayEquals(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119 }, hexBytes); + } + + @Test + void givenInitialisedHexFormat_whenByteArrayIsPassed_thenHexStringRepresentationIsReturned() { + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertEquals("abcdef0123456789", bytesAsString); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..6f26a8351c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PrimitiveTypeHexadecimalConversionUnitTest { + + private HexFormat hexFormat = HexFormat.of(); + + @Test + void givenInitialisedHexFormat_whenPrimitiveByteIsPassed_thenHexStringRepresentationIsReturned() { + String fromByte = hexFormat.toHexDigits((byte)64); + assertEquals("40", fromByte); + } + + @Test + void givenInitialisedHexFormat_whenPrimitiveLongIsPassed_thenHexStringRepresentationIsReturned() { + String fromLong = hexFormat.toHexDigits(1234_5678_9012_3456L); + assertEquals("000462d53c8abac0", fromLong); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java new file mode 100644 index 0000000000..28189d0e8c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StringFormattingUnitTest { + + private HexFormat hexFormat = HexFormat.of().withPrefix("[").withSuffix("]").withDelimiter(", "); + + @Test + public void givenInitialisedHexFormatWithFormattedStringOptions_whenByteArrayIsPassed_thenHexStringRepresentationFormattedCorrectlyIsReturned() { + assertEquals("[48], [0c], [11]", hexFormat.formatHex(new byte[] {72, 12, 17})); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java new file mode 100644 index 0000000000..c2a33fb4b5 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class UppercaseLowercaseOutputUnitTest { + + @Test + public void givenInitialisedHexFormat_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() { + HexFormat hexFormat = HexFormat.of(); + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertTrue(isLowerCase(bytesAsString)); + } + + @Test + public void givenInitialisedHexFormatWithUpperCaseOption_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() { + HexFormat hexFormat = HexFormat.of().withUpperCase(); + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertTrue(isUpperCase(bytesAsString)); + } + + private boolean isLowerCase(String str) { + char[] charArray = str.toCharArray(); + for (int i=0; i < charArray.length; i++) { + if (Character.isUpperCase(charArray[i])) + return false; + } + return true; + } + + private boolean isUpperCase(String str) { + char[] charArray = str.toCharArray(); + for (int i=0; i < charArray.length; i++) { + if (Character.isLowerCase(charArray[i])) + return false; + } + return true; + } +} From b0176d85cf875611928eb330e2495bb3a4181fd6 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Sun, 7 Nov 2021 19:14:37 +0530 Subject: [PATCH 27/31] JAVA-1672: removing surefire configurations from parents --- guest/junit5-example/pom.xml | 7 ------- parent-boot-2/pom.xml | 6 ------ parent-java/pom.xml | 13 ------------- parent-spring-4/pom.xml | 10 ---------- parent-spring-5/pom.xml | 13 ------------- persistence-modules/pom.xml | 3 --- pom.xml | 5 ----- spring-web-modules/spring-boot-jsp/pom.xml | 1 - testing-modules/pom.xml | 16 ---------------- 9 files changed, 74 deletions(-) diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml index a88f739891..3bfa72f21f 100644 --- a/guest/junit5-example/pom.xml +++ b/guest/junit5-example/pom.xml @@ -42,13 +42,6 @@ maven-surefire-plugin ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - - math diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 8e8dbba54d..42081fa115 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -58,11 +58,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - @@ -97,7 +92,6 @@ 1.9.1 3.4.0 - 2.22.2 \ No newline at end of file diff --git a/parent-java/pom.xml b/parent-java/pom.xml index ae6eeb40a9..4e5081393c 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -40,23 +40,10 @@ - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - 31.0.1-jre 2.3.7 2.2 - 2.22.2 \ No newline at end of file diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index 630fa0baf3..a36e1060ed 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -24,15 +24,6 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.codehaus.cargo @@ -57,7 +48,6 @@ 4.3.27.RELEASE 1.6.1 - 2.22.2 \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 01e8671099..1263a56e2b 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -23,23 +23,10 @@ - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - 5.3.9 5.2.3.RELEASE 1.5.10.RELEASE - 2.22.2 \ No newline at end of file diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index c3df8866b1..4d42ff54cd 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -99,9 +99,6 @@ 5.2.17.Final 42.2.20 - - - 2.22.2 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 855cf54f0a..01b55d48f9 100644 --- a/pom.xml +++ b/pom.xml @@ -113,11 +113,6 @@ - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - org.junit.jupiter junit-jupiter-engine diff --git a/spring-web-modules/spring-boot-jsp/pom.xml b/spring-web-modules/spring-boot-jsp/pom.xml index 222facd100..b9b4a97e6b 100644 --- a/spring-web-modules/spring-boot-jsp/pom.xml +++ b/spring-web-modules/spring-boot-jsp/pom.xml @@ -92,7 +92,6 @@ 1.2 2.4.4 - 2.22.2 \ No newline at end of file diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 079c7fa792..28c743b2b3 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -50,20 +50,4 @@ zerocode - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - - - 2.22.2 - - \ No newline at end of file From d8ba53a958a18eaf093e9a25c66e7acbfa057214 Mon Sep 17 00:00:00 2001 From: rvsathe <38076470+rvsathe@users.noreply.github.com> Date: Mon, 8 Nov 2021 02:45:45 +0530 Subject: [PATCH 28/31] changes for BAEL 5164 (#11364) * BAEL 4293 correcting the unit test file ame. * changes for BAEL 5164 * added maven compiler properties for fixing compilation issues. * making BAEL 5164 java 8 compatible. --- .../core-java-collections-maps-4/pom.xml | 79 +++--- .../com/baeldung/nestedhashmaps/Address.java | 32 +++ .../com/baeldung/nestedhashmaps/Employee.java | 43 ++++ .../com/baeldung/nestedhashmaps/MapsUtil.java | 57 ++++ .../NestedHashMapExamplesClass.java | 118 +++++++++ .../NestedHashMapExamplesClassUnitTest.java | 243 ++++++++++++++++++ 6 files changed, 543 insertions(+), 29 deletions(-) create mode 100644 core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java create mode 100644 core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index 1835e3ceac..93ec782c94 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -1,34 +1,55 @@ - 4.0.0 - core-java-collections-maps-4 - 0.1.0-SNAPSHOT - core-java-collections-maps-4 - jar + 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"> + 4.0.0 + core-java-collections-maps-4 + 0.1.0-SNAPSHOT + core-java-collections-maps-4 + jar - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - ../pom.xml - + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + ../pom.xml + + + + UTF-8 + 1.8 + 1.8 + - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - - !performance - - - - - + + + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + - + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + !performance + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java new file mode 100644 index 0000000000..410758405e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java @@ -0,0 +1,32 @@ +package com.baeldung.nestedhashmaps; + +public class Address { + + private Integer addressId; + private String addressLocation; + + public Address() { + } + + public Address(Integer addressId, String addressLocation) { + this.addressId = addressId; + this.addressLocation = addressLocation; + } + + public Integer getAddressId() { + return addressId; + } + + public void setAddressId(Integer addressId) { + this.addressId = addressId; + } + + public String getAddressLocation() { + return addressLocation; + } + + public void setAddressLocation(String addressLocation) { + this.addressLocation = addressLocation; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java new file mode 100644 index 0000000000..2ab54ff17c --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java @@ -0,0 +1,43 @@ +package com.baeldung.nestedhashmaps; + +public class Employee { + + private Integer employeeId; + private Address address; + private String employeeName; + + public Employee() { + super(); + } + + public Employee(Integer employeeId, Address address, String employeeName) { + this.employeeId = employeeId; + this.address = address; + this.employeeName = employeeName; + } + + public Integer getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Integer employeeId) { + this.employeeId = employeeId; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public String getEmployeeName() { + return employeeName; + } + + public void setEmployeeName(String employeeName) { + this.employeeName = employeeName; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java new file mode 100644 index 0000000000..53781b0bc1 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java @@ -0,0 +1,57 @@ +package com.baeldung.nestedhashmaps; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +public class MapsUtil { + + MapsUtil() { + super(); + } + + public Map buildInnerMap(List batterList) { + Map innerBatterMap = new HashMap(); + + int index = 1; + for (String item : batterList) { + innerBatterMap.put(index, item); + index++; + } + + return innerBatterMap; + } + + public Map> createNestedMapfromStream(List listEmployee) { + Map> employeeAddressMap = listEmployee.stream() + .collect(Collectors.groupingBy(e -> e.getAddress().getAddressId(), + Collectors.toMap(f -> f.getAddress().getAddressLocation(), Employee::getEmployeeName))); + return employeeAddressMap; + } + + public Map> createNestedObjectMap(List listEmployee) { + Map> employeeMap = new HashMap<>(); + + employeeMap = listEmployee.stream().collect(Collectors.groupingBy((Employee emp) -> emp.getEmployeeId(), + Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress()))); + + return employeeMap; + } + + public Map flattenMap(Map source) { + Map converted = new HashMap<>(); + + for (Entry entry : source.entrySet()) { + if (entry.getValue() instanceof Map) { + flattenMap((Map) entry.getValue()) + .forEach((key, value) -> converted.put(entry.getKey() + "." + key, value)); + } else { + converted.put(entry.getKey().toString(), entry.getValue().toString()); + } + } + return converted; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java new file mode 100644 index 0000000000..ce63b72527 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java @@ -0,0 +1,118 @@ +package com.baeldung.nestedhashmaps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import java.util.List; + +public class NestedHashMapExamplesClass { + public static void main(String[] args) { + + MapsUtil mUtil = new MapsUtil(); + + List batterList = new ArrayList<>(); + Map> outerBakedGoodsMap = new HashMap<>(); + Map> outerBakedGoodsMap2 = new HashMap<>(); + Map> outerBakedGoodsMap3 = new HashMap<>(); + Map> outerBakedGoodsMap4 = new HashMap<>(); + + batterList.add("Mulberry"); + batterList.add("Cranberry"); + batterList.add("Blackberry"); + batterList.add("Mixed fruit"); + batterList.add("Orange"); + + outerBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList)); + + batterList.clear(); + batterList.add("Candy"); + batterList.add("Dark Chocolate"); + batterList.add("Chocolate"); + batterList.add("Jam filled"); + batterList.add("Pineapple"); + + outerBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList)); + outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList)); + batterList.clear(); + batterList.add("Banana"); + batterList.add("Red Velvet"); + batterList.add("Blackberry"); + batterList.add("Passion fruit"); + batterList.add("Kiwi"); + + outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap4.putAll(outerBakedGoodsMap); + + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap2)); + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap3)); + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap4)); + + outerBakedGoodsMap.get("Cake") + .put(6, "Cranberry"); + System.out.println(outerBakedGoodsMap); + + outerBakedGoodsMap.get("Cake") + .remove(5); + System.out.println(outerBakedGoodsMap); + + outerBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + System.out.println(outerBakedGoodsMap); + outerBakedGoodsMap.remove("Eclair"); + System.out.println(outerBakedGoodsMap); + System.out.println("Baked Goods Map Flattened: " + mUtil.flattenMap(outerBakedGoodsMap)); + + // Employees Map + List listEmployee = new ArrayList(); + + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + Map> employeeAddressMap = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap = mUtil.createNestedObjectMap(listEmployee); + Map> employeeMap2 = mUtil.createNestedObjectMap(listEmployee); + + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond")); + + Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee); + + System.out.println(employeeMap.equals(employeeMap1)); + System.out.println(employeeMap.equals(employeeMap2)); + + for (Map.Entry> outerBakedGoodsMapEntrySet : outerBakedGoodsMap.entrySet()) { + Map valueMap = outerBakedGoodsMapEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + for (Map.Entry> employeeEntrySet : employeeAddressMap.entrySet()) { + Map valueMap = employeeEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + System.out.println("Employee Address Map Flattened: " + mUtil.flattenMap(employeeAddressMap)); + + System.out.println(employeeAddressMap.equals(employeeAddressMap1)); + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java new file mode 100644 index 0000000000..a86e329bea --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java @@ -0,0 +1,243 @@ +package com.baeldung.nestedhashmaps; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThat; +import org.hamcrest.collection.IsMapContaining; + +public class NestedHashMapExamplesClassUnitTest { + private MapsUtil mUtil = new MapsUtil(); + private List batterList = new ArrayList<>(); + private List listEmployee = new ArrayList(); + private Map> actualBakedGoodsMap = new HashMap<>(); + private Map> actualEmployeeAddressMap = new HashMap<>(); + private Map> actualEmployeeMap = new HashMap<>(); + + @Test + public void whenCreateNestedHashMap_thenNestedMap() { + assertThat(mUtil.buildInnerMap(batterList), is(notNullValue())); + Assert.assertEquals(actualBakedGoodsMap.keySet().size(), 2); + Assert.assertThat(actualBakedGoodsMap, IsMapContaining.hasValue(equalTo(mUtil.buildInnerMap(batterList)))); + } + + private Map> setup() { + Map> expectedMap = new HashMap<>(); + expectedMap.put(Integer.valueOf(100), new HashMap() { + { + put("Misty Lanes", "Balin"); + } + }); + expectedMap.put(Integer.valueOf(200), new HashMap() { + { + put("Bag End", "Bilbo Baggins"); + } + }); + expectedMap.put(Integer.valueOf(156), new HashMap() { + { + put("Brambles Lane", "Bofur"); + } + }); + expectedMap.put(Integer.valueOf(124), new HashMap() { + { + put("Timbuktoo", "Thorin Oakenshield"); + } + }); + expectedMap.put(Integer.valueOf(23), new HashMap() { + { + put("Rivendell", "Elrond"); + } + }); + + return expectedMap; + } + + @Test + public void whenCreateNestedHashMapwithStreams_thenNestedMap() { + + Map> expectedMap = setup(); + + assertThat(actualEmployeeAddressMap, equalTo(expectedMap)); + } + + @Test + public void whenCompareTwoHashMapswithDifferenctValues_usingEquals_thenFail() { + Map> outerBakedGoodsMap2 = new HashMap<>(); + outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList)); + outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList)); + assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap); + + Map> outerBakedGoodsMap3 = new HashMap>(); + outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList)); + batterList = new ArrayList<>(); + batterList = Arrays.asList("Banana", "Red Velvet", "Blackberry", "Passion fruit", "Kiwi"); + + outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList)); + + assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap); + + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond")); + + Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee); + + assertNotEquals(employeeAddressMap1, actualEmployeeAddressMap); + + assertNotEquals(employeeMap1, actualEmployeeMap); + } + + @Test + public void whencomparingDifferentObjectValuesUsingEquals_thenFail() { + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + Map> employeeMap1 = listEmployee.stream().collect(Collectors.groupingBy( + (Employee emp) -> emp.getEmployeeId(), + Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress()))); + + assertNotSame(employeeMap1, actualEmployeeMap); + assertNotEquals(employeeMap1, actualEmployeeMap); + + Map> expectedMap = setupAddressObjectMap(); + assertNotSame(expectedMap, actualEmployeeMap); + assertNotEquals(expectedMap, actualEmployeeMap); + + } + + @Test + public void whenCompareTwoHashMapsUsingEquals_thenSuccess() { + Map> outerBakedGoodsMap4 = new HashMap<>(); + outerBakedGoodsMap4.putAll(actualBakedGoodsMap); + + assertEquals(actualBakedGoodsMap, outerBakedGoodsMap4); + + Map> employeeMap1 = new HashMap<>(); + employeeMap1.putAll(actualEmployeeMap); + assertEquals(actualEmployeeMap, employeeMap1); + } + + @Test + public void whenAddElementinHashMaps_thenSuccess() { + assertEquals(actualBakedGoodsMap.get("Cake").size(), 5); + actualBakedGoodsMap.get("Cake").put(6, "Cranberry"); + assertEquals(actualBakedGoodsMap.get("Cake").size(), 6); + } + + @Test + public void whenDeleteElementinHashMaps_thenSuccess() { + assertNotEquals(actualBakedGoodsMap.get("Cake").get(5), null); + actualBakedGoodsMap.get("Cake").remove(5); + assertEquals(actualBakedGoodsMap.get("Cake").get(5), null); + + actualBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + assertNotEquals(actualBakedGoodsMap.get("Eclair").get(1), null); + actualBakedGoodsMap.get("Eclair").remove(1); + assertEquals(actualBakedGoodsMap.get("Eclair").get(1), null); + + actualBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + assertNotEquals(actualBakedGoodsMap.get("Eclair"), null); + actualBakedGoodsMap.remove("Eclair"); + assertEquals(actualBakedGoodsMap.get("Eclair"), null); + } + + @Test + public void whenFlattenMap_thenRemovesNesting() { + + Map flattenedBakedGoodsMap = mUtil.flattenMap(actualBakedGoodsMap); + assertThat(flattenedBakedGoodsMap, IsMapContaining.hasKey("Donut.2")); + + Map flattenedEmployeeAddressMap = mUtil.flattenMap(actualEmployeeAddressMap); + assertThat(flattenedEmployeeAddressMap, IsMapContaining.hasKey("200.Bag End")); + } + + @Before + public void buildMaps() { + + batterList = Arrays.asList("Mulberry", "Cranberry", "Blackberry", "Mixed fruit", "Orange"); + + actualBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList)); + + batterList = new ArrayList<>(); + batterList = Arrays.asList("Candy", "Dark Chocolate", "Chocolate", "Jam filled", "Pineapple"); + + actualBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList)); + + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + actualEmployeeAddressMap = mUtil.createNestedMapfromStream(listEmployee); + + actualEmployeeMap = mUtil.createNestedObjectMap(listEmployee); + + } + + private Map> setupAddressObjectMap() { + + Map> expectedMap = new HashMap<>(); + + expectedMap.put(1, new HashMap() { + { + put(124, new Address(124, "Timbuktoo")); + } + }); + expectedMap.put(2, new HashMap() { + { + put(100, new Address(100, "Misty Lanes")); + } + }); + expectedMap.put(3, new HashMap() { + { + put(156, new Address(156, "Brambles Lane")); + } + }); + expectedMap.put(4, new HashMap() { + { + put(200, new Address(200, "Bag End")); + } + }); + expectedMap.put(5, new HashMap() { + { + put(23, new Address(23, "Rivendell")); + } + }); + return expectedMap; + } + +} From f200ce5b143e605f729941c97cf321c730d09382 Mon Sep 17 00:00:00 2001 From: Teica Date: Sun, 7 Nov 2021 22:19:54 +0100 Subject: [PATCH 29/31] BAEL-5227 check if a first letter of a string is uppercase (#11424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * BAEL-5227 check if the first letter of a string is uppercase * BAEL-5227 renaming the tests * BAEL-5227 renaming the tests * BAEL-5227 renaming the tests Co-authored-by: Matea Pejčinović --- .../StringFirstCharacterUppercase.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java diff --git a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java new file mode 100644 index 0000000000..0d9d3b6431 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java @@ -0,0 +1,32 @@ +package com.baeldung.isuppercase; + +import com.google.common.base.Ascii; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class StringFirstCharacterUppercase { + + @Test + public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() { + String example = "Katie"; + Assertions.assertTrue(Character.isUpperCase(example.charAt(0))); + } + + @Test + public void givenString_whenCheckingWithRegex_thenStringCapitalized() { + String example = "Katie"; + String regEx = "[A-Z]\\w*"; + assertThat(example, matchesPattern(regEx)); + } + + @Test + public void givenString_whenCheckingWithGuava_thenStringCapitalized() { + String example = "Katie"; + Assertions.assertTrue(Ascii.isUpperCase(example.charAt(0))); + } +} From 4a3a73111f6b5afa60d04a78b142b770afb31014 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Mon, 8 Nov 2021 13:41:04 +0530 Subject: [PATCH 30/31] JAVA-1672: removing redundant version declarations for surefire plugin --- guest/junit5-example/pom.xml | 2 +- spring-ejb/ejb-beans/pom.xml | 1 - spring-jenkins-pipeline/pom.xml | 1 + spring-security-modules/spring-ldap/pom.xml | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml index 3bfa72f21f..cc52b0e3d7 100644 --- a/guest/junit5-example/pom.xml +++ b/guest/junit5-example/pom.xml @@ -40,8 +40,8 @@ + org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} math diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 8a41da5448..6f20d949b0 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -135,7 +135,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} always diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 6f00dd5820..4e84bb8c70 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -62,6 +62,7 @@ + org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-security-modules/spring-ldap/pom.xml b/spring-security-modules/spring-ldap/pom.xml index 44f754673f..086be2df5a 100644 --- a/spring-security-modules/spring-ldap/pom.xml +++ b/spring-security-modules/spring-ldap/pom.xml @@ -106,7 +106,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} integration-test From 1d328e79d353a714cabbc7ea754ac8262c5141b7 Mon Sep 17 00:00:00 2001 From: chaos2418 <> Date: Mon, 8 Nov 2021 13:45:41 +0530 Subject: [PATCH 31/31] JAVA-1672: removing redundant junit dependencies --- core-java-modules/core-java-17/pom.xml | 12 ------------ .../core-java-collections-maps-4/pom.xml | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml index e422bd62bb..b1811ecf7f 100644 --- a/core-java-modules/core-java-17/pom.xml +++ b/core-java-modules/core-java-17/pom.xml @@ -23,18 +23,6 @@ ${assertj.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index 93ec782c94..2109804ff0 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -25,13 +25,13 @@ junit junit - 4.12 + ${junit.version} test org.hamcrest hamcrest-all - 1.3 + ${hamcrest-all.version} test