Understanding the Steps to Use Integrations Example Customization
This topic describes how to securely connect Windchill to an external system using mutual TLS (mTLS). External connection details such as endpoint URLs, certificates, and secrets are provided in a JSON file and submitted using the captureExternalConnections utility. The captured information is then reused in customization code through a helper class to securely call the external API, with a sample CCD package showing how to build and deploy the integration.
Capturing External Connection Information
To set up a secure MTLS connection with an external endpoint, ensure that the prerequisites such as the endpoint’s base-URL, URL fragments, client key-certificates, and server certificates are available in Windchill+. This information is used in the CCD utility to generate the SSL context.
Follow the Steps to Share Connection Information with PTC
1. Set up the materialAPI (external endpoint) using the instructions provided in the wnc-plus-outbound-demo-api repository.
After setting up the materialAPI, ensure that you have the following information:
Base-URL
Client-keycertchain
Server-certchain
In addition, you should have the BLOB_SAS_URL and a public key for encryption received from PTC.
2. Prepare a JSON file by replacing the placeholders mentioned in the following sample JSON file with your actual parameters.
MaterialAPI JSON
{
"blob_sas_url": "***replace with BLOB_SAS_URL received from PTC***",
"external_connections": {
"material_api": {
"baseurl": "***replace with your base-url***",
"secrets": {
"client_cert": "***replace with path to clientcertchain***",
"bearer_token": "Bearer ***replace with your bearer token***"
},
"server_cert": "***replace with path to server.certchain***",
"url_fragments": {
"get_material_number": "/api/material",
"get_material_data_stream": "/api/materialData/stream"
}
}
},
"public_key_for_encrypting_custom_secrets":"***replace with your public key for encryption received from PTC ***",
"apply_at":"***schedule atleast 1 hour after execution-time of utility***"
}
* 
The bearer_token is not a reserved keyword, and there is no specific handling for bearer token authentication in the sample implementation. It could essentially be any other string that the customization code can identify and utilize while constructing a request for the relevant external endpoint.
3. Specify the path to your JSON file and execute the capturExternalConnections utility from ${WT_HOME}/prog_examples/IntegrationsExample/captureExternalConnections.sh
./captureExternalConnections.sh -f <***path-to-your-json***>
If the external information is successfully captured, the following message appears: “Connection information submitted successfully.”
Using the Captured Connection Information in the Customization Code
This section describes the usage of the endpoint information captured using the captureExternalConnection utility in the integrations example customization code.
The connection information, captured using the captureExternalConnections utility, is accessed in the integrations example customization code using the CustomIntegrationHelper class.
The following code snippet shows how the connection information is obtained using the CustomIntegrationHelper class:
public String getPartNumber() throws Exception {
URI apiUrl = customIntegrationHelper.getNamedEndpointURI("get_material_number");
Map<String, String> map = customIntegrationHelper.getSecretsMap();
String bearerToken = map.get("bearer_token");
SSLContext sslContext = customIntegrationHelper.getInitializedSSLContext();
String uniqueNo = performGetRequest(apiUrl, sslContext, bearerToken);
if (log.isDebugEnabled()) {
log.debug("API URL for fetching part number: " + apiUrl);
log.debug("Unique number returned from API Client :" + uniqueNo);
}
return uniqueNo;
}
Examine the JSON that is used for capturing information and the customization code from customization/integrations/main/src/com/acme/ext/APIClient.java to understand how the CustomIntegrationHelper is used to access the connection information. In the table below, notice that the base-URL, bearer token, and the SSL context, generated using client and server certificate chains, are retrieved in the customization code using an object instance of CustomIntegrationHelper.
Connection information submitted via captureExternalConnections utility
Customization code submitted via CCD utility
"material_api": {
"baseurl": "replace with your base-url",
"url_fragments": {
"get_material_number": "/api/material",
"get_material_data_stream": "/api/materialData/stream"
},
"secrets": {
"client_cert": "replace with path to clientcertchain",
"bearer_token": "Bearer replace with your bearer token"
},
"server_cert": "replace with path to clientcertchain"
}
CustomIntegrationHelper customIntegrationHelper
= new CustomIntegrationHelper("material_api");

public String getPartNumber() throws Exception {
URL apiUr1 = customIntegrationHelper.getNamedEndpointURL("get_material_number");
Map<String, String> map = customIntegrationHelper.getSecretsMap();
String bearerToken = map.get("bearer_token");
SSLContext sslContext = customIntegrationHelper.getInitializedSSLContext();
.
.
.
}
* 
The bearer_token is not a reserved keyword, and there is no specific handling for bearer token authentication in the sample implementation. It could essentially be any other string that the customization code can identify and utilize while constructing a request for the relevant external endpoint.
CCD Package Contents and Deployment
This section describes the contents of the CCD package, and the reference to compile and deploy the integration example CCD package.
Overview of the CCD Package Contents
Java Files
File Name
Description
ApiClient.java
This class is used make requests to the external endpoint.
NumberGenerator.java
This class overrides Windchill’s NumberGenerator.java class and returns a unique number from the external endpoint, which is used to create the new ACME Engineered Material.
AcmeMaterialHelper.java
This class is used to persist the data to external endpoint when the ACME Engineered Material is created.
Streamer.java
This class establishes a stream connection with the external endpoint. It parses the responses received from the endpoint and appends them to the custom-table.
InventoryTableBuilder.java
This class contains the table builder for displaying the global inventory.
acmeManagerResource.java
This is a resource bundle file for the custom-actions.
Configurations
Load Files
File Name
Description
ACMEOrganization.xml
To create an organization named ACMEOrganization.
ACMEUser.xml
To create a user named acmeorgadmin and assign the user admin role in ACMEOrganization.
ACMEAttributes.xml
To create the prerequisite attributes.
ACMEEngineeredMaterial.xml
To create the new sub-type under part.
ACMERuleAlgorithm.xml
To create an OIR required for use case 1.
ACMELifeCycleTemplate.xml
To create a life cycle template for use case 2.
ACMEProcessTemplate.xml
To create a workflow for use case 2.
loadFileSet.xml
To load all the loadFiles collectively.
xconf
custom.site.xconf
Add the property values to refer the custom-actions and custom-actionModels defined in this customization.
Resources
Actions
File Name
Description
inventory-actionModels.xml
To define the action models used in this package.
inventory-actions.xml
To define the actions used in this package.
Compile and Deploy CCD Package
To compile and deploy the integrations example provided with the CCD, refer to the README.md file located at, <WT_HOME>/prog_examples in the CCD.
Was this helpful?