github.com/cs3org/reva/v2@v2.27.7/pkg/mentix/exchangers/exchanger.go (about)

     1  // Copyright 2018-2021 CERN
     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  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package exchangers
    20  
    21  import (
    22  	"fmt"
    23  	"strings"
    24  	"sync"
    25  
    26  	"github.com/rs/zerolog"
    27  
    28  	"github.com/cs3org/reva/v2/pkg/mentix/config"
    29  	"github.com/cs3org/reva/v2/pkg/mentix/entity"
    30  	"github.com/cs3org/reva/v2/pkg/mentix/meshdata"
    31  )
    32  
    33  // Exchanger is the base interface for importers and exporters.
    34  type Exchanger interface {
    35  	entity.Entity
    36  
    37  	// Start starts the exchanger; only exchangers which perform periodical background tasks should do something here.
    38  	Start() error
    39  	// Stop stops any running background activities of the exchanger.
    40  	Stop()
    41  
    42  	// MeshData returns the mesh data.
    43  	MeshData() *meshdata.MeshData
    44  
    45  	// Update is called whenever the mesh data set has changed to reflect these changes.
    46  	Update(meshdata.Map) error
    47  }
    48  
    49  // BaseExchanger implements basic exchanger functionality common to all exchangers.
    50  type BaseExchanger struct {
    51  	Exchanger
    52  
    53  	conf *config.Configuration
    54  	log  *zerolog.Logger
    55  
    56  	enabledConnectors []string
    57  
    58  	meshData *meshdata.MeshData
    59  
    60  	locker sync.RWMutex
    61  }
    62  
    63  // Activate activates the exchanger.
    64  func (exchanger *BaseExchanger) Activate(conf *config.Configuration, log *zerolog.Logger) error {
    65  	if conf == nil {
    66  		return fmt.Errorf("no configuration provided")
    67  	}
    68  	exchanger.conf = conf
    69  
    70  	if log == nil {
    71  		return fmt.Errorf("no logger provided")
    72  	}
    73  	exchanger.log = log
    74  
    75  	return nil
    76  }
    77  
    78  // Start starts the exchanger; only exchangers which perform periodical background tasks should do something here.
    79  func (exchanger *BaseExchanger) Start() error {
    80  	return nil
    81  }
    82  
    83  // Stop stops any running background activities of the exchanger.
    84  func (exchanger *BaseExchanger) Stop() {
    85  }
    86  
    87  // IsConnectorEnabled checks if the given connector is enabled for the exchanger.
    88  func (exchanger *BaseExchanger) IsConnectorEnabled(id string) bool {
    89  	for _, connectorID := range exchanger.enabledConnectors {
    90  		if connectorID == "*" || strings.EqualFold(connectorID, id) {
    91  			return true
    92  		}
    93  	}
    94  	return false
    95  }
    96  
    97  // Update is called whenever the mesh data set has changed to reflect these changes.
    98  func (exchanger *BaseExchanger) Update(meshDataSet meshdata.Map) error {
    99  	// Update the stored mesh data set
   100  	if err := exchanger.storeMeshDataSet(meshDataSet); err != nil {
   101  		return fmt.Errorf("unable to store the mesh data: %v", err)
   102  	}
   103  
   104  	return nil
   105  }
   106  
   107  func (exchanger *BaseExchanger) storeMeshDataSet(meshDataSet meshdata.Map) error {
   108  	// Store the new mesh data set by cloning it and then merging the cloned data into one object
   109  	meshDataSetCloned := make(meshdata.Map)
   110  	for connectorID, meshData := range meshDataSet {
   111  		if !exchanger.IsConnectorEnabled(connectorID) {
   112  			continue
   113  		}
   114  
   115  		meshDataCloned := meshData.Clone()
   116  		if meshDataCloned == nil {
   117  			return fmt.Errorf("unable to clone the mesh data")
   118  		}
   119  
   120  		meshDataSetCloned[connectorID] = meshDataCloned
   121  	}
   122  	exchanger.setMeshData(meshdata.MergeMeshDataMap(meshDataSetCloned))
   123  
   124  	return nil
   125  }
   126  
   127  func (exchanger *BaseExchanger) cloneMeshData() *meshdata.MeshData {
   128  	exchanger.locker.RLock()
   129  	meshDataClone := exchanger.meshData.Clone()
   130  	exchanger.locker.RUnlock()
   131  
   132  	return meshDataClone
   133  }
   134  
   135  // Config returns the configuration object.
   136  func (exchanger *BaseExchanger) Config() *config.Configuration {
   137  	return exchanger.conf
   138  }
   139  
   140  // Log returns the logger object.
   141  func (exchanger *BaseExchanger) Log() *zerolog.Logger {
   142  	return exchanger.log
   143  }
   144  
   145  // EnabledConnectors returns the list of all enabled connectors for the exchanger.
   146  func (exchanger *BaseExchanger) EnabledConnectors() []string {
   147  	return exchanger.enabledConnectors
   148  }
   149  
   150  // SetEnabledConnectors sets the list of all enabled connectors for the exchanger.
   151  func (exchanger *BaseExchanger) SetEnabledConnectors(connectors []string) {
   152  	exchanger.enabledConnectors = connectors
   153  }
   154  
   155  // MeshData returns the stored mesh data. The returned data is cloned to prevent accidental data changes.
   156  // Unauthorized sites are also removed if this exchanger doesn't allow them.
   157  func (exchanger *BaseExchanger) MeshData() *meshdata.MeshData {
   158  	return exchanger.cloneMeshData()
   159  }
   160  
   161  func (exchanger *BaseExchanger) setMeshData(meshData *meshdata.MeshData) {
   162  	exchanger.locker.Lock()
   163  	defer exchanger.locker.Unlock()
   164  
   165  	exchanger.meshData = meshData
   166  }
   167  
   168  // Locker returns the locking object.
   169  func (exchanger *BaseExchanger) Locker() *sync.RWMutex {
   170  	return &exchanger.locker
   171  }