How to Use Java to Access Automation System
JavaCDPClient allows Java applications to connect to running CDP Applications, retrieve their structure and read/write object values.
The library is available at Maven (https://search.maven.org/artifact/com.cdptech/cdpclient/) and the API is described in the javadoc (https://www.javadoc.io/doc/com.cdptech/cdpclient/).
Java Client Usage Guide
This guide will describe how to create a small Java project which is able to connect with a CDP Application and print out its CPULoad signal. The application is made using CDP Studio, the independent automation software for open PC-based real-time distributed control systems.
CDP System
The first step is to use CDP Studio to create a system. The Java application will later connect into that system. See the Creating a Blank System section to see how to create a system. Name the system MySystem and application MySystemApp.
Java Project
In this example we will use a third-party Java IDE called IntelliJ IDEA which can be downloaded from https://www.jetbrains.com/idea/download. For this example the Community edition is sufficient. However, any other tools may be used that support Maven based Java projects.
Open IntelliJ IDEA and select New Project. Then from the left side select Maven and use the wizard to create the project. The GroupId and ArtifactId can be filled with any value for this example.
Now that the project has been created open the pom.xml file. Add the following lines under the <project> element to include the CDP Client dependency and set up [SLF4J](https://www.slf4j.org/) logging for the underlying websocket library.
<dependencies> <dependency> <groupId>com.cdptech</groupId> <artifactId>cdpclient</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency> </dependencies>
It is also a good idea to set the Java version in this file (this example uses Java 8). Add the following as well under the <project> element:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>8</release> </configuration> </plugin> </plugins> </build>
If you see a Maven pop-up in the corner, click on the Load Maven Changes option.
Next expand the project tree to projectname/test/src/java. Right click on java directory and select New -> Java Class. Name it "Main". Open the class add the following code:
import com.cdptech.cdpclient.*; import java.net.URI; public class Main { public static void main(String[] args) { Client client = new Client(); client.init("127.0.0.1", 7689, new NotificationListener() { public void clientReady(Client client) { // Find a node and print its value changes client.findNode("MySystemApp.CPULoad").then((node, status) -> { if (status == Request.Status.RESOLVED) node.subscribeToValueChanges(value -> System.out.println(value + "\t" + value.getTimestamp()), 10); }); } public void connectionError(URI serverURI, Exception e) { e.printStackTrace(); } public void clientClosed(Client client) { System.out.println("Client closed"); } }); client.run(); } }
The node name "MySystemApp.CPULoad" uses the name-based routing syntax which uniquely identifies any object in CDP Studio. To learn more about this, see Intro 1: Connect Variables to HMI GUI.
Testing the Connection
Open CDP Studio and run the MySystem project. Note that this example presumes that Use Encryption and Require Authentication in the Security tab are disabled.
The application should print into the Application Output pane something like:
12:19:50.736 StudioAPIServer: listening on 127.0.0.1:7689
Note: If the IP or port is something different, make sure to modify the Java code written in previous step.
Next open the IntelliJ IDEA again. Right click on Main.java in the project tree and select Run 'Main.main(). The Java application will now start and if successful, it should start printing MySystemApp CPULoad changes:
0.0012706480304955528 2019-09-12T14:52:56.111784956Z 0.001272264631043257 2019-09-12T14:52:56.895650347Z 0.0012853470437017994 2019-09-12T14:52:57.895742591Z
Refer to the javadoc (https://www.javadoc.io/doc/com.cdptech/cdpclient/) for further information about using the client.
Security
Encryption
If Use Encryption in the Security tab is enabled, then TLS is used to encrypt the connection. Note that by default the Java client will not allow connecting to a server using a self-signed certificate (like the StudioAPI.crt that is automatically generated by CDP Studio). That can be overridden by calling either setTrustedCertificates()
or setIgnoreCertificates()
.
Client client = new Client(); // Trust the default self-signed StudioAPI.crt generated by CDP Studio and disable domain name verification. client.setTrustedCertificates(Collections.singletonList(new File("/path/to/application/StudioAPI.crt")), false); // Alternatively, for testing purposes it is also possible to completely disable certificate verification: // client.setIgnoreCertificates(true); client.init("127.0.0.1", 7689, new NotificationListener() { ...
Note: In production it is highly recommended to use a trusted CA signed certificate which will make the code above unnecessary.
Application Acceptance
When establishing a connection, the first step is to verify and accept the found application. For that the NotificationListener
can implement the optional applicationAcceptanceRequested
callback where it is possible to check the system use notification and also verify things like system name or certificate. For the system use notification it is recommended to prompt the user and allow them to either accept or reject the connection.
client.init("127.0.0.1", 7689, new NotificationListener() { ... public void applicationAcceptanceRequested(AuthRequest request) { // Print the system use message and accept the connection. In a real system should prompt the user. if (!request.getSystemUseNotification().isEmpty()) { System.out.println(request.getSystemUseNotification()); } request.accept(); } ... });
Note: If the applicationAcceptanceRequested
callback is not implemented, then by default all applications are accepted.
Authentication
If Require Authentication in the Security tab is enabled, the Java client must specify username and password to connect to the system. For that the NotificationListener
must also implement the credentialsRequested
callback which can provide usernames and passwords as needed.
client.init("127.0.0.1", 7689, new NotificationListener() { ... public void credentialsRequested(AuthRequest request) { if (request.getAuthResult().getCode() == CREDENTIALS_REQUIRED) { request.accept(AuthResponse.password("MyUser", "MyPassword")); } else if (request.getAuthResult().getCode() == REAUTHENTICATION_REQUIRED) { // Re-authentication is requested when the connection has been idle for too long. // It is strongly recommended to prompt the user for a password instead of using cached credentials. request.accept(AuthResponse.password("MyUser", "MyPassword")); } else if (request.getAuthResult().getCode() == NEW_PASSWORD_REQUIRED) { request.accept(AuthResponse.newPassword("MyUser", "MyPassword", "NewPassword")); } else { System.out.println("Authentication failed: " + request.getAuthResult()); request.reject(); // Or retry with different credentials } } }); ...
Refer to the javadoc (https://www.javadoc.io/doc/com.cdptech/cdpclient/) for further information.
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.