Skip to content

Commit d1df59f

Browse files
authored
feat: Implement plugin system for archivists' parsers (#295)
* feat: Implement plugin system for archivists' parsers This commit introduces a flexible plugin system for archivists' parsers, allowing new parsers to be registered dynamically. The system utilizes an initialization function that registers parsers via a `Register` function. The primary changes include: - Creation of `parser_registry.go` to handle parser registration and storage. - Modification of `parserstorer.go` to integrate the new parser registration system and utilize registered parsers during attestation storage. This system enhances the extensibility of the parser functionality and improves maintainability by decoupling the parser registration from the core logic. Changes: - Added `internal/metadatastorage/attestationcollection/parser_registry.go` for parser registration. - Updated `internal/metadatastorage/attestationcollection/parserstorer.go` to support the new plugin system. --------- Signed-off-by: Frederick F. Kautz IV <[email protected]>
1 parent 2eab116 commit d1df59f

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2024 The Archivista Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package attestationcollection
16+
17+
import (
18+
"context"
19+
"encoding/json"
20+
"github.com/in-toto/archivista/ent"
21+
"log"
22+
)
23+
24+
var registeredParsers map[string]AttestationParser
25+
26+
func init() {
27+
registeredParsers = make(map[string]AttestationParser)
28+
}
29+
30+
func Register(attestationType string, parser AttestationParser) {
31+
registeredParsers[attestationType] = parser
32+
log.Printf("parser registered: %s", attestationType)
33+
}
34+
35+
type AttestationParser func(ctx context.Context, tx *ent.Tx, attestation *ent.Attestation, attestationType string, message json.RawMessage) error
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2024 The Archivista Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package attestationcollection
16+
17+
import (
18+
"context"
19+
"encoding/json"
20+
"testing"
21+
22+
"github.com/in-toto/archivista/ent"
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
func TestRegister(t *testing.T) {
27+
// Define a mock parser function
28+
mockParser := func(ctx context.Context, tx *ent.Tx, attestation *ent.Attestation, attestationType string, message json.RawMessage) error {
29+
return nil
30+
}
31+
32+
// Register the mock parser
33+
Register("mockType", mockParser)
34+
35+
// Check if the parser is registered
36+
registeredParser, exists := registeredParsers["mockType"]
37+
var typedParser AttestationParser = mockParser
38+
assert.True(t, exists, "Parser should be registered")
39+
assert.IsType(t, typedParser, registeredParser, "Registered parser should match the mock parser")
40+
}

pkg/metadatastorage/attestationcollection/parserstorer.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ package attestationcollection
1717
import (
1818
"context"
1919
"encoding/json"
20-
2120
"github.com/google/uuid"
2221
"github.com/in-toto/archivista/ent"
2322
"github.com/in-toto/archivista/pkg/metadatastorage"
2423
"github.com/in-toto/go-witness/attestation"
24+
"github.com/in-toto/go-witness/log"
2525
)
2626

2727
const (
@@ -58,12 +58,21 @@ func (parsedCollection ParsedCollection) Store(ctx context.Context, tx *ent.Tx,
5858
}
5959

6060
for _, a := range parsedCollection.Attestations {
61-
if err := tx.Attestation.Create().
61+
newAttestation, err := tx.Attestation.Create().
6262
SetAttestationCollectionID(collection.ID).
6363
SetType(a.Type).
64-
Exec(ctx); err != nil {
64+
Save(ctx)
65+
if err != nil {
6566
return err
6667
}
68+
69+
// we parse if a parser is available. otherwise, we ignore it if no parser is available.
70+
if parser, exists := registeredParsers[a.Type]; exists {
71+
if err := parser(ctx, tx, newAttestation, a.Type, a.Attestation); err != nil {
72+
log.Errorf("failed to parse attestation of type %s: %w", a.Type, err)
73+
return err
74+
}
75+
}
6776
}
6877

6978
return nil

0 commit comments

Comments
 (0)