github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/messaging/msghandler/msghandler.go (about)

     1  /*
     2   *
     3   * Copyright SecureKey Technologies Inc. All Rights Reserved.
     4   *
     5   * SPDX-License-Identifier: Apache-2.0
     6   * /
     7   *
     8   */
     9  
    10  // Package msghandler dynamically maintains the list of registered message services.
    11  //
    12  // In addition to returning list of available message services as a message service provider implementation,
    13  // this message handler also provides register/unregister functionality which can be used to add/remove
    14  // message services from already running agent.
    15  //
    16  // (RFC Reference : https://github.com/hyperledger/aries-rfcs/blob/master/features/0351-purpose-decorator/README.md)
    17  //
    18  package msghandler
    19  
    20  import (
    21  	"fmt"
    22  	"sync"
    23  
    24  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
    25  )
    26  
    27  const (
    28  	errAlreadyRegistered = "registration failed, message service with name `%s` already registered"
    29  	errNeverRegistered   = "failed to unregister, unable to find registered message service with name `%s`"
    30  )
    31  
    32  // NewRegistrar returns new message registrar instance.
    33  func NewRegistrar() *Registrar {
    34  	return &Registrar{}
    35  }
    36  
    37  // Registrar is message service provider implementation which maintains list of registered message service
    38  // and also allows dynamic register/unregister of message services.
    39  type Registrar struct {
    40  	services []dispatcher.MessageService
    41  	lock     sync.RWMutex
    42  }
    43  
    44  // Services returns list of message services registered to this handler.
    45  func (m *Registrar) Services() []dispatcher.MessageService {
    46  	m.lock.RLock()
    47  	defer m.lock.RUnlock()
    48  
    49  	svcs := make([]dispatcher.MessageService, len(m.services))
    50  	copy(svcs, m.services)
    51  
    52  	return svcs
    53  }
    54  
    55  // Register registers given message services to this handler,
    56  // returns error in case of duplicate registration.
    57  func (m *Registrar) Register(msgServices ...dispatcher.MessageService) error {
    58  	if len(msgServices) == 0 {
    59  		return nil
    60  	}
    61  
    62  	m.lock.Lock()
    63  	defer m.lock.Unlock()
    64  
    65  	// if current list is empty, add all
    66  	if len(m.services) == 0 {
    67  		m.services = append(m.services, msgServices...)
    68  		return nil
    69  	}
    70  
    71  	// if current list is not empty, then look for duplicates before adding
    72  	for _, newMsgSvc := range msgServices {
    73  		for _, existingSvc := range m.services {
    74  			if existingSvc.Name() == newMsgSvc.Name() {
    75  				return fmt.Errorf(errAlreadyRegistered, newMsgSvc.Name())
    76  			}
    77  		}
    78  	}
    79  
    80  	m.services = append(m.services, msgServices...)
    81  
    82  	return nil
    83  }
    84  
    85  // Unregister unregisters message service with given name from this message handler,
    86  // returns error if given message service doesn't exists.
    87  func (m *Registrar) Unregister(name string) error {
    88  	m.lock.Lock()
    89  	defer m.lock.Unlock()
    90  
    91  	index := -1
    92  
    93  	for i, svc := range m.services {
    94  		if svc.Name() == name {
    95  			index = i
    96  
    97  			break
    98  		}
    99  	}
   100  
   101  	if index < 0 {
   102  		return fmt.Errorf(errNeverRegistered, name)
   103  	}
   104  
   105  	m.services = append(m.services[:index], m.services[index+1:]...)
   106  
   107  	return nil
   108  }