Compare commits

...
Author SHA1 Message Date
Gustavo Henrique Miranda 1dd2542656 Merge pull request #19 from gmbrax/fix/Fix-artist-proto-mismatch
Feature/Implement-BitRate-Management
2025-12-05 21:55:31 -03:00
Gustavo Henrique Santos Souza de MirandaandClaude Sonnet 4.5 c787eba20e Fix field name casing in UpdateArtistResponse proto message
Change field name from 'Artist' to 'artist' to follow protobuf naming conventions, which require lowercase field names with underscores for word separation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-05 21:48:46 -03:00
Gustavo Henrique Santos Souza de Miranda 2294a57ffd Implement bit-rate management feature
Add complete CRUD functionality for bit-rate management following the same pattern as bit-depth:
  - Create BitRate entity model with JPA annotations
  - Implement BitRateRepository with full CRUD operations
  - Add BitRateService with validation and business logic
  - Create BitRateMapper for protobuf/entity conversion
  - Implement action handlers: Create, GetAll, GetById, Update, Delete
  - Define bitrate.proto protobuf message definitions
  - Register BitRateService in DelegateActionManager

  🤖 Generated with [Claude Code](https://claude.com/claude-code)

  Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 20:43:04 -03:00
Gustavo Henrique Miranda 8c8b8ec765 Merge pull request #17 from gmbrax/fix/Fix-Repeated-return-on-CreateBitDepthHandler
Remove duplicate `newBuilder` call in `CreateBitDepthHandler`
2025-12-05 18:12:32 -03:00
Gustavo Henrique Santos Souza de Miranda 92b4b21e60 Remove duplicate TransportProtocol.Response.newBuilder() call in CreateBitDepthHandler. 2025-12-05 17:02:02 -03:00
Gustavo Henrique Miranda 026a3aefa4 Merge pull request #15 from gmbrax/feature/implement-bitdepth-management
Implement BitDepth Management with CRUD Operations
2025-12-05 04:55:14 -03:00
Gustavo Henrique Mirandaandcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> 93c458d856 Update src/main/java/com/mediamanager/service/delegate/handler/bitdepth/UpdateBitDepthHandler.java
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-05 04:54:40 -03:00
Gustavo Henrique Mirandaandcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> cd4b35f3c9 Update src/main/java/com/mediamanager/service/delegate/handler/bitdepth/CreateBitDepthHandler.java
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-05 04:54:29 -03:00
Gustavo Henrique Santos Souza de Miranda 2d77358d50 Implement BitDepth Management with CRUD Operations
- Add `BitDepth` entity with JPA annotations and database mapping.
- Create repository, service, and delegate handlers for BitDepth CRUD operations: `bitdepth.create`, `bitdepth.getAll`, `bitdepth.getById`, `bitdepth.update`, `bitdepth.delete`.
- Introduce Protobuf definitions for BitDepth messages.
- Register BitDepth service and handlers in `DelegateActionManager`.
- Create `BitDepthMapper` to map between Protobuf and entity models.
- Enhance error handling and logging for BitDepth operations.
2025-12-03 03:15:39 -03:00
Gustavo Henrique Miranda 9aadb7283c Merge pull request #14 from gmbrax/feature/Implement-composer-management
Implement Composer Management with CRUD Operations
2025-12-01 00:46:57 -03:00
Gustavo Henrique Miranda 371a2dd85c Merge branch 'develop' into feature/Implement-composer-management 2025-12-01 00:46:31 -03:00
Gustavo Henrique Miranda 4ac7ca4557 Merge pull request #13 from gmbrax/feature/Implement-artist-management
Implement Artist Management with CRUD Operations
2025-12-01 00:44:19 -03:00
Gustavo Henrique Santos Souza de Miranda db4217bec4 Implement Composer Management with CRUD Operations
- Add `Composer` entity with JPA annotations and database mapping.
- Create repository, service, and delegate handlers for Composer CRUD operations: `create_composer`, `get_composers`, `get_composer_by_id`, `update_composer`, `delete_composer`.
- Introduce Protobuf definitions for Composer messages.
- Register Composer service and handlers in `DelegateActionManager`.
- Add `ComposerMapper` to map between Protobuf and entity models.
- Enhance error handling and logging for Composer operations.
2025-12-01 00:16:57 -03:00
Gustavo Henrique Santos Souza de Miranda 51a46c37e5 Rename DeleteArtistHandle to DeleteArtistHandler for consistency and update related references. Clean up Protobuf comment in UpdateArtistResponse. 2025-11-30 17:33:25 -03:00
Gustavo Henrique Santos Souza de Miranda 0df4b31a4d Fix logging messages in ArtistRepository for clarity
- Correct references from "genre" to "artist" in logging statements.
- Remove unused `Genre` import for cleanup.
2025-11-30 12:59:57 -03:00
Gustavo Henrique Mirandaandcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> 3c42fd9735 Update src/main/java/com/mediamanager/mapper/ArtistMapper.java
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-11-30 12:54:18 -03:00
Gustavo Henrique Santos Souza de Miranda 0a61f1f2fa Implement Artist Management with CRUD Operations
- Add `Artist` entity with JPA annotations and database mapping.
- Create repository, service, and delegate handlers for Artist CRUD operations.
- Register handlers (`artist.create`, `artist.getAll`, `artist.getById`, `artist.update`, `artist.delete`) in `DelegateActionManager`.
- Introduce Protobuf definitions for Artist messages.
- Update `initializeServices` in `DelegateActionManager` for Artist service support.
- Add null-safe ID handling in `ArtistMapper` to prevent potential NPEs.
2025-11-30 12:46:50 -03:00
Gustavo Henrique Miranda fecb0288d3 Merge pull request #12 from gmbrax/feature/auto-handler-scanner
Feature/auto handler scanner
2025-11-29 20:37:26 -03:00
Gustavo Henrique Santos Souza de Miranda 5ce8f4ca2a Improve DelegateActionManager error handling for invalid handlers
- Add validation to ensure classes annotated with `@Action` implement `ActionHandler`, throwing `IllegalArgumentException` for mismatches.
- Fix minor formatting issue in `@Action` annotation for `GetGenreByIdHandler`.
2025-11-29 15:33:08 -03:00
Gustavo Henrique Mirandaandcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> a5bd6e2c39 Update src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-11-29 09:52:54 -03:00
Gustavo Henrique Santos Souza de Miranda f87d6b1b53 Refactor DelegateActionManager for dynamic handler registration
- Replace manual handler registration with automatic scanning and registration of handlers annotated with `@Action`.
- Introduce `ServiceLocator` to enable dependency injection for dynamically instantiated handlers.
- Add `initializeServices` to centralize service initialization and registration.
- Enhance error handling and logging for handler instantiation and registration processes.
2025-11-29 08:26:58 -03:00
Gustavo Henrique Santos Souza de Miranda b715bb1bd3 Add @Action annotation and ServiceLocator for improved handler registration
- Introduce `@Action` annotation to simplify action handler identification and tagging.
- Add `ServiceLocator` for dynamic service registration and retrieval.
- Annotate handlers (`CreateGenreHandler`, `GetGenreHandler`, `UpdateGenreHandler`, `DeleteGenreHandler`, etc.) with corresponding actions.
2025-11-29 07:54:46 -03:00
Gustavo Henrique Miranda 9c3a1126a7 Merge pull request #11 from gmbrax/feature/implement-genre-management
Implement Genre Management with CRUD Operations
2025-11-29 06:09:44 -03:00
Gustavo Henrique Santos Souza de Miranda f70c1e1d94 Switch from EntityManager to EntityManagerFactory across repositories, managers, and services for improved resource management and thread safety. 2025-11-29 03:02:49 -03:00
Gustavo Henrique Santos Souza de Miranda 32fff9c725 Add null-safe ID handling in GenreMapper and fix minor logging format in IPCManager
- Ensure `GenreMapper` sets ID only if it's non-null and valid (> 0) to prevent potential NPEs.
- Adjust logging format in `IPCManager` for consistent indentation.
2025-11-29 02:50:07 -03:00
Gustavo Henrique Santos Souza de Miranda 7b61b2071e Implement Genre Management with CRUD Operations
- Add `Genre` entity with JPA annotations and database mapping.
- Create repository, service, and delegate handlers for Genre CRUD operations.
- Register handlers (`create_genre`, `get_genres`, `get_genre_by_id`, `update_genre`, `delete_genre`) in `DelegateActionManager`.
- Introduce Protobuf definitions for Genre messages.
- Update `DatabaseManager` to expose `EntityManager`.
- Enhance `DelegateActionManager` constructor to use `EntityManager` for handler initialization.
2025-11-28 23:33:27 -03:00
Gustavo Henrique Miranda ba53d4d8c4 Merge pull request #10 from gmbrax/refactor/add-hibernate-and-reflection-dependency
Remove `Media` entity and integrate Hibernate ORM into `DatabaseManager`:
2025-11-28 00:38:21 -03:00
Gustavo Henrique Santos Souza de Miranda 081a1f1ed4 Add exception handling for entity scanning in DatabaseManager
- Wrap entity scanning in a try-catch block to handle potential exceptions.
- Log descriptive error messages and throw a runtime exception for failure cases.
- Warn if no `@Entity` classes are found during the scan.
2025-11-27 19:20:22 -03:00
Gustavo Henrique Santos Souza de Miranda e395e21e8c Add validation for required Hibernate configuration properties in DatabaseManager
- Ensure non-null and non-empty values for `hibernate.dialect`, `database.driver`, and `connectionUrl`.
- Throw `IllegalStateException` when required properties are missing.
2025-11-27 19:08:11 -03:00
Gustavo Henrique Santos Souza de Miranda 412a590a98 Add exception handling for Hibernate initialization in DatabaseManager
- Wrap Hibernate setup in a try-catch block.
- Log errors during initialization failure with descriptive messages.
- Throw a runtime exception if setup fails to ensure proper error propagation.
2025-11-27 19:04:44 -03:00
Gustavo Henrique Santos Souza de Miranda bc0199312f Add null and open-state checks for EntityManager and EntityManagerFactory closure
- Ensure safe closure of `EntityManager` and `EntityManagerFactory`.
- Add logging for successful closure and error handling during exceptions.
2025-11-27 18:55:43 -03:00
Gustavo Henrique Santos Souza de Miranda 4ae1e3075d Remove Media entity and integrate Hibernate ORM into DatabaseManager:
- Deleted `Media` class and its annotations.
- Added Hibernate ORM initialization in `DatabaseManager`, including dynamic entity scanning and configuration.
- Updated `pom.xml` to include dependencies for Hibernate community dialects and Reflections.
2025-11-27 18:40:08 -03:00
Gustavo Henrique Miranda fc09c4e257 Merge pull request #9 from gmbrax/fix/fix-unsecure-postgres-version
Fix the pom.xml
2025-11-24 22:19:31 -03:00
Gustavo Henrique Santos Souza de Miranda 53004a3730 Fix the pom.xml to alter the postgres dependency to a safer version due a CVE in the 42.7.5 then it was bumped t0 42.7.7 2025-11-24 21:59:35 -03:00
Gustavo Henrique Miranda 7e154eb01c Merge pull request #7 from gmbrax/feature/IPC-Unix-Socket
Feature/ipc unix socket
2025-11-22 23:41:12 -03:00
Gustavo Henrique Miranda 24fadf9474 Merge pull request #6 from gmbrax/feature/add-SQLite-Implementation
Feature/add sq lite implementation
2025-11-22 23:37:31 -03:00
Gustavo Henrique Santos Souza de Miranda 269780d8cf Add CloseHandler to support graceful connection termination.
- Extend `test.proto` with `CloseCommand` and `CloseResponse` messages.
- Introduce `CloseHandler` to process "close" actions and respond with connection termination notice.
- Update `DelegateActionManager` to register `CloseHandler`.
- Refactor `IPCManager` to handle "close" response headers and terminate client connections gracefully.
2025-11-22 23:27:04 -03:00
Gustavo Henrique Santos Souza de Miranda 6576b54057 - Add HeartbeatHandler and enhance EchoHandler for Protocol Buffers support.
- Extend `test.proto` schema with heartbeat and echo message definitions.
- Register `HeartbeatHandler` in `DelegateActionManager`.
- Refactor Log4j2 configuration to standardize log levels.
- Optimize client wait time in `IPCManager` for reduced latency.
2025-11-22 02:29:28 -03:00
64 changed files with 3415 additions and 156 deletions
+12 -1
View File
@@ -13,7 +13,7 @@
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hibernate.version>7.1.7.Final</hibernate.version> <hibernate.version>7.1.7.Final</hibernate.version>
<postgresql.version>42.7.5</postgresql.version> <postgresql.version>42.7.7</postgresql.version>
<hikaricp.version>5.1.0</hikaricp.version> <hikaricp.version>5.1.0</hikaricp.version>
<log4j.version>2.23.1</log4j.version> <log4j.version>2.23.1</log4j.version>
<junit.version>5.10.2</junit.version> <junit.version>5.10.2</junit.version>
@@ -35,6 +35,12 @@
<version>${hibernate.version}</version> <version>${hibernate.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- HikariCP for connection pooling --> <!-- HikariCP for connection pooling -->
<dependency> <dependency>
<groupId>com.zaxxer</groupId> <groupId>com.zaxxer</groupId>
@@ -88,6 +94,11 @@
<artifactId>sqlite-jdbc</artifactId> <artifactId>sqlite-jdbc</artifactId>
<version>3.44.1.0</version> <version>3.44.1.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -60,7 +60,7 @@ public class MediaManagerApplication {
default: default:
} }
databaseManager.init(); databaseManager.init();
actionManager = new DelegateActionManager(); actionManager = new DelegateActionManager(databaseManager.getEntityManagerFactory());
actionManager.start(); actionManager.start();
ipcManager = new IPCManager(config,actionManager); ipcManager = new IPCManager(config,actionManager);
ipcManager.init(); ipcManager.init();
@@ -0,0 +1,41 @@
package com.mediamanager.mapper;
import com.mediamanager.model.Artist;
import com.mediamanager.protocol.messages.ArtistMessages;
public class ArtistMapper {
public static ArtistMessages.Artist toProtobuf(Artist entity){
if (entity == null) {
return null;
}
String name = entity.getName();
if (name == null) {
throw new IllegalArgumentException("Artist name cannot be null");
}
ArtistMessages.Artist.Builder builder = ArtistMessages.Artist.newBuilder()
.setName(name);
// Only set ID when it's present and valid (> 0). Avoids NPE for null IDs.
Integer id = entity.getId();
if (id != null && id > 0) {
builder.setId(id);
}
return builder.build();
}
public static Artist toEntity(ArtistMessages.Artist protobuf) {
if (protobuf == null) {
return null;
}
Artist entity = new Artist();
if (protobuf.getId() > 0) {
entity.setId(protobuf.getId());
}
entity.setName(protobuf.getName());
return entity;
}
}
@@ -0,0 +1,39 @@
package com.mediamanager.mapper;
import com.mediamanager.model.BitDepth;
import com.mediamanager.protocol.messages.BitDepthMessages;
public class BitDepthMapper {
public static BitDepthMessages.BitDepth toProtobuf(BitDepth entity) {
if (entity == null){
return null;
}
String value = entity.getValue();
if (value == null) {
throw new IllegalArgumentException("Bit depth value cannot be null");
}
BitDepthMessages.BitDepth.Builder builder = BitDepthMessages.BitDepth.newBuilder()
.setValue(value);
Integer id = entity.getId();
if (id != null && id > 0) {
builder.setId(id);
}
return builder.build();
}
public static BitDepth toEntity(BitDepthMessages.BitDepth protobuf) {
if (protobuf == null) {
return null;
}
BitDepth entity = new BitDepth();
if (protobuf.getId() > 0) {
entity.setId(protobuf.getId());
}
entity.setValue(protobuf.getValue());
return entity;
}
}
@@ -0,0 +1,39 @@
package com.mediamanager.mapper;
import com.mediamanager.model.BitRate;
import com.mediamanager.protocol.messages.BitRateMessages;
public class BitRateMapper {
public static BitRateMessages.BitRate toProtobuf(BitRate entity) {
if (entity == null) {
return null;
}
String value = entity.getValue();
if (value == null) {
throw new IllegalArgumentException("Bit rate value cannot be null");
}
BitRateMessages.BitRate.Builder builder = BitRateMessages.BitRate.newBuilder()
.setValue(value);
Integer id = entity.getId();
if (id != null && id > 0) {
builder.setId(id);
}
return builder.build();
}
public static BitRate toEntity(BitRateMessages.BitRate protobuf) {
if (protobuf == null) {
return null;
}
BitRate entity = new BitRate();
if (protobuf.getId() > 0) {
entity.setId(protobuf.getId());
}
entity.setValue(protobuf.getValue());
return entity;
}
}
@@ -0,0 +1,38 @@
package com.mediamanager.mapper;
import com.mediamanager.model.Composer;
import com.mediamanager.protocol.messages.ComposerMessages;
public class ComposerMapper {
public static ComposerMessages.Composer toProtobuf(Composer entity) {
if (entity == null) {
return null;
}
ComposerMessages.Composer.Builder builder = ComposerMessages.Composer.newBuilder()
.setName(entity.getName());
Integer id = entity.getId();
if (id != null && id > 0) {
builder.setId(id);
}
return builder.build();
}
public static Composer toEntity(ComposerMessages.Composer protobuf) {
if (protobuf == null) {
return null;
}
Composer entity = new Composer();
if (protobuf.getId() > 0) {
entity.setId(protobuf.getId());
}
entity.setName(protobuf.getName());
return entity;
}
}
@@ -0,0 +1,40 @@
package com.mediamanager.mapper;
import com.mediamanager.model.Genre;
import com.mediamanager.protocol.messages.GenreMessages;
public class GenreMapper {
public static GenreMessages.Genre toProtobuf(Genre entity) {
if (entity == null) {
return null;
}
GenreMessages.Genre.Builder builder = GenreMessages.Genre.newBuilder()
.setName(entity.getName());
// Only set ID when it's present and valid (> 0). Avoids NPE for null IDs.
Integer id = entity.getId();
if (id != null && id > 0) {
builder.setId(id);
}
return builder.build();
}
public static Genre toEntity(GenreMessages.Genre protobuf) {
if (protobuf == null) {
return null;
}
Genre entity = new Genre();
// Só seta ID se for > 0 (protobuf default é 0)
if (protobuf.getId() > 0) {
entity.setId(protobuf.getId());
}
entity.setName(protobuf.getName());
return entity;
}
}
@@ -0,0 +1,27 @@
package com.mediamanager.model;
import jakarta.persistence.*;
@Entity
@Table(name = "artist")
public class Artist {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,32 @@
package com.mediamanager.model;
import jakarta.persistence.*;
@Entity
@Table(name = "bit_depth")
public class BitDepth {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String value;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,31 @@
package com.mediamanager.model;
import jakarta.persistence.*;
@Entity
@Table(name = "bit_rate")
public class BitRate {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String value;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,31 @@
package com.mediamanager.model;
import jakarta.persistence.*;
@Entity
@Table(name = "composer")
public class Composer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,30 @@
package com.mediamanager.model;
import jakarta.persistence.*;
@Entity
@Table(name = "genre")
public class Genre {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -1,128 +0,0 @@
package com.mediamanager.model;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "media")
public class Media {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false, unique = true)
private String filePath;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private MediaType type;
@Column
private Long fileSize;
@Column
private String mimeType;
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
// Constructors
public Media() {}
public Media(String title, String filePath, MediaType type) {
this.title = title;
this.filePath = filePath;
this.type = type;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public MediaType getType() {
return type;
}
public void setType(MediaType type) {
this.type = type;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public enum MediaType {
VIDEO,
AUDIO,
IMAGE,
DOCUMENT,
OTHER
}
}
@@ -0,0 +1,104 @@
package com.mediamanager.repository;
import com.mediamanager.model.Artist;
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 ArtistRepository {
private static final Logger logger = LogManager.getLogger(ArtistRepository.class);
private final EntityManagerFactory entityManagerFactory;
public ArtistRepository(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public Artist save(Artist artist){
logger.debug("Saving Artist: {}", artist.getName());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
em.persist(artist);
em.getTransaction().commit();
logger.debug("Artist saved with ID: {}", artist.getId());
return artist;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error saving Artist", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public List<Artist> findAll(){
logger.debug("Finding all Artists");
EntityManager em = entityManagerFactory.createEntityManager();
try {
return em
.createQuery("SELECT a FROM Artist a ORDER BY a.name", Artist.class)
.getResultList();
} finally {
if (em.isOpen()) em.close();
}
}
public Optional<Artist> findById(Integer id){
logger.debug("Finding artist by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
try {
Artist artist = em.find(Artist.class, id);
return Optional.ofNullable(artist);
} finally {
if (em.isOpen()) em.close();
}
}
public Artist update(Artist artist){
logger.debug("Updating artist ID: {}", artist.getId());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
Artist updated = em.merge(artist);
em.getTransaction().commit();
logger.debug("Artist updated successfully");
return updated;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error updating artist", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public boolean deleteById(Integer id){
logger.debug("Deleting Artist by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
Artist artist = em.find(Artist.class, id);
if (artist == null) {
em.getTransaction().rollback();
return false;
}
em.remove(artist);
em.getTransaction().commit();
logger.debug("Artist deleted successfully");
return true;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error deleting artist", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
}
@@ -0,0 +1,100 @@
package com.mediamanager.repository;
import com.mediamanager.model.BitDepth;
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 BitDepthRepository {
private static final Logger logger = LogManager.getLogger(BitDepthRepository.class);
private final EntityManagerFactory entityManagerFactory;
public BitDepthRepository(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public BitDepth save(BitDepth bitDepth) {
logger.debug("Saving BitDepth: {}", bitDepth.getValue());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
em.persist(bitDepth);
em.getTransaction().commit();
logger.debug("BitDepth saved with ID: {}", bitDepth.getId());
return bitDepth;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error saving BitDepth", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public List<BitDepth> findAll(){
logger.debug("Finding all BitDepths");
EntityManager em = entityManagerFactory.createEntityManager();
try{
return em.createQuery("SELECT b FROM BitDepth b ORDER BY b.value", BitDepth.class).getResultList();
}finally {
if (em.isOpen()) em.close();
}
}
public Optional<BitDepth> findById(Integer id){
logger.debug("Finding BitDepth by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
try{
BitDepth bitDepth = em.find(BitDepth.class, id);
return Optional.ofNullable(bitDepth);
}finally {
if (em.isOpen()) em.close();
}
}
public BitDepth update(BitDepth bitDepth){
logger.debug("Updating BitDepth ID: {}", bitDepth.getId());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
BitDepth updated = em.merge(bitDepth);
em.getTransaction().commit();
logger.debug("BitDepth updated successfully");
return updated;
}catch (Exception e){
em.getTransaction().rollback();
logger.error("Error updating BitDepth", e);
throw e;
}finally {
if (em.isOpen()) em.close();
}
}
public boolean deleteById(Integer id){
logger.debug("Deleting BitDepth by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
BitDepth bitDepth = em.find(BitDepth.class, id);
if (bitDepth == null) {
em.getTransaction().rollback();
return false;
}
em.remove(bitDepth);
em.getTransaction().commit();
logger.debug("BitDepth deleted successfully");
return true;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error deleting BitDepth", e);
throw e;
}finally {
if (em.isOpen()) em.close();
}
}
}
@@ -0,0 +1,101 @@
package com.mediamanager.repository;
import com.mediamanager.model.BitRate;
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 BitRateRepository {
private static final Logger logger = LogManager.getLogger(BitRateRepository.class);
private final EntityManagerFactory entityManagerFactory;
public BitRateRepository(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public BitRate save(BitRate bitRate) {
logger.debug("Saving BitRate: {}", bitRate.getValue());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
em.persist(bitRate);
em.getTransaction().commit();
logger.debug("BitRate saved with ID: {}", bitRate.getId());
return bitRate;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error saving BitRate", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public List<BitRate> findAll(){
logger.debug("Finding all BitRates");
EntityManager em = entityManagerFactory.createEntityManager();
try{
return em.createQuery("SELECT b FROM BitRate b ORDER BY b.value", BitRate.class).getResultList();
}finally {
if (em.isOpen()) em.close();
}
}
public Optional<BitRate> findById(Integer id){
logger.debug("Finding BitRate by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
try{
BitRate bitRate = em.find(BitRate.class, id);
return Optional.ofNullable(bitRate);
} finally {
if (em.isOpen()) em.close();
}
}
public BitRate update(BitRate bitRate){
logger.debug("Updating BitRate ID: {}", bitRate.getId());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
BitRate updated = em.merge(bitRate);
em.getTransaction().commit();
logger.debug("BitRate updated with ID: {}", bitRate.getId());
return updated;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error updating BitRate", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public boolean deleteById(Integer id){
logger.debug("Deleting BitRate by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
BitRate bitRate = em.find(BitRate.class, id);
if (bitRate == null) {
em.getTransaction().rollback();
return false;
}
em.remove(bitRate);
em.getTransaction().commit();
logger.debug("BitRate deleted successfully");
return true;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error deleting BitRate", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
}
@@ -0,0 +1,102 @@
package com.mediamanager.repository;
import com.mediamanager.model.Composer;
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 ComposerRepository {
private static final Logger logger = LogManager.getLogger(ComposerRepository.class);
private final EntityManagerFactory entityManagerFactory;
public ComposerRepository(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public Composer save(Composer composer) {
logger.debug("Saving composer: {}", composer.getName());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
//ToDo: Add Id Validation
//ToDo: Add to all Repositories
em.persist(composer);
em.getTransaction().commit();
logger.debug("Composer saved with IS: {}", composer.getId());
return composer;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error saving composer", e);
throw e;
}finally {
if (em.isOpen()) em.close();
}
}
public List<Composer> findAll(){
logger.debug("Finding all composers");
EntityManager em = entityManagerFactory.createEntityManager();
try{
return em.createQuery("SELECT c FROM Composer c ORDER BY c.name", Composer.class).getResultList();
} finally {
if (em.isOpen()) em.close();
}
}
public Optional<Composer> findById(Integer id){
logger.debug("Finding composer by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
try{
Composer composer = em.find(Composer.class, id);
return Optional.ofNullable(composer);
} finally {
if (em.isOpen()) em.close();
}
}
public Composer update(Composer composer){
logger.debug("Updating composer ID: {}", composer.getId());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
Composer updated = em.merge(composer);
em.getTransaction().commit();
logger.debug("Composer updated successfully");
return updated;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error updating composer", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
public boolean deleteById(Integer id){
logger.debug("Deleting composer by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try{
Composer composer = em.find(Composer.class, id);
if (composer == null) {
em.getTransaction().rollback();
return false;
}
em.remove(composer);
em.getTransaction().commit();
logger.debug("Composer deleted successfully");
return true;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error deleting composer", e);
throw e;
}finally {
if (em.isOpen()) em.close();
}
}
}
@@ -0,0 +1,121 @@
package com.mediamanager.repository;
import com.mediamanager.model.Genre;
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;
/**
* Repository para acesso a dados de Genre
* Encapsula todas as operações de banco de dados
*/
public class GenreRepository {
private static final Logger logger = LogManager.getLogger(GenreRepository.class);
private final EntityManagerFactory entityManagerFactory;
public GenreRepository(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
/**
* Salva um novo genre
*/
public Genre save(Genre genre) {
logger.debug("Saving genre: {}", genre.getName());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
em.persist(genre);
em.getTransaction().commit();
logger.debug("Genre saved with ID: {}", genre.getId());
return genre;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error saving genre", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
/**
* Busca todos os genres
*/
public List<Genre> findAll() {
logger.debug("Finding all genres");
EntityManager em = entityManagerFactory.createEntityManager();
try {
return em
.createQuery("SELECT g FROM Genre g ORDER BY g.name", Genre.class)
.getResultList();
} finally {
if (em.isOpen()) em.close();
}
}
/**
* Busca genre por ID
*/
public Optional<Genre> findById(Integer id) {
logger.debug("Finding genre by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
try {
Genre genre = em.find(Genre.class, id);
return Optional.ofNullable(genre);
} finally {
if (em.isOpen()) em.close();
}
}
/**
* Atualiza um genre existente
*/
public Genre update(Genre genre) {
logger.debug("Updating genre ID: {}", genre.getId());
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
Genre updated = em.merge(genre);
em.getTransaction().commit();
logger.debug("Genre updated successfully");
return updated;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error updating genre", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
/**
* Deleta um genre por ID
*/
public boolean deleteById(Integer id) {
logger.debug("Deleting genre by ID: {}", id);
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
try {
Genre genre = em.find(Genre.class, id);
if (genre == null) {
em.getTransaction().rollback();
return false;
}
em.remove(genre);
em.getTransaction().commit();
logger.debug("Genre deleted successfully");
return true;
} catch (Exception e) {
em.getTransaction().rollback();
logger.error("Error deleting genre", e);
throw e;
} finally {
if (em.isOpen()) em.close();
}
}
}
@@ -0,0 +1,65 @@
package com.mediamanager.service.artist;
import com.mediamanager.model.Artist;
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 ArtistService {
private static final Logger logger = LogManager.getLogger(ArtistService.class);
private final ArtistRepository artistRepository;
public ArtistService(ArtistRepository artistRepository) {
this.artistRepository = artistRepository;
}
public Artist createArtist(String name){
logger.info("Creating artist: {}", name);
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Artist name cannot be empty");
}
Artist artist = new Artist();
artist.setName(name.trim());
return artistRepository.save(artist);
}
public List<Artist> getAllArtists(){
logger.info("Getting all artists");
return artistRepository.findAll();
}
public Optional<Artist> getArtistById(Integer id){
logger.info("Getting artist by ID: {}", id);
return artistRepository.findById(id);
}
public Optional<Artist> updateArtist(Integer id, String name){
logger.info("Updating artist ID {}: {}", id, name);
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Artist name cannot be empty");
}
Optional<Artist> existingArtist = artistRepository.findById(id);
if(existingArtist.isEmpty()){
logger.warn("Artist not found with ID: {}", id);
return Optional.empty();
}
Artist artist = existingArtist.get();
artist.setName(name.trim());
Artist updatedArtist = artistRepository.update(artist);
return Optional.of(updatedArtist);
}
public boolean deleteArtist(Integer id){
logger.info("Deleting artist ID: {}", id);
return artistRepository.deleteById(id);
}
}
@@ -0,0 +1,61 @@
package com.mediamanager.service.bitdepth;
import com.mediamanager.model.BitDepth;
import com.mediamanager.repository.BitDepthRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.Optional;
public class BitDepthService {
private static final Logger logger = LogManager.getLogger(BitDepthService.class);
private final BitDepthRepository bitDepthRepository;
public BitDepthService(BitDepthRepository bitDepthRepository) {
this.bitDepthRepository = bitDepthRepository;
}
public BitDepth createBitDepth(String value){
logger.info("Creating bit-depth: {}", value);
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("Bit-depth value cannot be empty");
}
BitDepth bitDepth = new BitDepth();
bitDepth.setValue(value.trim());
return bitDepthRepository.save(bitDepth);
}
public List<BitDepth> getAllBitDepths(){
logger.info("Getting all bit-depths");
return bitDepthRepository.findAll();
}
public Optional<BitDepth> getBitDepthById(Integer id){
logger.info("Getting bit-depth by ID: {}", id);
return bitDepthRepository.findById(id);
}
public Optional<BitDepth> updateBitDepth(Integer id, String value){
logger.info("Updating bit-depth ID {}: {}", id, value);
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("Bit-depth value cannot be empty");
}
Optional<BitDepth> existingBitDepth = bitDepthRepository.findById(id);
if(existingBitDepth.isEmpty()){
logger.warn("Bit-depth not found with ID: {}", id);
return Optional.empty();
}
BitDepth bitDepth = existingBitDepth.get();
bitDepth.setValue(value.trim());
BitDepth updatedBitDepth = bitDepthRepository.update(bitDepth);
return Optional.of(updatedBitDepth);
}
public boolean deleteBitDepth(Integer id){
logger.info("Deleting bit-depth ID: {}", id);
return bitDepthRepository.deleteById(id);
}
}
@@ -0,0 +1,65 @@
package com.mediamanager.service.bitrate;
import com.mediamanager.model.BitRate;
import com.mediamanager.repository.BitRateRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.Optional;
public class BitRateService {
private static final Logger logger = LogManager.getLogger(BitRateService.class);
private final BitRateRepository bitRateRepository;
public BitRateService(BitRateRepository bitRateRepository) {
this.bitRateRepository = bitRateRepository;
}
public BitRate createBitRate(String value){
logger.info("Creating bit-rate: {}",value);
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("Bit-rate value cannot be empty");
}
BitRate bitRate = new BitRate();
bitRate.setValue(value.trim());
return bitRateRepository.save(bitRate);
}
public List<BitRate> getAllBitRates(){
logger.info("Getting all bit-rates");
return bitRateRepository.findAll();
}
public Optional<BitRate> getBitRateById(Integer id){
logger.info("Getting bit-rate by ID: {}", id);
return bitRateRepository.findById(id);
}
public Optional<BitRate> updateBitRate(Integer id, String value){
logger.info("Updating bit-rate ID {}: {}", id, value);
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("Bit-rate value cannot be empty");
}
Optional<BitRate> existingBitRate = bitRateRepository.findById(id);
if(existingBitRate.isEmpty()) {
logger.warn("Bit-rate not found with ID: {}", id);
return Optional.empty();
}
BitRate bitRate = existingBitRate.get();
bitRate.setValue(value.trim());
BitRate updatedBitRate = bitRateRepository.update(bitRate);
return Optional.of(updatedBitRate);
}
public boolean deleteBitRate(Integer id){
logger.info("Deleting bit-rate ID: {}", id);
return bitRateRepository.deleteById(id);
}
}
@@ -0,0 +1,70 @@
package com.mediamanager.service.composer;
import com.mediamanager.model.Composer;
import com.mediamanager.repository.ComposerRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.Optional;
public class ComposerService {
private static final Logger logger = LogManager.getLogger(ComposerService.class);
private final ComposerRepository composerRepository;
public ComposerService(ComposerRepository composerRepository) {
this.composerRepository = composerRepository;
}
public Composer createComposer(String name) {
logger.info("Creating composer: {}", name);
if(name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Composer name cannot be empty");
}
Composer composer = new Composer();
composer.setName(name.trim());
return composerRepository.save(composer);
}
public List<Composer> getAllComposers() {
logger.info("Getting all composers");
return composerRepository.findAll();
}
public Optional<Composer> getComposerById(Integer id) {
logger.info("Getting composer by ID: {}", id);
return composerRepository.findById(id);
}
public Optional<Composer> updateComposer(Integer id, String name) {
logger.info("Updating composer ID {}: {}", id, name);
if(name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Composer name cannot be empty");
}
Optional<Composer> existingComposer = composerRepository.findById(id);
if(existingComposer.isEmpty()) {
logger.warn("Composer not found with ID: {}", id);
return Optional.empty();
}
Composer composer = existingComposer.get();
composer.setName(name.trim());
Composer updated = composerRepository.update(composer);
return Optional.of(updated);
}
public boolean deleteComposer(Integer id) {
logger.info("Deleting composer ID: {}", id);
return composerRepository.deleteById(id);
}
}
@@ -1,16 +1,24 @@
package com.mediamanager.service.database; package com.mediamanager.service.database;
import jakarta.persistence.EntityManagerFactory;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.hibernate.cfg.Configuration;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import jakarta.persistence.Entity;
import java.util.Set;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Properties; import java.util.Properties;
public abstract class DatabaseManager { public abstract class DatabaseManager {
protected final Properties configuration; protected final Properties configuration;
protected Connection connection; protected Connection connection;
protected String connectionUrl;
protected EntityManagerFactory entityManagerFactory;
protected static final Logger logger = LogManager.getLogger(DatabaseManager.class); protected static final Logger logger = LogManager.getLogger(DatabaseManager.class);
public DatabaseManager(Properties config) { public DatabaseManager(Properties config) {
@@ -38,6 +46,14 @@ public abstract class DatabaseManager {
} }
public void close() { public void close() {
if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
try {
entityManagerFactory.close();
logger.info("EntityManagerFactory closed");
} catch (Exception e) {
logger.error("Error closing EntityManagerFactory: {}", e.getMessage());
}
}
if (connection != null) { if (connection != null) {
try { try {
logger.info("Closing database connection..."); logger.info("Closing database connection...");
@@ -50,6 +66,7 @@ public abstract class DatabaseManager {
logger.debug("No database connection to close"); logger.debug("No database connection to close");
} }
} }
protected boolean testConnection() { protected boolean testConnection() {
try (Statement stmt = connection.createStatement()) { try (Statement stmt = connection.createStatement()) {
stmt.execute("SELECT 1"); stmt.execute("SELECT 1");
@@ -59,4 +76,67 @@ public abstract class DatabaseManager {
return false; return false;
} }
} }
protected void initializeHibernate() {
logger.info("Initializing Hibernate ORM...");
Configuration hibernateConfig = new Configuration();
String dialect = configuration.getProperty("hibernate.dialect");
String hbm2ddl = configuration.getProperty("hibernate.hbm2ddl.auto");
String driver = configuration.getProperty("database.driver");
if (dialect == null || dialect.isEmpty()) {
throw new IllegalStateException("hibernate.dialect property is required but not configured");
}
if (driver == null || driver.isEmpty()) {
throw new IllegalStateException("database.driver property is required but not configured");
}
if (connectionUrl == null || connectionUrl.isEmpty()) {
throw new IllegalStateException("connectionUrl must be set before initializing Hibernate");
}
hibernateConfig.setProperty("hibernate.connection.url", connectionUrl);
hibernateConfig.setProperty("hibernate.connection.driver_class", driver);
hibernateConfig.setProperty("hibernate.dialect", dialect);
hibernateConfig.setProperty("hibernate.hbm2ddl.auto", hbm2ddl);
hibernateConfig.setProperty("hibernate.show_sql",
configuration.getProperty("hibernate.show_sql", "false"));
hibernateConfig.setProperty("hibernate.format_sql",
configuration.getProperty("hibernate.format_sql", "true"));
logger.info("Scanning for entities in package: com.mediamanager.model");
Set<Class<?>> entityClasses;
try {
Reflections reflections = new Reflections("com.mediamanager.model", Scanners.TypesAnnotated);
entityClasses = reflections.getTypesAnnotatedWith(Entity.class);
} catch (Exception e) {
logger.error("Failed to scan for entities: {}", e.getMessage());
throw new RuntimeException("Entity scanning failed", e);
}
logger.info("Found {} entities", entityClasses.size());
if (entityClasses.isEmpty()) {
logger.warn("No @Entity classes found in package com.mediamanager.model - is this expected?");
}
for (Class<?> entityClass : entityClasses) {
logger.debug("Registering entity: {}", entityClass.getSimpleName());
hibernateConfig.addAnnotatedClass(entityClass);
}
try {
entityManagerFactory = hibernateConfig.buildSessionFactory().unwrap(EntityManagerFactory.class);
} catch (Exception e) {
logger.error("Failed to initialize Hibernate: {}", e.getMessage());
throw new RuntimeException("Hibernate initialization failed", e);
}
logger.info("Hibernate ORM initialized successfully");
}
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
} }
@@ -16,7 +16,7 @@ public class SqliteDatabaseManager extends DatabaseManager {
private static final Logger logger = LogManager.getLogger(SqliteDatabaseManager.class); private static final Logger logger = LogManager.getLogger(SqliteDatabaseManager.class);
private String connectionUrl;
public SqliteDatabaseManager(Properties config) { public SqliteDatabaseManager(Properties config) {
super(config); super(config);
@@ -45,12 +45,14 @@ public class SqliteDatabaseManager extends DatabaseManager {
this.connectionUrl = "jdbc:sqlite:" + dbFile.toAbsolutePath().toString(); this.connectionUrl = "jdbc:sqlite:" + dbFile.toAbsolutePath().toString();
logger.info("Database file path: {}", dbFile); logger.info("Database file path: {}", dbFile);
logger.info("Connection URL: {}", this.connectionUrl); logger.info("Connection URL: {}", this.connectionUrl);
initializeHibernate();
this.connection = createConnection(); this.connection = createConnection();
configurePerformancePragmas(); configurePerformancePragmas();
performSanityChecks(); performSanityChecks();
ensureSchemaExists(); ensureSchemaExists();
logger.info("SQLite database initialized successfully"); logger.info("SQLite database initialized successfully");
} }
@Override @Override
@@ -2,29 +2,81 @@ package com.mediamanager.service.delegate;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.mediamanager.protocol.TransportProtocol; import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.service.delegate.handler.EchoHandler; import com.mediamanager.repository.*;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.repository.GenreRepository;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import jakarta.persistence.EntityManagerFactory;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import java.lang.reflect.Constructor;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class DelegateActionManager { public class DelegateActionManager {
private static final Logger logger = LogManager.getLogger(DelegateActionManager.class); private static final Logger logger = LogManager.getLogger(DelegateActionManager.class);
private final Map<String, ActionHandler> handlerRegistry; private final Map<String, ActionHandler> handlerRegistry;
private final ServiceLocator serviceLocator;
public DelegateActionManager() { private final EntityManagerFactory entityManagerFactory;
public DelegateActionManager(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
this.serviceLocator = new ServiceLocator();
initializeServices();
logger.debug("DelegateActionManager created"); logger.debug("DelegateActionManager created");
this.handlerRegistry = new HashMap<>(); this.handlerRegistry = new HashMap<>();
registerHandlers(); autoRegisterHandlers();
} }
private void registerHandlers() { private void initializeServices() {
handlerRegistry.put("echo",new EchoHandler()); logger.info("Initializing services...");
GenreRepository genreRepository = new GenreRepository(entityManagerFactory);
GenreService genreService = new GenreService(genreRepository);
serviceLocator.register(GenreService.class, genreService);
ArtistRepository artistRepository = new ArtistRepository(entityManagerFactory);
ArtistService artistService = new ArtistService(artistRepository);
serviceLocator.register(ArtistService.class, artistService);
ComposerRepository composerRepository = new ComposerRepository(entityManagerFactory);
ComposerService composerService = new ComposerService(composerRepository);
serviceLocator.register(ComposerService.class, composerService);
BitDepthRepository bitDepthRepository = new BitDepthRepository(entityManagerFactory);
BitDepthService bitDepthService = new BitDepthService(bitDepthRepository);
serviceLocator.register(BitDepthService.class, bitDepthService);
BitRateRepository bitRateRepository = new BitRateRepository(entityManagerFactory);
BitRateService bitRateService = new BitRateService(bitRateRepository);
serviceLocator.register(BitRateService.class, bitRateService);
serviceLocator.logRegisteredServices();
logger.info("Services initialized successfully");
} }
public void start(){ public void start(){
logger.info("DelegateActionManager started"); logger.info("DelegateActionManager started");
} }
@@ -33,6 +85,117 @@ public class DelegateActionManager {
logger.info("DelegateActionManager stopped"); logger.info("DelegateActionManager stopped");
} }
@SuppressWarnings("unchecked")
private ActionHandler instantiateHandler(Class<?> clazz) throws Exception {
if(!ActionHandler.class.isAssignableFrom(clazz)){
throw new IllegalArgumentException(
clazz.getName() + " is annotated with @Action but does not implement ActionHandler");
}
logger.debug("Attempting to instantiate handler: {}", clazz.getSimpleName());
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
// Sort constructors by parameter count (descending) to prefer DI constructors
java.util.Arrays.sort(constructors, (c1, c2) ->
Integer.compare(c2.getParameterCount(), c1.getParameterCount()));
for (Constructor<?> constructor : constructors) {
Class<?>[] paramTypes = constructor.getParameterTypes();
Object[] params = new Object[paramTypes.length];
boolean allDependenciesResolved = true;
for (int i = 0; i < paramTypes.length; i++) {
Object service = serviceLocator.get(paramTypes[i]);
if (service == null) {
allDependenciesResolved = false;
logger.debug("Cannot resolve dependency {} for {}",
paramTypes[i].getSimpleName(),
clazz.getSimpleName());
break; // Para de tentar esse construtor
}
params[i] = service;
}
if (allDependenciesResolved) {
logger.debug("Using constructor with {} params for {}",
paramTypes.length, clazz.getSimpleName());
return (ActionHandler) constructor.newInstance(params);
}
}
throw new IllegalStateException(
String.format(
"Cannot instantiate handler %s. No suitable constructor found. " +
"Make sure all required services are registered in ServiceLocator.",
clazz.getName()
)
);
}
private void autoRegisterHandlers() {
logger.info("Starting auto-registration of handlers...");
Reflections reflections = new Reflections(
"com.mediamanager.service.delegate.handler",
Scanners.TypesAnnotated
);
Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(Action.class);
logger.info("Found {} handler classes with @Action annotation", annotatedClasses.size());
int successCount = 0;
int failureCount = 0;
for (Class<?> handlerClass : annotatedClasses) {
try {
Action actionAnnotation = handlerClass.getAnnotation(Action.class);
String actionName = actionAnnotation.value();
logger.debug("Processing handler: {} for action '{}'",
handlerClass.getSimpleName(),
actionName);
ActionHandler handler = instantiateHandler(handlerClass);
handlerRegistry.put(actionName, handler);
logger.info("✓ Registered handler: '{}' -> {}",
actionName,
handlerClass.getSimpleName());
successCount++;
} catch (Exception e) {
logger.error("✗ Failed to register handler: {}",
handlerClass.getName(),
e);
failureCount++;
}
}
logger.info("Auto-registration complete: {} successful, {} failed, {} total",
successCount,
failureCount,
successCount + failureCount);
if (failureCount > 0) {
logger.warn("Some handlers failed to register. Check logs above for details.");
}
}
public TransportProtocol.Response ProcessedRequest(TransportProtocol.Request request){ public TransportProtocol.Response ProcessedRequest(TransportProtocol.Request request){
String requestId = request.getRequestId(); String requestId = request.getRequestId();
logger.info("Processing request: {}", requestId); logger.info("Processing request: {}", requestId);
@@ -0,0 +1,45 @@
package com.mediamanager.service.delegate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
public class ServiceLocator {
private static final Logger logger = LogManager.getLogger(ServiceLocator.class);
private final Map<Class<?>, Object> services = new HashMap<>();
public <T> void register(Class<T> serviceClass, T serviceInstance) {
if (serviceInstance == null) {
throw new IllegalArgumentException("Service instance cannot be null");
}
services.put(serviceClass, serviceInstance);
logger.debug("Registered service: {} -> {}",
serviceClass.getSimpleName(),
serviceInstance.getClass().getSimpleName());
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> serviceClass) {
return (T) services.get(serviceClass);
}
public boolean has(Class<?> serviceClass) {
return services.containsKey(serviceClass);
}
public int size() {
return services.size();
}
public void logRegisteredServices() {
logger.info("Registered services: {}", services.size());
services.forEach((clazz, instance) ->
logger.info(" - {} -> {}",
clazz.getSimpleName(),
instance.getClass().getSimpleName())
);
}
}
@@ -0,0 +1,13 @@
package com.mediamanager.service.delegate.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Action {
String value();
}
@@ -0,0 +1,34 @@
package com.mediamanager.service.delegate.handler;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TestProtocol.CloseCommand;
import com.mediamanager.protocol.TestProtocol.CloseResponse;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("close")
public class CloseHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CloseHandler.class);
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
CloseCommand.parseFrom(requestPayload); // Valida
logger.info("Close command received - connection will close");
CloseResponse response = CloseResponse.newBuilder()
.setMessage("Connection closing. Goodbye!")
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(ByteString.copyFrom(response.toByteArray()))
.setStatusCode(200)
.putHeaders("Connection", "close"); // ← Marca para fechar
}
}
@@ -1,17 +1,41 @@
package com.mediamanager.service.delegate.handler; package com.mediamanager.service.delegate.handler;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TestProtocol.EchoCommand; // ← Import
import com.mediamanager.protocol.TestProtocol.EchoResponse; // ← Import
import com.mediamanager.protocol.TransportProtocol; import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.service.delegate.ActionHandler; import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("echo")
public class EchoHandler implements ActionHandler { public class EchoHandler implements ActionHandler {
@Override private static final Logger logger = LogManager.getLogger(EchoHandler.class);
public TransportProtocol.Response.Builder handle(ByteString requestPayload) {
String payloadText = requestPayload.toStringUtf8();
String responseText = "Server received: " + payloadText;
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException { // ← Pode lançar exceção
// 1. Parse Protobuf bytes → EchoCommand
EchoCommand command = EchoCommand.parseFrom(requestPayload);
logger.debug("Echo received: {}", command.getMessage());
// 2. Cria EchoResponse (Protobuf)
EchoResponse echoResponse = EchoResponse.newBuilder()
.setMessage(command.getMessage())
.setServerTimestamp(System.currentTimeMillis())
.build();
// 3. Serializa EchoResponse → bytes
ByteString responsePayload = ByteString.copyFrom(echoResponse.toByteArray());
// 4. Retorna Response
return TransportProtocol.Response.newBuilder() return TransportProtocol.Response.newBuilder()
.setPayload(ByteString.copyFromUtf8(responseText)) .setPayload(responsePayload)
.setStatusCode(200); .setStatusCode(200);
} }
} }
@@ -0,0 +1,38 @@
package com.mediamanager.service.delegate.handler;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TestProtocol.HeartbeatCommand;
import com.mediamanager.protocol.TestProtocol.HeartbeatResponse;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("heartbeat")
public class HeartbeatHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(HeartbeatHandler.class);
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
HeartbeatCommand command = HeartbeatCommand.parseFrom(requestPayload);
long serverTime = System.currentTimeMillis();
logger.debug("Heartbeat received. Client T1={}, Server T2={}",
command.getClientTimestamp(), serverTime);
HeartbeatResponse response = HeartbeatResponse.newBuilder()
.setClientTimestamp(command.getClientTimestamp()) // Echo T1
.setServerTimestamp(serverTime) // T2
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(ByteString.copyFrom(response.toByteArray()))
.setStatusCode(200);
}
}
@@ -0,0 +1,50 @@
package com.mediamanager.service.delegate.handler.artist;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ArtistMapper;
import com.mediamanager.model.Artist;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("artist.create")
public class CreateArtistHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CreateArtistHandler.class);
private final ArtistService artistService;
public CreateArtistHandler(ArtistService artistService) {
this.artistService = artistService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
ArtistMessages.CreateArtistRequest createRequest =
ArtistMessages.CreateArtistRequest.parseFrom(requestPayload);
Artist artist = artistService.createArtist(createRequest.getName());
ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artist);
ArtistMessages.CreateArtistResponse createArtistResponse = ArtistMessages.CreateArtistResponse.newBuilder()
.setArtist(artistProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(createArtistResponse.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 artist", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,62 @@
package com.mediamanager.service.delegate.handler.artist;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("artist.delete")
public class DeleteArtistHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(DeleteArtistHandler.class);
private final ArtistService artistService;
public DeleteArtistHandler(ArtistService artistService) {
this.artistService = artistService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
ArtistMessages.DeleteArtistRequest deleteRequest =
ArtistMessages.DeleteArtistRequest.parseFrom(requestPayload);
int id = deleteRequest.getId();
boolean success = artistService.deleteArtist(id);
ArtistMessages.DeleteArtistResponse deleteResponse;
if (success) {
deleteResponse = ArtistMessages.DeleteArtistResponse.newBuilder()
.setSuccess(true)
.setMessage("Artist deleted successfully")
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(deleteResponse.toByteString());
} else {
deleteResponse = ArtistMessages.DeleteArtistResponse.newBuilder()
.setSuccess(false)
.setMessage("Artist not found")
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(deleteResponse.toByteString());
}
} catch (Exception e) {
logger.error("Error deleting artist", e);
ArtistMessages.DeleteArtistResponse deleteResponse =
ArtistMessages.DeleteArtistResponse.newBuilder()
.setSuccess(false)
.setMessage("Error: " + e.getMessage())
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(deleteResponse.toByteString());
}
}
}
@@ -0,0 +1,56 @@
package com.mediamanager.service.delegate.handler.artist;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ArtistMapper;
import com.mediamanager.model.Artist;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action(value = "artist.getById")
public class GetArtistByIdHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetArtistByIdHandler.class);
private final ArtistService artistService;
public GetArtistByIdHandler(ArtistService artistService) {
this.artistService = artistService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException{
try{
ArtistMessages.GetArtistByIdRequest getByIdRequest =
ArtistMessages.GetArtistByIdRequest.parseFrom(requestPayload);
int id = getByIdRequest.getId();
Optional<Artist> artistOpt = artistService.getArtistById(id);
if (artistOpt.isEmpty()){
logger.warn("Artist not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Artist not found"));
}
ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artistOpt.get());
ArtistMessages.GetArtistByIdResponse getByIdResponse = ArtistMessages.GetArtistByIdResponse.newBuilder()
.setArtist(artistProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getByIdResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting artist by ID", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage()));
}
}
}
@@ -0,0 +1,48 @@
package com.mediamanager.service.delegate.handler.artist;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ArtistMapper;
import com.mediamanager.model.Artist;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
@Action("artist.getAll")
public class GetArtistHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetArtistHandler.class);
private final ArtistService artistService;
public GetArtistHandler(ArtistService artistService){this.artistService = artistService;}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
List<Artist> artists = artistService.getAllArtists();
ArtistMessages.GetArtistsResponse.Builder responseBuilder = ArtistMessages.GetArtistsResponse.newBuilder();
for (Artist artist : artists) {
ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artist);
responseBuilder.addArtists(artistProto);
}
ArtistMessages.GetArtistsResponse getArtistsResponse = responseBuilder.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getArtistsResponse.toByteString());
}catch (Exception e){
logger.error("Error getting artists", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,65 @@
package com.mediamanager.service.delegate.handler.artist;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ArtistMapper;
import com.mediamanager.model.Artist;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.service.artist.ArtistService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("artist.update")
public class UpdateArtistHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(UpdateArtistHandler.class);
private final ArtistService artistService;
public UpdateArtistHandler(ArtistService artistService) {
this.artistService = artistService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
ArtistMessages.UpdateArtistRequest updateRequest =
ArtistMessages.UpdateArtistRequest.parseFrom(requestPayload);
int id = updateRequest.getId();
String newName = updateRequest.getName();
Optional<Artist> artistOpt = artistService.updateArtist(id, newName);
if(artistOpt.isEmpty()){
logger.warn("Artist not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Artist not found"));
}
ArtistMessages.Artist artistProto = ArtistMapper.toProtobuf(artistOpt.get());
ArtistMessages.UpdateArtistResponse updateResponse = ArtistMessages.UpdateArtistResponse.newBuilder()
.setArtist(artistProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(updateResponse.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 updating artist", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,51 @@
package com.mediamanager.service.delegate.handler.bitdepth;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitDepthMapper;
import com.mediamanager.model.BitDepth;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ArtistMessages;
import com.mediamanager.protocol.messages.BitDepthMessages;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("bitdepth.create")
public class CreateBitDepthHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CreateBitDepthHandler.class);
private final BitDepthService bitDepthService;
public CreateBitDepthHandler(BitDepthService bitDepthService) {
this.bitDepthService = bitDepthService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
BitDepthMessages.CreateBitDepthRequest createRequest =
BitDepthMessages.CreateBitDepthRequest.parseFrom(requestPayload);
BitDepth bitDepth = bitDepthService.createBitDepth(createRequest.getValue());
BitDepthMessages.BitDepth BitDepthProto = BitDepthMapper.toProtobuf(bitDepth);
BitDepthMessages.CreateBitDepthResponse createBitDepthResponse = BitDepthMessages.CreateBitDepthResponse.newBuilder()
.setBitdepth(BitDepthProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(createBitDepthResponse.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 bit-depth", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,62 @@
package com.mediamanager.service.delegate.handler.bitdepth;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitDepthMessages;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("bitdepth.delete")
public class DeleteBitDepthHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(DeleteBitDepthHandler.class);
private final BitDepthService bitDepthService;
public DeleteBitDepthHandler(BitDepthService bitDepthService) {
this.bitDepthService = bitDepthService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
BitDepthMessages.DeleteBitDepthRequest deleteRequest =
BitDepthMessages.DeleteBitDepthRequest.parseFrom(requestPayload);
int id = deleteRequest.getId();
boolean success = bitDepthService.deleteBitDepth(id);
BitDepthMessages.DeleteBitDepthResponse deleteResponse;
if (success) {
deleteResponse = BitDepthMessages.DeleteBitDepthResponse.newBuilder()
.setSuccess(true)
.setMessage("Bit-Depth deleted successfully")
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(deleteResponse.toByteString());
} else {
deleteResponse = BitDepthMessages.DeleteBitDepthResponse.newBuilder()
.setSuccess(false)
.setMessage("Bit-Depth not found")
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(deleteResponse.toByteString());
}
} catch (Exception e) {
logger.error("Error deleting bit-depth", e);
BitDepthMessages.DeleteBitDepthResponse deleteResponse =
BitDepthMessages.DeleteBitDepthResponse.newBuilder()
.setSuccess(false)
.setMessage("Error: " + e.getMessage())
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(deleteResponse.toByteString());
}
}
}
@@ -0,0 +1,56 @@
package com.mediamanager.service.delegate.handler.bitdepth;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitDepthMapper;
import com.mediamanager.model.BitDepth;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitDepthMessages;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action(value = "bitdepth.getById")
public class GetBitDepthByIdHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetBitDepthByIdHandler.class);
private final BitDepthService bitDepthServicee;
public GetBitDepthByIdHandler(BitDepthService bitDepthServicee) {
this.bitDepthServicee = bitDepthServicee;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException{
try{
BitDepthMessages.GetBitDepthByIdRequest getByIdRequest =
BitDepthMessages.GetBitDepthByIdRequest.parseFrom(requestPayload);
int id = getByIdRequest.getId();
Optional<BitDepth> bitDepthOpt = bitDepthServicee.getBitDepthById(id);
if (bitDepthOpt.isEmpty()){
logger.warn("BitDepth not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("BitDepth not found"));
}
BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepthOpt.get());
BitDepthMessages.GetBitDepthByIdResponse getByIdResponse = BitDepthMessages.GetBitDepthByIdResponse.newBuilder()
.setBitdepth(bitDepthProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getByIdResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting bit-depth by ID", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage()));
}
}
}
@@ -0,0 +1,48 @@
package com.mediamanager.service.delegate.handler.bitdepth;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitDepthMapper;
import com.mediamanager.model.BitDepth;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitDepthMessages;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
@Action("bitdepth.getAll")
public class GetBitDepthHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetBitDepthHandler.class);
private final BitDepthService bitDepthService;
public GetBitDepthHandler(BitDepthService bitDepthService){this.bitDepthService = bitDepthService;}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
List<BitDepth> bitDepths = bitDepthService.getAllBitDepths();
BitDepthMessages.GetBitDepthsResponse.Builder responseBuilder = BitDepthMessages.GetBitDepthsResponse.newBuilder();
for (BitDepth bitDepth : bitDepths) {
BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepth);
responseBuilder.addBitdepths(bitDepthProto);
}
BitDepthMessages.GetBitDepthsResponse getBitDepthsResponse = responseBuilder.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getBitDepthsResponse.toByteString());
}catch (Exception e){
logger.error("Error getting bit-depths", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,65 @@
package com.mediamanager.service.delegate.handler.bitdepth;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitDepthMapper;
import com.mediamanager.model.BitDepth;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitDepthMessages;
import com.mediamanager.service.bitdepth.BitDepthService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("bitdepth.update")
public class UpdateBitDepthHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(UpdateBitDepthHandler.class);
private final BitDepthService bitDepthService;
public UpdateBitDepthHandler(BitDepthService bitDepthService) {
this.bitDepthService = bitDepthService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
BitDepthMessages.UpdateBitDepthRequest updateRequest =
BitDepthMessages.UpdateBitDepthRequest.parseFrom(requestPayload);
int id = updateRequest.getId();
String newValue = updateRequest.getValue();
Optional<BitDepth> bitDepthOpt = bitDepthService.updateBitDepth(id, newValue);
if(bitDepthOpt.isEmpty()){
logger.warn("BitDepth not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("BitDepth not found"));
}
BitDepthMessages.BitDepth bitDepthProto = BitDepthMapper.toProtobuf(bitDepthOpt.get());
BitDepthMessages.UpdateBitDepthResponse updateResponse = BitDepthMessages.UpdateBitDepthResponse.newBuilder()
.setBitdepth(bitDepthProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(updateResponse.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 updating bit-depth", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,50 @@
package com.mediamanager.service.delegate.handler.bitrate;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitRateMapper;
import com.mediamanager.model.BitRate;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitRateMessages;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("bitrate.create")
public class CreateBitRateHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CreateBitRateHandler.class);
private final BitRateService bitRateService;
public CreateBitRateHandler(BitRateService bitRateService) {
this.bitRateService = bitRateService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
BitRateMessages.CreateBitRateRequest createRequest =
BitRateMessages.CreateBitRateRequest.parseFrom(requestPayload);
BitRate bitRate = bitRateService.createBitRate(createRequest.getValue());
BitRateMessages.BitRate BitRateProto = BitRateMapper.toProtobuf(bitRate);
BitRateMessages.CreateBitRateResponse createBitRateResponse = BitRateMessages.CreateBitRateResponse.newBuilder()
.setBitrate(BitRateProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(createBitRateResponse.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 bit-rate", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,62 @@
package com.mediamanager.service.delegate.handler.bitrate;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitRateMessages;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("bitrate.delete")
public class DeleteBitRateHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(DeleteBitRateHandler.class);
private final BitRateService bitRateService;
public DeleteBitRateHandler(BitRateService bitRateService) {
this.bitRateService = bitRateService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
BitRateMessages.DeleteBitRateRequest deleteRequest =
BitRateMessages.DeleteBitRateRequest.parseFrom(requestPayload);
int id = deleteRequest.getId();
boolean success = bitRateService.deleteBitRate(id);
BitRateMessages.DeleteBitRateResponse deleteResponse;
if (success) {
deleteResponse = BitRateMessages.DeleteBitRateResponse.newBuilder()
.setSuccess(true)
.setMessage("Bit-Rate deleted successfully")
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(deleteResponse.toByteString());
} else {
deleteResponse = BitRateMessages.DeleteBitRateResponse.newBuilder()
.setSuccess(false)
.setMessage("Bit-Rate not found")
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(deleteResponse.toByteString());
}
} catch (Exception e) {
logger.error("Error deleting bit-rate", e);
BitRateMessages.DeleteBitRateResponse deleteResponse =
BitRateMessages.DeleteBitRateResponse.newBuilder()
.setSuccess(false)
.setMessage("Error: " + e.getMessage())
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(deleteResponse.toByteString());
}
}
}
@@ -0,0 +1,56 @@
package com.mediamanager.service.delegate.handler.bitrate;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitRateMapper;
import com.mediamanager.model.BitRate;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitRateMessages;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action(value = "bitrate.getById")
public class GetBitRateByIdHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetBitRateByIdHandler.class);
private final BitRateService bitRateService;
public GetBitRateByIdHandler(BitRateService bitRateService) {
this.bitRateService = bitRateService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException{
try{
BitRateMessages.GetBitRateByIdRequest getByIdRequest =
BitRateMessages.GetBitRateByIdRequest.parseFrom(requestPayload);
int id = getByIdRequest.getId();
Optional<BitRate> bitRateOpt = bitRateService.getBitRateById(id);
if (bitRateOpt.isEmpty()){
logger.warn("BitRate not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("BitRate not found"));
}
BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRateOpt.get());
BitRateMessages.GetBitRateByIdResponse getByIdResponse = BitRateMessages.GetBitRateByIdResponse.newBuilder()
.setBitrate(bitRateProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getByIdResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting bit-rate by ID", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage()));
}
}
}
@@ -0,0 +1,48 @@
package com.mediamanager.service.delegate.handler.bitrate;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitRateMapper;
import com.mediamanager.model.BitRate;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitRateMessages;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
@Action("bitrate.getAll")
public class GetBitRateHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetBitRateHandler.class);
private final BitRateService bitRateService;
public GetBitRateHandler(BitRateService bitRateService){this.bitRateService = bitRateService;}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
List<BitRate> bitRates = bitRateService.getAllBitRates();
BitRateMessages.GetBitRatesResponse.Builder responseBuilder = BitRateMessages.GetBitRatesResponse.newBuilder();
for (BitRate bitRate : bitRates) {
BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRate);
responseBuilder.addBitrates(bitRateProto);
}
BitRateMessages.GetBitRatesResponse getBitRatesResponse = responseBuilder.build();
return TransportProtocol.Response.newBuilder()
.setPayload(getBitRatesResponse.toByteString());
}catch (Exception e){
logger.error("Error getting bit-rates", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,65 @@
package com.mediamanager.service.delegate.handler.bitrate;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.BitRateMapper;
import com.mediamanager.model.BitRate;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.BitRateMessages;
import com.mediamanager.service.bitrate.BitRateService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("bitrate.update")
public class UpdateBitRateHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(UpdateBitRateHandler.class);
private final BitRateService bitRateService;
public UpdateBitRateHandler(BitRateService bitRateService) {
this.bitRateService = bitRateService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException {
try{
BitRateMessages.UpdateBitRateRequest updateRequest =
BitRateMessages.UpdateBitRateRequest.parseFrom(requestPayload);
int id = updateRequest.getId();
String newValue = updateRequest.getValue();
Optional<BitRate> bitRateOpt = bitRateService.updateBitRate(id, newValue);
if(bitRateOpt.isEmpty()){
logger.warn("BitRate not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("BitRate not found"));
}
BitRateMessages.BitRate bitRateProto = BitRateMapper.toProtobuf(bitRateOpt.get());
BitRateMessages.UpdateBitRateResponse updateResponse = BitRateMessages.UpdateBitRateResponse.newBuilder()
.setBitrate(bitRateProto)
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(updateResponse.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 updating bit-rate", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,51 @@
package com.mediamanager.service.delegate.handler.composer;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ComposerMapper;
import com.mediamanager.model.Composer;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ComposerMessages;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("composer.create")
public class CreateComposerHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CreateComposerHandler.class);
private final ComposerService composerService;
public CreateComposerHandler(ComposerService composerService) {
this.composerService = composerService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try{
ComposerMessages.CreateComposerRequest CreateRequest = ComposerMessages.CreateComposerRequest
.parseFrom(requestPayload);
Composer composer = composerService.createComposer(CreateRequest.getName());
ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composer);
ComposerMessages.CreateComposerResponse createResponse = ComposerMessages.CreateComposerResponse
.newBuilder().setComposer(composerProto).build();
return TransportProtocol.Response.newBuilder().setPayload(createResponse.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 composer", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,53 @@
package com.mediamanager.service.delegate.handler.composer;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ComposerMessages;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action( "composer.delete")
public class DeleteComposerHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(DeleteComposerHandler.class);
private final ComposerService composerService;
public DeleteComposerHandler(ComposerService composerService){
this.composerService = composerService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
ComposerMessages.DeleteComposerRequest deleteRequest =
ComposerMessages.DeleteComposerRequest.parseFrom(requestPayload);
int id = deleteRequest.getId();
boolean success = composerService.deleteComposer(id);
ComposerMessages.DeleteComposerResponse deleteResponse;
if(success){
deleteResponse = ComposerMessages.DeleteComposerResponse.newBuilder().setSuccess(true)
.setMessage("Composer deleted successfully").build();
return TransportProtocol.Response.newBuilder()
.setPayload(deleteResponse.toByteString());
}else {
deleteResponse = ComposerMessages.DeleteComposerResponse.newBuilder().setSuccess(false)
.setMessage("Composer not found").build();
return TransportProtocol.Response.newBuilder().setStatusCode(404)
.setPayload(deleteResponse.toByteString());
}
} catch (Exception e) {
logger.error("Error deleting composer", e);
ComposerMessages.DeleteComposerResponse deleteResponse = ComposerMessages.DeleteComposerResponse
.newBuilder().setSuccess(false).setMessage("Error: " + e.getMessage()).build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(500).setPayload(deleteResponse.toByteString());
}
}
}
@@ -0,0 +1,57 @@
package com.mediamanager.service.delegate.handler.composer;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ComposerMapper;
import com.mediamanager.model.Composer;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ComposerMessages;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action( "composer.getById")
public class GetComposerByIdHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetComposerByIdHandler.class);
private final ComposerService composerService;
public GetComposerByIdHandler(ComposerService composerService){
this.composerService = composerService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try{
ComposerMessages.GetComposerByIdRequest getByIdRequest = ComposerMessages.GetComposerByIdRequest
.parseFrom(requestPayload);
int id = getByIdRequest.getId();
Optional<Composer> composerOpt = composerService.getComposerById(id);
if (composerOpt.isEmpty()) {
logger.warn("Composer not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Composer not found"));
}
ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composerOpt.get());
ComposerMessages.GetComposerByIdResponse getByIdResponse = ComposerMessages.GetComposerByIdResponse
.newBuilder().setComposer(composerProto).build();
return TransportProtocol.Response.newBuilder().setPayload(getByIdResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting composer by ID", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,50 @@
package com.mediamanager.service.delegate.handler.composer;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ComposerMapper;
import com.mediamanager.model.Composer;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ComposerMessages;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
@Action( "composer.getAll")
public class GetComposerHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetComposerHandler.class);
private final ComposerService composerService;
public GetComposerHandler(ComposerService composerService){
this.composerService = composerService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try{
List<Composer> composers = composerService.getAllComposers();
ComposerMessages.GetComposersResponse.Builder responseBuilder = ComposerMessages.GetComposersResponse.newBuilder();
for(Composer composer : composers){
ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composer);
responseBuilder.addComposers(composerProto);
}
ComposerMessages.GetComposersResponse getGenresResponse = responseBuilder.build();
return TransportProtocol.Response.newBuilder().setPayload(getGenresResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting composers", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,56 @@
package com.mediamanager.service.delegate.handler.composer;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.ComposerMapper;
import com.mediamanager.model.Composer;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.ComposerMessages;
import com.mediamanager.service.composer.ComposerService;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("composer.update")
public class UpdateComposerHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(UpdateComposerHandler.class);
private final ComposerService composerService;
public UpdateComposerHandler(ComposerService composerService){
this.composerService = composerService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try{
ComposerMessages.UpdateComposerRequest updateRequest = ComposerMessages.UpdateComposerRequest
.parseFrom(requestPayload);
int id = updateRequest.getId();
String newName = updateRequest.getName();
Optional<Composer> composerOpt = composerService.updateComposer(id, newName);
if (composerOpt.isEmpty()) {
logger.warn("Composer not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Composer not found"));
}
ComposerMessages.Composer composerProto = ComposerMapper.toProtobuf(composerOpt.get());
ComposerMessages.UpdateComposerResponse updateResponse = ComposerMessages.UpdateComposerResponse
.newBuilder().setComposer(composerProto).build();
return TransportProtocol.Response.newBuilder().setPayload(updateResponse.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 updating composer", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,62 @@
package com.mediamanager.service.delegate.handler.genre;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.GenreMapper;
import com.mediamanager.model.Genre;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("genre.create")
public class CreateGenreHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(CreateGenreHandler.class);
private final GenreService genreService;
public CreateGenreHandler(GenreService genreService) {
this.genreService = genreService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
// 1. Parse protobuf request
GenreMessages.CreateGenreRequest createRequest =
GenreMessages.CreateGenreRequest.parseFrom(requestPayload);
// 2. Chama service (lógica de negócio)
Genre genre = genreService.createGenre(createRequest.getName());
// 3. Converte entity para protobuf
GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genre);
// 4. Cria response protobuf
GenreMessages.CreateGenreResponse createResponse =
GenreMessages.CreateGenreResponse.newBuilder()
.setGenre(genreProto)
.build();
// 5. Retorna
return TransportProtocol.Response.newBuilder()
.setPayload(createResponse.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 genre", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,72 @@
package com.mediamanager.service.delegate.handler.genre;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Action("genre.delete")
public class DeleteGenreHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(DeleteGenreHandler.class);
private final GenreService genreService;
public DeleteGenreHandler(GenreService genreService) {
this.genreService = genreService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
// 1. Parse protobuf request
GenreMessages.DeleteGenreRequest deleteRequest =
GenreMessages.DeleteGenreRequest.parseFrom(requestPayload);
int id = deleteRequest.getId();
// 2. Deleta via service
boolean success = genreService.deleteGenre(id);
// 3. Cria response
GenreMessages.DeleteGenreResponse deleteResponse;
if (success) {
deleteResponse = GenreMessages.DeleteGenreResponse.newBuilder()
.setSuccess(true)
.setMessage("Genre deleted successfully")
.build();
return TransportProtocol.Response.newBuilder()
.setPayload(deleteResponse.toByteString());
} else {
deleteResponse = GenreMessages.DeleteGenreResponse.newBuilder()
.setSuccess(false)
.setMessage("Genre not found")
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(deleteResponse.toByteString());
}
} catch (Exception e) {
logger.error("Error deleting genre", e);
GenreMessages.DeleteGenreResponse deleteResponse =
GenreMessages.DeleteGenreResponse.newBuilder()
.setSuccess(false)
.setMessage("Error: " + e.getMessage())
.build();
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(deleteResponse.toByteString());
}
}
}
@@ -0,0 +1,66 @@
package com.mediamanager.service.delegate.handler.genre;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.GenreMapper;
import com.mediamanager.model.Genre;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("genre.getById")
public class GetGenreByIdHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetGenreByIdHandler.class);
private final GenreService genreService;
public GetGenreByIdHandler(GenreService genreService) {
this.genreService = genreService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
// 1. Parse protobuf request
GenreMessages.GetGenreByIdRequest getByIdRequest =
GenreMessages.GetGenreByIdRequest.parseFrom(requestPayload);
int id = getByIdRequest.getId();
// 2. Busca via service
Optional<Genre> genreOpt = genreService.getGenreById(id);
if (genreOpt.isEmpty()) {
logger.warn("Genre not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Genre not found"));
}
// 3. Converte para protobuf
GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genreOpt.get());
GenreMessages.GetGenreByIdResponse getByIdResponse =
GenreMessages.GetGenreByIdResponse.newBuilder()
.setGenre(genreProto)
.build();
// 4. Retorna
return TransportProtocol.Response.newBuilder()
.setPayload(getByIdResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting genre by ID", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,56 @@
package com.mediamanager.service.delegate.handler.genre;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.GenreMapper;
import com.mediamanager.model.Genre;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
@Action("genre.getAll")
public class GetGenreHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(GetGenreHandler.class);
private final GenreService genreService;
public GetGenreHandler(GenreService genreService) {
this.genreService = genreService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
// 1. Busca todos os genres via service
List<Genre> genres = genreService.getAllGenres();
// 2. Converte cada Genre para protobuf
GenreMessages.GetGenresResponse.Builder responseBuilder =
GenreMessages.GetGenresResponse.newBuilder();
for (Genre genre : genres) {
GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genre);
responseBuilder.addGenres(genreProto);
}
GenreMessages.GetGenresResponse getGenresResponse = responseBuilder.build();
// 3. Retorna
return TransportProtocol.Response.newBuilder()
.setPayload(getGenresResponse.toByteString());
} catch (Exception e) {
logger.error("Error getting genres", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,73 @@
package com.mediamanager.service.delegate.handler.genre;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mediamanager.mapper.GenreMapper;
import com.mediamanager.model.Genre;
import com.mediamanager.protocol.TransportProtocol;
import com.mediamanager.protocol.messages.GenreMessages;
import com.mediamanager.service.delegate.ActionHandler;
import com.mediamanager.service.delegate.annotation.Action;
import com.mediamanager.service.genre.GenreService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Optional;
@Action("genre.update")
public class UpdateGenreHandler implements ActionHandler {
private static final Logger logger = LogManager.getLogger(UpdateGenreHandler.class);
private final GenreService genreService;
public UpdateGenreHandler(GenreService genreService) {
this.genreService = genreService;
}
@Override
public TransportProtocol.Response.Builder handle(ByteString requestPayload)
throws InvalidProtocolBufferException {
try {
// 1. Parse protobuf request
GenreMessages.UpdateGenreRequest updateRequest =
GenreMessages.UpdateGenreRequest.parseFrom(requestPayload);
int id = updateRequest.getId();
String newName = updateRequest.getName();
// 2. Atualiza via service
Optional<Genre> genreOpt = genreService.updateGenre(id, newName);
if (genreOpt.isEmpty()) {
logger.warn("Genre not found with ID: {}", id);
return TransportProtocol.Response.newBuilder()
.setStatusCode(404)
.setPayload(ByteString.copyFromUtf8("Genre not found"));
}
// 3. Converte para protobuf
GenreMessages.Genre genreProto = GenreMapper.toProtobuf(genreOpt.get());
GenreMessages.UpdateGenreResponse updateResponse =
GenreMessages.UpdateGenreResponse.newBuilder()
.setGenre(genreProto)
.build();
// 4. Retorna
return TransportProtocol.Response.newBuilder()
.setPayload(updateResponse.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 updating genre", e);
return TransportProtocol.Response.newBuilder()
.setStatusCode(500)
.setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage()));
}
}
}
@@ -0,0 +1,88 @@
package com.mediamanager.service.genre;
import com.mediamanager.model.Genre;
import com.mediamanager.repository.GenreRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import java.util.Optional;
/**
* Service para lógica de negócio relacionada a Genre
*/
public class GenreService {
private static final Logger logger = LogManager.getLogger(GenreService.class);
private final GenreRepository genreRepository;
public GenreService(GenreRepository genreRepository) {
this.genreRepository = genreRepository;
}
/**
* Cria um novo genre
*/
public Genre createGenre(String name) {
logger.info("Creating genre: {}", name);
// Aqui poderia ter validações de negócio
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Genre name cannot be empty");
}
Genre genre = new Genre();
genre.setName(name.trim());
return genreRepository.save(genre);
}
/**
* Busca todos os genres
*/
public List<Genre> getAllGenres() {
logger.info("Getting all genres");
return genreRepository.findAll();
}
/**
* Busca genre por ID
*/
public Optional<Genre> getGenreById(Integer id) {
logger.info("Getting genre by ID: {}", id);
return genreRepository.findById(id);
}
/**
* Atualiza um genre existente
*/
public Optional<Genre> updateGenre(Integer id, String name) {
logger.info("Updating genre ID {}: {}", id, name);
// Validação
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Genre name cannot be empty");
}
Optional<Genre> existingGenre = genreRepository.findById(id);
if (existingGenre.isEmpty()) {
logger.warn("Genre not found with ID: {}", id);
return Optional.empty();
}
Genre genre = existingGenre.get();
genre.setName(name.trim());
Genre updated = genreRepository.update(genre);
return Optional.of(updated);
}
/**
* Deleta um genre por ID
*/
public boolean deleteGenre(Integer id) {
logger.info("Deleting genre ID: {}", id);
return genreRepository.deleteById(id);
}
}
@@ -125,7 +125,7 @@ public class IPCManager {
} }
logger.info("Closing IPC connection..."); logger.info("Closing IPC connection...");
running.set(false); running.set(false);
if (serverChannel != null && serverChannel.isOpen()) { if (serverChannel != null && serverChannel.isOpen()) {
@@ -185,7 +185,7 @@ public class IPCManager {
// Nenhum cliente conectado no momento // Nenhum cliente conectado no momento
// Dorme por um curto período antes de verificar novamente // Dorme por um curto período antes de verificar novamente
// Isso evita consumir CPU desnecessariamente em um loop vazio // Isso evita consumir CPU desnecessariamente em um loop vazio
Thread.sleep(100); // 100 milissegundos Thread.sleep(1); // 1 milissegundos
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -223,9 +223,16 @@ public class IPCManager {
logger.debug("Client {} handler thread started", clientId); logger.debug("Client {} handler thread started", clientId);
try { try {
TransportProtocol.Request request = readRequest(channel); // LOOP: processa múltiplas requests na mesma conexão
while (channel.isOpen()) {
TransportProtocol.Request request = readRequest(channel);
if (request == null) {
// Cliente desconectou gracefully
logger.info("Client {} disconnected (end of stream)", clientId);
break;
}
if (request != null) {
logger.info("Client {} sent request {}", clientId, request.getRequestId()); logger.info("Client {} sent request {}", clientId, request.getRequestId());
// Processa usando o DelegateActionManager // Processa usando o DelegateActionManager
@@ -233,17 +240,29 @@ public class IPCManager {
// Envia resposta de volta // Envia resposta de volta
writeResponse(channel, response); writeResponse(channel, response);
logger.info("Client {} response sent", clientId); logger.info("Client {} response sent", clientId);
} else {
logger.warn("Client {} sent null message", clientId); // Verifica se é comando CLOSE
String connectionHeader = response.getHeadersOrDefault("Connection", "");
if ("close".equals(connectionHeader)) {
logger.info("Client {} requested connection close", clientId);
break; // Sai do loop e fecha
}
} }
} catch (IOException e) {
if (channel.isOpen()) {
logger.error("IO error handling client {}", clientId, e);
} else {
logger.debug("Client {} connection closed by peer", clientId);
}
} catch (Exception e) { } catch (Exception e) {
logger.error("Error handling client {}", clientId, e); logger.error("Unexpected error handling client {}", clientId, e);
} finally { } finally {
try { try {
channel.close(); if (channel.isOpen()) {
channel.close();
}
logger.debug("Client {} channel closed", clientId); logger.debug("Client {} channel closed", clientId);
} catch (IOException e) { } catch (IOException e) {
logger.error("Error closing client {} channel", clientId, e); logger.error("Error closing client {} channel", clientId, e);
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol.messages";
option java_outer_classname = "ArtistMessages";
package mediamanager.messages;
message Artist {
int32 id = 1;
string name = 2;
}
message CreateArtistRequest {
string name = 1;
}
message CreateArtistResponse {
Artist artist = 1;
}
message GetArtistsRequest {
}
message GetArtistsResponse {
repeated Artist artists = 1;
}
message GetArtistByIdRequest {
int32 id = 1;
}
message GetArtistByIdResponse {
Artist artist = 1;
}
message UpdateArtistRequest {
int32 id = 1;
string name = 2; // Novo nome
}
message UpdateArtistResponse {
Artist artist = 1;
}
message DeleteArtistRequest {
int32 id = 1;
}
message DeleteArtistResponse {
bool success = 1;
string message = 2;
}
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol.messages";
option java_outer_classname = "BitDepthMessages";
package mediamanager.messages;
message BitDepth {
int32 id = 1;
string value = 2;
}
message CreateBitDepthRequest {
string value = 1;
}
message CreateBitDepthResponse {
BitDepth bitdepth = 1;
}
message GetBitDepthsRequest {
}
message GetBitDepthsResponse {
repeated BitDepth bitdepths = 1;
}
message GetBitDepthByIdRequest {
int32 id = 1;
}
message GetBitDepthByIdResponse {
BitDepth bitdepth = 1;
}
message UpdateBitDepthRequest {
int32 id = 1;
string value = 2; // Novo nome
}
message UpdateBitDepthResponse {
BitDepth bitdepth = 1;
}
message DeleteBitDepthRequest {
int32 id = 1;
}
message DeleteBitDepthResponse {
bool success = 1;
string message = 2;
}
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol.messages";
option java_outer_classname = "BitRateMessages";
package mediamanager.messages;
message BitRate{
int32 id =1;
string value = 2;
}
message CreateBitRateRequest{
string value = 1;
}
message CreateBitRateResponse{
BitRate bitrate = 1;
}
message GetBitRatesRequest{
}
message GetBitRatesResponse{
repeated BitRate bitrates = 1;
}
message GetBitRateByIdRequest{
int32 id = 1;
}
message GetBitRateByIdResponse{
BitRate bitrate = 1;
}
message UpdateBitRateRequest{
int32 id = 1;
string value = 2;
}
message UpdateBitRateResponse{
BitRate bitrate = 1;
}
message DeleteBitRateRequest{
int32 id =1;
}
message DeleteBitRateResponse{
bool success = 1;
string message = 2;
}
+51
View File
@@ -0,0 +1,51 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol.messages";
option java_outer_classname = "ComposerMessages";
package mediamanager.messages;
message Composer {
int32 id =1;
string name =2;
}
message CreateComposerRequest{
string name =1;
}
message CreateComposerResponse{
Composer composer = 1;
}
message GetComposersRequest{}
message GetComposersResponse{
repeated Composer composers = 1;
}
message GetComposerByIdRequest{
int32 id =1;
}
message GetComposerByIdResponse{
Composer composer =1;
}
message UpdateComposerRequest{
int32 id = 1;
string name=2;
}
message UpdateComposerResponse{
Composer composer = 1;
}
message DeleteComposerRequest{
int32 id = 1;
}
message DeleteComposerResponse{
bool success = 1;
string message = 2;
}
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol.messages";
option java_outer_classname = "GenreMessages";
package mediamanager.messages;
message Genre {
int32 id = 1;
string name = 2;
}
message CreateGenreRequest {
string name = 1;
}
message CreateGenreResponse {
Genre genre = 1;
}
message GetGenresRequest {
}
message GetGenresResponse {
repeated Genre genres = 1;
}
message GetGenreByIdRequest {
int32 id = 1;
}
message GetGenreByIdResponse {
Genre genre = 1;
}
message UpdateGenreRequest {
int32 id = 1;
string name = 2; // Novo nome
}
message UpdateGenreResponse {
Genre genre = 1; // Genre atualizado
}
message DeleteGenreRequest {
int32 id = 1;
}
message DeleteGenreResponse {
bool success = 1;
string message = 2;
}
+30
View File
@@ -0,0 +1,30 @@
syntax = "proto3";
option java_package = "com.mediamanager.protocol";
option java_outer_classname = "TestProtocol";
package mediamanager.test;
message EchoCommand {
string message = 1;
}
message EchoResponse {
string message = 1;
int64 server_timestamp = 2;
}
message HeartbeatCommand {
int64 client_timestamp = 1;
}
message HeartbeatResponse {
int64 client_timestamp = 1;
int64 server_timestamp = 2;
}
message CloseCommand {
// Vazio - apenas sinaliza fechamento
}
message CloseResponse {
string message = 1;
}
+3 -3
View File
@@ -18,17 +18,17 @@
</Appenders> </Appenders>
<Loggers> <Loggers>
<Logger name="com.mediamanager" level="debug" additivity="false"> <Logger name="com.mediamanager" level="INFO" additivity="false">
<AppenderRef ref="Console"/> <AppenderRef ref="Console"/>
<AppenderRef ref="FileAppender"/> <AppenderRef ref="FileAppender"/>
</Logger> </Logger>
<Logger name="org.hibernate" level="info" additivity="false"> <Logger name="org.hibernate" level="INFO" additivity="false">
<AppenderRef ref="Console"/> <AppenderRef ref="Console"/>
<AppenderRef ref="FileAppender"/> <AppenderRef ref="FileAppender"/>
</Logger> </Logger>
<Root level="info"> <Root level="INFO">
<AppenderRef ref="Console"/> <AppenderRef ref="Console"/>
<AppenderRef ref="FileAppender"/> <AppenderRef ref="FileAppender"/>
</Root> </Root>