diff --git a/src/main/java/com/mediamanager/mapper/TrackHasArtistMapper.java b/src/main/java/com/mediamanager/mapper/TrackHasArtistMapper.java new file mode 100644 index 0000000..f8a0d20 --- /dev/null +++ b/src/main/java/com/mediamanager/mapper/TrackHasArtistMapper.java @@ -0,0 +1,47 @@ +package com.mediamanager.mapper; + +import com.mediamanager.model.TrackHasArtist; +import com.mediamanager.protocol.messages.TrackHasArtistMessages; + +public class TrackHasArtistMapper { + public static TrackHasArtistMessages.TrackHasArtist toProtobuf(TrackHasArtist entity) { + if (entity == null) { + return null; + } + + TrackHasArtistMessages.TrackHasArtist.Builder builder = TrackHasArtistMessages.TrackHasArtist.newBuilder(); + + Integer id = entity.getId(); + if (id != null) { + builder.setId(id); + } + + // Map Track foreign key + if (entity.getTrack() != null && entity.getTrack().getId() != null) { + builder.setFkTrackId(entity.getTrack().getId()); + } + + // Map Artist foreign key + if (entity.getArtist() != null && entity.getArtist().getId() != null) { + builder.setFkArtistId(entity.getArtist().getId()); + } + + return builder.build(); + } + + public static TrackHasArtist toEntity(TrackHasArtistMessages.TrackHasArtist protobuf) { + if (protobuf == null) { + return null; + } + + TrackHasArtist entity = new TrackHasArtist(); + + if (protobuf.getId() > 0) { + entity.setId(protobuf.getId()); + } + + // Note: Foreign key relationships (Track, Artist) are handled in the service layer + + return entity; + } +} diff --git a/src/main/java/com/mediamanager/model/TrackHasArtist.java b/src/main/java/com/mediamanager/model/TrackHasArtist.java new file mode 100644 index 0000000..abba89e --- /dev/null +++ b/src/main/java/com/mediamanager/model/TrackHasArtist.java @@ -0,0 +1,55 @@ +package com.mediamanager.model; + +import jakarta.persistence.*; + +@Entity +@Table(name = "trackhasartist") +public class TrackHasArtist { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_track_id", nullable = false) + private Track track; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_artist_id", nullable = false) + private Artist artist; + + public TrackHasArtist() {} + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Track getTrack() { + return track; + } + + public void setTrack(Track track) { + this.track = track; + } + + public Artist getArtist() { + return artist; + } + + public void setArtist(Artist artist) { + this.artist = artist; + } + + @Override + public String toString() { + return "TrackHasArtist{" + + "id=" + id + + ", trackId=" + (track != null ? track.getId() : null) + + ", artistId=" + (artist != null ? artist.getId() : null) + + '}'; + } +} diff --git a/src/main/java/com/mediamanager/repository/TrackHasArtistRepository.java b/src/main/java/com/mediamanager/repository/TrackHasArtistRepository.java new file mode 100644 index 0000000..1d81f37 --- /dev/null +++ b/src/main/java/com/mediamanager/repository/TrackHasArtistRepository.java @@ -0,0 +1,85 @@ +package com.mediamanager.repository; + + +import com.mediamanager.model.TrackHasArtist; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + + +import java.util.List; +import java.util.Optional; + +public class TrackHasArtistRepository { + private static final Logger logger = LogManager.getLogger(TrackHasArtistRepository.class); + + private final EntityManagerFactory entityManagerFactory; + + public TrackHasArtistRepository(EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + public TrackHasArtist save(TrackHasArtist trackHasArtist) { + logger.debug("Saving TrackHasArtist: {}", trackHasArtist); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + em.persist(trackHasArtist); + em.getTransaction().commit(); + logger.debug("TrackHasArtist has been saved successfully"); + return trackHasArtist; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while saving TrackHasArtist: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public List findAll() { + logger.debug("Finding All TrackHasArtist"); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + return em.createQuery("select t from TrackHasArtist t", TrackHasArtist.class).getResultList(); + }finally { + if (em.isOpen()) em.close(); + } + } + + public Optional findById(Integer id) { + logger.debug("Finding TrackHasArtist with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + TrackHasArtist trackHasArtist = em.find(TrackHasArtist.class, id); + return Optional.ofNullable(trackHasArtist); + }finally { + if (em.isOpen()) em.close(); + } + } + + public boolean deleteById(Integer id){ + logger.debug("Deleting TrackHasArtist with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try{ + TrackHasArtist trackHasArtist = em.find(TrackHasArtist.class, id); + if (trackHasArtist == null) { + em.getTransaction().rollback(); + return false; + } + em.remove(trackHasArtist); + em.getTransaction().commit(); + logger.debug("TrackHasArtist has been deleted successfully"); + return true; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while deleting TrackHasArtist: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + +} diff --git a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java index da043f5..724c87d 100644 --- a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java +++ b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java @@ -13,6 +13,7 @@ import com.mediamanager.service.bitdepth.BitDepthService; import com.mediamanager.service.bitrate.BitRateService; import com.mediamanager.service.composer.ComposerService; import com.mediamanager.service.trackhasgenre.TrackHasGenreService; +import com.mediamanager.service.trackhasartist.TrackHasArtistService; import com.mediamanager.repository.GenreRepository; import com.mediamanager.service.artist.ArtistService; @@ -117,6 +118,10 @@ public class DelegateActionManager { TrackHasGenreService trackHasGenreService = new TrackHasGenreService(trackHasGenreRepository, trackRepository, genreRepository); serviceLocator.register(TrackHasGenreService.class, trackHasGenreService); + TrackHasArtistRepository trackHasArtistRepository = new TrackHasArtistRepository(entityManagerFactory); + TrackHasArtistService trackHasArtistService = new TrackHasArtistService(trackHasArtistRepository, trackRepository, artistRepository); + serviceLocator.register(TrackHasArtistService.class, trackHasArtistService); + serviceLocator.logRegisteredServices(); logger.info("Services initialized successfully"); diff --git a/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/CreateTrackHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/CreateTrackHasArtistHandler.java new file mode 100644 index 0000000..37af6c3 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/CreateTrackHasArtistHandler.java @@ -0,0 +1,54 @@ +package com.mediamanager.service.delegate.handler.trackhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackHasArtistMapper; +import com.mediamanager.model.TrackHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.trackhasartist.TrackHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("trackhasartist.create") +public class CreateTrackHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(CreateTrackHasArtistHandler.class); + private final TrackHasArtistService trackHasArtistService; + + public CreateTrackHasArtistHandler(TrackHasArtistService trackHasArtistService) { + this.trackHasArtistService = trackHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + TrackHasArtistMessages.CreateTrackHasArtistRequest createRequest = + TrackHasArtistMessages.CreateTrackHasArtistRequest.parseFrom(requestPayload); + + TrackHasArtist trackHasArtist = trackHasArtistService.createTrackHasArtist( + createRequest.getFkTrackId() > 0 ? createRequest.getFkTrackId() : null, + createRequest.getFkArtistId() > 0 ? createRequest.getFkArtistId() : null + ); + + TrackHasArtistMessages.TrackHasArtist trackHasArtistProto = TrackHasArtistMapper.toProtobuf(trackHasArtist); + TrackHasArtistMessages.CreateTrackHasArtistResponse createTrackHasArtistResponse = TrackHasArtistMessages.CreateTrackHasArtistResponse.newBuilder() + .setTrackhasartist(trackHasArtistProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(createTrackHasArtistResponse.toByteString()); + } catch (IllegalArgumentException e) { + logger.error("Validation error", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(400) + .setPayload(ByteString.copyFromUtf8("Validation error: " + e.getMessage())); + + } catch (Exception e) { + logger.error("Error creating track has artist", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/DeleteTrackHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/DeleteTrackHasArtistHandler.java new file mode 100644 index 0000000..1b7c643 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/DeleteTrackHasArtistHandler.java @@ -0,0 +1,62 @@ +package com.mediamanager.service.delegate.handler.trackhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.trackhasartist.TrackHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("trackhasartist.delete") +public class DeleteTrackHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(DeleteTrackHasArtistHandler.class); + + private final TrackHasArtistService trackHasArtistService; + + public DeleteTrackHasArtistHandler(TrackHasArtistService trackHasArtistService) { + this.trackHasArtistService = trackHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + + try { + TrackHasArtistMessages.DeleteTrackHasArtistRequest deleteRequest = + TrackHasArtistMessages.DeleteTrackHasArtistRequest.parseFrom(requestPayload); + int id = deleteRequest.getId(); + boolean success = trackHasArtistService.deleteTrackHasArtist(id); + TrackHasArtistMessages.DeleteTrackHasArtistResponse deleteResponse; + if (success) { + deleteResponse = TrackHasArtistMessages.DeleteTrackHasArtistResponse.newBuilder() + .setSuccess(true) + .setMessage("Track has artist deleted successfully") + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(deleteResponse.toByteString()); + } else { + deleteResponse = TrackHasArtistMessages.DeleteTrackHasArtistResponse.newBuilder() + .setSuccess(false) + .setMessage("Track has artist not found") + .build(); + + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(deleteResponse.toByteString()); + } + } catch (Exception e) { + logger.error("Error deleting track has artist", e); + TrackHasArtistMessages.DeleteTrackHasArtistResponse deleteResponse = + TrackHasArtistMessages.DeleteTrackHasArtistResponse.newBuilder() + .setSuccess(false) + .setMessage("Error: " + e.getMessage()) + .build(); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(deleteResponse.toByteString()); + } + } + } diff --git a/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistByIdHandler.java new file mode 100644 index 0000000..db3996f --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistByIdHandler.java @@ -0,0 +1,56 @@ +package com.mediamanager.service.delegate.handler.trackhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackHasArtistMapper; +import com.mediamanager.model.TrackHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.trackhasartist.TrackHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action(value = "trackhasartist.getById") +public class GetTrackHasArtistByIdHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetTrackHasArtistByIdHandler.class); + private final TrackHasArtistService trackHasArtistService; + + public GetTrackHasArtistByIdHandler(TrackHasArtistService trackHasArtistService) { + this.trackHasArtistService = trackHasArtistService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException{ + + try{ + TrackHasArtistMessages.GetTrackHasArtistByIdRequest getByIdRequest = + TrackHasArtistMessages.GetTrackHasArtistByIdRequest.parseFrom(requestPayload); + int id = getByIdRequest.getId(); + + Optional trackHasArtistOpt = trackHasArtistService.getTrackHasArtistById(id); + + if (trackHasArtistOpt.isEmpty()){ + logger.warn("TrackHasArtist not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("TrackHasArtist not found")); + } + TrackHasArtistMessages.TrackHasArtist trackHasArtistProto = TrackHasArtistMapper.toProtobuf(trackHasArtistOpt.get()); + TrackHasArtistMessages.GetTrackHasArtistByIdResponse getByIdResponse = TrackHasArtistMessages.GetTrackHasArtistByIdResponse.newBuilder() + .setTrackhasartist(trackHasArtistProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(getByIdResponse.toByteString()); + } catch (Exception e) { + logger.error("Error getting track has artist by ID", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistHandler.java new file mode 100644 index 0000000..1734264 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/trackhasartist/GetTrackHasArtistHandler.java @@ -0,0 +1,48 @@ +package com.mediamanager.service.delegate.handler.trackhasartist; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.TrackHasArtistMapper; +import com.mediamanager.model.TrackHasArtist; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.TrackHasArtistMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.trackhasartist.TrackHasArtistService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + + +@Action("trackhasartist.getAll") +public class GetTrackHasArtistHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetTrackHasArtistHandler.class); + + private final TrackHasArtistService trackHasArtistService; + + public GetTrackHasArtistHandler(TrackHasArtistService trackHasArtistService){this.trackHasArtistService = trackHasArtistService;} + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + List trackHasArtists = trackHasArtistService.getAllTrackHasArtists(); + TrackHasArtistMessages.GetTrackHasArtistsResponse.Builder responseBuilder = TrackHasArtistMessages.GetTrackHasArtistsResponse.newBuilder(); + + for (TrackHasArtist trackHasArtist : trackHasArtists) { + TrackHasArtistMessages.TrackHasArtist trackHasArtistProto = TrackHasArtistMapper.toProtobuf(trackHasArtist); + responseBuilder.addTrackhasartist(trackHasArtistProto); + } + TrackHasArtistMessages.GetTrackHasArtistsResponse getTrackHasArtistsResponse = responseBuilder.build(); + + return TransportProtocol.Response.newBuilder() + .setPayload(getTrackHasArtistsResponse.toByteString()); + + }catch (Exception e){ + logger.error("Error getting track has artists", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/trackhasartist/TrackHasArtistService.java b/src/main/java/com/mediamanager/service/trackhasartist/TrackHasArtistService.java new file mode 100644 index 0000000..bad7a27 --- /dev/null +++ b/src/main/java/com/mediamanager/service/trackhasartist/TrackHasArtistService.java @@ -0,0 +1,77 @@ +package com.mediamanager.service.trackhasartist; + +import com.mediamanager.model.Track; +import com.mediamanager.model.TrackHasArtist; +import com.mediamanager.model.Artist; +import com.mediamanager.repository.TrackHasArtistRepository; +import com.mediamanager.repository.TrackRepository; +import com.mediamanager.repository.ArtistRepository; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; +import java.util.Optional; + +public class TrackHasArtistService { + private static final Logger logger = LogManager.getLogger(TrackHasArtistService.class); + private final TrackHasArtistRepository repository; + private final TrackRepository trackRepository; + private final ArtistRepository artistRepository; + + public TrackHasArtistService(TrackHasArtistRepository repository, TrackRepository trackRepository, ArtistRepository artistRepository) { + this.repository = repository; + this.trackRepository = trackRepository; + this.artistRepository = artistRepository; + } + + public TrackHasArtist createTrackHasArtist(Integer trackId, Integer artistId) { + logger.debug("Creating track has artist relationship - trackId:{}, artistId:{}", trackId, artistId); + + if (trackId == null || trackId <= 0) { + throw new IllegalArgumentException("Track ID cannot be null or invalid"); + } + if (artistId == null || artistId <= 0) { + throw new IllegalArgumentException("Artist ID cannot be null or invalid"); + } + + // Verify Track exists + Optional track = trackRepository.findById(trackId); + if (track.isEmpty()) { + throw new IllegalArgumentException("Track not found with id: " + trackId); + } + + // Verify Artist exists + Optional artist = artistRepository.findById(artistId); + if (artist.isEmpty()) { + throw new IllegalArgumentException("Artist not found with id: " + artistId); + } + + TrackHasArtist trackHasArtist = new TrackHasArtist(); + trackHasArtist.setTrack(track.get()); + trackHasArtist.setArtist(artist.get()); + + return repository.save(trackHasArtist); + } + + public List getAllTrackHasArtists() { + logger.info("Getting all track has artist relationships"); + return repository.findAll(); + } + + public Optional getTrackHasArtistById(Integer id) { + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } + logger.info("Getting track has artist by id:{}", id); + return repository.findById(id); + } + + public boolean deleteTrackHasArtist(Integer id) { + if (id == null) { + throw new IllegalArgumentException("Track has artist id cannot be null"); + } + logger.info("Deleting track has artist:{}", id); + return repository.deleteById(id); + } + +} diff --git a/src/main/proto/trackhasartist.proto b/src/main/proto/trackhasartist.proto new file mode 100644 index 0000000..42b8621 --- /dev/null +++ b/src/main/proto/trackhasartist.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +option java_package = "com.mediamanager.protocol.messages"; +option java_outer_classname = "TrackHasArtistMessages"; + +package mediamanager.messages; + +message TrackHasArtist{ + int32 id = 1; + int32 fk_track_id = 2; + int32 fk_artist_id =3; +} + +message CreateTrackHasArtistRequest { + int32 fk_track_id = 1; + int32 fk_artist_id = 2; +} + +message CreateTrackHasArtistResponse { + TrackHasArtist trackhasartist = 1; +} + +message GetTrackHasArtistsRequest { + +} + +message GetTrackHasArtistsResponse { + repeated TrackHasArtist trackhasartist = 1; +} + +message GetTrackHasArtistByIdRequest { + int32 id = 1; +} + +message GetTrackHasArtistByIdResponse { + TrackHasArtist trackhasartist = 1; +} + +message DeleteTrackHasArtistRequest { + int32 id = 1; +} + +message DeleteTrackHasArtistResponse { + bool success = 1; + string message = 2; +} \ No newline at end of file