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

Use parent context to calculate hash. Save full hash in context. #239

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 3 additions & 1 deletion src/main/java/no/ndla/taxonomy/domain/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
* @param isActive Metadata from node. True if subjectCategory is active or otherResources.
* @param isPrimary Is this context marked as primary. From nodeConnection.
* @param relevanceId ID of relevance. From nodeConnection.
* @param contextId Hash of root publicId + nodeConnection publicId. Unique for this context.
* @param hash Hash of parent contextId + nodeConnection publicId. Unique for this context.
* @param contextId Short form of hash.
* @param rank The rank of the context. From nodeConnection.
* @param connectionId The id of the connection. From nodeConnection.
*/
Expand All @@ -41,6 +42,7 @@ public record Context(
boolean isActive,
boolean isPrimary,
String relevanceId,
String hash,
String contextId,
int rank,
String connectionId) {}
2 changes: 1 addition & 1 deletion src/main/java/no/ndla/taxonomy/domain/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class Version extends DomainEntity {

public Version() {
setPublicId(URI.create("urn:version:" + UUID.randomUUID()));
this.hash = HashUtil.shortHash(getPublicId());
this.hash = new HashUtil(getPublicId(), "").shortHash();
this.created = Instant.now();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private Set<Context> createContexts(Node node) {
.matches(String.format("%s|%s|%s", Constants.Active, Constants.Beta, Constants.OtherResources));
// This entity can be root path
if (node.isContext()) {
var hash = new HashUtil(node.getPublicId(), "");
returnedContexts.add(new Context(
node.getPublicId().toString(),
LanguageField.fromNode(node),
Expand All @@ -41,7 +42,8 @@ private Set<Context> createContexts(Node node) {
activeContext,
true,
"urn:relevance:core",
HashUtil.semiHash(node.getPublicId()),
hash.fullHash(),
hash.semiHash(),
0,
""));
}
Expand All @@ -56,6 +58,7 @@ private Set<Context> createContexts(Node node) {
parentContext.breadcrumbs(), LanguageField.fromNode(parent));
List<String> parentIds = parentContext.parentIds();
parentIds.add(parent.getPublicId().toString());
var hash = new HashUtil(parentContext.contextId(), parentConnection.getPublicId());
return new Context(
parentContext.rootId(),
parentContext.rootName(),
Expand All @@ -71,7 +74,8 @@ private Set<Context> createContexts(Node node) {
.flatMap(relevance -> Optional.of(
relevance.getPublicId().toString()))
.orElse("urn:relevance:core"),
HashUtil.semiHash(parentContext.rootId() + parentConnection.getPublicId()),
hash.fullHash(),
hash.semiHash(),
parentConnection.getRank(),
parentConnection.getPublicId().toString());
})
Expand Down
1 change: 1 addition & 0 deletions src/main/java/no/ndla/taxonomy/service/dtos/NodeDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public Set<ResourceTypeWithConnectionDTO> getResourceTypes() {
return resourceTypes;
}

@JsonProperty
public Set<String> getSupportedLanguages() {
return supportedLanguages;
}
Expand Down
37 changes: 23 additions & 14 deletions src/main/java/no/ndla/taxonomy/util/HashUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,38 @@
* Util for generating hashes in different lengths
*/
public class HashUtil {
private static String generateHash(Object original, int length) {
String hash = new DigestUtils("SHA3-256").digestAsHex(original.toString());
if (length > 0) return hash.substring(0, length);
return hash;

private final String hash;

public HashUtil(Object parentId, Object connectionId) {
this.hash = generateHash(parentId, connectionId);
}

public HashUtil(String hash) {
this.hash = hash;
}

public String shortHash() {
return hash.substring(0, 4);
}

public static String shortHash(Object original) {
return generateHash(original, 4);
public String mediumHash() {
return hash.substring(0, 8);
}

public static String mediumHash(Object original) {
return generateHash(original, 8);
public String semiHash() {
return hash.substring(0, 12);
}

public static String semiHash(Object original) {
return generateHash(original, 12);
public String longHash() {
return hash.substring(0, 16);
}

public static String longHash(Object original) {
return generateHash(original, 16);
public String fullHash() {
return hash;
}

public static String fullHash(Object original) {
return generateHash(original, 0);
private String generateHash(Object part1, Object part2) {
return new DigestUtils("SHA3-256").digestAsHex(part1.toString() + part2.toString());
}
}
9 changes: 9 additions & 0 deletions src/main/resources/db-master-changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1479,4 +1479,13 @@
</sql>
</changeSet>

<changeSet id="20240311 Add full hash to context as copy of contextId" author="Gunnar Velle">
<sql>
UPDATE node
SET contexts = (
SELECT jsonb_agg(jsonb_set(obj, '{hash}', to_jsonb(obj->>'contextId'), true))
FROM jsonb_array_elements(contexts) AS obj
)
</sql>
</changeSet>
</databaseChangeLog>
3 changes: 3 additions & 0 deletions src/test/java/no/ndla/taxonomy/domain/NodeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ void pickTheCorrectContext() {
true,
"urn:relevance:core",
"1",
"1",
0,
"urn:connection1");
var context2 = new Context(
Expand All @@ -349,6 +350,7 @@ void pickTheCorrectContext() {
true,
"urn:relevance:core",
"2",
"2",
0,
"urn:connection2");
var context3 = new Context(
Expand All @@ -365,6 +367,7 @@ void pickTheCorrectContext() {
true,
"urn:relevance:core",
"3",
"3",
0,
"urn:connection3");

Expand Down
13 changes: 4 additions & 9 deletions src/test/java/no/ndla/taxonomy/rest/v1/QueryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import no.ndla.taxonomy.rest.v1.dtos.searchapi.LanguageFieldDTO;
import no.ndla.taxonomy.rest.v1.dtos.searchapi.TaxonomyContextDTO;
import no.ndla.taxonomy.service.dtos.NodeDTO;
import no.ndla.taxonomy.util.HashUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletResponse;
Expand Down Expand Up @@ -402,14 +401,10 @@ public void that_contexts_can_be_found_by_path() throws Exception {
.contentUri("urn:article:1")
.publicId("urn:resource:1"))));
Node resource = nodeRepository.getByPublicId(URI.create("urn:resource:1"));
String hash = HashUtil.semiHash(root.getPublicId().toString()
+ resource.getParentConnections().stream()
.findFirst()
.get()
.getPublicId()
.toString());

var response = testUtils.getResource("/v1/queries/path?path=" + String.format("/one-fine-resource__%s", hash));
var response = testUtils.getResource("/v1/queries/path?path="
+ String.format(
"/one-fine-resource__%s",
resource.getContexts().stream().findFirst().get().contextId()));
var result = testUtils.getObject(TaxonomyContextDTO[].class, response);

assertEquals(1, result.length);
Expand Down
16 changes: 8 additions & 8 deletions src/test/java/no/ndla/taxonomy/util/HashUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public class HashUtilTest {

@Test
public void get_different_length_hashes() {
String shortHash = HashUtil.shortHash("original");
String mediumHash = HashUtil.mediumHash("original");
String semiHash = HashUtil.semiHash("original");
String longHash = HashUtil.longHash("original");
String fullHash = HashUtil.fullHash("original");
String shortHash = new HashUtil("original", "").shortHash();
String mediumHash = new HashUtil("original", "").mediumHash();
String semiHash = new HashUtil("original", "").semiHash();
String longHash = new HashUtil("original", "").longHash();
String fullHash = new HashUtil("original", "").fullHash();

assertEquals(4, shortHash.length());
assertEquals(8, mediumHash.length());
Expand All @@ -30,9 +30,9 @@ public void get_different_length_hashes() {

@Test
public void same_string_gives_same_hashes() {
String hash1 = HashUtil.mediumHash("original");
String hash2 = HashUtil.mediumHash("original");
String hash3 = HashUtil.longHash("original");
String hash1 = new HashUtil("original", "").mediumHash();
String hash2 = new HashUtil("original", "").mediumHash();
String hash3 = new HashUtil("original", "").longHash();
assertEquals(hash1, hash2);
assertTrue(hash3.startsWith(hash2));
}
Expand Down
Loading