Skip to content

Commit

Permalink
rename proxy to bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
mandelsoft committed Nov 28, 2023
1 parent 203c9ee commit d82a4f1
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 255 deletions.
77 changes: 77 additions & 0 deletions pkg/contexts/ocm/cpi/repocpi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Context Programming Interface for Repositories

Package repocpi contains the implementation support
for repository backends. It offers three methods
to create component version, component and repository
objects based on three simple implementation interfaces.

The basic provisioning model is layered:

![Implamentation Layers](ocmimpllayers.png)

- on layer 1 there is the *user facing API* defined
in package [github.com/open-component-model/ocm/pkg/contexts/ocm].

- on layer 2 (this package) there is a backend agnostic
implementation of standard functionality based on layer 3.
This is divided into two parts

a) the *view* objects provided by the `Dup()` calls of the layer 1 API.
All dups are internally based on a single base object.
These objects are called *bridge*. They act as base object
for the views and as abstraction for the implementation objects
providing *generic* implementations potentially based on
the implementation functionality.
(see bridge design pattern https://refactoring.guru/design-patterns/bridge)

b) the *bridge* object as base for all dup views is used to implement some
common functionality like the view management. The bridge object
is closed, when the last view disappears.
This bridge object then calls the final
storage backend implementation interface.

- the storage backend implementations based on the implementation
interfaces provided by layer 2.

The implementation interfaces and the functions to create API objects are:

- interface [ComponentVersionAccessImpl] is used to create an ocm.ComponentVersionAccess object
using the function [NewComponentVersionAccess].
- interface [ComponentAccessImpl] is used to create an ocm.ComponentAccess object
using the function [NewComponentAccess].
- interface [RepositoryImpl] is used to create an ocm.ComponentAccess object
using the function [NewRepository].

Component version implementations provide basic access to component versions
and their descriptors. They keep a reference to component implementations, which are
again based on repository implementations. The task of repository implementations is
to provide component objects. Their implementations are responsible to provide
component version objects.

## Simplified Respository Implementation Interface
Besides this basic implementation interfaces with separated objects for a
repository, component and component version, there is support for a simplified
implementation interface (`StorageBackendImpl`). This is a single interface
bundling all required functionality to implement the objects for the three
concerned elements. With `NewStorageBackend` it is possible to instantiate
a new kind of repository based on this single interface. The required
objects for components and component versions are generically provided
based on the methods provided by this interface.

## Comparison of Implementation Models

The simplified implementation model does not provide access to the
implementation objects for components and component versions.
Therefore, it is not possible to keep state for those elements.

Storage Backend Implementations requiring such state, like the OCI
implementation based on the OCI abstraction provided by the OCI
context, therefore use dedicated implementations for repository,
component and component version objects. This model provides
complete control over the lifecycle of those elements.

If a storage backend implementation is stateless or just keeps
state at the repository level, the simplified implementation model
can be chosen.


32 changes: 16 additions & 16 deletions pkg/contexts/ocm/cpi/repocpi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type StorageBackendImpl interface {
}

type storageBackendRepository struct {
proxy RepositoryProxy
bridge RepositoryBridge
closed atomic.Bool
noref cpi.Repository
kind string
Expand All @@ -78,9 +78,9 @@ func NewStorageBackend(kind string, impl StorageBackendImpl) cpi.Repository {
return NewRepository(backend, kind)
}

func (s *storageBackendRepository) SetProxy(proxy RepositoryProxy) {
s.proxy = proxy
s.noref = NewNoneRefRepositoryView(proxy)
func (s *storageBackendRepository) SetBridge(bridge RepositoryBridge) {
s.bridge = bridge
s.noref = NewNoneRefRepositoryView(bridge)
}

func (s *storageBackendRepository) Close() error {
Expand Down Expand Up @@ -124,19 +124,19 @@ func (s *storageBackendRepository) LookupComponent(name string) (*ComponentAcces
////////////////////////////////////////////////////////////////////////////////

type storageBackendComponent struct {
proxy ComponentAccessProxy
repo *storageBackendRepository
name string
bridge ComponentAccessBridge
repo *storageBackendRepository
name string
}

var _ ComponentAccessImpl = (*storageBackendComponent)(nil)

func (s *storageBackendComponent) SetProxy(proxy ComponentAccessProxy) {
s.proxy = proxy
func (s *storageBackendComponent) SetBridge(bridge ComponentAccessBridge) {
s.bridge = bridge
}

func (s *storageBackendComponent) GetParentProxy() RepositoryViewManager {
return s.repo.proxy
func (s *storageBackendComponent) GetParentBridge() RepositoryViewManager {
return s.repo.bridge
}

func (s *storageBackendComponent) Close() error {
Expand Down Expand Up @@ -213,7 +213,7 @@ func (s *storageBackendComponent) NewVersion(version string, overwrite ...bool)
////////////////////////////////////////////////////////////////////////////////

type storageBackendComponentVersion struct {
proxy ComponentVersionAccessProxy
bridge ComponentVersionAccessBridge
comp *storageBackendComponent
name common.NameVersion
descriptor *compdesc.ComponentDescriptor
Expand All @@ -229,12 +229,12 @@ func (s *storageBackendComponentVersion) GetContext() cpi.Context {
return s.comp.repo.impl.GetContext()
}

func (s *storageBackendComponentVersion) SetProxy(proxy ComponentVersionAccessProxy) {
s.proxy = proxy
func (s *storageBackendComponentVersion) SetBridge(bridge ComponentVersionAccessBridge) {
s.bridge = bridge
}

func (s *storageBackendComponentVersion) GetParentProxy() ComponentAccessProxy {
return s.comp.proxy
func (s *storageBackendComponentVersion) GetParentBridge() ComponentAccessBridge {
return s.comp.bridge
}

func (s *storageBackendComponentVersion) Repository() cpi.Repository {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type ComponentVersionAccessInfo struct {
// ComponentAccessImpl is the provider implementation
// interface for component versions.
type ComponentAccessImpl interface {
SetProxy(proxy ComponentAccessProxy)
GetParentProxy() RepositoryViewManager
SetBridge(bridge ComponentAccessBridge)
GetParentBridge() RepositoryViewManager

GetContext() cpi.Context
GetName() string
Expand All @@ -42,67 +42,67 @@ type ComponentAccessImpl interface {
io.Closer
}

type _componentAccessProxyBase = resource.ResourceImplBase[cpi.ComponentAccess]
type _componentAccessBridgeBase = resource.ResourceImplBase[cpi.ComponentAccess]

type componentAccessProxy struct {
*_componentAccessProxyBase
type componentAccessBridge struct {
*_componentAccessBridgeBase
ctx cpi.Context
name string
impl ComponentAccessImpl
}

func newComponentAccessProxy(impl ComponentAccessImpl, closer ...io.Closer) (ComponentAccessProxy, error) {
base, err := resource.NewResourceImplBase[cpi.ComponentAccess, cpi.Repository](impl.GetParentProxy(), closer...)
func newComponentAccessBridge(impl ComponentAccessImpl, closer ...io.Closer) (ComponentAccessBridge, error) {
base, err := resource.NewResourceImplBase[cpi.ComponentAccess, cpi.Repository](impl.GetParentBridge(), closer...)
if err != nil {
return nil, err
}
b := &componentAccessProxy{
_componentAccessProxyBase: base,
ctx: impl.GetContext(),
name: impl.GetName(),
impl: impl,
b := &componentAccessBridge{
_componentAccessBridgeBase: base,
ctx: impl.GetContext(),
name: impl.GetName(),
impl: impl,
}
impl.SetProxy(b)
impl.SetBridge(b)
return b, nil
}

func (b *componentAccessProxy) Close() error {
func (b *componentAccessBridge) Close() error {
list := errors.ErrListf("closing component %s", b.name)
refmgmt.AllocLog.Trace("closing component proxy", "name", b.name)
refmgmt.AllocLog.Trace("closing component bridge", "name", b.name)
list.Add(b.impl.Close())
list.Add(b._componentAccessProxyBase.Close())
refmgmt.AllocLog.Trace("closed component proxy", "name", b.name)
list.Add(b._componentAccessBridgeBase.Close())
refmgmt.AllocLog.Trace("closed component bridge", "name", b.name)
return list.Result()
}

func (b *componentAccessProxy) GetContext() cpi.Context {
func (b *componentAccessBridge) GetContext() cpi.Context {
return b.ctx
}

func (b *componentAccessProxy) GetName() string {
func (b *componentAccessBridge) GetName() string {
return b.name
}

func (b *componentAccessProxy) IsReadOnly() bool {
func (b *componentAccessBridge) IsReadOnly() bool {
return b.impl.IsReadOnly()
}

func (c *componentAccessProxy) IsOwned(cv cpi.ComponentVersionAccess) bool {
proxy, err := GetComponentVersionAccessProxy(cv)
func (c *componentAccessBridge) IsOwned(cv cpi.ComponentVersionAccess) bool {
bridge, err := GetComponentVersionAccessBridge(cv)
if err != nil {
return false
}

impl := proxy.(*componentVersionAccessProxy).impl
cvcompmgr := impl.GetParentProxy()
impl := bridge.(*componentVersionAccessBridge).impl
cvcompmgr := impl.GetParentBridge()
return c == cvcompmgr
}

func (b *componentAccessProxy) ListVersions() ([]string, error) {
func (b *componentAccessBridge) ListVersions() ([]string, error) {
return b.impl.ListVersions()
}

func (b *componentAccessProxy) LookupVersion(version string) (cpi.ComponentVersionAccess, error) {
func (b *componentAccessBridge) LookupVersion(version string) (cpi.ComponentVersionAccess, error) {
i, err := b.impl.LookupVersion(version)
if err != nil {
return nil, err
Expand All @@ -113,11 +113,11 @@ func (b *componentAccessProxy) LookupVersion(version string) (cpi.ComponentVersi
return NewComponentVersionAccess(b.GetName(), version, i.Impl, i.Lazy, i.Persistent, !compositionmodeattr.Get(b.GetContext()))
}

func (b *componentAccessProxy) HasVersion(vers string) (bool, error) {
func (b *componentAccessBridge) HasVersion(vers string) (bool, error) {
return b.impl.HasVersion(vers)
}

func (b *componentAccessProxy) NewVersion(version string, overrides ...bool) (cpi.ComponentVersionAccess, error) {
func (b *componentAccessBridge) NewVersion(version string, overrides ...bool) (cpi.ComponentVersionAccess, error) {
i, err := b.impl.NewVersion(version, overrides...)
if err != nil {
return nil, err
Expand All @@ -128,11 +128,11 @@ func (b *componentAccessProxy) NewVersion(version string, overrides ...bool) (cp
return NewComponentVersionAccess(b.GetName(), version, i.Impl, i.Lazy, false, !compositionmodeattr.Get(b.GetContext()))
}

func (c *componentAccessProxy) AddVersion(cv cpi.ComponentVersionAccess, opts *cpi.AddVersionOptions) (ferr error) {
func (c *componentAccessBridge) AddVersion(cv cpi.ComponentVersionAccess, opts *cpi.AddVersionOptions) (ferr error) {
var finalize finalizer.Finalizer
defer finalize.FinalizeWithErrorPropagation(&ferr)

cvproxy, err := GetComponentVersionAccessProxy(cv)
cvbridge, err := GetComponentVersionAccessBridge(cv)
if err != nil {
return err
}
Expand All @@ -146,28 +146,28 @@ func (c *componentAccessProxy) AddVersion(cv cpi.ComponentVersionAccess, opts *c
finalize.With(func() error {
return eff.Close()
})
cvproxy, err = GetComponentVersionAccessProxy(eff)
cvbridge, err = GetComponentVersionAccessBridge(eff)
if err != nil {
return err
}

d := eff.GetDescriptor()
*d = *cv.GetDescriptor().Copy()

err = c.setupLocalBlobs("resource", cv, cvproxy, d.Resources, &opts.BlobUploadOptions)
err = c.setupLocalBlobs("resource", cv, cvbridge, d.Resources, &opts.BlobUploadOptions)
if err == nil {
err = c.setupLocalBlobs("source", cv, cvproxy, d.Sources, &opts.BlobUploadOptions)
err = c.setupLocalBlobs("source", cv, cvbridge, d.Sources, &opts.BlobUploadOptions)
}
if err != nil {
return err
}
}
cvproxy.EnablePersistence()
err = cvproxy.Update(!cvproxy.UseDirectAccess())
cvbridge.EnablePersistence()
err = cvbridge.Update(!cvbridge.UseDirectAccess())
return err
}

func (c *componentAccessProxy) setupLocalBlobs(kind string, src cpi.ComponentVersionAccess, tgtproxy ComponentVersionAccessProxy, it compdesc.ArtifactAccessor, opts *cpi.BlobUploadOptions) (ferr error) {
func (c *componentAccessBridge) setupLocalBlobs(kind string, src cpi.ComponentVersionAccess, tgtbridge ComponentVersionAccessBridge, it compdesc.ArtifactAccessor, opts *cpi.BlobUploadOptions) (ferr error) {
ctx := src.GetContext()
// transfer all local blobs
prov := func(spec cpi.AccessSpec) (blob blobaccess.BlobAccess, ref string, global cpi.AccessSpec, err error) {
Expand All @@ -176,10 +176,10 @@ func (c *componentAccessProxy) setupLocalBlobs(kind string, src cpi.ComponentVer
if err != nil {
return nil, "", nil, err
}
return m.AsBlobAccess(), cpi.ReferenceHint(spec, src), cpi.GlobalAccess(spec, tgtproxy.GetContext()), nil
return m.AsBlobAccess(), cpi.ReferenceHint(spec, src), cpi.GlobalAccess(spec, tgtbridge.GetContext()), nil
}
return nil, "", nil, nil
}

return tgtproxy.(*componentVersionAccessProxy).setupLocalBlobs(kind, prov, it, false, opts)
return tgtbridge.(*componentVersionAccessBridge).setupLocalBlobs(kind, prov, it, false, opts)
}
Loading

0 comments on commit d82a4f1

Please sign in to comment.