github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/ledger/ledgermgmt/ledger_mgmt.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package ledgermgmt 18 19 import ( 20 "errors" 21 "sync" 22 23 "fmt" 24 25 "github.com/hyperledger/fabric/core/ledger" 26 "github.com/hyperledger/fabric/core/ledger/kvledger" 27 logging "github.com/op/go-logging" 28 ) 29 30 var logger = logging.MustGetLogger("ledgermgmt") 31 32 // ErrLedgerAlreadyOpened is thrown by a CreateLedger call if a ledger with the given id is already opened 33 var ErrLedgerAlreadyOpened = errors.New("Ledger already opened") 34 35 // ErrLedgerMgmtNotInitialized is thrown when ledger mgmt is used before initializing this 36 var ErrLedgerMgmtNotInitialized = errors.New("ledger mgmt should be initialized before using") 37 38 var openedLedgers map[string]ledger.PeerLedger 39 var ledgerProvider ledger.PeerLedgerProvider 40 var lock sync.Mutex 41 var initialized bool 42 var once sync.Once 43 44 // Initialize initializes ledgermgmt 45 func Initialize() { 46 once.Do(func() { 47 initialize() 48 }) 49 } 50 51 func initialize() { 52 logger.Info("Initializing ledger mgmt") 53 lock.Lock() 54 defer lock.Unlock() 55 initialized = true 56 openedLedgers = make(map[string]ledger.PeerLedger) 57 provider, err := kvledger.NewProvider() 58 if err != nil { 59 panic(fmt.Errorf("Error in instantiating ledger provider: %s", err)) 60 } 61 ledgerProvider = provider 62 logger.Info("ledger mgmt initialized") 63 } 64 65 // CreateLedger creates a new ledger with the given id 66 func CreateLedger(id string) (ledger.PeerLedger, error) { 67 logger.Infof("Creating leadger with id = %s", id) 68 lock.Lock() 69 defer lock.Unlock() 70 if !initialized { 71 return nil, ErrLedgerMgmtNotInitialized 72 } 73 l, err := ledgerProvider.Create(id) 74 if err != nil { 75 return nil, err 76 } 77 l = wrapLedger(id, l) 78 openedLedgers[id] = l 79 logger.Infof("Created leadger with id = %s", id) 80 return l, nil 81 } 82 83 // OpenLedger returns a ledger for the given id 84 func OpenLedger(id string) (ledger.PeerLedger, error) { 85 logger.Infof("Opening leadger with id = %s", id) 86 lock.Lock() 87 defer lock.Unlock() 88 if !initialized { 89 return nil, ErrLedgerMgmtNotInitialized 90 } 91 l, ok := openedLedgers[id] 92 if ok { 93 return nil, ErrLedgerAlreadyOpened 94 } 95 l, err := ledgerProvider.Open(id) 96 if err != nil { 97 return nil, err 98 } 99 l = wrapLedger(id, l) 100 openedLedgers[id] = l 101 logger.Infof("Opened leadger with id = %s", id) 102 return l, nil 103 } 104 105 // GetLedgerIDs returns the ids of the ledgers created 106 func GetLedgerIDs() ([]string, error) { 107 lock.Lock() 108 defer lock.Unlock() 109 if !initialized { 110 return nil, ErrLedgerMgmtNotInitialized 111 } 112 return ledgerProvider.List() 113 } 114 115 // Close closes all the opened ledgers and any resources held for ledger management 116 func Close() { 117 logger.Infof("Closing ledger mgmt") 118 lock.Lock() 119 defer lock.Unlock() 120 if !initialized { 121 return 122 } 123 for _, l := range openedLedgers { 124 l.(*closableLedger).closeWithoutLock() 125 } 126 ledgerProvider.Close() 127 openedLedgers = nil 128 logger.Infof("ledger mgmt closed") 129 } 130 131 func wrapLedger(id string, l ledger.PeerLedger) ledger.PeerLedger { 132 return &closableLedger{id, l} 133 } 134 135 // closableLedger extends from actual validated ledger and overwrites the Close method 136 type closableLedger struct { 137 id string 138 ledger.PeerLedger 139 } 140 141 // Close closes the actual ledger and removes the entries from opened ledgers map 142 func (l *closableLedger) Close() { 143 lock.Lock() 144 defer lock.Unlock() 145 l.closeWithoutLock() 146 } 147 148 func (l *closableLedger) closeWithoutLock() { 149 l.PeerLedger.Close() 150 delete(openedLedgers, l.id) 151 }