From ad893be8ac4d6fea0f1e2799cad6b3c8c3ba40c1 Mon Sep 17 00:00:00 2001 From: palani-a Date: Sun, 30 Jan 2022 22:12:18 +0530 Subject: [PATCH] Implementation for Simple Hexagonal Architecture --- .../ConferenceApplication.java | 15 ++ .../controllers/SessionController.java | 54 ++++++++ .../controllers/SpeakerController.java | 57 ++++++++ .../simplehexagonal/domain/Session.java | 58 ++++++++ .../simplehexagonal/domain/Speaker.java | 90 ++++++++++++ .../domain/repository/SessionRepository.java | 17 +++ .../domain/repository/SpeakerRepository.java | 17 +++ .../domain/services/SessionService.java | 19 +++ .../domain/services/SessionServiceImpl.java | 40 ++++++ .../domain/services/SpeakerService.java | 19 +++ .../domain/services/SpeakerServiceImpl.java | 39 ++++++ .../config/BeanConfiguration.java | 30 ++++ .../repositories/SessionEntity.java | 99 ++++++++++++++ .../repositories/SessionJpaRepository.java | 9 ++ .../repositories/SessionRepositoryImpl.java | 42 ++++++ .../repositories/SpeakerEntity.java | 129 ++++++++++++++++++ .../repositories/SpeakerJpaRepository.java | 9 ++ .../repositories/SpeakerRepositoryImpl.java | 42 ++++++ .../resources/simple-hexagonal.properties | 8 ++ .../services/SessionServiceUnitTest.java | 74 ++++++++++ .../services/SpeakerServiceUnitTest.java | 74 ++++++++++ 21 files changed, 941 insertions(+) create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/ConferenceApplication.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SessionController.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SpeakerController.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/Session.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/Speaker.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SessionRepository.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SpeakerRepository.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionService.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionServiceImpl.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerService.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceImpl.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/config/BeanConfiguration.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionEntity.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionJpaRepository.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionRepositoryImpl.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerEntity.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerJpaRepository.java create mode 100644 ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerRepositoryImpl.java create mode 100644 ddd/src/main/resources/simple-hexagonal.properties create mode 100644 ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SessionServiceUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceUnitTest.java diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/ConferenceApplication.java b/ddd/src/main/java/com/baeldung/simplehexagonal/ConferenceApplication.java new file mode 100644 index 0000000000..106b013ab6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/ConferenceApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.simplehexagonal; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication(scanBasePackages = "com.baeldung.simplehexagonal") +@PropertySource(value = { "classpath:simple-hexagonal.properties" }) +public class ConferenceApplication { + + public static void main(String[] args) { + SpringApplication.run(ConferenceApplication.class, args); + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SessionController.java b/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SessionController.java new file mode 100644 index 0000000000..5cc3880851 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SessionController.java @@ -0,0 +1,54 @@ +package com.baeldung.simplehexagonal.application.controllers; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.simplehexagonal.domain.Session; +import com.baeldung.simplehexagonal.domain.services.SessionService; + +@RestController +@RequestMapping("/api/v1/sessions") +public class SessionController { + + private SessionService sessionService; + + @Autowired + public SessionController(SessionService sessionService) { + this.sessionService = sessionService; + } + + @GetMapping + public List findAll() { + return sessionService.findAll(); + } + + @GetMapping + @RequestMapping("{id}") + public Session get(@PathVariable Long id) { + return sessionService.get(id); + } + + @PostMapping + public Session create(@RequestBody final Session session) { + return sessionService.create(session); + } + + @RequestMapping(value = "{id}", method = RequestMethod.DELETE) + public void delete(@PathVariable Long id) { + sessionService.delete(id); + } + + @RequestMapping(value = "{id}", method = RequestMethod.PUT) + public Session update(@PathVariable Long id, @RequestBody Session session) { + return sessionService.update(id, session); + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SpeakerController.java b/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SpeakerController.java new file mode 100644 index 0000000000..bea5370da7 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/application/controllers/SpeakerController.java @@ -0,0 +1,57 @@ +package com.baeldung.simplehexagonal.application.controllers; + +import java.util.List; + +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.simplehexagonal.domain.Speaker; +import com.baeldung.simplehexagonal.domain.services.SpeakerService; + +@RestController +@RequestMapping("/api/v1/speakers") +public class SpeakerController { + + private SpeakerService speakerService; + + @Autowired + public SpeakerController(SpeakerService speakerService) { + this.speakerService = speakerService; + } + + @GetMapping + public List findAll() { + return speakerService.findAll(); + } + + @GetMapping + @RequestMapping("{id}") + public Speaker get(@PathVariable Long id) { + return speakerService.get(id); + } + + @PostMapping + public Speaker create(@RequestBody final Speaker speaker) { + return speakerService.save(speaker); + } + + @RequestMapping(value = "{id}", method = RequestMethod.DELETE) + public void delete(@PathVariable Long id) { + speakerService.delete(id); + } + + @RequestMapping(value = "{id}", method = RequestMethod.PUT) + public Speaker update(@PathVariable Long id, @RequestBody Speaker speaker) { + Speaker currentSpeaker = speakerService.get(id); + BeanUtils.copyProperties(speaker, currentSpeaker, "speaker_id"); + return speakerService.save(currentSpeaker); + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Session.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Session.java new file mode 100644 index 0000000000..93c88b1461 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Session.java @@ -0,0 +1,58 @@ +package com.baeldung.simplehexagonal.domain; + +import java.util.List; + +public class Session { + + private Long sessionId; + + private String sessionName; + private String sessionDescription; + private Integer sessionLength; + + private List speakers; + + public Session() { + } + + public Long getSessionId() { + return sessionId; + } + + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + public String getSessionName() { + return sessionName; + } + + public void setSessionName(String sessionName) { + this.sessionName = sessionName; + } + + public String getSessionDescription() { + return sessionDescription; + } + + public void setSessionDescription(String sessionDescription) { + this.sessionDescription = sessionDescription; + } + + public Integer getSessionLength() { + return sessionLength; + } + + public void setSessionLength(Integer sessionLength) { + this.sessionLength = sessionLength; + } + + public List getSpeakers() { + return speakers; + } + + public void setSpeakers(List speakers) { + this.speakers = speakers; + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Speaker.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Speaker.java new file mode 100644 index 0000000000..078c7d38f7 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/Speaker.java @@ -0,0 +1,90 @@ +package com.baeldung.simplehexagonal.domain; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class Speaker { + + private Long speakerId; + + private String firstName; + private String lastName; + private String title; + private String company; + private String speakerBio; + + private byte[] speakerPhoto; + + @JsonIgnore + private List sessions; + + public Speaker() { + + } + + public Long getSpeakerId() { + return speakerId; + } + + public void setSpeakerId(Long speakerId) { + this.speakerId = speakerId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getSpeakerBio() { + return speakerBio; + } + + public void setSpeakerBio(String speakerBio) { + this.speakerBio = speakerBio; + } + + public byte[] getSpeakerPhoto() { + return speakerPhoto; + } + + public void setSpeakerPhoto(byte[] speakerPhoto) { + this.speakerPhoto = speakerPhoto; + } + + public List getSessions() { + return sessions; + } + + public void setSessions(List sessions) { + this.sessions = sessions; + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SessionRepository.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SessionRepository.java new file mode 100644 index 0000000000..7011506ffb --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SessionRepository.java @@ -0,0 +1,17 @@ +package com.baeldung.simplehexagonal.domain.repository; + +import java.util.List; + +import com.baeldung.simplehexagonal.domain.Session; + +public interface SessionRepository { + + List findAll(); + + Session findById(Long id); + + Session save(Session session); + + void deleteById(Long id); + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SpeakerRepository.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SpeakerRepository.java new file mode 100644 index 0000000000..a12863f85f --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/repository/SpeakerRepository.java @@ -0,0 +1,17 @@ +package com.baeldung.simplehexagonal.domain.repository; + +import java.util.List; + +import com.baeldung.simplehexagonal.domain.Speaker; + +public interface SpeakerRepository { + + List findAll(); + + Speaker findById(Long id); + + Speaker save(Speaker Speaker); + + void deleteById(Long id); + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionService.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionService.java new file mode 100644 index 0000000000..eff942672e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionService.java @@ -0,0 +1,19 @@ +package com.baeldung.simplehexagonal.domain.services; + +import java.util.List; + +import com.baeldung.simplehexagonal.domain.Session; + +public interface SessionService { + + List findAll(); + + Session get(Long id); + + Session create(Session session); + + void delete(Long id); + + Session update(Long id, Session session); + +} \ No newline at end of file diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionServiceImpl.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionServiceImpl.java new file mode 100644 index 0000000000..abf8ea1f86 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SessionServiceImpl.java @@ -0,0 +1,40 @@ +package com.baeldung.simplehexagonal.domain.services; + +import java.util.List; + +import org.springframework.beans.BeanUtils; + +import com.baeldung.simplehexagonal.domain.Session; +import com.baeldung.simplehexagonal.domain.repository.SessionRepository; + +public class SessionServiceImpl implements SessionService { + + private SessionRepository sessionRepository; + + public SessionServiceImpl(SessionRepository sessionRepository) { + this.sessionRepository = sessionRepository; + } + + public List findAll() { + return sessionRepository.findAll(); + } + + public Session get(Long id) { + return sessionRepository.findById(id); + } + + public Session create(Session session) { + return sessionRepository.save(session); + } + + public void delete(Long id) { + sessionRepository.deleteById(id); + } + + public Session update(Long id, Session session) { + Session currentSession = sessionRepository.findById(id); + BeanUtils.copyProperties(session, currentSession, "session_id"); + return sessionRepository.save(currentSession); + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerService.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerService.java new file mode 100644 index 0000000000..041fb24fe1 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerService.java @@ -0,0 +1,19 @@ +package com.baeldung.simplehexagonal.domain.services; + +import java.util.List; + +import com.baeldung.simplehexagonal.domain.Speaker; + +public interface SpeakerService { + + List findAll(); + + Speaker get(Long id); + + Speaker save(Speaker speaker); + + void delete(Long id); + + Speaker update(Long id, Speaker speaker); + +} \ No newline at end of file diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceImpl.java b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceImpl.java new file mode 100644 index 0000000000..cf01259983 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceImpl.java @@ -0,0 +1,39 @@ +package com.baeldung.simplehexagonal.domain.services; + +import java.util.List; + +import org.springframework.beans.BeanUtils; + +import com.baeldung.simplehexagonal.domain.Speaker; +import com.baeldung.simplehexagonal.domain.repository.SpeakerRepository; + +public class SpeakerServiceImpl implements SpeakerService { + + private SpeakerRepository speakerRepository; + + public SpeakerServiceImpl(SpeakerRepository speakerRepository) { + this.speakerRepository = speakerRepository; + } + + public List findAll() { + return speakerRepository.findAll(); + } + + public Speaker get(Long id) { + return speakerRepository.findById(id); + } + + public Speaker save(Speaker speaker) { + return speakerRepository.save(speaker); + } + + public void delete(Long id) { + speakerRepository.deleteById(id); + } + + public Speaker update(Long id, Speaker speaker) { + Speaker currentSpeaker = speakerRepository.findById(id); + BeanUtils.copyProperties(speaker, currentSpeaker, "speaker_id"); + return speakerRepository.save(currentSpeaker); + } +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/config/BeanConfiguration.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/config/BeanConfiguration.java new file mode 100644 index 0000000000..c1875354d9 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/config/BeanConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.simplehexagonal.infrastructure.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import com.baeldung.simplehexagonal.ConferenceApplication; +import com.baeldung.simplehexagonal.domain.repository.SessionRepository; +import com.baeldung.simplehexagonal.domain.repository.SpeakerRepository; +import com.baeldung.simplehexagonal.domain.services.SessionService; +import com.baeldung.simplehexagonal.domain.services.SessionServiceImpl; +import com.baeldung.simplehexagonal.domain.services.SpeakerService; +import com.baeldung.simplehexagonal.domain.services.SpeakerServiceImpl; + +@Configuration +@ComponentScan(basePackageClasses = ConferenceApplication.class) +@EnableJpaRepositories(basePackages = "com.baeldung.simplehexagonal") +public class BeanConfiguration { + + @Bean + SessionService sessionService(SessionRepository sessionRepository) { + return new SessionServiceImpl(sessionRepository); + } + + @Bean + SpeakerService speakerService(SpeakerRepository speakerRepository) { + return new SpeakerServiceImpl(speakerRepository); + } +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionEntity.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionEntity.java new file mode 100644 index 0000000000..b9d9c765da --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionEntity.java @@ -0,0 +1,99 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; + +import com.baeldung.simplehexagonal.domain.Session; +import com.baeldung.simplehexagonal.domain.Speaker; + +@Entity(name = "sessions") +public class SessionEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long session_id; + + private String session_name; + private String session_description; + private Integer session_length; + + @ManyToMany + @JoinTable(name = "session_speakers", joinColumns = @JoinColumn(name = "session_id"), inverseJoinColumns = @JoinColumn(name = "speaker_id")) + private List speakerEntities; + + public SessionEntity() { + } + + public SessionEntity(Session session) { + this.setSession_id(session.getSessionId()); + this.setSession_name(session.getSessionName()); + this.setSession_description(session.getSessionDescription()); + this.setSession_length(session.getSessionLength()); + List speakerEntities = session.getSpeakers() + .stream() + .map(it -> new SpeakerEntity(it)) + .toList(); + this.speakerEntities = speakerEntities; + } + + public Session toSession() { + Session session = new Session(); + session.setSessionId(session_id); + session.setSessionName(session_name); + session.setSessionDescription(session_description); + session.setSessionLength(session_length); + List speakers = speakerEntities.stream() + .map(it -> it.toSpeaker()) + .toList(); + session.setSpeakers(speakers); + return session; + } + + public Long getSession_id() { + return session_id; + } + + public void setSession_id(Long session_id) { + this.session_id = session_id; + } + + public String getSession_name() { + return session_name; + } + + public void setSession_name(String session_name) { + this.session_name = session_name; + } + + public String getSession_description() { + return session_description; + } + + public void setSession_description(String session_description) { + this.session_description = session_description; + } + + public Integer getSession_length() { + return session_length; + } + + public void setSession_length(Integer session_length) { + this.session_length = session_length; + } + + public List getSpeakerEntities() { + return speakerEntities; + } + + public void setSpeakerEntities(List speakerEntities) { + this.speakerEntities = speakerEntities; + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionJpaRepository.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionJpaRepository.java new file mode 100644 index 0000000000..83cc944dd6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionJpaRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SessionJpaRepository extends JpaRepository { + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionRepositoryImpl.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionRepositoryImpl.java new file mode 100644 index 0000000000..3af9021fff --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SessionRepositoryImpl.java @@ -0,0 +1,42 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.simplehexagonal.domain.Session; +import com.baeldung.simplehexagonal.domain.repository.SessionRepository; + +@Component +public class SessionRepositoryImpl implements SessionRepository { + + @Autowired + private SessionJpaRepository sessionJpaRepository; + + @Override + public List findAll() { + return sessionJpaRepository.findAll() + .stream() + .map(SessionEntity::toSession) + .collect(Collectors.toList()); + } + + @Override + public Session findById(Long id) { + SessionEntity sessionEntity = sessionJpaRepository.getById(id); + return sessionEntity.toSession(); + } + + @Override + public Session save(Session session) { + return sessionJpaRepository.saveAndFlush(new SessionEntity(session)) + .toSession(); + } + + public void deleteById(Long id) { + sessionJpaRepository.deleteById(id); + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerEntity.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerEntity.java new file mode 100644 index 0000000000..8937ac578f --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerEntity.java @@ -0,0 +1,129 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.ManyToMany; + +import org.hibernate.annotations.Type; + +import com.baeldung.simplehexagonal.domain.Speaker; +import com.fasterxml.jackson.annotation.JsonIgnore; + +@Entity(name = "speakers") +public class SpeakerEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long speaker_id; + + private String first_name; + private String last_name; + private String title; + private String company; + private String speaker_bio; + + @Lob + @Type(type = "org.hibernate.type.BinaryType") + private byte[] speaker_photo; + + @JsonIgnore + @ManyToMany(mappedBy = "speakerEntities", fetch = FetchType.LAZY) + private List sessionEntities; + + public SpeakerEntity() { + + } + + public SpeakerEntity(Speaker speaker) { + this.setSpeaker_id(speaker.getSpeakerId()); + this.setFirst_name(speaker.getFirstName()); + this.setLast_name(speaker.getLastName()); + this.setTitle(speaker.getTitle()); + this.setCompany(speaker.getCompany()); + this.setSpeaker_bio(speaker.getSpeakerBio()); + this.setSpeaker_photo(speaker.getSpeakerPhoto()); + } + + public Speaker toSpeaker() { + Speaker speaker = new Speaker(); + speaker.setSpeakerId(speaker_id); + speaker.setFirstName(first_name); + speaker.setLastName(last_name); + speaker.setTitle(title); + speaker.setCompany(company); + speaker.setSpeakerBio(speaker_bio); + speaker.setSpeakerPhoto(speaker_photo); + return speaker; + } + + public Long getSpeaker_id() { + return speaker_id; + } + + public void setSpeaker_id(Long speaker_id) { + this.speaker_id = speaker_id; + } + + public String getFirst_name() { + return first_name; + } + + public void setFirst_name(String first_name) { + this.first_name = first_name; + } + + public String getLast_name() { + return last_name; + } + + public void setLast_name(String last_name) { + this.last_name = last_name; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getSpeaker_bio() { + return speaker_bio; + } + + public void setSpeaker_bio(String speaker_bio) { + this.speaker_bio = speaker_bio; + } + + public byte[] getSpeaker_photo() { + return speaker_photo; + } + + public void setSpeaker_photo(byte[] speaker_photo) { + this.speaker_photo = speaker_photo; + } + + public List getSessionEntities() { + return sessionEntities; + } + + public void setSessionEntities(List sessionEntities) { + this.sessionEntities = sessionEntities; + } + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerJpaRepository.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerJpaRepository.java new file mode 100644 index 0000000000..9bbce066fb --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerJpaRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SpeakerJpaRepository extends JpaRepository { + +} diff --git a/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerRepositoryImpl.java b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerRepositoryImpl.java new file mode 100644 index 0000000000..294bd0a1ff --- /dev/null +++ b/ddd/src/main/java/com/baeldung/simplehexagonal/infrastructure/repositories/SpeakerRepositoryImpl.java @@ -0,0 +1,42 @@ +package com.baeldung.simplehexagonal.infrastructure.repositories; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.simplehexagonal.domain.Speaker; +import com.baeldung.simplehexagonal.domain.repository.SpeakerRepository; + +@Component +public class SpeakerRepositoryImpl implements SpeakerRepository { + + @Autowired + private SpeakerJpaRepository speakerJpaRepository; + + @Override + public List findAll() { + return speakerJpaRepository.findAll() + .stream() + .map(SpeakerEntity::toSpeaker) + .collect(Collectors.toList()); + } + + @Override + public Speaker findById(Long id) { + SpeakerEntity speakerEntity = speakerJpaRepository.getById(id); + return speakerEntity.toSpeaker(); + } + + @Override + public Speaker save(Speaker speaker) { + return speakerJpaRepository.saveAndFlush(new SpeakerEntity(speaker)) + .toSpeaker(); + } + + public void deleteById(Long id) { + speakerJpaRepository.deleteById(id); + } + +} diff --git a/ddd/src/main/resources/simple-hexagonal.properties b/ddd/src/main/resources/simple-hexagonal.properties new file mode 100644 index 0000000000..6277d15543 --- /dev/null +++ b/ddd/src/main/resources/simple-hexagonal.properties @@ -0,0 +1,8 @@ +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password=admin +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.hibernate.ddl-auto=none +spring.jpa.show-sql=true +spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false \ No newline at end of file diff --git a/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SessionServiceUnitTest.java b/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SessionServiceUnitTest.java new file mode 100644 index 0000000000..3fdc34e402 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SessionServiceUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.simplehexagonal.domain.services; + +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.util.Assert.notNull; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.baeldung.simplehexagonal.domain.Session; +import com.baeldung.simplehexagonal.domain.repository.SessionRepository; +import com.baeldung.simplehexagonal.domain.services.SessionServiceImpl; + +public class SessionServiceUnitTest { + + private SessionServiceImpl sessionService; + + private SessionRepository sessionRepository; + + Session session; + + @BeforeEach + void setUp() { + sessionRepository = mock(SessionRepository.class); + sessionService = new SessionServiceImpl(sessionRepository); + + session = new Session(); + session.setSessionId(1L); + session.setSessionName("Introduction to Hexagonal Architecture"); + session.setSessionDescription("A quick and practical eample of Hexagonal Architecture"); + session.setSessionLength(30); + + when(sessionRepository.save(Mockito.any())).thenReturn(session); + when(sessionRepository.findById(1L)).thenReturn(session); + } + + @Test + void testFindAll() { + List list = sessionService.findAll(); + notNull(list, "should not return null"); + } + + @Test + void testGet() { + Session mySession = sessionService.get(1L); + notNull(mySession, "should not return null"); + } + + @Test + void testCreate() { + session = sessionService.create(new Session()); + notNull(session.getSessionId(), "Id should be populated"); + } + + @Test + void testDelete() { + try { + sessionService.delete(1L); + } catch (Exception e) { + fail("Should not throw error"); + } + } + + @Test + void testUpdate() { + Session updatedSession = sessionService.update(1L, new Session()); + notNull(updatedSession, "Id should be populated"); + } + +} diff --git a/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceUnitTest.java b/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceUnitTest.java new file mode 100644 index 0000000000..5fd3f9dcab --- /dev/null +++ b/ddd/src/test/java/com/baeldung/simplehexagonal/domain/services/SpeakerServiceUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.simplehexagonal.domain.services; + +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.util.Assert.notNull; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.baeldung.simplehexagonal.domain.Speaker; +import com.baeldung.simplehexagonal.domain.repository.SpeakerRepository; +import com.baeldung.simplehexagonal.domain.services.SpeakerServiceImpl; + +public class SpeakerServiceUnitTest { + + private SpeakerServiceImpl speakerService; + + private SpeakerRepository speakerRepository; + + Speaker speaker; + + @BeforeEach + void setUp() { + speakerRepository = mock(SpeakerRepository.class); + speakerService = new SpeakerServiceImpl(speakerRepository); + + speaker = new Speaker(); + speaker.setSpeakerId(1L); + speaker.setTitle("Mr"); + speaker.setFirstName("Palani"); + speaker.setLastName("Arun"); + + when(speakerRepository.save(Mockito.any())).thenReturn(speaker); + when(speakerRepository.findById(1L)).thenReturn(speaker); + } + + @Test + void testFindAll() { + List list = speakerService.findAll(); + notNull(list, "should not return null"); + } + + @Test + void testGet() { + Speaker mySpeaker = speakerService.get(1L); + notNull(mySpeaker, "should not return null"); + } + + @Test + void testCreate() { + speaker = speakerService.save(new Speaker()); + notNull(speaker.getSpeakerId(), "Id should be populated"); + } + + @Test + void testDelete() { + try { + speakerService.delete(1L); + } catch (Exception e) { + fail("Should not throw error"); + } + } + + @Test + void testUpdate() { + Speaker updatedSpeaker = speakerService.update(1L, new Speaker()); + notNull(updatedSpeaker, "Id should be populated"); + } + +}