Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add routine to disconnect all invisible children of subjects. #279

Merged
merged 6 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/no/ndla/taxonomy/config/AsyncConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableAsync;

@Profile("!default")
@Profile("!(default|junit)")
@EnableAsync
@Configuration
public class AsyncConfig {}
12 changes: 12 additions & 0 deletions src/main/java/no/ndla/taxonomy/repositories/NodeRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ List<Integer> findIdsFiltered(
""")
List<Node> findProgrammes();

@Query(
"""
SELECT DISTINCT n FROM Node n
LEFT JOIN FETCH n.resourceResourceTypes rrt
LEFT JOIN FETCH rrt.resourceType
LEFT JOIN FETCH n.parentConnections pc
LEFT JOIN FETCH n.childConnections cc
WHERE n.nodeType = "SUBJECT"
AND n.context = true
""")
List<Node> findRootSubjects();

@Query(
"""
SELECT DISTINCT n FROM Node n
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public class VersionPostPut implements UpdatableDto<Version> {
@JsonProperty
@Schema(
description =
"If specified, set the id to this value. Must start with urn:subject: and be a valid URI. If omitted, an id will be assigned automatically.",
example = "urn:subject:1")
"If specified, set the id to this value. Must start with urn:version: and be a valid URI. If ommitted, an id will be assigned automatically.",
example = "urn:version:1")
public Optional<URI> id = Optional.empty();

@JsonProperty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.net.URI;
import java.util.Collection;
import java.util.Optional;
import no.ndla.taxonomy.domain.DomainEntity;
import no.ndla.taxonomy.domain.Node;
import no.ndla.taxonomy.domain.NodeConnection;
import no.ndla.taxonomy.domain.Relevance;
Expand All @@ -34,4 +35,6 @@ void updateParentChild(
Collection<NodeConnection> getChildConnections(Node entity);

void disconnectAllChildren(Node entity);

Optional<DomainEntity> disconnectAllInvisibleNodes();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import java.net.URI;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import no.ndla.taxonomy.domain.Node;
import no.ndla.taxonomy.domain.NodeConnection;
import no.ndla.taxonomy.domain.NodeType;
import no.ndla.taxonomy.domain.Relevance;
import no.ndla.taxonomy.domain.*;
import no.ndla.taxonomy.repositories.NodeConnectionRepository;
import no.ndla.taxonomy.repositories.NodeRepository;
import no.ndla.taxonomy.rest.NotFoundHttpResponseException;
Expand All @@ -26,6 +23,7 @@
@Transactional(propagation = Propagation.MANDATORY)
@Service
public class NodeConnectionServiceImpl implements NodeConnectionService {

private final NodeConnectionRepository nodeConnectionRepository;
private final ContextUpdaterService contextUpdaterService;
private final NodeRepository nodeRepository;
Expand Down Expand Up @@ -295,4 +293,24 @@ public void disconnectAllParents(URI nodeId) {
public void disconnectAllChildren(Node entity) {
Set.copyOf(entity.getChildConnections()).forEach(this::disconnectParentChildConnection);
}

@Transactional
@Override
public Optional<DomainEntity> disconnectAllInvisibleNodes() {
nodeRepository.findRootSubjects().forEach(subject -> {
disconnectInvisibleConnections(subject);
nodeRepository.save(subject);
});
return Optional.empty();
}

private void disconnectInvisibleConnections(Node node) {
if (!node.isVisible()) {
node.getParentConnections().forEach(this::disconnectParentChildConnection);
} else {
node.getChildConnections()
.forEach(nodeConnection ->
nodeConnection.getChild().ifPresent(this::disconnectInvisibleConnections));
}
}
}
36 changes: 31 additions & 5 deletions src/main/java/no/ndla/taxonomy/service/VersionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,43 @@
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import no.ndla.taxonomy.domain.Version;
import no.ndla.taxonomy.domain.VersionType;
import no.ndla.taxonomy.repositories.VersionRepository;
import no.ndla.taxonomy.rest.v1.commands.VersionPostPut;
import no.ndla.taxonomy.service.dtos.VersionDTO;
import no.ndla.taxonomy.service.exceptions.NotFoundServiceException;
import no.ndla.taxonomy.service.task.Deleter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly = true)
@Service
public class VersionService {
final Logger logger = LoggerFactory.getLogger(this.getClass());
private final VersionRepository versionRepository;
private final EntityManager entityManager;
private final VersionRepository versionRepository;
private final NodeConnectionService nodeConnectionService;
private final URNValidator validator = new URNValidator();
private final ExecutorService executor = Executors.newSingleThreadExecutor();

@Value("${spring.datasource.hikari.schema:taxonomy_api}")
private String defaultSchema;

public VersionService(VersionRepository versionRepository, EntityManager entityManager) {
this.versionRepository = versionRepository;
public VersionService(
EntityManager entityManager,
VersionRepository versionRepository,
NodeConnectionService nodeConnectionService) {
this.entityManager = entityManager;
this.versionRepository = versionRepository;
this.nodeConnectionService = nodeConnectionService;
}

@Transactional
Expand Down Expand Up @@ -70,19 +80,35 @@ public List<VersionDTO> getVersionsOfType(VersionType versionType) {
}

@Transactional
@Async
public void publishBetaAndArchiveCurrent(URI id) {
Optional<Version> published = versionRepository.findFirstByVersionType(VersionType.PUBLISHED);
if (published.isPresent()) {
Version version = published.get();
version.setVersionType(VersionType.ARCHIVED);
version.setArchived(Instant.now());
versionRepository.save(version);
versionRepository.saveAndFlush(version);
}
Version beta = versionRepository.getByPublicId(id);
beta.setVersionType(VersionType.PUBLISHED);
beta.setLocked(true);
beta.setPublished(Instant.now());
versionRepository.save(beta);
versionRepository.saveAndFlush(beta);

disconnectAllInvisibleNodes(beta.getHash());
}

private void disconnectAllInvisibleNodes(String hash) {
// Use a task to run in a separate thread against a specified schema
// Do not care about the result so no need to wait for it
try {
Deleter deleter = new Deleter();
deleter.setNodeConnectionService(nodeConnectionService);
deleter.setVersion(schemaFromHash(hash));
executor.submit(deleter);
} catch (Exception e) {
logger.info(e.getMessage(), e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeg husker vi snakka om det, men jeg husker ikke helt hva det var igjen. Hvorfor burde ikke denne være logger.error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Det kunne den fint vore, men tenkte berre at det ikkje gav så masse ekstra verdi. Vil sannsynligvis ikkje skje uansett.

}
}

@Transactional
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/no/ndla/taxonomy/service/task/Deleter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Part of NDLA taxonomy-api
* Copyright (C) 2024 NDLA
*
* See LICENSE
*/

package no.ndla.taxonomy.service.task;

import java.util.Optional;
import no.ndla.taxonomy.domain.DomainEntity;
import no.ndla.taxonomy.service.NodeConnectionService;

public class Deleter extends Task<DomainEntity> {
private NodeConnectionService nodeConnectionService;

public void setNodeConnectionService(NodeConnectionService nodeService) {
this.nodeConnectionService = nodeService;
}

@Override
protected Optional<DomainEntity> execute() {
return nodeConnectionService.disconnectAllInvisibleNodes();
}
}
2 changes: 1 addition & 1 deletion src/test/java/no/ndla/taxonomy/rest/v1/RestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@SpringBootTest
@ActiveProfiles("junit")
@Transactional
public abstract class RestTest extends AbstractIntegrationTest {
public class RestTest extends AbstractIntegrationTest {

@Autowired
EntityManager entityManager;
Expand Down
13 changes: 10 additions & 3 deletions src/test/java/no/ndla/taxonomy/rest/v1/VersionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,17 @@ public void can_update_version() throws Exception {

@Test
public void can_publish_version() throws Exception {
Version version = builder.version(); // BETA
testUtils.updateResource("/v1/versions/" + version.getPublicId() + "/publish", null);
var versionUri = URI.create("urn:version:beta");
final var createVersionCommand = new VersionPostPut() {
{
id = Optional.of(versionUri);
name = "Beta";
}
};
testUtils.createResource("/v1/versions", createVersionCommand);
testUtils.updateResource("/v1/versions/" + versionUri + "/publish", null);

Version updated = versionRepository.getByPublicId(version.getPublicId());
Version updated = versionRepository.getByPublicId(versionUri);
assertEquals(VersionType.PUBLISHED, updated.getVersionType());
assertTrue(updated.isLocked());
assertNotNull(updated.getPublished());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@DirtiesContext
public class AbstractIntegrationTest {

static final PostgreSQLContainer<?> postgresDB;

static {
postgresDB = new PostgreSQLContainer<>("postgres:16.3");
postgresDB.start();
}
@Container
private static final PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3");

@Autowired
EntityManager entityManager;
Expand Down
Loading