(Java) Is there a way for me to send data with every change in the database via WebSocket?

64 views Asked by At

I'm a beginner in programming (and Java too) and I need to implement a service that shows changes in real time, I'm trying to use WebSocket for this. I have the following action:

 @Scheduled(fixedRate = 100000)
    public void sendRealTimeUpdates() {
        List<OrdemDeServico> ordemEmProducao = repository.findByStatus("Em Produção");
        List<EmProducaoDTO> dtos = ordemEmProducao.stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
        messagingTemplate.convertAndSend("/topic/ordemDeServico", dtos);
    }

However, instead of performing this action every 1 minute, I'd like it to perform a change in the status field of my OrdemDeServico class each time. Here is the class update function

@Transactional
    public OrdemDeServicoDTO update(Long id, OrdemDeServicoDTO dto){
        try{
            OrdemDeServico entity = repository.getReferenceById(id);
            copyDtoToEntity(dto, entity);
            if(dto.getTechnicianId() != null && dto.getTechnicianId() != 0){
                Tecnico tecnico = tecnicoRepository.findById(dto.getTechnicianId())
                        .orElseThrow(() -> new ResourceNotFoundException("Tecnico não encontrado"));
                entity.setTechnician(tecnico);
            } else {
                entity.setTechnician(null);
            }
            entity = repository.save(entity);
            return new OrdemDeServicoDTO(entity);
        } catch (EntityNotFoundException e){
            throw new ResourceNotFoundException("Nenhuma Ordem de Serviço encontrada com o id: " + id);
        }
       }

I thought about putting an if/else directly inside the update method, but I don't know if that would be good practice:

@Transactional
    public OrdemDeServicoDTO update(Long id, OrdemDeServicoDTO dto){
        try{
            OrdemDeServico entity = repository.getReferenceById(id);
            copyDtoToEntity(dto, entity);
            if(dto.getTechnicianId() != null && dto.getTechnicianId() != 0){
                Tecnico tecnico = tecnicoRepository.findById(dto.getTechnicianId())
                        .orElseThrow(() -> new ResourceNotFoundException("Tecnico não encontrado"));
                entity.setTechnician(tecnico);
            } else {
                entity.setTechnician(null);
            }
            entity = repository.save(entity);


            if(entity.getStatus().equals("Em Produção")){
                EmProducaoDTO emProducaoDto = convertToDto(entity);
                messagingTemplate.convertAndSend("/topic/ordemDeServico", emProducaoDto);
            }

            return new OrdemDeServicoDTO(entity);
        } catch (EntityNotFoundException e){
            throw new ResourceNotFoundException("Nenhuma Ordem de Serviço encontrada com o id: " + id);
        }
    }

It may be obvious to most people, but I'm still learning, thanks guys.

1

There are 1 answers

0
Roma S On

I think you should use something like this:
Dto.java:

@Getter
@Setter
@ToString
public class Dto {
    private String status;
}

MessagingService.java:

public class MessagingService {
    public void sendMessage(Dto dto) {
        System.out.println(
                String.format(
                        "Send message to %s, data=%s",
                        "/topic/your_topic",
                        dto
                )
        );
    }
}

NotifierService.java:

@RequiredArgsConstructor
public class NotifierService {
    private final MessagingService messagingService;

    public void notifyIfNeeded(Dto dto) {
        if (STATUS_FOR_NOTIFY.equals(dto.getStatus())) {
            messagingService.sendMessage(dto);
        }
    }
}

DtoUpdateService.java:

public class DtoUpdateService {
    @Transactional
    public Dto update(Long id, Dto dto) {
        //your logic here
        dto.setStatus(STATUSES[new Random().nextInt(STATUSES.length)]);
        return dto;
    }
}

UpdaterService.java:

@RequiredArgsConstructor
public class UpdaterService {
    private final DtoUpdateService dtoUpdateService;
    private final NotifierService notifierService;

    public Dto update(Long id, Dto dto) {
        Dto updated = dtoUpdateService.update(id, dto);
        notifierService.notifyIfNeeded(updated);
        return updated;
    }
}

Main:

public class Answer77231555 {
    public static final String STATUS_FOR_NOTIFY = "status_for_notify";
    public static final String STATUS_NOT_FOR_NOTIFY = "any_else";
    public static final String[] STATUSES = new String[]{STATUS_FOR_NOTIFY, STATUS_NOT_FOR_NOTIFY};

    public static void main(String[] args) {
        Dto dto = new Dto();
        DtoUpdateService dtoUpdateService = new DtoUpdateService();
        MessagingService messagingService = new MessagingService();
        NotifierService notifierService = new NotifierService(messagingService);
        UpdaterService updaterService = new UpdaterService(dtoUpdateService, notifierService);
        updaterService.update(1L, dto);
        updaterService.update(1L, dto);
        updaterService.update(1L, dto);
        updaterService.update(1L, dto);
    }
}