-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Save entry list compressed in extension state (#416)
* Save entry list compressed in extension state * address review feedback
- Loading branch information
1 parent
f04e971
commit f2f0817
Showing
8 changed files
with
495 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package common | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/andybalholm/brotli" | ||
) | ||
|
||
type compressedEntriesState struct { | ||
CompressedState []byte `json:"compressedState"` | ||
} | ||
|
||
// CompressEntriesState compresses the entries state data. | ||
func CompressEntriesState(state []byte) ([]byte, error) { | ||
if len(state) == 0 || string(state) == "{}" { | ||
return nil, nil | ||
} | ||
|
||
var stateCompressed bytes.Buffer | ||
writer := brotli.NewWriter(&stateCompressed) | ||
defer writer.Close() | ||
|
||
if _, err := writer.Write(state); err != nil { | ||
return nil, fmt.Errorf("failed writing entries state data for compression: %w", err) | ||
} | ||
|
||
// Close ensures any unwritten data is flushed. Without this, the `stateCompressed` | ||
// buffer would not contain any data. Hence, we have to call it explicitly here after writing, in addition to the | ||
// 'defer' call above. | ||
if err := writer.Close(); err != nil { | ||
return nil, fmt.Errorf("failed closing the brotli writer after compressing the entries state data: %w", err) | ||
} | ||
|
||
return json.Marshal(&compressedEntriesState{CompressedState: stateCompressed.Bytes()}) | ||
} | ||
|
||
// LooksLikeCompressedEntriesState checks if the given state data has the string compressedState in the first 20 bytes. | ||
func LooksLikeCompressedEntriesState(state []byte) bool { | ||
if len(state) < len("compressedState") { | ||
return false | ||
} | ||
|
||
return bytes.Contains(state[:min(20, len(state))], []byte("compressedState")) | ||
} | ||
|
||
// DecompressEntriesState decompresses the entries state data. | ||
func DecompressEntriesState(stateCompressed []byte) ([]byte, error) { | ||
if len(stateCompressed) == 0 { | ||
return nil, nil | ||
} | ||
|
||
var entriesState compressedEntriesState | ||
if err := json.Unmarshal(stateCompressed, &entriesState); err != nil { | ||
return nil, fmt.Errorf("failed unmarshalling JSON to compressed entries state structure: %w", err) | ||
} | ||
|
||
reader := brotli.NewReader(bytes.NewReader(entriesState.CompressedState)) | ||
var state bytes.Buffer | ||
if _, err := state.ReadFrom(reader); err != nil { | ||
return nil, fmt.Errorf("failed reading machine state data for decompression: %w", err) | ||
} | ||
|
||
return state.Bytes(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// SPDX-FileCopyrightText: 2025 SAP SE or an SAP affiliate company and Gardener contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package common | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("CompressedState", func() { | ||
It("should compress and decompress", func() { | ||
state := []byte(`{"entries":[{"name":"entry1","spec":{}},{"name":"entry2","spec":{}}]}`) | ||
data, err := CompressEntriesState(state) | ||
Expect(err).To(BeNil()) | ||
Expect(data).NotTo(BeNil()) | ||
|
||
state2, err := DecompressEntriesState(data) | ||
Expect(err).To(BeNil()) | ||
Expect(state2).NotTo(BeNil()) | ||
Expect(state).To(Equal(state2)) | ||
}) | ||
|
||
It("should recognise compressed state data by heuristic", func() { | ||
state := []byte(`{"entries":[{"name":"entry1","spec":{}},{"name":"entry2","spec":{}}]}`) | ||
data, err := CompressEntriesState(state) | ||
Expect(err).To(BeNil()) | ||
Expect(data).NotTo(BeNil()) | ||
|
||
Expect(LooksLikeCompressedEntriesState(data)).To(BeTrue()) | ||
Expect(LooksLikeCompressedEntriesState(state)).To(BeFalse()) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package lifecycle_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestLifecycle(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Lifecycle Suite") | ||
} |
Oops, something went wrong.