Skip to content

Commit

Permalink
FGJ-4 Fabcar sample
Browse files Browse the repository at this point in the history
Implementation of Fabcar client for Java Gateway SDK
Changes to first-network to generate the CCP files with
embedded PEM certificates rather than paths to files on disk

Change-Id: Iff15425e96ce28c6f96079cee474c35868fab554
Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>

FGJ-4 split java fabcar into separate classes

Incorporate review comments from previous CR
Split enroll/register/transactions into separate classes

Change-Id: I384cec59c7f53a37864bfc28be11e785a61421f3
Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>

FGJ-4 add license header to fabcar java sample

Change-Id: Ic658fe3bdece9875ca3ceaf28d94c5fb48879083
Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>
  • Loading branch information
andrew-coleman authored and Simon Stone committed Jul 30, 2019
1 parent 597d150 commit 171a7d2
Show file tree
Hide file tree
Showing 18 changed files with 458 additions and 196 deletions.
5 changes: 5 additions & 0 deletions fabcar/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/bin/
/target/
.settings/
.classpath
.project
56 changes: 56 additions & 0 deletions fabcar/java/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fabcar-java</groupId>
<artifactId>fabcar-java</artifactId>
<version>1.4.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>hyperledger</id>
<name>Hyperledger Nexus</name>
<url>https://nexus.hyperledger.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.hyperledger.fabric</groupId>
<artifactId>fabric-gateway-java</artifactId>
<version>1.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.12.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
52 changes: 52 additions & 0 deletions fabcar/java/src/main/java/org/example/ClientApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
SPDX-License-Identifier: Apache-2.0
*/

package org.example;

import java.nio.file.Path;
import java.nio.file.Paths;

import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Wallet;

public class ClientApp {

public static void main(String[] args) throws Exception {
// Load a file system based wallet for managing identities.
Path walletPath = Paths.get("wallet");
Wallet wallet = Wallet.createFileSystemWallet(walletPath);

// load a CCP
Path networkConfigPath = Paths.get("..", "..", "first-network", "connection-org1.yaml");

Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, "user1").networkConfig(networkConfigPath).discovery(true);

// create a gateway connection
try (Gateway gateway = builder.connect()) {

// get the network and contract
Network network = gateway.getNetwork("mychannel");
Contract contract = network.getContract("fabcar");

byte[] result;

result = contract.evaluateTransaction("queryAllCars");
System.out.println(new String(result));

contract.submitTransaction("createCar", "CAR10", "VW", "Polo", "Grey", "Mary");

result = contract.evaluateTransaction("queryCar", "CAR10");
System.out.println(new String(result));

contract.submitTransaction("changeCarOwner", "CAR10", "Archie");

result = contract.evaluateTransaction("queryCar", "CAR10");
System.out.println(new String(result));
}
}

}
50 changes: 50 additions & 0 deletions fabcar/java/src/main/java/org/example/EnrollAdmin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
SPDX-License-Identifier: Apache-2.0
*/

package org.example;

import java.nio.file.Paths;
import java.util.Properties;

import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.gateway.Wallet.Identity;
import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory;
import org.hyperledger.fabric_ca.sdk.EnrollmentRequest;
import org.hyperledger.fabric_ca.sdk.HFCAClient;

public class EnrollAdmin {

public static void main(String[] args) throws Exception {

// Create a CA client for interacting with the CA.
Properties props = new Properties();
props.put("pemFile",
"../../first-network/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem");
props.put("allowAllHostNames", "true");
HFCAClient caClient = HFCAClient.createNewInstance("https://localhost:7054", props);
CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite();
caClient.setCryptoSuite(cryptoSuite);

// Create a wallet for managing identities
Wallet wallet = Wallet.createFileSystemWallet(Paths.get("wallet"));

// Check to see if we've already enrolled the admin user.
boolean adminExists = wallet.exists("admin");
if (adminExists) {
System.out.println("An identity for the admin user \"admin\" already exists in the wallet");
return;
}

// Enroll the admin user, and import the new identity into the wallet.
final EnrollmentRequest enrollmentRequestTLS = new EnrollmentRequest();
enrollmentRequestTLS.addHost("localhost");
enrollmentRequestTLS.setProfile("tls");
Enrollment enrollment = caClient.enroll("admin", "adminpw", enrollmentRequestTLS);
Identity user = Identity.createIdentity("Org1MSP", enrollment.getCert(), enrollment.getKey());
wallet.put("admin", user);
System.out.println("Successfully enrolled user \"admin\" and imported it into the wallet");
}
}
107 changes: 107 additions & 0 deletions fabcar/java/src/main/java/org/example/RegisterUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
SPDX-License-Identifier: Apache-2.0
*/

package org.example;

import java.nio.file.Paths;
import java.security.PrivateKey;
import java.util.Properties;
import java.util.Set;

import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.gateway.Wallet.Identity;
import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.User;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;

public class RegisterUser {

public static void main(String[] args) throws Exception {

// Create a CA client for interacting with the CA.
Properties props = new Properties();
props.put("pemFile",
"../../first-network/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem");
props.put("allowAllHostNames", "true");
HFCAClient caClient = HFCAClient.createNewInstance("https://localhost:7054", props);
CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite();
caClient.setCryptoSuite(cryptoSuite);

// Create a wallet for managing identities
Wallet wallet = Wallet.createFileSystemWallet(Paths.get("wallet"));

// Check to see if we've already enrolled the user.
boolean userExists = wallet.exists("user1");
if (userExists) {
System.out.println("An identity for the user \"user1\" already exists in the wallet");
return;
}

userExists = wallet.exists("admin");
if (!userExists) {
System.out.println("\"admin\" needs to be enrolled and added to the wallet first");
return;
}

Identity adminIdentity = wallet.get("admin");
User admin = new User() {

@Override
public String getName() {
return "admin";
}

@Override
public Set<String> getRoles() {
return null;
}

@Override
public String getAccount() {
return null;
}

@Override
public String getAffiliation() {
return "org1.department1";
}

@Override
public Enrollment getEnrollment() {
return new Enrollment() {

@Override
public PrivateKey getKey() {
return adminIdentity.getPrivateKey();
}

@Override
public String getCert() {
return adminIdentity.getCertificate();
}
};
}

@Override
public String getMspId() {
return "Org1MSP";
}

};

// Register the user, enroll the user, and import the new identity into the wallet.
RegistrationRequest registrationRequest = new RegistrationRequest("user1");
registrationRequest.setAffiliation("org1.department1");
registrationRequest.setEnrollmentID("user1");
String enrollmentSecret = caClient.register(registrationRequest, admin);
Enrollment enrollment = caClient.enroll("user1", enrollmentSecret);
Identity user = Identity.createIdentity("Org1MSP", enrollment.getCert(), enrollment.getKey());
wallet.put("user1", user);
System.out.println("Successfully enrolled user \"user1\" and imported it into the wallet");
}

}
17 changes: 17 additions & 0 deletions fabcar/java/src/test/java/org/example/ClientTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
SPDX-License-Identifier: Apache-2.0
*/

package org.example;

import org.junit.Test;

public class ClientTest {

@Test
public void testFabCar() throws Exception {
EnrollAdmin.main(null);
RegisterUser.main(null);
ClientApp.main(null);
}
}
Empty file added fabcar/java/wallet/.gitkeep
Empty file.
3 changes: 1 addition & 2 deletions fabcar/javascript/enrollAdmin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ async function main() {

// Create a new CA client for interacting with the CA.
const caInfo = ccp.certificateAuthorities['ca.org1.example.com'];
const caTLSCACertsPath = path.resolve(__dirname, '..', '..', 'first-network', caInfo.tlsCACerts.path);
const caTLSCACerts = fs.readFileSync(caTLSCACertsPath);
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);

// Create a new file system based wallet for managing identities.
Expand Down
15 changes: 15 additions & 0 deletions fabcar/startFabric.sh
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,19 @@ TypeScript:
return all cars, but you can update the application to evaluate other transactions:
node dist/query
Java:
Start by changing into the "java" directory:
cd java
Then, install dependencies and run the test using:
mvn test
The test will invoke the sample client app which perform the following:
- Enroll admin and user1 and import them into the wallet (if they don't already exist there)
- Submit a transaction to create a new car
- Evaluate a transaction (query) to return details of this car
- Submit a transaction to change the owner of this car
- Evaluate a transaction (query) to return the updated details of this car
EOF
3 changes: 1 addition & 2 deletions fabcar/typescript/src/enrollAdmin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ async function main() {

// Create a new CA client for interacting with the CA.
const caInfo = ccp.certificateAuthorities['ca.org1.example.com'];
const caTLSCACertsPath = path.resolve(__dirname, '..', '..', '..', 'first-network', caInfo.tlsCACerts.path);
const caTLSCACerts = fs.readFileSync(caTLSCACertsPath);
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);

// Create a new file system based wallet for managing identities.
Expand Down
2 changes: 2 additions & 0 deletions first-network/byfn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ function generateCerts() {
exit 1
fi
echo
echo "Generate CCP files for Org1 and Org2"
./ccp-generate.sh
}

# The `configtxgen tool is used to create four artifacts: orderer **bootstrap
Expand Down
49 changes: 49 additions & 0 deletions first-network/ccp-generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

function one_line_pem {
echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`"
}

function json_ccp {
local PP=$(one_line_pem $5)
local CP=$(one_line_pem $6)
sed -e "s/\${ORG}/$1/" \
-e "s/\${P0PORT}/$2/" \
-e "s/\${P1PORT}/$3/" \
-e "s/\${CAPORT}/$4/" \
-e "s#\${PEERPEM}#$PP#" \
-e "s#\${CAPEM}#$CP#" \
ccp-template.json
}

function yaml_ccp {
local PP=$(one_line_pem $5)
local CP=$(one_line_pem $6)
sed -e "s/\${ORG}/$1/" \
-e "s/\${P0PORT}/$2/" \
-e "s/\${P1PORT}/$3/" \
-e "s/\${CAPORT}/$4/" \
-e "s#\${PEERPEM}#$PP#" \
-e "s#\${CAPEM}#$CP#" \
ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g'
}

ORG=1
P0PORT=7051
P1PORT=8051
CAPORT=7054
PEERPEM=crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
CAPEM=crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem

echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org1.json
echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org1.yaml

ORG=2
P0PORT=9051
P1PORT=10051
CAPORT=8054
PEERPEM=crypto-config/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
CAPEM=crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem

echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org2.json
echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org2.yaml
Loading

0 comments on commit 171a7d2

Please sign in to comment.