github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/ledger/blkstorage/fsblkstorage/fs_blockstore_provider.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package fsblkstorage
     8  
     9  import (
    10  	"os"
    11  
    12  	"github.com/hyperledger/fabric/common/ledger/blkstorage"
    13  	"github.com/hyperledger/fabric/common/ledger/dataformat"
    14  	"github.com/hyperledger/fabric/common/ledger/util"
    15  	"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
    16  	"github.com/hyperledger/fabric/common/metrics"
    17  	"github.com/pkg/errors"
    18  )
    19  
    20  func dataFormatVersion(indexConfig *blkstorage.IndexConfig) string {
    21  	// in version 2.0 we merged three indexable into one `IndexableAttrTxID`
    22  	if indexConfig.Contains(blkstorage.IndexableAttrTxID) {
    23  		return dataformat.Version20
    24  	}
    25  	return dataformat.Version1x
    26  }
    27  
    28  // FsBlockstoreProvider provides handle to block storage - this is not thread-safe
    29  type FsBlockstoreProvider struct {
    30  	conf            *Conf
    31  	indexConfig     *blkstorage.IndexConfig
    32  	leveldbProvider *leveldbhelper.Provider
    33  	stats           *stats
    34  }
    35  
    36  // NewProvider constructs a filesystem based block store provider
    37  func NewProvider(conf *Conf, indexConfig *blkstorage.IndexConfig, metricsProvider metrics.Provider) (blkstorage.BlockStoreProvider, error) {
    38  	dbConf := &leveldbhelper.Conf{
    39  		DBPath:                conf.getIndexDir(),
    40  		ExpectedFormatVersion: dataFormatVersion(indexConfig),
    41  	}
    42  
    43  	p, err := leveldbhelper.NewProvider(dbConf)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	dirPath := conf.getChainsDir()
    49  	if _, err := os.Stat(dirPath); err != nil {
    50  		if !os.IsNotExist(err) { // NotExist is the only permitted error type
    51  			return nil, errors.Wrapf(err, "failed to read ledger directory %s", dirPath)
    52  		}
    53  
    54  		logger.Info("Creating new file ledger directory at", dirPath)
    55  		if err = os.MkdirAll(dirPath, 0755); err != nil {
    56  			return nil, errors.Wrapf(err, "failed to create ledger directory: %s", dirPath)
    57  		}
    58  	}
    59  
    60  	// create stats instance at provider level and pass to newFsBlockStore
    61  	stats := newStats(metricsProvider)
    62  	return &FsBlockstoreProvider{conf, indexConfig, p, stats}, nil
    63  }
    64  
    65  // CreateBlockStore simply calls OpenBlockStore
    66  func (p *FsBlockstoreProvider) CreateBlockStore(ledgerid string) (blkstorage.BlockStore, error) {
    67  	return p.OpenBlockStore(ledgerid)
    68  }
    69  
    70  // OpenBlockStore opens a block store for given ledgerid.
    71  // If a blockstore is not existing, this method creates one
    72  // This method should be invoked only once for a particular ledgerid
    73  func (p *FsBlockstoreProvider) OpenBlockStore(ledgerid string) (blkstorage.BlockStore, error) {
    74  	indexStoreHandle := p.leveldbProvider.GetDBHandle(ledgerid)
    75  	return newFsBlockStore(ledgerid, p.conf, p.indexConfig, indexStoreHandle, p.stats), nil
    76  }
    77  
    78  // Exists tells whether the BlockStore with given id exists
    79  func (p *FsBlockstoreProvider) Exists(ledgerid string) (bool, error) {
    80  	exists, _, err := util.FileExists(p.conf.getLedgerBlockDir(ledgerid))
    81  	return exists, err
    82  }
    83  
    84  // List lists the ids of the existing ledgers
    85  func (p *FsBlockstoreProvider) List() ([]string, error) {
    86  	return util.ListSubdirs(p.conf.getChainsDir())
    87  }
    88  
    89  // Close closes the FsBlockstoreProvider
    90  func (p *FsBlockstoreProvider) Close() {
    91  	p.leveldbProvider.Close()
    92  }