Skip to content

Commit

Permalink
Fixes/updates to PREMIS event recording (#19)
Browse files Browse the repository at this point in the history
* Renamed event adding functions
* Fixed PREMIS event recording to add one event per file
* Updated PREMIS event recording and tests to work with updated
  transfer structure
* Return subpaths within transfer, instead of absolute paths, in file
  format validator list of failures
  • Loading branch information
mcantelon committed Aug 19, 2024
1 parent 819e9c5 commit 7a5f516
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 85 deletions.
2 changes: 1 addition & 1 deletion internal/activities/add_premis_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (md *AddPREMISEventActivity) Execute(
return nil, err
}

err = premis.AppendEventXML(doc, eventSummary, params.Agent)
err = premis.AppendEventXMLForEachObject(doc, eventSummary, params.Agent)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/activities/add_premis_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (md *AddPREMISObjectsActivity) Execute(
object := premis.Object{
IdType: "UUID",
IdValue: uuid.New().String(),
OriginalName: premis.OriginalNameForSubpath(subpath),
OriginalName: premis.OriginalNameForSubpath(params.ContentPath, subpath),
}

err = premis.AppendObjectXML(doc, object)
Expand Down
4 changes: 2 additions & 2 deletions internal/activities/validate_file_formats.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ func (a *ValidateFileFormats) Execute(
}

// Append PREMIS event to XML and write results.
originalName := premis.OriginalNameForSubpath(subpath)
originalName := premis.OriginalNameForSubpath(params.ContentPath, subpath)

doc, err := premis.ParseOrInitialize(params.PREMISFilePath)
if err != nil {
return err
}

err = premis.AppendEventAndLinkToObject(doc, eventSummary, params.Agent, originalName)
err = premis.AppendEventXMLForSingleObject(doc, eventSummary, params.Agent, originalName)
if err != nil {
return err
}
Expand Down
55 changes: 38 additions & 17 deletions internal/activities/validate_file_formats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package activities_test

import (
"fmt"
"path/filepath"
"testing"

temporalsdk_activity "go.temporal.io/sdk/activity"
Expand Down Expand Up @@ -29,7 +30,7 @@ const premisValidFormatsContent = `<?xml version="1.0" encoding="UTF-8"?>
</premis:formatDesignation>
</premis:format>
</premis:objectCharacteristics>
<premis:originalName>data/objects/dir/file1.txt</premis:originalName>
<premis:originalName>data/objects/dir/content/file1.txt</premis:originalName>
</premis:object>
<premis:object xsi:type="premis:file">
<premis:objectIdentifier>
Expand All @@ -43,7 +44,7 @@ const premisValidFormatsContent = `<?xml version="1.0" encoding="UTF-8"?>
</premis:formatDesignation>
</premis:format>
</premis:objectCharacteristics>
<premis:originalName>data/objects/file2.txt</premis:originalName>
<premis:originalName>data/objects/dir/content/dir/file2.txt</premis:originalName>
</premis:object>
</premis:premis>
`
Expand All @@ -62,7 +63,7 @@ const premisInvalidFormatsContent = `<?xml version="1.0" encoding="UTF-8"?>
</premis:formatDesignation>
</premis:format>
</premis:objectCharacteristics>
<premis:originalName>data/objects/dir/file1.png</premis:originalName>
<premis:originalName>data/objects/test_transfer/content/dir/file1.png</premis:originalName>
</premis:object>
<premis:object xsi:type="premis:file">
<premis:objectIdentifier>
Expand All @@ -76,21 +77,46 @@ const premisInvalidFormatsContent = `<?xml version="1.0" encoding="UTF-8"?>
</premis:formatDesignation>
</premis:format>
</premis:objectCharacteristics>
<premis:originalName>data/objects/file2.png</premis:originalName>
<premis:originalName>data/objects/test_transfer/content/file2.png</premis:originalName>
</premis:object>
</premis:premis>
`

func TestValidateFileFormats(t *testing.T) {
t.Parallel()

invalidFormatsPath := fs.NewDir(t, "",
fs.WithDir("dir",
fs.WithFile("file1.png", pngContent),
invalidFormatsTransferPath := fs.NewDir(t, "",
fs.WithDir("test_transfer",
fs.WithDir("content",
fs.WithDir("content",
fs.WithFile("file2.png", pngContent),
fs.WithDir("dir",
fs.WithFile("file1.png", pngContent),
),
),
),
),
).Path()

invalidFormatsContentPath := filepath.Join(invalidFormatsTransferPath, "test_transfer", "content", "content")

validFormatsTransferPath := fs.NewDir(t, "",
fs.WithDir("data",
fs.WithDir("dir",
fs.WithDir("content",
fs.WithDir("content",
fs.WithFile("file1.txt", "content"),
fs.WithDir("dir",
fs.WithFile("file2.txt", "content"),
),
),
),
),
),
fs.WithFile("file2.png", pngContent),
).Path()

validFormatsContentPath := filepath.Join(validFormatsTransferPath, "data", "dir", "content", "content")

tests := []struct {
name string
params activities.ValidateFileFormatsParams
Expand All @@ -101,12 +127,7 @@ func TestValidateFileFormats(t *testing.T) {
{
name: "Successes with valid formats",
params: activities.ValidateFileFormatsParams{
ContentPath: fs.NewDir(t, "",
fs.WithDir("dir",
fs.WithFile("file1.txt", "content"),
),
fs.WithFile("file2.txt", "content"),
).Path(),
ContentPath: validFormatsContentPath,
PREMISFilePath: fs.NewFile(t, "premis.xml",
fs.WithContent(premisValidFormatsContent),
).Path(),
Expand All @@ -117,7 +138,7 @@ func TestValidateFileFormats(t *testing.T) {
{
name: "Fails with invalid formats",
params: activities.ValidateFileFormatsParams{
ContentPath: invalidFormatsPath,
ContentPath: invalidFormatsContentPath,
PREMISFilePath: fs.NewFile(t, "premis.xml",
fs.WithContent(premisInvalidFormatsContent),
).Path(),
Expand All @@ -128,12 +149,12 @@ func TestValidateFileFormats(t *testing.T) {
fmt.Sprintf(
`file format %q not allowed: "%s/dir/file1.png"`,
"fmt/11",
invalidFormatsPath,
invalidFormatsContentPath,
),
fmt.Sprintf(
`file format %q not allowed: "%s/file2.png"`,
"fmt/11",
invalidFormatsPath,
invalidFormatsContentPath,
),
},
},
Expand Down
52 changes: 25 additions & 27 deletions internal/premis/premis.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func AppendObjectXML(doc *etree.Document, object Object) error {
return nil
}

func AppendEventAndLinkToObject(
func AppendEventXMLForSingleObject(
doc *etree.Document,
eventSummary EventSummary,
agent Agent,
Expand All @@ -168,42 +168,46 @@ func AppendEventAndLinkToObject(
return err
}

// Define PREMIS event.
event := eventFromEventSummaryAndAgent(eventSummary, agent)

// Add PREMIS event element and, if necessary, agent element.
addEventElement(PREMISEl, event)

// Attempt to get object using originalName.
objectEl, err := FindObjectByOriginalName(PREMISEl, originalName)
if err != nil {
return err
}

// Add event for object, if found.
if objectEl != nil {
LinkEventToObject(objectEl, event)
appendEventXMLForObjects(PREMISEl, eventSummary, agent, []*etree.Element{objectEl})
} else {
return fmt.Errorf("append event and link to object: object '%s' not found", originalName)
return fmt.Errorf("append event and link to object: object '%s' not found as premis originalname", originalName)
}

return nil
}

func AppendEventXML(doc *etree.Document, eventSummary EventSummary, agent Agent) error {
func AppendEventXMLForEachObject(doc *etree.Document, eventSummary EventSummary, agent Agent) error {
PREMISEl, err := getRoot(doc)
if err != nil {
return err
}

// Define PREMIS event.
event := eventFromEventSummaryAndAgent(eventSummary, agent)
// Add events for each existing object.
objectEls := PREMISEl.FindElements("//premis:object")
appendEventXMLForObjects(PREMISEl, eventSummary, agent, objectEls)

// Add PREMIS event element and, if necessary, agent element.
addEventElement(PREMISEl, event)
return nil
}

func appendEventXMLForObjects(PREMISEl *etree.Element, eventSummary EventSummary, agent Agent, objectEls []*etree.Element) {
for _, objectEl := range objectEls {
// Define PREMIS event.
event := eventFromEventSummaryAndAgent(eventSummary, agent)

// Add a link to this event to every PREMIS object.
linkEventToObjects(PREMISEl, event)
// Add PREMIS event element and, if necessary, agent element.
addEventElement(PREMISEl, event)

return nil
// Link event to object
LinkEventToObject(objectEl, event)
}
}

func AppendAgentXML(doc *etree.Document, agent Agent) error {
Expand Down Expand Up @@ -286,14 +290,6 @@ func addEventElement(PREMISEl *etree.Element, event Event) {
addEventAgentIdentifierElement(eventEl, event)
}

func linkEventToObjects(PREMISEl *etree.Element, eventFull Event) {
objectEls := PREMISEl.FindElements("//premis:object")

for _, objectEl := range objectEls {
LinkEventToObject(objectEl, eventFull)
}
}

func LinkEventToObject(objectEl *etree.Element, eventFull Event) {
linkEventIdEl := objectEl.CreateElement("premis:linkingEventIdentifier")

Expand Down Expand Up @@ -418,14 +414,16 @@ func FilesWithinDirectory(contentPath string) ([]string, error) {
return subpaths, nil
}

func OriginalNameForSubpath(subpath string) string {
func OriginalNameForSubpath(contentPath string, subpath string) string {
transferDirName := filepath.Base(filepath.Dir(filepath.Dir(contentPath)))

if filepath.Base(subpath) == "Prozess_Digitalisierung_PREMIS.xml" {
// This file later gets renamed in TransformSIP.
parentDirName := filepath.Base(filepath.Dir(subpath))
filename := fmt.Sprintf("Prozess_Digitalisierung_PREMIS_%s.xml", parentDirName)
return filepath.Join("data", "metadata", filename)
} else {
return filepath.Join("data", "objects", subpath)
return filepath.Join("data", "objects", transferDirName, "content", subpath)
}
}

Expand Down
Loading

0 comments on commit 7a5f516

Please sign in to comment.