github.com/defanghe/fabric@v2.1.1+incompatible/core/chaincode/platforms/java/platform.go (about) 1 /* 2 Copyright DTCC 2016 All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package java 8 9 import ( 10 "archive/tar" 11 "bytes" 12 "compress/gzip" 13 "errors" 14 "fmt" 15 "io" 16 "net/url" 17 "regexp" 18 "strings" 19 20 pb "github.com/hyperledger/fabric-protos-go/peer" 21 "github.com/hyperledger/fabric/common/flogging" 22 "github.com/hyperledger/fabric/core/chaincode/platforms/util" 23 ) 24 25 var logger = flogging.MustGetLogger("chaincode.platform.java") 26 27 // Platform for java chaincodes in java 28 type Platform struct{} 29 30 // Name returns the name of this platform 31 func (p *Platform) Name() string { 32 return pb.ChaincodeSpec_JAVA.String() 33 } 34 35 //ValidatePath validates the java chaincode paths 36 func (p *Platform) ValidatePath(rawPath string) error { 37 path, err := url.Parse(rawPath) 38 if err != nil || path == nil { 39 logger.Errorf("invalid chaincode path %s %v", rawPath, err) 40 return fmt.Errorf("invalid path: %s", err) 41 } 42 43 return nil 44 } 45 46 func (p *Platform) ValidateCodePackage(code []byte) error { 47 // File to be valid should match first RegExp and not match second one. 48 filesToMatch := regexp.MustCompile(`^(/)?src/((src|META-INF)/.*|(build\.gradle|settings\.gradle|pom\.xml))`) 49 filesToIgnore := regexp.MustCompile(`.*\.class$`) 50 is := bytes.NewReader(code) 51 gr, err := gzip.NewReader(is) 52 if err != nil { 53 return fmt.Errorf("failure opening codepackage gzip stream: %s", err) 54 } 55 tr := tar.NewReader(gr) 56 57 for { 58 header, err := tr.Next() 59 if err == io.EOF { 60 break 61 } 62 if err != nil { 63 return err 64 } 65 66 // -------------------------------------------------------------------------------------- 67 // Check name for conforming path 68 // -------------------------------------------------------------------------------------- 69 if !filesToMatch.MatchString(header.Name) || filesToIgnore.MatchString(header.Name) { 70 return fmt.Errorf("illegal file detected in payload: \"%s\"", header.Name) 71 } 72 73 // -------------------------------------------------------------------------------------- 74 // Check that file mode makes sense 75 // -------------------------------------------------------------------------------------- 76 // Acceptable flags: 77 // ISREG == 0100000 78 // -rw-rw-rw- == 0666 79 // 80 // Anything else is suspect in this context and will be rejected 81 // -------------------------------------------------------------------------------------- 82 if header.Mode&^0100666 != 0 { 83 return fmt.Errorf("illegal file mode detected for file %s: %o", header.Name, header.Mode) 84 } 85 } 86 return nil 87 } 88 89 // WritePackage writes the java chaincode package 90 func (p *Platform) GetDeploymentPayload(path string) ([]byte, error) { 91 logger.Debugf("Packaging java project from path %s", path) 92 93 if path == "" { 94 logger.Error("ChaincodeSpec's path cannot be empty") 95 return nil, errors.New("ChaincodeSpec's path cannot be empty") 96 } 97 98 // trim trailing slash if it exists 99 if path[len(path)-1] == '/' { 100 path = path[:len(path)-1] 101 } 102 103 buf := &bytes.Buffer{} 104 gw := gzip.NewWriter(buf) 105 tw := tar.NewWriter(gw) 106 107 excludedDirs := []string{"target", "build", "out"} 108 excludedFileTypes := map[string]bool{".class": true} 109 err := util.WriteFolderToTarPackage(tw, path, excludedDirs, nil, excludedFileTypes) 110 if err != nil { 111 logger.Errorf("Error writing java project to tar package %s", err) 112 return nil, fmt.Errorf("failed to create chaincode package: %s", err) 113 } 114 115 tw.Close() 116 gw.Close() 117 118 return buf.Bytes(), nil 119 } 120 121 func (p *Platform) GenerateDockerfile() (string, error) { 122 var buf []string 123 124 buf = append(buf, "FROM "+util.GetDockerImageFromConfig("chaincode.java.runtime")) 125 buf = append(buf, "ADD binpackage.tar /root/chaincode-java/chaincode") 126 127 dockerFileContents := strings.Join(buf, "\n") 128 129 return dockerFileContents, nil 130 } 131 132 func (p *Platform) DockerBuildOptions(path string) (util.DockerBuildOptions, error) { 133 return util.DockerBuildOptions{ 134 Image: util.GetDockerImageFromConfig("chaincode.java.runtime"), 135 Cmd: "./build.sh", 136 }, nil 137 }