From 5aeb54516c0df6428c10f1b44357517f842e3b53 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Santos Souza de Miranda Date: Sat, 6 Dec 2025 02:41:48 -0300 Subject: [PATCH 1/5] Implement sampling rate management with full CRUD operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces comprehensive sampling rate management functionality to the MediaManager system, following the established patterns from BitDepth and BitRate implementations. Core Components Added: - SamplingRate entity model with JPA annotations for database persistence - SamplingRateRepository with full CRUD operations (save, findAll, findById, update, deleteById) - SamplingRateService business logic layer with validation and error handling - SamplingRateMapper for bidirectional entity-protobuf conversions Protocol Buffers: - Defined samplingrate.proto with complete message specifications - SamplingRate message structure (id, value) - Request/Response pairs for all CRUD operations (Create, GetAll, GetById, Update, Delete) - Fixed typo in UpdateSamplingRateRequest (valeu -> value) Action Handlers: - CreateSamplingRateHandler: Validates and creates new sampling rate entries - GetSamplingRateHandler: Retrieves all sampling rates from the database - GetSamplingRateByIdHandler: Fetches individual sampling rates with 404 handling - UpdateSamplingRateHandler: Updates existing sampling rates with validation - DeleteSamplingRateHandler: Removes sampling rates with success confirmation Integration: - Registered SamplingRateService in DelegateActionManager - All handlers follow the @Action annotation pattern for automatic discovery - Consistent error handling with appropriate HTTP status codes (400, 404, 500) This implementation provides a complete foundation for managing audio sampling rates within the media management system, enabling clients to perform all standard CRUD operations through the established protocol buffer interface. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../mapper/SamplingRateMapper.java | 35 ++++++ .../com/mediamanager/model/SamplingRate.java | 30 +++++ .../repository/SamplingRateRepository.java | 103 ++++++++++++++++++ .../delegate/DelegateActionManager.java | 5 + .../CreateSamplingRateHandler.java | 50 +++++++++ .../DeleteSamplingRateHandler.java | 62 +++++++++++ .../GetSamplingRateByIdHandler.java | 56 ++++++++++ .../samplingrate/GetSamplingRateHandler.java | 48 ++++++++ .../UpdateSamplingRateHandler.java | 65 +++++++++++ .../samplingrate/SamplingRateService.java | 59 ++++++++++ src/main/proto/samplingrate.proto | 51 +++++++++ 11 files changed, 564 insertions(+) create mode 100644 src/main/java/com/mediamanager/mapper/SamplingRateMapper.java create mode 100644 src/main/java/com/mediamanager/model/SamplingRate.java create mode 100644 src/main/java/com/mediamanager/repository/SamplingRateRepository.java create mode 100644 src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java create mode 100644 src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java create mode 100644 src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java create mode 100644 src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java create mode 100644 src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java create mode 100644 src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java create mode 100644 src/main/proto/samplingrate.proto diff --git a/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java b/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java new file mode 100644 index 0000000..d1701cd --- /dev/null +++ b/src/main/java/com/mediamanager/mapper/SamplingRateMapper.java @@ -0,0 +1,35 @@ +package com.mediamanager.mapper; + +import com.mediamanager.model.SamplingRate; +import com.mediamanager.protocol.messages.SamplingRateMessages; + +public class SamplingRateMapper { + public static SamplingRateMessages.SamplingRate toProtobuf(SamplingRate entity) { + if (entity == null) { + return null; + } + String value = entity.getValue(); + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("Value cannot be null or empty"); + } + SamplingRateMessages.SamplingRate.Builder builder = SamplingRateMessages.SamplingRate.newBuilder() + .setValue(value); + Integer id = entity.getId(); + if (id != null) { + builder.setId(id); + } + return builder.build(); + } + + public static SamplingRate toEntity(SamplingRateMessages.SamplingRate protobuf) { + if (protobuf == null) { + return null; + } + SamplingRate entity = new SamplingRate(); + if (protobuf.getId() >0) { + entity.setId(protobuf.getId()); + } + entity.setValue(protobuf.getValue()); + return entity; + } +} diff --git a/src/main/java/com/mediamanager/model/SamplingRate.java b/src/main/java/com/mediamanager/model/SamplingRate.java new file mode 100644 index 0000000..e090226 --- /dev/null +++ b/src/main/java/com/mediamanager/model/SamplingRate.java @@ -0,0 +1,30 @@ +package com.mediamanager.model; + +import jakarta.persistence.*; + +@Entity +@Table(name = "sampling_rate") +public class SamplingRate { + @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; + } +} diff --git a/src/main/java/com/mediamanager/repository/SamplingRateRepository.java b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java new file mode 100644 index 0000000..e434b9b --- /dev/null +++ b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java @@ -0,0 +1,103 @@ +package com.mediamanager.repository; + + +import com.mediamanager.model.SamplingRate; +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 SamplingRateRepository { + private static final Logger logger = LogManager.getLogger(SamplingRateRepository.class); + + private final EntityManagerFactory entityManagerFactory; + + public SamplingRateRepository(EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + public SamplingRate save(SamplingRate samplingRate) { + logger.debug("Saving SamplingRate: {}", samplingRate.getValue()); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + em.persist(samplingRate); + em.getTransaction().commit(); + logger.debug("SamplingRate has been saved successfully"); + return samplingRate; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while saving SamplingRate: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public List findAll() { + logger.debug("Finding All SamplingRate"); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + return em.createQuery("select s from SamplingRate s", SamplingRate.class).getResultList(); + }finally { + if (em.isOpen()) em.close(); + } + } + + public Optional findById(Integer id) { + logger.debug("Finding SamplingRate with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + try{ + SamplingRate samplingRate = em.find(SamplingRate.class, id); + return Optional.of(samplingRate); + }finally { + if (em.isOpen()) em.close(); + } + } + + public SamplingRate update(SamplingRate samplingRate) { + logger.debug("Updating SamplingRate: {}", samplingRate.getValue()); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try { + SamplingRate updated = em.merge(samplingRate); + em.getTransaction().commit(); + logger.debug("SamplingRate has been updated successfully"); + return updated; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while updating SamplingRate: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + + public boolean deleteById(Integer id){ + logger.debug("Deleting SamplingRate with id: {}", id); + EntityManager em = entityManagerFactory.createEntityManager(); + em.getTransaction().begin(); + try{ + SamplingRate samplingRate = em.find(SamplingRate.class, id); + if (samplingRate == null) { + em.getTransaction().rollback(); + return false; + } + em.remove(samplingRate); + em.getTransaction().commit(); + logger.debug("SamplingRate has been deleted successfully"); + return true; + } catch (Exception e) { + em.getTransaction().rollback(); + logger.error("Error while deleting SamplingRate: {}", e.getMessage()); + throw e; + } finally { + if (em.isOpen()) em.close(); + } + } + +} diff --git a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java index 67daf24..e4715ba 100644 --- a/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java +++ b/src/main/java/com/mediamanager/service/delegate/DelegateActionManager.java @@ -11,6 +11,7 @@ import com.mediamanager.service.artist.ArtistService; import com.mediamanager.service.delegate.annotation.Action; import com.mediamanager.service.genre.GenreService; +import com.mediamanager.service.samplingrate.SamplingRateService; import jakarta.persistence.EntityManagerFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -70,6 +71,10 @@ public class DelegateActionManager { BitRateService bitRateService = new BitRateService(bitRateRepository); serviceLocator.register(BitRateService.class, bitRateService); + SamplingRateRepository samplingRateRepository = new SamplingRateRepository(entityManagerFactory); + SamplingRateService samplingRateService = new SamplingRateService(samplingRateRepository); + serviceLocator.register(SamplingRateService.class, samplingRateService); + serviceLocator.logRegisteredServices(); logger.info("Services initialized successfully"); diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java new file mode 100644 index 0000000..a3e0715 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/CreateSamplingRateHandler.java @@ -0,0 +1,50 @@ +package com.mediamanager.service.delegate.handler.samplingrate; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.SamplingRateMapper; +import com.mediamanager.model.SamplingRate; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.SamplingRateMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.samplingrate.SamplingRateService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("samplingrate.create") +public class CreateSamplingRateHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(CreateSamplingRateHandler.class); + private final SamplingRateService samplingRateService; + + public CreateSamplingRateHandler(SamplingRateService samplingRateService) { + this.samplingRateService = samplingRateService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + SamplingRateMessages.CreateSamplingRateRequest createRequest = + SamplingRateMessages.CreateSamplingRateRequest.parseFrom(requestPayload); + SamplingRate samplingRate = samplingRateService.createSamplingRate(createRequest.getValue()); + SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRate); + SamplingRateMessages.CreateSamplingRateResponse createSamplingRateResponse = SamplingRateMessages.CreateSamplingRateResponse.newBuilder() + .setSamplingrate(samplingRateProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(createSamplingRateResponse.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 sampling rate", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} + diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java new file mode 100644 index 0000000..1881045 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/DeleteSamplingRateHandler.java @@ -0,0 +1,62 @@ +package com.mediamanager.service.delegate.handler.samplingrate; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.SamplingRateMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.samplingrate.SamplingRateService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Action("samplingrate.delete") +public class DeleteSamplingRateHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(DeleteSamplingRateHandler.class); + + private final SamplingRateService samplingRateService; + + public DeleteSamplingRateHandler(SamplingRateService samplingRateService) { + this.samplingRateService = samplingRateService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException { + + try { + SamplingRateMessages.DeleteSamplingRateRequest deleteRequest = + SamplingRateMessages.DeleteSamplingRateRequest.parseFrom(requestPayload); + int id = deleteRequest.getId(); + boolean success = samplingRateService.deleteSamplingRate(id); + SamplingRateMessages.DeleteSamplingRateResponse deleteResponse; + if (success) { + deleteResponse = SamplingRateMessages.DeleteSamplingRateResponse.newBuilder() + .setSuccess(true) + .setMessage("Sampling rate deleted successfully") + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(deleteResponse.toByteString()); + } else { + deleteResponse = SamplingRateMessages.DeleteSamplingRateResponse.newBuilder() + .setSuccess(false) + .setMessage("Sampling rate not found") + .build(); + + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(deleteResponse.toByteString()); + } + } catch (Exception e) { + logger.error("Error deleting sampling rate", e); + SamplingRateMessages.DeleteSamplingRateResponse deleteResponse = + SamplingRateMessages.DeleteSamplingRateResponse.newBuilder() + .setSuccess(false) + .setMessage("Error: " + e.getMessage()) + .build(); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(deleteResponse.toByteString()); + } + } + } diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java new file mode 100644 index 0000000..f17ddd6 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java @@ -0,0 +1,56 @@ +package com.mediamanager.service.delegate.handler.samplingrate; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.SamplingRateMapper; +import com.mediamanager.model.SamplingRate; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.SamplingRateMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.samplingrate.SamplingRateService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action(value = "samplingrate.getById") +public class GetSamplingRateByIdHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetSamplingRateByIdHandler.class); + private final SamplingRateService samplingRateService; + + public GetSamplingRateByIdHandler(SamplingRateService samplingRateService) { + this.samplingRateService = samplingRateService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) + throws InvalidProtocolBufferException{ + + try{ + SamplingRateMessages.GetSamplingRateByIDRequest getByIdRequest = + SamplingRateMessages.GetSamplingRateByIDRequest.parseFrom(requestPayload); + int id = getByIdRequest.getId(); + + Optional samplingRateOpt = samplingRateService.getSamplingRateById(id); + + if (samplingRateOpt.isEmpty()){ + logger.warn("SamplingRate not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("SamplingRate not found")); + } + SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRateOpt.get()); + SamplingRateMessages.GetSamplingRateByIdResponse getByIdResponse = SamplingRateMessages.GetSamplingRateByIdResponse.newBuilder() + .setSamplingrate(samplingRateProto) + .build(); + return TransportProtocol.Response.newBuilder() + .setPayload(getByIdResponse.toByteString()); + } catch (Exception e) { + logger.error("Error getting sampling rate by ID", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: "+ e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java new file mode 100644 index 0000000..5e51e46 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateHandler.java @@ -0,0 +1,48 @@ +package com.mediamanager.service.delegate.handler.samplingrate; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.SamplingRateMapper; +import com.mediamanager.model.SamplingRate; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.SamplingRateMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.samplingrate.SamplingRateService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; + + +@Action("samplingrate.getAll") +public class GetSamplingRateHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(GetSamplingRateHandler.class); + + private final SamplingRateService samplingRateService; + + public GetSamplingRateHandler(SamplingRateService samplingRateService){this.samplingRateService = samplingRateService;} + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + List samplingRates = samplingRateService.getAllSamplingRates(); + SamplingRateMessages.GetSamplingRatesResponse.Builder responseBuilder = SamplingRateMessages.GetSamplingRatesResponse.newBuilder(); + + for (SamplingRate samplingRate : samplingRates) { + SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRate); + responseBuilder.addSamplingrates(samplingRateProto); + } + SamplingRateMessages.GetSamplingRatesResponse getSamplingRatesResponse = responseBuilder.build(); + + return TransportProtocol.Response.newBuilder() + .setPayload(getSamplingRatesResponse.toByteString()); + + }catch (Exception e){ + logger.error("Error getting sampling rates", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java new file mode 100644 index 0000000..770ea82 --- /dev/null +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/UpdateSamplingRateHandler.java @@ -0,0 +1,65 @@ +package com.mediamanager.service.delegate.handler.samplingrate; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mediamanager.mapper.SamplingRateMapper; +import com.mediamanager.model.SamplingRate; +import com.mediamanager.protocol.TransportProtocol; +import com.mediamanager.protocol.messages.SamplingRateMessages; +import com.mediamanager.service.delegate.ActionHandler; +import com.mediamanager.service.delegate.annotation.Action; +import com.mediamanager.service.samplingrate.SamplingRateService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Optional; + +@Action("samplingrate.update") +public class UpdateSamplingRateHandler implements ActionHandler { + private static final Logger logger = LogManager.getLogger(UpdateSamplingRateHandler.class); + private final SamplingRateService samplingRateService; + + public UpdateSamplingRateHandler(SamplingRateService samplingRateService) { + this.samplingRateService = samplingRateService; + } + + @Override + public TransportProtocol.Response.Builder handle(ByteString requestPayload) throws InvalidProtocolBufferException { + try{ + SamplingRateMessages.UpdateSamplingRateRequest updateRequest = + SamplingRateMessages.UpdateSamplingRateRequest.parseFrom(requestPayload); + + int id = updateRequest.getId(); + String newValue = updateRequest.getValue(); + + Optional samplingRateOpt = samplingRateService.updateSamplingRate(id, newValue); + + if(samplingRateOpt.isEmpty()){ + logger.warn("SamplingRate not found with ID: {}", id); + return TransportProtocol.Response.newBuilder() + .setStatusCode(404) + .setPayload(ByteString.copyFromUtf8("SamplingRate not found")); + } + + SamplingRateMessages.SamplingRate samplingRateProto = SamplingRateMapper.toProtobuf(samplingRateOpt.get()); + + SamplingRateMessages.UpdateSamplingRateResponse updateResponse = SamplingRateMessages.UpdateSamplingRateResponse.newBuilder() + .setSamplingrate(samplingRateProto) + .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 sampling rate", e); + return TransportProtocol.Response.newBuilder() + .setStatusCode(500) + .setPayload(ByteString.copyFromUtf8("Error: " + e.getMessage())); + } + } +} diff --git a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java new file mode 100644 index 0000000..cb304e9 --- /dev/null +++ b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java @@ -0,0 +1,59 @@ +package com.mediamanager.service.samplingrate; + +import com.mediamanager.model.SamplingRate; +import com.mediamanager.repository.SamplingRateRepository; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; +import java.util.Optional; + +public class SamplingRateService { + private static final Logger logger = LogManager.getLogger(SamplingRateService.class); + private final SamplingRateRepository repository; + + public SamplingRateService(SamplingRateRepository repository) { + this.repository = repository; + } + + public SamplingRate createSamplingRate(String value) { + logger.debug("Creating sampling rate:{}", value); + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty"); + } + SamplingRate samplingRate = new SamplingRate(); + samplingRate.setValue(value); + return repository.save(samplingRate); + } + + public List getAllSamplingRates() { + logger.info("Getting all sampling rates"); + return repository.findAll(); + } + + public Optional getSamplingRateById(Integer id) { + logger.info("Getting sampling rate by id:{}", id); + return repository.findById(id); + } + + public Optional updateSamplingRate(Integer id, String value) { + logger.info("Updating sampling rate:{}", value); + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty");} + Optional existingSamplingRate = repository.findById(id); + if(existingSamplingRate.isEmpty()) { + logger.warn("Sampling rate not found with id:{}", id); + return Optional.empty(); + } + SamplingRate samplingRate = existingSamplingRate.get(); + samplingRate.setValue(value); + SamplingRate updatedSamplingRate = repository.update(samplingRate); + return Optional.of(updatedSamplingRate); + } + + public boolean deleteSamplingRate(Integer id) { + logger.info("Deleting sampling rate:{}", id); + return repository.deleteById(id); + } + +} diff --git a/src/main/proto/samplingrate.proto b/src/main/proto/samplingrate.proto new file mode 100644 index 0000000..595278f --- /dev/null +++ b/src/main/proto/samplingrate.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +option java_package = "com.mediamanager.protocol.messages"; +option java_outer_classname = "SamplingRateMessages"; + +package mediamanager.messages; + +message SamplingRate{ + int32 id=1; + string value=2; +} + +message CreateSamplingRateRequest{ + string value= 1; +} + +message CreateSamplingRateResponse{ + SamplingRate samplingrate =1; +} + +message GetSamplingRatesRequest{} + +message GetSamplingRatesResponse{ + repeated SamplingRate samplingrates = 1; +} + +message GetSamplingRateByIDRequest{ + int32 id =1; +} + +message GetSamplingRateByIdResponse{ + SamplingRate samplingrate = 1; +} + +message UpdateSamplingRateRequest{ + int32 id = 1; + string value = 2; +} + +message UpdateSamplingRateResponse{ + SamplingRate samplingrate = 1; +} + +message DeleteSamplingRateRequest{ + int32 id =1; +} + +message DeleteSamplingRateResponse{ + bool success = 1; + string message =2; +} \ No newline at end of file From 5ff972ebcb2175c1ee6f8aa6b8358b3b0b78d81d Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Santos Souza de Miranda Date: Sat, 6 Dec 2025 02:55:36 -0300 Subject: [PATCH 2/5] Fix message name casing in SamplingRate proto definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standardize the naming convention by changing `GetSamplingRateByIDRequest` to `GetSamplingRateByIdRequest`, using "Id" instead of "ID" for consistency with other proto message names across the codebase. Updated the corresponding handler to reference the corrected message name. This aligns with the established naming pattern and improves code consistency following the same convention applied in other proto definitions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../handler/samplingrate/GetSamplingRateByIdHandler.java | 4 ++-- src/main/proto/samplingrate.proto | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java index f17ddd6..c791798 100644 --- a/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java +++ b/src/main/java/com/mediamanager/service/delegate/handler/samplingrate/GetSamplingRateByIdHandler.java @@ -28,8 +28,8 @@ public class GetSamplingRateByIdHandler implements ActionHandler { throws InvalidProtocolBufferException{ try{ - SamplingRateMessages.GetSamplingRateByIDRequest getByIdRequest = - SamplingRateMessages.GetSamplingRateByIDRequest.parseFrom(requestPayload); + SamplingRateMessages.GetSamplingRateByIdRequest getByIdRequest = + SamplingRateMessages.GetSamplingRateByIdRequest.parseFrom(requestPayload); int id = getByIdRequest.getId(); Optional samplingRateOpt = samplingRateService.getSamplingRateById(id); diff --git a/src/main/proto/samplingrate.proto b/src/main/proto/samplingrate.proto index 595278f..7a5f316 100644 --- a/src/main/proto/samplingrate.proto +++ b/src/main/proto/samplingrate.proto @@ -24,7 +24,7 @@ message GetSamplingRatesResponse{ repeated SamplingRate samplingrates = 1; } -message GetSamplingRateByIDRequest{ +message GetSamplingRateByIdRequest{ int32 id =1; } From 4fa147282fdc3d4ce7f5a4812ed014747edb0822 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Miranda Date: Sat, 6 Dec 2025 22:07:39 -0300 Subject: [PATCH 3/5] Update src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../mediamanager/service/samplingrate/SamplingRateService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java index cb304e9..1b9144e 100644 --- a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java +++ b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java @@ -32,6 +32,9 @@ public class SamplingRateService { } public Optional getSamplingRateById(Integer id) { + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } logger.info("Getting sampling rate by id:{}", id); return repository.findById(id); } From ff09d1b89a85d10af1f0c2c3b89054ba3c44e1ef Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Santos Souza de Miranda Date: Sat, 6 Dec 2025 22:18:40 -0300 Subject: [PATCH 4/5] Fix null handling and validation in SamplingRate management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses potential runtime exceptions and improves input validation: - Replace Optional.of() with Optional.ofNullable() in SamplingRateRepository.findById() to properly handle cases where no sampling rate is found, preventing NullPointerException - Add null validation for id parameter in SamplingRateService.deleteSamplingRate() to ensure proper error handling before repository operations - Clean up code formatting in updateSamplingRate() validation block These changes enhance the robustness of the sampling rate management feature by preventing NPEs and providing clearer error messages for invalid inputs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../com/mediamanager/repository/SamplingRateRepository.java | 2 +- .../service/samplingrate/SamplingRateService.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mediamanager/repository/SamplingRateRepository.java b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java index e434b9b..4d2fd82 100644 --- a/src/main/java/com/mediamanager/repository/SamplingRateRepository.java +++ b/src/main/java/com/mediamanager/repository/SamplingRateRepository.java @@ -53,7 +53,7 @@ public class SamplingRateRepository { EntityManager em = entityManagerFactory.createEntityManager(); try{ SamplingRate samplingRate = em.find(SamplingRate.class, id); - return Optional.of(samplingRate); + return Optional.ofNullable(samplingRate); }finally { if (em.isOpen()) em.close(); } diff --git a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java index 1b9144e..b347815 100644 --- a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java +++ b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java @@ -42,7 +42,8 @@ public class SamplingRateService { public Optional updateSamplingRate(Integer id, String value) { logger.info("Updating sampling rate:{}", value); if (value == null || value.trim().isEmpty()) { - throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty");} + throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty"); + } Optional existingSamplingRate = repository.findById(id); if(existingSamplingRate.isEmpty()) { logger.warn("Sampling rate not found with id:{}", id); @@ -55,6 +56,9 @@ public class SamplingRateService { } public boolean deleteSamplingRate(Integer id) { + if (id == null) { + throw new IllegalArgumentException("Sampling rate id cannot be null"); + } logger.info("Deleting sampling rate:{}", id); return repository.deleteById(id); } From 94297e75b9b87eb18d7f13c3f291ebe48d1d5f8b Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Santos Souza de Miranda Date: Sat, 6 Dec 2025 22:30:51 -0300 Subject: [PATCH 5/5] Add id validation and improve code formatting in updateSamplingRate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhance input validation and code quality in the SamplingRate service: - Add null check for id parameter in updateSamplingRate() method to prevent potential NullPointerException when calling repository.findById() - Standardize indentation throughout the updateSamplingRate() method body, improving code readability and consistency with project style guidelines This complements the previous validation improvements by ensuring all method parameters are properly validated before use, creating a more defensive and robust API surface. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../samplingrate/SamplingRateService.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java index b347815..005e8e5 100644 --- a/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java +++ b/src/main/java/com/mediamanager/service/samplingrate/SamplingRateService.java @@ -40,19 +40,22 @@ public class SamplingRateService { } public Optional updateSamplingRate(Integer id, String value) { - logger.info("Updating sampling rate:{}", value); - if (value == null || value.trim().isEmpty()) { - throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty"); - } - Optional existingSamplingRate = repository.findById(id); - if(existingSamplingRate.isEmpty()) { - logger.warn("Sampling rate not found with id:{}", id); - return Optional.empty(); - } - SamplingRate samplingRate = existingSamplingRate.get(); - samplingRate.setValue(value); - SamplingRate updatedSamplingRate = repository.update(samplingRate); - return Optional.of(updatedSamplingRate); + if (id == null) { + throw new IllegalArgumentException("ID cannot be null"); + } + logger.info("Updating sampling rate:{}", value); + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException("Sampling-Rate value cannot be null or empty"); + } + Optional existingSamplingRate = repository.findById(id); + if(existingSamplingRate.isEmpty()) { + logger.warn("Sampling rate not found with id:{}", id); + return Optional.empty(); + } + SamplingRate samplingRate = existingSamplingRate.get(); + samplingRate.setValue(value); + SamplingRate updatedSamplingRate = repository.update(samplingRate); + return Optional.of(updatedSamplingRate); } public boolean deleteSamplingRate(Integer id) {