feat(servers): permitir tipos vindos do banco
- remove enums fixos de tipo, aplicação e dbType - atualiza DTOs, controller e repositório para lidar com strings normalizadas - normaliza e registra tipos durante criação e importação em massamaster
parent
bba78772db
commit
a43fc58ff7
|
|
@ -3,9 +3,6 @@ package com.hitcommunications.servermanager.controllers;
|
||||||
import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse;
|
import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse;
|
||||||
import com.hitcommunications.servermanager.model.dtos.NewServerDTO;
|
import com.hitcommunications.servermanager.model.dtos.NewServerDTO;
|
||||||
import com.hitcommunications.servermanager.model.dtos.ServerDTO;
|
import com.hitcommunications.servermanager.model.dtos.ServerDTO;
|
||||||
import com.hitcommunications.servermanager.model.enums.Applications;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.DatabaseType;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.ServersType;
|
|
||||||
import com.hitcommunications.servermanager.services.ServersService;
|
import com.hitcommunications.servermanager.services.ServersService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
|
@ -72,14 +69,14 @@ public class ServersController {
|
||||||
@GetMapping("/type/{type}")
|
@GetMapping("/type/{type}")
|
||||||
@Operation(summary = "Lista servidores por tipo.")
|
@Operation(summary = "Lista servidores por tipo.")
|
||||||
@ApiResponse(responseCode = "200", description = "Lista retornada.")
|
@ApiResponse(responseCode = "200", description = "Lista retornada.")
|
||||||
public ResponseEntity<List<ServerDTO>> getByType(@PathVariable ServersType type) {
|
public ResponseEntity<List<ServerDTO>> getByType(@PathVariable String type) {
|
||||||
return ResponseEntity.ok().body(serversService.getByType(type));
|
return ResponseEntity.ok().body(serversService.getByType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/type")
|
@GetMapping("/type")
|
||||||
@Operation(summary = "Conta servidores agrupando por tipo.")
|
@Operation(summary = "Conta servidores agrupando por tipo.")
|
||||||
@ApiResponse(responseCode = "200", description = "Mapa retornado.")
|
@ApiResponse(responseCode = "200", description = "Mapa retornado.")
|
||||||
public ResponseEntity<Map<ServersType, Integer>> countAllByType() {
|
public ResponseEntity<Map<String, Integer>> countAllByType() {
|
||||||
return ResponseEntity.ok().body(serversService.countAllByType());
|
return ResponseEntity.ok().body(serversService.countAllByType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +93,7 @@ public class ServersController {
|
||||||
@GetMapping("/application/{application}")
|
@GetMapping("/application/{application}")
|
||||||
@Operation(summary = "Lista servidores por aplicação.")
|
@Operation(summary = "Lista servidores por aplicação.")
|
||||||
@ApiResponse(responseCode = "200", description = "Lista retornada.")
|
@ApiResponse(responseCode = "200", description = "Lista retornada.")
|
||||||
public ResponseEntity<List<ServerDTO>> getByApplication(@PathVariable Applications application) {
|
public ResponseEntity<List<ServerDTO>> getByApplication(@PathVariable String application) {
|
||||||
return ResponseEntity.ok().body(serversService.getByApplication(application));
|
return ResponseEntity.ok().body(serversService.getByApplication(application));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,9 +102,9 @@ public class ServersController {
|
||||||
@ApiResponse(responseCode = "200", description = "Resultados retornados.")
|
@ApiResponse(responseCode = "200", description = "Resultados retornados.")
|
||||||
public ResponseEntity<List<ServerDTO>> getAll(
|
public ResponseEntity<List<ServerDTO>> getAll(
|
||||||
@RequestParam(value = "query", required = false) String query,
|
@RequestParam(value = "query", required = false) String query,
|
||||||
@RequestParam(value = "type", required = false) ServersType type,
|
@RequestParam(value = "type", required = false) String type,
|
||||||
@RequestParam(value = "application", required = false) Applications application,
|
@RequestParam(value = "application", required = false) String application,
|
||||||
@RequestParam(value = "dbType", required = false) DatabaseType dbType
|
@RequestParam(value = "dbType", required = false) String dbType
|
||||||
) {
|
) {
|
||||||
return ResponseEntity.ok().body(serversService.search(query, type, application, dbType));
|
return ResponseEntity.ok().body(serversService.search(query, type, application, dbType));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
package com.hitcommunications.servermanager.model.dtos;
|
package com.hitcommunications.servermanager.model.dtos;
|
||||||
|
|
||||||
import com.hitcommunications.servermanager.model.enums.Applications;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.DatabaseType;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.ServersType;
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
|
@ -12,9 +9,8 @@ public record NewServerDTO(
|
||||||
@NotNull Integer port,
|
@NotNull Integer port,
|
||||||
@NotBlank String user,
|
@NotBlank String user,
|
||||||
@NotBlank String password,
|
@NotBlank String password,
|
||||||
@NotNull ServersType type,
|
@NotBlank String type,
|
||||||
@NotNull Applications application,
|
@NotBlank String application,
|
||||||
@NotNull DatabaseType dbType
|
@NotBlank String dbType
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
package com.hitcommunications.servermanager.model.dtos;
|
package com.hitcommunications.servermanager.model.dtos;
|
||||||
|
|
||||||
import com.hitcommunications.servermanager.model.enums.Applications;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.DatabaseType;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.ServersType;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
public record ServerDTO(
|
public record ServerDTO(
|
||||||
|
|
@ -13,9 +9,9 @@ public record ServerDTO(
|
||||||
Integer port,
|
Integer port,
|
||||||
String user,
|
String user,
|
||||||
String password,
|
String password,
|
||||||
ServersType type,
|
String type,
|
||||||
Applications application,
|
String application,
|
||||||
DatabaseType dbType,
|
String dbType,
|
||||||
Timestamp createdAt,
|
Timestamp createdAt,
|
||||||
Timestamp updatedAt
|
Timestamp updatedAt
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.hitcommunications.servermanager.model.enums;
|
|
||||||
|
|
||||||
public enum Applications {
|
|
||||||
ASTERISK,
|
|
||||||
HITMANAGER,
|
|
||||||
HITMANAGER_V2,
|
|
||||||
OMNIHIT,
|
|
||||||
HITPHONE,
|
|
||||||
CDR,
|
|
||||||
FUNCIONALIDADE,
|
|
||||||
VOICEMAIL
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.hitcommunications.servermanager.model.enums;
|
|
||||||
|
|
||||||
public enum DatabaseType {
|
|
||||||
MYSQL,
|
|
||||||
POSTGRESQL,
|
|
||||||
SQLSERVER,
|
|
||||||
ORACLE,
|
|
||||||
REDIS,
|
|
||||||
MONGODB,
|
|
||||||
MARIADB,
|
|
||||||
NONE
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package com.hitcommunications.servermanager.model.enums;
|
|
||||||
|
|
||||||
public enum ServersType {
|
|
||||||
PRODUCTION,
|
|
||||||
HOMOLOGATION,
|
|
||||||
DATABASE
|
|
||||||
}
|
|
||||||
|
|
@ -8,16 +8,12 @@ import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
import com.hitcommunications.servermanager.model.Servers;
|
import com.hitcommunications.servermanager.model.Servers;
|
||||||
import com.hitcommunications.servermanager.model.enums.Applications;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.DatabaseType;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.ServersType;
|
|
||||||
|
|
||||||
public interface ServersRepository extends JpaRepository<Servers, String> {
|
public interface ServersRepository extends JpaRepository<Servers, String> {
|
||||||
Optional<Servers> findByName(String name);
|
Optional<Servers> findByName(String name);
|
||||||
List<Servers> findByType(ServersType type);
|
List<Servers> findByType(String type);
|
||||||
List<Servers> findByApplication(Applications application);
|
List<Servers> findByApplication(String application);
|
||||||
Optional<Servers> findByIpAndPort(String ip, Integer port);
|
Optional<Servers> findByIpAndPort(String ip, Integer port);
|
||||||
Integer countAllByType(ServersType type);
|
Integer countAllByType(String type);
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
select s.* from "server-manager".tab_servers s
|
select s.* from "server-manager".tab_servers s
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse;
|
||||||
import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse.FailedRow;
|
import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse.FailedRow;
|
||||||
import com.hitcommunications.servermanager.model.dtos.NewServerDTO;
|
import com.hitcommunications.servermanager.model.dtos.NewServerDTO;
|
||||||
import com.hitcommunications.servermanager.model.dtos.ServerDTO;
|
import com.hitcommunications.servermanager.model.dtos.ServerDTO;
|
||||||
import com.hitcommunications.servermanager.model.enums.Applications;
|
import com.hitcommunications.servermanager.model.enums.TypeCategory;
|
||||||
import com.hitcommunications.servermanager.model.enums.DatabaseType;
|
|
||||||
import com.hitcommunications.servermanager.model.enums.ServersType;
|
|
||||||
import com.hitcommunications.servermanager.repositories.ServersRepository;
|
import com.hitcommunications.servermanager.repositories.ServersRepository;
|
||||||
|
import com.hitcommunications.servermanager.services.TypeOptionService;
|
||||||
|
import com.hitcommunications.servermanager.utils.TypeNormalizer;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
@ -18,18 +18,20 @@ import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ServersService {
|
public class ServersService {
|
||||||
private final ServersMapper mapper;
|
private final ServersMapper mapper;
|
||||||
private final ServersRepository repo;
|
private final ServersRepository repo;
|
||||||
|
private final TypeOptionService typeOptionService;
|
||||||
|
|
||||||
public ServerDTO create(NewServerDTO createDTO) {
|
public ServerDTO create(NewServerDTO createDTO) {
|
||||||
Servers entity = mapper.toEntity(createDTO);
|
Servers entity = mapper.toEntity(createDTO);
|
||||||
|
applyNormalizedTypeData(entity, createDTO);
|
||||||
entity = repo.save(entity);
|
entity = repo.save(entity);
|
||||||
return mapper.toDTO(entity);
|
return mapper.toDTO(entity);
|
||||||
}
|
}
|
||||||
|
|
@ -46,25 +48,34 @@ public class ServersService {
|
||||||
.orElseThrow(() -> new RuntimeException("Server not found with name: " + name));
|
.orElseThrow(() -> new RuntimeException("Server not found with name: " + name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServerDTO> getByType(ServersType type) {
|
public List<ServerDTO> getByType(String type) {
|
||||||
return repo.findByType(type)
|
String normalized = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
||||||
|
return repo.findByType(normalized)
|
||||||
.stream()
|
.stream()
|
||||||
.map(mapper::toDTO)
|
.map(mapper::toDTO)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<ServersType, Integer> countAllByType() {
|
public Map<String, Integer> countAllByType() {
|
||||||
Map<ServersType, Integer> response = new HashMap<>();
|
Map<String, Integer> response = new LinkedHashMap<>();
|
||||||
|
|
||||||
for(ServersType type : ServersType.values()) {
|
typeOptionService.list(TypeCategory.SERVER_TYPE).forEach(type -> {
|
||||||
response.put(type, repo.countAllByType(type));
|
response.put(type, repo.countAllByType(type));
|
||||||
}
|
});
|
||||||
|
|
||||||
|
// Garantir que valores existentes, mas não registrados, também apareçam
|
||||||
|
repo.findAll().stream()
|
||||||
|
.map(Servers::getType)
|
||||||
|
.filter(type -> type != null && !response.containsKey(type))
|
||||||
|
.distinct()
|
||||||
|
.forEach(type -> response.put(type, repo.countAllByType(type)));
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServerDTO> getByApplication(Applications application) {
|
public List<ServerDTO> getByApplication(String application) {
|
||||||
return repo.findByApplication(application)
|
String normalized = normalizeFilter(application, TypeCategory.APPLICATION);
|
||||||
|
return repo.findByApplication(normalized)
|
||||||
.stream()
|
.stream()
|
||||||
.map(mapper::toDTO)
|
.map(mapper::toDTO)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
@ -91,6 +102,7 @@ public class ServersService {
|
||||||
|
|
||||||
processed++;
|
processed++;
|
||||||
try {
|
try {
|
||||||
|
registerTypeOptionsFromRow(columns);
|
||||||
NewServerDTO dto = toNewServerDTO(columns);
|
NewServerDTO dto = toNewServerDTO(columns);
|
||||||
create(dto);
|
create(dto);
|
||||||
succeeded++;
|
succeeded++;
|
||||||
|
|
@ -125,13 +137,29 @@ public class ServersService {
|
||||||
Integer port = Integer.parseInt(columns[2]);
|
Integer port = Integer.parseInt(columns[2]);
|
||||||
String user = columns[3];
|
String user = columns[3];
|
||||||
String password = columns[4];
|
String password = columns[4];
|
||||||
ServersType type = ServersType.valueOf(columns[5].toUpperCase());
|
String type = columns[5];
|
||||||
Applications application = Applications.valueOf(columns[6].toUpperCase());
|
String application = columns[6];
|
||||||
DatabaseType dbType = DatabaseType.valueOf(columns[7].toUpperCase());
|
String dbType = columns[7];
|
||||||
|
|
||||||
return new NewServerDTO(name, ip, port, user, password, type, application, dbType);
|
return new NewServerDTO(name, ip, port, user, password, type, application, dbType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerTypeOptionsFromRow(String[] columns) {
|
||||||
|
if (columns.length < 8) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
registerTypeOption(TypeCategory.SERVER_TYPE, columns[5]);
|
||||||
|
registerTypeOption(TypeCategory.APPLICATION, columns[6]);
|
||||||
|
registerTypeOption(TypeCategory.DATABASE, columns[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerTypeOption(TypeCategory category, String value) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
typeOptionService.register(category, value);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isHeaderRow(String[] columns) {
|
private boolean isHeaderRow(String[] columns) {
|
||||||
if (columns.length < 8) {
|
if (columns.length < 8) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -148,11 +176,11 @@ public class ServersService {
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServerDTO> search(String query, ServersType type, Applications application, DatabaseType dbType) {
|
public List<ServerDTO> search(String query, String type, String application, String dbType) {
|
||||||
String normalizedQuery = (query == null || query.isBlank()) ? null : query.trim();
|
String normalizedQuery = (query == null || query.isBlank()) ? null : query.trim();
|
||||||
String typeFilter = type != null ? type.name() : null;
|
String typeFilter = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
||||||
String applicationFilter = application != null ? application.name() : null;
|
String applicationFilter = normalizeFilter(application, TypeCategory.APPLICATION);
|
||||||
String dbTypeFilter = dbType != null ? dbType.name() : null;
|
String dbTypeFilter = normalizeFilter(dbType, TypeCategory.DATABASE);
|
||||||
|
|
||||||
return repo.search(normalizedQuery, typeFilter, applicationFilter, dbTypeFilter)
|
return repo.search(normalizedQuery, typeFilter, applicationFilter, dbTypeFilter)
|
||||||
.stream()
|
.stream()
|
||||||
|
|
@ -165,6 +193,7 @@ public class ServersService {
|
||||||
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
||||||
|
|
||||||
mapper.partialUpdate(updateDTO, entity);
|
mapper.partialUpdate(updateDTO, entity);
|
||||||
|
applyNormalizedTypeData(entity, updateDTO);
|
||||||
entity = repo.save(entity);
|
entity = repo.save(entity);
|
||||||
return mapper.toDTO(entity);
|
return mapper.toDTO(entity);
|
||||||
}
|
}
|
||||||
|
|
@ -176,4 +205,30 @@ public class ServersService {
|
||||||
repo.deleteById(id);
|
repo.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyNormalizedTypeData(Servers entity, NewServerDTO dto) {
|
||||||
|
entity.setType(normalizeAndRegister(TypeCategory.SERVER_TYPE, dto.type()));
|
||||||
|
entity.setApplication(normalizeAndRegister(TypeCategory.APPLICATION, dto.application()));
|
||||||
|
entity.setDbType(normalizeAndRegister(TypeCategory.DATABASE, dto.dbType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String normalizeFilter(String value, TypeCategory category) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String normalized = TypeNormalizer.normalize(value);
|
||||||
|
if (normalized == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
typeOptionService.register(category, normalized);
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String normalizeAndRegister(TypeCategory category, String value) {
|
||||||
|
String normalized = TypeNormalizer.normalize(value);
|
||||||
|
if (normalized == null) {
|
||||||
|
throw new IllegalArgumentException("Valor inválido para " + category.name());
|
||||||
|
}
|
||||||
|
typeOptionService.register(category, normalized);
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue