github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/common/ccprovider/targzmetadataprovider.go (about)

     1  /*
     2  # Copyright State Street Corp. All Rights Reserved.
     3  #
     4  # SPDX-License-Identifier: Apache-2.0
     5  */
     6  package ccprovider
     7  
     8  import (
     9  	"archive/tar"
    10  	"bytes"
    11  	"compress/gzip"
    12  	"io"
    13  	"strings"
    14  )
    15  
    16  // The targz metadata provider is reference for other providers (such as what CAR would
    17  // implement). Currently it treats only statedb metadata but will be generalized in future
    18  // to allow for arbitrary metadata to be packaged with the chaincode.
    19  const (
    20  	ccPackageStatedbDir = "META-INF/statedb/"
    21  )
    22  
    23  type PersistenceAdapter func([]byte) ([]byte, error)
    24  
    25  func (pa PersistenceAdapter) GetDBArtifacts(codePackage []byte) ([]byte, error) {
    26  	return pa(codePackage)
    27  }
    28  
    29  // MetadataAsTarEntries extracts metadata from a chaincode package
    30  func MetadataAsTarEntries(code []byte) ([]byte, error) {
    31  	is := bytes.NewReader(code)
    32  	gr, err := gzip.NewReader(is)
    33  	if err != nil {
    34  		ccproviderLogger.Errorf("Failure opening codepackage gzip stream: %s", err)
    35  		return nil, err
    36  	}
    37  
    38  	statedbTarBuffer := bytes.NewBuffer(nil)
    39  	tw := tar.NewWriter(statedbTarBuffer)
    40  
    41  	tr := tar.NewReader(gr)
    42  
    43  	// For each file in the code package tar,
    44  	// add it to the statedb artifact tar if it has "statedb" in the path
    45  	for {
    46  		header, err := tr.Next()
    47  		if err == io.EOF {
    48  			// We only get here if there are no more entries to scan
    49  			break
    50  		}
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  
    55  		if !strings.HasPrefix(header.Name, ccPackageStatedbDir) {
    56  			continue
    57  		}
    58  
    59  		if err = tw.WriteHeader(header); err != nil {
    60  			ccproviderLogger.Error("Error adding header to statedb tar:", err, header.Name)
    61  			return nil, err
    62  		}
    63  		if _, err := io.Copy(tw, tr); err != nil {
    64  			ccproviderLogger.Error("Error copying file to statedb tar:", err, header.Name)
    65  			return nil, err
    66  		}
    67  		ccproviderLogger.Debug("Wrote file to statedb tar:", header.Name)
    68  	}
    69  
    70  	if err = tw.Close(); err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	ccproviderLogger.Debug("Created metadata tar")
    75  
    76  	return statedbTarBuffer.Bytes(), nil
    77  }