255 lines
9.4 KiB
Java
255 lines
9.4 KiB
Java
package com.hitcommunications.servermanager.services;
|
|
|
|
import com.hitcommunications.servermanager.mappers.ServersMapper;
|
|
import com.hitcommunications.servermanager.model.Servers;
|
|
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.dtos.PagedResponse;
|
|
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.data.domain.Page;
|
|
import org.springframework.data.domain.PageRequest;
|
|
import org.springframework.data.domain.Pageable;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.ArrayList;
|
|
import java.util.LinkedHashMap;
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class ServersService {
|
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
|
private static final int MAX_PAGE_SIZE = 50;
|
|
|
|
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);
|
|
}
|
|
|
|
public ServerDTO getById(String id) {
|
|
return repo.findById(id)
|
|
.map(mapper::toDTO)
|
|
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
|
}
|
|
|
|
public ServerDTO getByName(String name) {
|
|
return repo.findByName(name)
|
|
.map(mapper::toDTO)
|
|
.orElseThrow(() -> new RuntimeException("Server not found with name: " + name));
|
|
}
|
|
|
|
public List<ServerDTO> getByType(String type) {
|
|
String normalized = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
|
return repo.findByType(normalized)
|
|
.stream()
|
|
.map(mapper::toDTO)
|
|
.toList();
|
|
}
|
|
|
|
public Map<String, Integer> countAllByType() {
|
|
Map<String, Integer> response = new LinkedHashMap<>();
|
|
|
|
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(String application) {
|
|
String normalized = normalizeFilter(application, TypeCategory.APPLICATION);
|
|
return repo.findByApplication(normalized)
|
|
.stream()
|
|
.map(mapper::toDTO)
|
|
.toList();
|
|
}
|
|
|
|
public BulkServerImportResponse bulkCreate(MultipartFile file) {
|
|
List<FailedRow> failures = new ArrayList<>();
|
|
int succeeded = 0;
|
|
int processed = 0;
|
|
|
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
|
|
String line;
|
|
int lineNumber = 0;
|
|
while ((line = reader.readLine()) != null) {
|
|
lineNumber++;
|
|
if (line.isBlank()) {
|
|
continue;
|
|
}
|
|
|
|
String[] columns = parseColumns(line);
|
|
if (isHeaderRow(columns)) {
|
|
continue;
|
|
}
|
|
|
|
processed++;
|
|
try {
|
|
registerTypeOptionsFromRow(columns);
|
|
NewServerDTO dto = toNewServerDTO(columns);
|
|
create(dto);
|
|
succeeded++;
|
|
} catch (Exception ex) {
|
|
failures.add(new FailedRow(lineNumber, ex.getMessage(), line));
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Erro ao ler arquivo CSV.", e);
|
|
}
|
|
|
|
int failed = failures.size();
|
|
return new BulkServerImportResponse(processed, succeeded, failed, failures);
|
|
}
|
|
|
|
private String[] parseColumns(String line) {
|
|
String[] rawColumns = line.split(";");
|
|
String[] columns = new String[rawColumns.length];
|
|
for (int i = 0; i < rawColumns.length; i++) {
|
|
columns[i] = rawColumns[i].trim();
|
|
}
|
|
return columns;
|
|
}
|
|
|
|
private NewServerDTO toNewServerDTO(String[] columns) {
|
|
if (columns.length < 8) {
|
|
throw new IllegalArgumentException("Linha incompleta. Esperado 8 colunas.");
|
|
}
|
|
|
|
String name = columns[0];
|
|
String ip = columns[1];
|
|
Integer port = Integer.parseInt(columns[2]);
|
|
String user = columns[3];
|
|
String password = columns[4];
|
|
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;
|
|
}
|
|
return "name".equalsIgnoreCase(columns[0]) &&
|
|
"ip".equalsIgnoreCase(columns[1]) &&
|
|
"port".equalsIgnoreCase(columns[2]);
|
|
}
|
|
|
|
public List<ServerDTO> getAll() {
|
|
return repo.findAll()
|
|
.stream()
|
|
.map(mapper::toDTO)
|
|
.toList();
|
|
}
|
|
|
|
public PagedResponse<ServerDTO> search(String query, String type, String application, String dbType, Integer page, Integer size) {
|
|
String normalizedQuery = (query == null || query.isBlank()) ? null : query.trim();
|
|
String typeFilter = normalizeFilter(type, TypeCategory.SERVER_TYPE);
|
|
String applicationFilter = normalizeFilter(application, TypeCategory.APPLICATION);
|
|
String dbTypeFilter = normalizeFilter(dbType, TypeCategory.DATABASE);
|
|
int safePage = page != null && page >= 0 ? page : 0;
|
|
int requestedSize = (size != null && size > 0) ? size : DEFAULT_PAGE_SIZE;
|
|
int safeSize = Math.min(requestedSize, MAX_PAGE_SIZE);
|
|
Pageable pageable = PageRequest.of(safePage, safeSize);
|
|
|
|
Page<Servers> result = repo.search(normalizedQuery, typeFilter, applicationFilter, dbTypeFilter, pageable);
|
|
List<ServerDTO> content = result.getContent()
|
|
.stream()
|
|
.map(mapper::toDTO)
|
|
.toList();
|
|
|
|
return new PagedResponse<>(
|
|
content,
|
|
result.getTotalElements(),
|
|
result.getTotalPages(),
|
|
result.getNumber(),
|
|
result.getSize()
|
|
);
|
|
}
|
|
|
|
public ServerDTO update(String id, NewServerDTO updateDTO) {
|
|
Servers entity = repo.findById(id)
|
|
.orElseThrow(() -> new RuntimeException("Server not found with id: " + id));
|
|
|
|
mapper.partialUpdate(updateDTO, entity);
|
|
applyNormalizedTypeData(entity, updateDTO);
|
|
entity = repo.save(entity);
|
|
return mapper.toDTO(entity);
|
|
}
|
|
|
|
public void delete(String id) {
|
|
if (!repo.existsById(id)) {
|
|
throw new RuntimeException("Server not found with id: " + 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;
|
|
}
|
|
}
|