feat(types): tornar tipos configuráveis
- converte entidades de servidores para armazenar type/application/db como texto - adiciona modelo e API para registrar/listar TypeOptions com normalização - centraliza schema/data scripts para criar schema e seedar tipos e usuário padrãomaster
parent
ed247c423e
commit
6d5a64be89
|
|
@ -0,0 +1,29 @@
|
|||
package com.hitcommunications.servermanager.controllers;
|
||||
|
||||
import com.hitcommunications.servermanager.model.enums.TypeCategory;
|
||||
import com.hitcommunications.servermanager.services.TypeOptionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/type-options")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "Type Options")
|
||||
public class TypeOptionsController {
|
||||
|
||||
private final TypeOptionService typeOptionService;
|
||||
|
||||
@GetMapping("/{category}")
|
||||
@Operation(summary = "Lista os valores disponíveis para um tipo de categoria (SERVER_TYPE, APPLICATION, DATABASE).")
|
||||
public ResponseEntity<List<String>> list(@PathVariable TypeCategory category) {
|
||||
return ResponseEntity.ok(typeOptionService.list(category));
|
||||
}
|
||||
}
|
||||
|
|
@ -5,15 +5,10 @@ import java.sql.Timestamp;
|
|||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
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.utils.ServerIdGenerator;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
|
@ -51,17 +46,14 @@ public class Servers {
|
|||
@Column(nullable = false)
|
||||
private String password;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ServersType type;
|
||||
@Column(nullable = false, length = 80)
|
||||
private String type;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Applications application;
|
||||
@Column(nullable = false, length = 80)
|
||||
private String application;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private DatabaseType dbType;
|
||||
@Column(nullable = false, length = 80, name = "db_type")
|
||||
private String dbType;
|
||||
|
||||
@CreationTimestamp
|
||||
private Timestamp createdAt;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.hitcommunications.servermanager.model;
|
||||
|
||||
import com.hitcommunications.servermanager.model.enums.TypeCategory;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Entity
|
||||
@Table(name = "tab_type_options", schema = "server-manager", uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = {"category", "value"})
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class TypeOption {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(nullable = false, updatable = false)
|
||||
private Long id;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false, length = 32)
|
||||
private TypeCategory category;
|
||||
|
||||
@Column(nullable = false, length = 80)
|
||||
private String value;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.hitcommunications.servermanager.model.enums;
|
||||
|
||||
public enum TypeCategory {
|
||||
SERVER_TYPE,
|
||||
APPLICATION,
|
||||
DATABASE
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.hitcommunications.servermanager.repositories;
|
||||
|
||||
import com.hitcommunications.servermanager.model.TypeOption;
|
||||
import com.hitcommunications.servermanager.model.enums.TypeCategory;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface TypeOptionRepository extends JpaRepository<TypeOption, Long> {
|
||||
Optional<TypeOption> findByCategoryAndValue(TypeCategory category, String value);
|
||||
List<TypeOption> findAllByCategoryOrderByValueAsc(TypeCategory category);
|
||||
}
|
||||
|
|
@ -29,8 +29,6 @@ public class ServersService {
|
|||
private final ServersRepository repo;
|
||||
|
||||
public ServerDTO create(NewServerDTO createDTO) {
|
||||
ensureUniqueIpAndPort(createDTO.ip(), createDTO.port(), null);
|
||||
|
||||
Servers entity = mapper.toEntity(createDTO);
|
||||
entity = repo.save(entity);
|
||||
return mapper.toDTO(entity);
|
||||
|
|
@ -166,8 +164,6 @@ public class ServersService {
|
|||
Servers entity = repo.findById(id)
|
||||
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
||||
|
||||
ensureUniqueIpAndPort(updateDTO.ip(), updateDTO.port(), id);
|
||||
|
||||
mapper.partialUpdate(updateDTO, entity);
|
||||
entity = repo.save(entity);
|
||||
return mapper.toDTO(entity);
|
||||
|
|
@ -180,11 +176,4 @@ public class ServersService {
|
|||
repo.deleteById(id);
|
||||
}
|
||||
|
||||
private void ensureUniqueIpAndPort(String ip, Integer port, String currentServerId) {
|
||||
repo.findByIpAndPort(ip, port).ifPresent(existingServer -> {
|
||||
if (currentServerId == null || !existingServer.getId().equals(currentServerId)) {
|
||||
throw new RuntimeException("Server already exists with IP: " + ip + " and port: " + port);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.hitcommunications.servermanager.services;
|
||||
|
||||
import com.hitcommunications.servermanager.model.TypeOption;
|
||||
import com.hitcommunications.servermanager.model.enums.TypeCategory;
|
||||
import com.hitcommunications.servermanager.repositories.TypeOptionRepository;
|
||||
import com.hitcommunications.servermanager.utils.TypeNormalizer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TypeOptionService {
|
||||
|
||||
private final TypeOptionRepository repository;
|
||||
|
||||
@Transactional
|
||||
public void register(TypeCategory category, String rawValue) {
|
||||
String normalized = TypeNormalizer.normalize(rawValue);
|
||||
if (normalized == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
repository.findByCategoryAndValue(category, normalized)
|
||||
.orElseGet(() -> repository.save(
|
||||
TypeOption.builder()
|
||||
.category(category)
|
||||
.value(normalized)
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
public List<String> list(TypeCategory category) {
|
||||
return repository.findAllByCategoryOrderByValueAsc(category)
|
||||
.stream()
|
||||
.map(TypeOption::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.hitcommunications.servermanager.utils;
|
||||
|
||||
import java.text.Normalizer;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class TypeNormalizer {
|
||||
|
||||
private static final Pattern DIACRITICS = Pattern.compile("\\p{M}");
|
||||
|
||||
private TypeNormalizer() {
|
||||
}
|
||||
|
||||
public static String normalize(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String trimmed = value.trim();
|
||||
if (trimmed.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String normalized = Normalizer.normalize(trimmed, Normalizer.Form.NFD);
|
||||
normalized = DIACRITICS.matcher(normalized).replaceAll("");
|
||||
normalized = normalized.replaceAll("[^A-Za-z0-9_\\- ]", "");
|
||||
normalized = normalized.replaceAll("\\s+", "_");
|
||||
return normalized.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ spring:
|
|||
init:
|
||||
mode: always
|
||||
schema-locations: classpath:schema.sql
|
||||
data-locations: classpath:data.sql
|
||||
|
||||
datasource:
|
||||
url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
|
||||
|
|
|
|||
|
|
@ -18,3 +18,26 @@ INSERT INTO "server-manager".tab_users (
|
|||
CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO "server-manager".tab_type_options (id, category, value)
|
||||
VALUES
|
||||
(101, 'SERVER_TYPE', 'PRODUCTION'),
|
||||
(102, 'SERVER_TYPE', 'HOMOLOGATION'),
|
||||
(103, 'SERVER_TYPE', 'DATABASE'),
|
||||
(201, 'APPLICATION', 'ASTERISK'),
|
||||
(202, 'APPLICATION', 'HITMANAGER'),
|
||||
(203, 'APPLICATION', 'HITMANAGER_V2'),
|
||||
(204, 'APPLICATION', 'OMNIHIT'),
|
||||
(205, 'APPLICATION', 'HITPHONE'),
|
||||
(206, 'APPLICATION', 'CDR'),
|
||||
(207, 'APPLICATION', 'FUNCIONALIDADE'),
|
||||
(208, 'APPLICATION', 'VOICEMAIL'),
|
||||
(301, 'DATABASE', 'MYSQL'),
|
||||
(302, 'DATABASE', 'POSTGRESQL'),
|
||||
(303, 'DATABASE', 'SQLSERVER'),
|
||||
(304, 'DATABASE', 'ORACLE'),
|
||||
(305, 'DATABASE', 'REDIS'),
|
||||
(306, 'DATABASE', 'MONGODB'),
|
||||
(307, 'DATABASE', 'MARIADB'),
|
||||
(308, 'DATABASE', 'NONE')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
CREATE SCHEMA IF NOT EXISTS "server-manager";
|
||||
CREATE SCHEMA IF NOT EXISTS "server-manager";
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
|
|
|||
Loading…
Reference in New Issue