package eu.old.eudat.migration; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.DescriptionTagEntity; import eu.eudat.data.ReferenceEntity; import eu.eudat.data.TagEntity; import eu.old.eudat.data.dao.entities.DatasetDao; import eu.old.eudat.data.entities.Dataset; import eu.old.eudat.elastic.entities.Tag; import eu.old.eudat.elastic.repository.DatasetRepository; import eu.old.eudat.logic.services.operations.DatabaseRepository; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; import jakarta.xml.bind.JAXBException; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.time.Instant; import java.util.*; @Service public class TagMigrationService { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TagMigrationService.class)); private final DatabaseRepository databaseRepository; private final DatasetRepository datasetRepository; private static final int PageSize = 500; private static final boolean TestMode = false; private final EntityManager entityManager; public TagMigrationService(DatabaseRepository databaseRepository, DatasetRepository datasetRepository, EntityManager entityManager) { this.databaseRepository = databaseRepository; this.datasetRepository = datasetRepository; this.entityManager = entityManager; } public void migrate() throws IOException, JAXBException, ParserConfigurationException, InstantiationException, IllegalAccessException, SAXException { DatasetDao datasetDao = databaseRepository.getDatasetDao(); long total = datasetDao.asQueryable().count(); logger.debug("Migrate Tags for Dataset Total : " + total); int page = 0; Map savedTagIdsByName = new HashMap<>(); HashSet existingTagIds = new HashSet<>(); List items; do { items = datasetDao.asQueryable().orderBy((builder, root) -> builder.asc(root.get("created"))).orderBy((builder, root) -> builder.asc(root.get("ID"))).skip(page * PageSize).take(PageSize).toList(); if (items != null && !items.isEmpty()) { logger.debug("Migrate Dataset tags " + page * PageSize + " of " + total); List elasticDatasets = this.datasetRepository.findByIds(items.stream().map(x -> x.getId().toString()).toList()); for (Dataset item : items) { List found = elasticDatasets.stream().filter(x -> item.getId().toString().equals(x.getId())).toList(); if (found.isEmpty()) { logger.error("No dataset with id {} found on elastic search. Skipping tag migration for this dataset", item.getId()); continue; } eu.old.eudat.elastic.entities.Dataset elasticDataset = found.getFirst(); boolean tagAlreadyExists; if (elasticDataset.getTags() != null && !elasticDataset.getTags().isEmpty()) { for (Tag tag : elasticDataset.getTags()) { tagAlreadyExists = savedTagIdsByName.containsKey(new TagKey(item, tag)); //TODO we want owner logic ? if (!tagAlreadyExists) { TagEntity tagEntity = new TagEntity(); if (!existingTagIds.contains(UUID.fromString(tag.getId()))) tagEntity.setId(UUID.fromString(tag.getId())); else tagEntity.setId(UUID.randomUUID()); tagEntity.setLabel(tag.getName()); tagEntity.setCreatedAt(Instant.now()); tagEntity.setUpdatedAt(Instant.now()); if (item.getCreator() != null) tagEntity.setCreatedById(item.getCreator().getId()); tagEntity.setIsActive(IsActive.Active); savedTagIdsByName.put(new TagKey(item, tag), tagEntity.getId()); this.entityManager.persist(tagEntity); } DescriptionTagEntity descriptionTagEntity = new DescriptionTagEntity(); descriptionTagEntity.setId(UUID.randomUUID()); descriptionTagEntity.setTagId(savedTagIdsByName.get(new TagKey(item, tag))); descriptionTagEntity.setDescriptionId(item.getId()); descriptionTagEntity.setCreatedAt(Instant.now()); descriptionTagEntity.setUpdatedAt(Instant.now()); descriptionTagEntity.setIsActive(IsActive.Active); this.entityManager.persist(descriptionTagEntity); existingTagIds.add(descriptionTagEntity.getTagId()); } } this.entityManager.flush(); } page++; } } while (items != null && !items.isEmpty() && !TestMode); } public static class TagKey { private final UUID owner; private final String name; private final int hashCode; public TagKey(Dataset item, Tag tag) { this.name = tag.getName(); if (item.getCreator() != null) this.owner = item.getCreator().getId(); else this.owner = null; hashCode = Objects.hash(this.owner, this.name); } public UUID getOwner() { return owner; } public String getName() { return name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TagKey that = (TagKey) o; return Objects.equals(owner, that.getOwner()) && Objects.equals(name, that.getName()); } @Override public int hashCode() { return this.hashCode; } } }