- Print
- DarkLight
Requirements
- Knowing your Host Name: it corresponds to your Darwinium Node and consists of two words which are prefixed onto the Darwinium domain:
- Created and deployed a Darwinium journey with API Steps, obtaining:
- Journey Name
- API Step Name
These complete the URL path: /api/event/<journeyname>/<stepname>
- Gone through self-serve certificate signingin Portal, obtaining:
- Private key that you generated
- Darwinium certificate that you downloaded from the Darwinium Portal to use as authentication to the Darwinium AP
Python
import requests
import json
import ssl
import http.client
# Generate certificate through Portal > API Access > Add certificate
# Ensure in Portal, set permission to node you want to call as true
certificate_path = '/path/to/certificate/dwn_api__Darwinium.pem'
private_key_path = '/path/to/private.key'
password = 'pass' # If a password was applied on private key
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.load_cert_chain(certfile=certificate_path,
keyfile=private_key_path,
password=password)
# Find node subdomain name in Portal. API Helper provides this also
host = '{your}-{node}.node.darwinidentity.com'
url = '/api/event/{yourjourney}/{yourstep}'
# API request data in JSON format
body = {
'journey_id': '123456789abcdef883ecd14399547569',
# For schema help: Portal > Workflows > {yourjourney}.journey.yaml > {yourstep}
# 'Help me construct API' opens API Helper for params and nesting
}
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
try:
connection = http.client.HTTPSConnection(host, port=9443, context=context)
connection.request(method='POST',
url=url,
headers=headers,
body=json.dumps(body))
response = connection.getresponse()
# Process response
print(response.status, response.reason)
data = json.loads(response.read())
except requests.exceptions.RequestException as e:
print('Error:', e)
JavaScript
// Generate certificate through Portal > API Access > Add certificate
// Ensure in Portal, set permission to node you want to call as true
const certificatePath = '/path/to/certificate/dwn_api__Darwinium.pem';
const privateKeyPath = '/path/to/private.key';
// Find node subdomain name in Portal. API Helper provides this also
const apiUrl = 'https://{your-node}.node.darwinidentity.com:9443/api/event/{yourjourney}/{yourstep}';
const https = require('https');
const fs = require('fs');
const certificate = fs.readFileSync(certificatePath);
const privateKey = fs.readFileSync(privateKeyPath);
const requestData = {
journey_id: '123456789abcdef883ecd14399547569'
// For schema help: Portal > Workflows > {yourjourney}.journey.yaml > {yourstep}
// 'Help me construct API' opens API Helper for params and nesting
};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(requestData),
cert: certificate,
key: privateKey,
passphrase: 'pass' // If a passphrase was applied on private key
};
// Make the API call
const req = https.request(apiUrl, options, response => {
let data = '';
response.on('data', chunk => {
data += chunk;
});
response.on('end', () => {
// Process the API response here
console.log(data);
});
});
req.on('error', error => {
console.error('Error:', error);
});
req.write(JSON.stringify(requestData));
req.end();
Java
The following shell command needs to be run for java ecosystem. Since the JDK support for DER formatted private keys is better, it is recommended that one convert the PEM format private key file generated in the step above be converted into DER format.
openssl rsa -inform pem -in privateKey.pem -outform der -out privateKey.der
Pass the path of this DER private key file in the documented java example:
Example Class:
package com.darwinium.java.examples;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONObject;
import java.security.cert.Certificate;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class DWNApiRequestSubmitter {
public boolean SubmitApiRequest(String apiServerUrl, String certificateFilePath, String privateKeyFilePath,
String password, JSONObject jsonParam) {
try {
HttpClient client = createHttpsClient(certificateFilePath, privateKeyFilePath, password);
postRequest(client, jsonParam, apiServerUrl);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void postRequest(HttpClient client, JSONObject jsonParam, String url) throws Exception {
HttpPost post = new HttpPost(url);
StringEntity entity = new StringEntity(jsonParam.toString());
post.setEntity(entity);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(post);
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
}
public HttpClient createHttpsClient(String certificateFilePath, String privateKeyFilePath, String password)
throws Exception {
Certificate certificate = readCertificateFromFile(certificateFilePath);
// PrivateKey privateKey = readRSAPKCS8PrivateKeyFromFile(privateKeyFilePath);
PrivateKey privateKey = readRSAPrivateKeyFromDERFile(privateKeyFilePath, password);
SSLContext sslContext = createSSLContext(certificate, privateKey, password);
HttpClientBuilder builder = HttpClients.custom().setSSLContext(sslContext);
return builder.build();
}
public static Certificate readCertificateFromFile(String filePath) throws Exception {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(fis);
fis.close();
return certificate;
}
public static PrivateKey readRSAPKCS8PrivateKeyFromFile(String filePath) throws Exception {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
byte[] keyBytes = new byte[(int) file.length()];
fis.read(keyBytes);
fis.close();
String privateKeyPEM = new String(keyBytes, StandardCharsets.UTF_8)
.replace("-----BEGIN PRIVATE KEY-----", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PRIVATE KEY-----", "");
byte[] decodedKey = Base64.getDecoder().decode(privateKeyPEM);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
return keyFactory.generatePrivate(keySpec);
}
public static PrivateKey readRSAPrivateKeyFromDERFile(String filePath, String password) throws Exception {
byte[] keyBytes = Files.readAllBytes(Paths.get(filePath));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
public static SSLContext createSSLContext(Certificate certificate, PrivateKey privateKey, String passphrase)
throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null);
keyStore.setCertificateEntry("certificate", certificate);
keyStore.setKeyEntry("privateKey", privateKey, passphrase.toCharArray(), new Certificate[] { certificate });
// keyStore.setKeyEntry("privateKey", privateKey, null, new Certificate[] {
// certificate });
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, passphrase.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
return sslContext;
}
}
Example usage of using class to call the API:
package com.darwinium.java.examples;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import javax.net.ssl.SSLContext;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
public class DWNApiRequestSubmitterTest {
private DWNApiRequestSubmitter classUnderTest = new DWNApiRequestSubmitter();
@Rule
public TestName testName = new TestName();
@Before
public void setup() {
classUnderTest = new DWNApiRequestSubmitter();
System.out.println("Start " + testName.getMethodName());
}
@Test
public void test_APIServerCall() {
String jsonString = "{\"identity\":{\"ACCOUNT\":{\"name\":{\"first\": \"Andy\"}}}}";
JSONObject jsonPayload = new JSONObject(jsonString);
boolean responseStatusFlag = classUnderTest.SubmitApiRequest(
"https://first-second.node.darwinidentity.com:9443/api/event/journeyname/stepname",
"/path/to/dwn_api_Darwinium_signed_certificate.pem",
"/path/to/privatekey_DER_format.der",
"password",
jsonPayload);
assertEquals(true, responseStatusFlag);
}
}
Postman
The following steps describe how to configure Postman to make Event API Calls to validate your Journey API Step.
Within Postman navigate to the settings menu by selecting the cog icon on the top menu bar on the right hand side. Then from the Settings menu select certificates and click add new certificate.
1. In the Host field enter the hostname and port for the Journey API Step endpoint.
2. The CRT file should be the dwn_api__DWN.pem file that you have downloaded when configuring the certificates for API Access
3. The key file should be the privkey.key file that was created when your generated the keys to create the API Access Certificate
4. If you added a passphrase to your key then this should be entered
You can now add your certificate.
You can now make an API call via Postman to you Journey API Step. There is some sample code below that can be uploaded to Postman
curl --location 'https://{yournode}.node.darwinidentity.com:9443/api/event/{yourjourney}/{yourstep}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"journey_id": "{yourjourneyid}"
}'