Example API Code
  • 28 Nov 2024
  • 7 Minutes to read
  • Contributors
  • Dark
    Light

Example API Code

  • Dark
    Light

Article summary

Requirements

  1. Knowing your Host Name: it corresponds to your Darwinium Node and consists of two words which are prefixed onto the Darwinium domain: 

    1. your-node.node.darwinidentity.com

  2. Gone through self-serve certificate signingin Portal, obtaining:

    1. Private key that you generated

    2. Darwinium certificate that you downloaded from the Darwinium Portal to use as authentication to the Darwinium API

  3. (for Event API): Created and deployed a Darwinium journey with API Step, obtaining:

    1. Journey Name

    2. API Step Name
      These complete the URL path:   /api/event/<journeyname>/<stepname>

Event API

Calling the Event API

In CAPITALS should be replaced by your parameters

https://YOUR-NODE.node.darwinidentity.com:9443/api/event/JOURNEYNAME/STEPNAME
  • {
        "identity": {
            "ACCOUNT": {
                "username": {
                    "username": "exampleusername"
                },
                "email": {
                    "PERSONAL": {
                        "email": "test@test.com"
                    }
                }
            }
        },
        "custom": {
            "general_purpose": {
                "mytestattribute": "test123"
            }
        }
    }

Label APIs

Calling the Label API

https://YOUR-NODE.node.darwinidentity.com:9443/api/label/add
https://YOUR-NODE.node.darwinidentity.com:9443/api/label/remove
  • Host: https://YOUR-NODE.node.darwinidentity.com

  • Port: 9443

  • Path: /api/label/add

  • Add label: Example Body

    {
      "id": "monitor_list",
      "attributes": [
        {
          "name": "identity['ACCOUNT'].username.username",
          "value": "exampleusername"
        },
        {
          "name": "profiling.tcp_connection['PRIMARY'].ip_address",
          "value": "127.0.0.1"
        }
      ],
      "contexts": ["manual_add"]
    }
  • Remove label: Example Body

{
  "label_uuid":"4ffaf030fc6440739273c27ae774199c"
}

Example: 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://YOUR-NODE.node.darwinidentity.com:9443/api/event/JOURNEYNAME/STEPNAME' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
  "journey_id": "YOURJOURNEYID"
}'

Example: 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);
  }
}


Was this article helpful?

Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.
ESC

Eddy AI, facilitating knowledge discovery through conversational intelligence