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 }