Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trying to connect to a kubernetes cluster created with tools/operator using java SDK #304

Open
ymolists opened this issue Mar 10, 2021 · 5 comments

Comments

@ymolists
Copy link

ymolists commented Mar 10, 2021

I am super new to fabric. Can someone please point me to how i would go about connecting a java app using the fabric java SDK ? I can contribute a sample app as a PR if that would be something people can use.

I am trying to make sense of this fabric-samples java project. I noticed the operator generates connection profiles and ca certs for all orgs. However its not clicking how my client can talk to the cluster stood up by the operator using those generated files.

Can anyone help ?

@ymolists ymolists changed the title trying to connect to a kubernetes cluster created with tools/operator trying to connect to a kubernetes cluster created with tools/operator using java SDK Mar 10, 2021
@ymolists
Copy link
Author

ymolists commented Mar 11, 2021

//        public static boolean USE_PROFILE = true;
    public static boolean USE_PROFILE = false;

    public static String BUILD_DIR = "build/fabric-000";
    public static String CRYPTO_DIR = BUILD_DIR + "/crypto-config";

    public static String ORG1_PEER = CRYPTO_DIR + "/peerOrganizations/org1";
    public static String ORG1_ORDERER = CRYPTO_DIR + "/ordererOrganizations/ordererorg1";

    public static String ORG1_CA_CERT = ORG1_PEER + "/ca/ca.org1-cert.pem";
//    public static String ORG1_CA_CERT =ORG1_ORDERER+"/ca/ca.ordererorg1-cert.pem";

    public static String ORG1_CONNECTION_PROFILE = "connection-profile/connection_profile_org1.yaml";
//    public static String ORG1_SERVER_CERT = "orderers/orderer0-ordererorg1.ordererorg1/tls/server.crt";


    private static NetworkConfig networkConfig;

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

        File yamlFile = Paths.get(BUILD_DIR, ORG1_CONNECTION_PROFILE).toFile();
        networkConfig = NetworkConfig.fromYamlFile(yamlFile);

        networkConfig.getOrdererNames().forEach(ordererName -> {
            try {
                System.out.println("orderer: " + ordererName);

                Properties ordererProperties = networkConfig.getOrdererProperties(ordererName);
                Properties testProp = getEndPointProperties("orderer", ordererName);
                ordererProperties.setProperty("clientCertFile", testProp.getProperty("clientCertFile"));
                ordererProperties.setProperty("clientKeyFile", testProp.getProperty("clientKeyFile"));
                networkConfig.setOrdererProperties(ordererName, ordererProperties);
            } catch (InvalidArgumentException e) {
                throw new RuntimeException(e);
            }
        });

        networkConfig.getPeerNames().forEach(peerName -> {
            try {
                System.out.println("peer: " + peerName);

                Properties peerProperties = networkConfig.getPeerProperties(peerName);
                Properties testProp = getEndPointProperties("peer", peerName);
                peerProperties.setProperty("clientCertFile", testProp.getProperty("clientCertFile"));
                peerProperties.setProperty("clientKeyFile", testProp.getProperty("clientKeyFile"));
                networkConfig.setPeerProperties(peerName, peerProperties);

            } catch (InvalidArgumentException e) {
                throw new RuntimeException(e);
            }
        });

        HFCAClient hfcaClient;

        if (USE_PROFILE) {
            //Check if we get access to defined CAs!
            NetworkConfig.OrgInfo org = networkConfig.getOrganizationInfo("org1");
            NetworkConfig.CAInfo caInfo = org.getCertificateAuthorities().get(0);
            Properties caProps = caInfo.getProperties();

            hfcaClient = HFCAClient.createNewInstance(caInfo);
            CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite();
            hfcaClient.setCryptoSuite(cryptoSuite);
            caProps.put("allowAllHostNames", "true");
            System.out.println("hfcaClient CAName:" + hfcaClient.getCAName());

//            props.put("pemBytes", (byte[]) pemBytes);
//            Object pemBytes = caProps.get("pemBytes");
//            if (!(pemBytes instanceof byte[])) {
//                throw new RuntimeException("Expecting bytes in pemBytes");
//            }
        } else {
            File pemFile = Paths.get(ORG1_CA_CERT).toFile();
            if (!pemFile.exists()) {
                throw new RuntimeException(String.format("Missing pem file Could not find at location: %s", pemFile.getAbsolutePath()));
            }

            Properties props = new Properties();
            props.put("allowAllHostNames", "true");
            props.put("pemFile", pemFile.getAbsolutePath());

            hfcaClient = HFCAClient.createNewInstance("https://localhost:7054", props);
            CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite();
            hfcaClient.setCryptoSuite(cryptoSuite);
        }

        HFCAInfo info = hfcaClient.info(); //makes actual REST call.
        System.out.println("info CAName:" + info.getCAName());

//        Collection<NetworkConfig.UserInfo> registrars = caInfo.getRegistrars();
//        NetworkConfig.UserInfo registrar = registrars.iterator().next();
//        registrar.setEnrollment(hfcaClient.enroll(registrar.getName(), registrar.getEnrollSecret()));
    }

in both cases (when i enable using the profile or when i use the pem file directly i get this :

orderer: orderer0-ordererorg1
peer: peer0-org1
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:325)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:268)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1340)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1215)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1158)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:445)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:423)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1475)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1381)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:412)
	at org.apache.http.conn.ssl.SSLSocketFactory.createLayeredSocket(SSLSocketFactory.java:570)
	at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:554)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.hyperledger.fabric_ca.sdk.HFCAClient.httpPost(HFCAClient.java:1326)
	at org.hyperledger.fabric_ca.sdk.HFCAClient.info(HFCAClient.java:559)
	at application.java.Network.main(Network.java:104)

@lindluni
Copy link
Contributor

lindluni commented Mar 11, 2021

@mbwhite Im not sure what unable to find valid certification path to requested target means in the error stack, is it looking for a truststore rather than a single pem?

Any chance you can provide some insight here, as I don't think it's an actual issue with the network we generate from the operator tool.

I'll end by saying I've never actually used the Java SDK, so my insight here is limited.

@mbwhite
Copy link
Member

mbwhite commented Mar 11, 2021

@bestbeforetoday might be the best placed if I'm honest from a client SDK perspective.

@ymolists to clarify were you deploying Fabric into K8S using your own deployments?

@lindluni
Copy link
Contributor

lindluni commented Mar 11, 2021

Thank Matthew. He is using our Fabric-Test tool to deploy the network. I know interacting with the network with the Node SDK works with no caveats, but I've never used the Java SDK for anything.

@ymolists
Copy link
Author

@mbwhite as @Iindluni said am using fabric-test/tools/operator to deploy the cluster on k8s.

i observed the following on the ca-org1 pod

ca
2021/03/11 17:31:12 [INFO] The issuer key was successfully stored. The public key is at: /etc/hyperledger/fabric-ca-server/IssuerPublicKey, secret key is at: /etc/hyperledger/fabric-ca-server/msp/keystore/IssuerSecretKey
ca
2021/03/11 17:31:12 [DEBUG] Intializing revocation authority for issuer 'ca0-org1'
ca
2021/03/11 17:31:12 [DEBUG] Initialize Idemix issuer revocation key material
ca
2021/03/11 17:31:12 [INFO] Idemix issuer revocation public and secret keys were generated for CA 'ca0-org1'
ca
2021/03/11 17:31:12 [INFO] The revocation key was successfully stored. The public key is at: /etc/hyperledger/fabric-ca-server/IssuerRevocationPublicKey, private key is at: /etc/hyperledger/fabric-ca-server/msp/keystore/IssuerRevocationPrivateKey
ca
2021/03/11 17:31:12 [DEBUG] Intializing nonce manager for issuer 'ca0-org1'
ca
2021/03/11 17:31:12 [INFO] Home directory for default CA: /etc/hyperledger/fabric-ca-server
ca
2021/03/11 17:31:12 [DEBUG] 1 CA instance(s) running on server
ca
2021/03/11 17:31:12 [INFO] Operation Server Listening on 127.0.0.1:9443
ca
2021/03/11 17:31:12 [DEBUG] TLS is enabled
ca
2021/03/11 17:31:12 [DEBUG] TLS Certificate: /etc/hyperledger/fabric/artifacts/tlsca.org1-cert.pem, TLS Key: /etc/hyperledger/fabric/artifacts/tlsca-priv_sk
ca
2021/03/11 17:31:12 [DEBUG] Could not load TLS certificate with BCCSP: Could not find matching private key for SKI: Failed getting key for SKI [[243 56 28 210 58 129 20 52 139 112 209 223 11 153 56 252 91 213 147 18 125 184 245 193 9 67 8 183 128 57 154 255]]: Key with SKI f3381cd23a8114348b70d1df0b9938fc5bd593127db8f5c1094308b780399aff not found in /etc/hyperledger/fabric-ca-server/msp/keystore
ca
2021/03/11 17:31:12 [DEBUG] Attempting fallback with certfile /etc/hyperledger/fabric/artifacts/tlsca.org1-cert.pem and keyfile /etc/hyperledger/fabric/artifacts/tlsca-priv_sk
ca
2021/03/11 17:31:12 [DEBUG] Client authentication type requested: noclientcert
ca
2021/03/11 17:31:12 [INFO] Listening on https://0.0.0.0:7054

it seems like the container is not able to load the ca cert file and defaulting to use the tls cert instead. ? After i noticed that i changed my above java code to use the tls cert instead of the ca cert i was using and voila !

here is where i used the the tls certs in the new code

I checked the cert saved in the connection profile by the fabric-test tool is using the ca cert not the tls cert ? that section of the code is failing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants