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.NewServerDTO;
|
||||
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 io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
|
@ -72,14 +69,14 @@ public class ServersController {
|
|||
@GetMapping("/type/{type}")
|
||||
@Operation(summary = "Lista servidores por tipo.")
|
||||
@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));
|
||||
}
|
||||
|
||||
@GetMapping("/type")
|
||||
@Operation(summary = "Conta servidores agrupando por tipo.")
|
||||
@ApiResponse(responseCode = "200", description = "Mapa retornado.")
|
||||
public ResponseEntity<Map<ServersType, Integer>> countAllByType() {
|
||||
public ResponseEntity<Map<String, Integer>> countAllByType() {
|
||||
return ResponseEntity.ok().body(serversService.countAllByType());
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +93,7 @@ public class ServersController {
|
|||
@GetMapping("/application/{application}")
|
||||
@Operation(summary = "Lista servidores por aplicação.")
|
||||
@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));
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +102,9 @@ public class ServersController {
|
|||
@ApiResponse(responseCode = "200", description = "Resultados retornados.")
|
||||
public ResponseEntity<List<ServerDTO>> getAll(
|
||||
@RequestParam(value = "query", required = false) String query,
|
||||
@RequestParam(value = "type", required = false) ServersType type,
|
||||
@RequestParam(value = "application", required = false) Applications application,
|
||||
@RequestParam(value = "dbType", required = false) DatabaseType dbType
|
||||
@RequestParam(value = "type", required = false) String type,
|
||||
@RequestParam(value = "application", required = false) String application,
|
||||
@RequestParam(value = "dbType", required = false) String dbType
|
||||
) {
|
||||
return ResponseEntity.ok().body(serversService.search(query, type, application, dbType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
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.NotNull;
|
||||
|
||||
|
|
@ -12,9 +9,8 @@ public record NewServerDTO(
|
|||
@NotNull Integer port,
|
||||
@NotBlank String user,
|
||||
@NotBlank String password,
|
||||
@NotNull ServersType type,
|
||||
@NotNull Applications application,
|
||||
@NotNull DatabaseType dbType
|
||||
@NotBlank String type,
|
||||
@NotBlank String application,
|
||||
@NotBlank String dbType
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
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;
|
||||
|
||||
public record ServerDTO(
|
||||
|
|
@ -13,9 +9,9 @@ public record ServerDTO(
|
|||
Integer port,
|
||||
String user,
|
||||
String password,
|
||||
ServersType type,
|
||||
Applications application,
|
||||
DatabaseType dbType,
|
||||
String type,
|
||||
String application,
|
||||
String dbType,
|
||||
Timestamp createdAt,
|
||||
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 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> {
|
||||
Optional<Servers> findByName(String name);
|
||||
List<Servers> findByType(ServersType type);
|
||||
List<Servers> findByApplication(Applications application);
|
||||
List<Servers> findByType(String type);
|
||||
List<Servers> findByApplication(String application);
|
||||
Optional<Servers> findByIpAndPort(String ip, Integer port);
|
||||
Integer countAllByType(ServersType type);
|
||||
Integer countAllByType(String type);
|
||||
|
||||
@Query(value = """
|
||||
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.NewServerDTO;
|
||||
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.model.enums.TypeCategory;
|
||||
import com.hitcommunications.servermanager.repositories.ServersRepository;
|
||||
import com.hitcommunications.servermanager.services.TypeOptionService;
|
||||
import com.hitcommunications.servermanager.utils.TypeNormalizer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
|
@ -18,18 +18,20 @@ import java.io.BufferedReader;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ServersService {
|
||||
private final ServersMapper mapper;
|
||||
private final ServersRepository repo;
|
||||
private final TypeOptionService typeOptionService;
|
||||
|
||||
public ServerDTO create(NewServerDTO createDTO) {
|
||||
Servers entity = mapper.toEntity(createDTO);
|
||||
applyNormalizedTypeData(entity, createDTO);
|
||||
entity = repo.save(entity);
|
||||
return mapper.toDTO(entity);
|
||||
}
|
||||
|
|
@ -46,25 +48,34 @@ public class ServersService {
|
|||
.orElseThrow(() -> new RuntimeException("Server not found with name: " + name));
|
||||
}
|
||||
|
||||
public List<ServerDTO> getByType(ServersType type) {
|
||||
return repo.findByType(type)
|
||||
public List<ServerDTO> getByType(String type) {
|
||||
String normalized = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
||||
return repo.findByType(normalized)
|
||||
.stream()
|
||||
.map(mapper::toDTO)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Map<ServersType, Integer> countAllByType() {
|
||||
Map<ServersType, Integer> response = new HashMap<>();
|
||||
public Map<String, Integer> countAllByType() {
|
||||
Map<String, Integer> response = new LinkedHashMap<>();
|
||||
|
||||
for(ServersType type : ServersType.values()) {
|
||||
typeOptionService.list(TypeCategory.SERVER_TYPE).forEach(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;
|
||||
}
|
||||
|
||||
public List<ServerDTO> getByApplication(Applications application) {
|
||||
return repo.findByApplication(application)
|
||||
public List<ServerDTO> getByApplication(String application) {
|
||||
String normalized = normalizeFilter(application, TypeCategory.APPLICATION);
|
||||
return repo.findByApplication(normalized)
|
||||
.stream()
|
||||
.map(mapper::toDTO)
|
||||
.toList();
|
||||
|
|
@ -91,6 +102,7 @@ public class ServersService {
|
|||
|
||||
processed++;
|
||||
try {
|
||||
registerTypeOptionsFromRow(columns);
|
||||
NewServerDTO dto = toNewServerDTO(columns);
|
||||
create(dto);
|
||||
succeeded++;
|
||||
|
|
@ -125,13 +137,29 @@ public class ServersService {
|
|||
Integer port = Integer.parseInt(columns[2]);
|
||||
String user = columns[3];
|
||||
String password = columns[4];
|
||||
ServersType type = ServersType.valueOf(columns[5].toUpperCase());
|
||||
Applications application = Applications.valueOf(columns[6].toUpperCase());
|
||||
DatabaseType dbType = DatabaseType.valueOf(columns[7].toUpperCase());
|
||||
String type = columns[5];
|
||||
String application = columns[6];
|
||||
String dbType = columns[7];
|
||||
|
||||
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) {
|
||||
if (columns.length < 8) {
|
||||
return false;
|
||||
|
|
@ -148,11 +176,11 @@ public class ServersService {
|
|||
.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 typeFilter = type != null ? type.name() : null;
|
||||
String applicationFilter = application != null ? application.name() : null;
|
||||
String dbTypeFilter = dbType != null ? dbType.name() : null;
|
||||
String typeFilter = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
||||
String applicationFilter = normalizeFilter(application, TypeCategory.APPLICATION);
|
||||
String dbTypeFilter = normalizeFilter(dbType, TypeCategory.DATABASE);
|
||||
|
||||
return repo.search(normalizedQuery, typeFilter, applicationFilter, dbTypeFilter)
|
||||
.stream()
|
||||
|
|
@ -165,6 +193,7 @@ public class ServersService {
|
|||
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
||||
|
||||
mapper.partialUpdate(updateDTO, entity);
|
||||
applyNormalizedTypeData(entity, updateDTO);
|
||||
entity = repo.save(entity);
|
||||
return mapper.toDTO(entity);
|
||||
}
|
||||
|
|
@ -176,4 +205,30 @@ public class ServersService {
|
|||
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