github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/chaincode/platforms/java/platform.go (about)

     1  /*
     2  Copyright DTCC 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 java
    18  
    19  import (
    20  	"archive/tar"
    21  	"bytes"
    22  	"compress/gzip"
    23  	"errors"
    24  	"fmt"
    25  	"net/url"
    26  	"strings"
    27  
    28  	cutil "github.com/hyperledger/fabric/core/container/util"
    29  	pb "github.com/hyperledger/fabric/protos/peer"
    30  	//	"path/filepath"
    31  )
    32  
    33  // Platform for java chaincodes in java
    34  type Platform struct {
    35  }
    36  
    37  var buildCmds = map[string]string{
    38  	"src/build.gradle": "gradle -b build.gradle clean && gradle -b build.gradle build",
    39  	"src/pom.xml":      "mvn -f pom.xml clean && mvn -f pom.xml package",
    40  }
    41  
    42  //getBuildCmd returns the type of build gradle/maven based on the file
    43  //found in java chaincode project root
    44  //build.gradle - gradle  - returns the first found build type
    45  //pom.xml - maven
    46  func getBuildCmd(codePackage []byte) (string, error) {
    47  
    48  	is := bytes.NewReader(codePackage)
    49  	gr, err := gzip.NewReader(is)
    50  	if err != nil {
    51  		return "", fmt.Errorf("failure opening gzip stream: %s", err)
    52  	}
    53  	tr := tar.NewReader(gr)
    54  
    55  	for {
    56  		header, err := tr.Next()
    57  		if err != nil {
    58  			return "", errors.New("Build file not found")
    59  		}
    60  
    61  		if cmd, ok := buildCmds[header.Name]; ok == true {
    62  			return cmd, nil
    63  		}
    64  	}
    65  }
    66  
    67  //ValidateSpec validates the java chaincode specs
    68  func (javaPlatform *Platform) ValidateSpec(spec *pb.ChaincodeSpec) error {
    69  	path, err := url.Parse(spec.ChaincodeId.Path)
    70  	if err != nil || path == nil {
    71  		return fmt.Errorf("invalid path: %s", err)
    72  	}
    73  
    74  	//we have no real good way of checking existence of remote urls except by downloading and testing
    75  	//which we do later anyway. But we *can* - and *should* - test for existence of local paths.
    76  	//Treat empty scheme as a local filesystem path
    77  	//	if url.Scheme == "" {
    78  	//		pathToCheck := filepath.Join(os.Getenv("GOPATH"), "src", spec.ChaincodeId.Path)
    79  	//		exists, err := pathExists(pathToCheck)
    80  	//		if err != nil {
    81  	//			return fmt.Errorf("Error validating chaincode path: %s", err)
    82  	//		}
    83  	//		if !exists {
    84  	//			return fmt.Errorf("Path to chaincode does not exist: %s", spec.ChaincodeId.Path)
    85  	//		}
    86  	//	}
    87  	return nil
    88  }
    89  
    90  func (javaPlatform *Platform) ValidateDeploymentSpec(cds *pb.ChaincodeDeploymentSpec) error {
    91  	// FIXME: Java platform needs to implement its own validation similar to GOLANG
    92  	return nil
    93  }
    94  
    95  // WritePackage writes the java chaincode package
    96  func (javaPlatform *Platform) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
    97  
    98  	var err error
    99  
   100  	inputbuf := bytes.NewBuffer(nil)
   101  	gw := gzip.NewWriter(inputbuf)
   102  	tw := tar.NewWriter(gw)
   103  
   104  	//ignore the generated hash. Just use the tw
   105  	//The hash could be used in a future enhancement
   106  	//to check, warn of duplicate installs etc.
   107  	_, err = collectChaincodeFiles(spec, tw)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	err = writeChaincodePackage(spec, tw)
   113  
   114  	tw.Close()
   115  	gw.Close()
   116  
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	payload := inputbuf.Bytes()
   122  
   123  	return payload, nil
   124  }
   125  
   126  func (javaPlatform *Platform) GenerateDockerfile(cds *pb.ChaincodeDeploymentSpec) (string, error) {
   127  	var err error
   128  	var buf []string
   129  
   130  	buildCmd, err := getBuildCmd(cds.CodePackage)
   131  	if err != nil {
   132  		return "", err
   133  	}
   134  
   135  	buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
   136  	buf = append(buf, "ADD codepackage.tgz /root/chaincode")
   137  	buf = append(buf, "RUN  cd /root/chaincode/src && "+buildCmd)
   138  	buf = append(buf, "RUN  cp /root/chaincode/src/build/chaincode.jar /root")
   139  	buf = append(buf, "RUN  cp /root/chaincode/src/build/libs/* /root/libs")
   140  
   141  	dockerFileContents := strings.Join(buf, "\n")
   142  
   143  	return dockerFileContents, nil
   144  }
   145  
   146  func (javaPlatform *Platform) GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec, tw *tar.Writer) error {
   147  	return cutil.WriteBytesToPackage("codepackage.tgz", cds.CodePackage, tw)
   148  }