You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/08/10 12:02:11 UTC

[plc4x] 01/05: - Added a new exampe that posts PLC data to a web-service

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 4e905aac0c8cab991d93d193762c3e68c06bdc82
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Aug 10 13:57:49 2020 +0200

    - Added a new exampe that posts PLC data to a web-service
---
 plc4j/examples/hello-webservice/pom.xml            |  98 +++++++++++++
 .../java/examples/hellowebservice/CliOptions.java  |  99 +++++++++++++
 .../examples/hellowebservice/HelloWebservice.java  | 155 +++++++++++++++++++++
 .../src/main/resources/logback.xml                 |  38 +++++
 plc4j/examples/pom.xml                             |   1 +
 pom.xml                                            |   7 +-
 6 files changed, 397 insertions(+), 1 deletion(-)

diff --git a/plc4j/examples/hello-webservice/pom.xml b/plc4j/examples/hello-webservice/pom.xml
new file mode 100644
index 0000000..29f678f
--- /dev/null
+++ b/plc4j/examples/hello-webservice/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x.examples</groupId>
+    <artifactId>plc4j-examples</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4j-webservice</artifactId>
+  <name>PLC4J: Examples: Hello-Webservice</name>
+  <description>Hello world application sending PLC4X data to a remote Webservice.</description>
+
+  <properties>
+    <app.main.class>org.apache.plc4x.java.examples.hellowebservice.HelloWebservice</app.main.class>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>log4j-over-slf4j</artifactId>
+      <version>1.7.25</version>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+    </dependency>
+
+    <!--dependency>
+      <groupId>org.apache.plc4x.sandbox</groupId>
+      <artifactId>test-java-amsads-driver</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+      <scope>runtime</scope>
+    </dependency-->
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <configuration>
+          <usedDependencies combine.children="append">
+            <usedDependency>org.slf4j:log4j-over-slf4j</usedDependency>
+          </usedDependencies>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file
diff --git a/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/CliOptions.java b/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/CliOptions.java
new file mode 100644
index 0000000..e855d00
--- /dev/null
+++ b/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/CliOptions.java
@@ -0,0 +1,99 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.java.examples.hellowebservice;
+
+import org.apache.commons.cli.*;
+
+public class CliOptions {
+
+    private static Options options;
+
+    private final String connectionString;
+    private final String[] fieldAddress;
+    private final String webserviceUrl;
+
+    public static CliOptions fromArgs(String[] args) {
+        options = new Options();
+        // Required arguments
+        options.addOption(
+            Option.builder()
+                .type(String.class)
+                .longOpt("connection-string")
+                .hasArg()
+                .desc("Connection String")
+                .required()
+                .build());
+        options.addOption(
+            Option.builder()
+                .type(String.class)
+                .longOpt("field-addresses")
+                .hasArgs()
+                .desc("Field Addresses (Space separated).")
+                .required()
+                .build());
+        options.addOption(
+            Option.builder()
+                .type(String.class)
+                .longOpt("webservice-url")
+                .hasArgs()
+                .desc("Target URL of the Webservice we are publishing to.")
+                .required()
+                .build());
+
+        CommandLineParser parser = new DefaultParser();
+        CommandLine commandLine;
+        try {
+            commandLine = parser.parse(options, args);
+
+            String connectionString = commandLine.getOptionValue("connection-string");
+            String[] fieldAddress = commandLine.getOptionValues("field-addresses");
+            String webserviceUrl = commandLine.getOptionValue("webservice-url");
+
+            return new CliOptions(connectionString, fieldAddress, webserviceUrl);
+        } catch (ParseException e) {
+            System.err.println(e.getMessage());
+            return null;
+        }
+    }
+
+    public static void printHelp() {
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.printHelp("HelloPlc4x", options);
+    }
+
+    public CliOptions(String connectionString, String[] fieldAddress, String webserviceUrl) {
+        this.connectionString = connectionString;
+        this.fieldAddress = fieldAddress;
+        this.webserviceUrl = webserviceUrl;
+    }
+
+    public String getConnectionString() {
+        return connectionString;
+    }
+
+    public String[] getFieldAddress() {
+        return fieldAddress;
+    }
+
+    public String getWebserviceUrl() {
+        return webserviceUrl;
+    }
+
+}
diff --git a/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/HelloWebservice.java b/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/HelloWebservice.java
new file mode 100644
index 0000000..da5bfe5
--- /dev/null
+++ b/plc4j/examples/hello-webservice/src/main/java/org/apache/plc4x/java/examples/hellowebservice/HelloWebservice.java
@@ -0,0 +1,155 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.examples.hellowebservice;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
+import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Scanner;
+import java.util.function.Consumer;
+
+public class HelloWebservice {
+
+    private static final Logger logger = LoggerFactory.getLogger(HelloWebservice.class);
+
+    private final CliOptions options;
+
+    public HelloWebservice(CliOptions options) {
+        this.options = options;
+    }
+
+    public void run() throws Exception {
+        // Establish a connection to the plc.
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection(options.getConnectionString())) {
+
+            // Check if this connection support subscriptions.
+            if (!plcConnection.getMetadata().canSubscribe()) {
+                logger.error("This connection doesn't support subscriptions.");
+                return;
+            }
+
+            // Create a new read request:
+            // - Give the single item requested the alias name "value"
+            final PlcSubscriptionRequest.Builder builder = plcConnection.subscriptionRequestBuilder();
+            for (int i = 0; i < options.getFieldAddress().length; i++) {
+                builder.addChangeOfStateField("value-" + i, options.getFieldAddress()[i]);
+            }
+            PlcSubscriptionRequest subscriptionRequest = builder.build();
+
+            // Execute the subscription response.
+            final PlcSubscriptionResponse subscriptionResponse = subscriptionRequest.execute().get();
+
+            // Attach handlers for the incoming data.
+            for (String subscriptionName : subscriptionResponse.getFieldNames()) {
+                final PlcSubscriptionHandle subscriptionHandle =
+                    subscriptionResponse.getSubscriptionHandle(subscriptionName);
+                subscriptionHandle.register(new ValueChangeHandler(options.getWebserviceUrl()));
+            }
+
+            // Wait for the user to press "Enter" to abort the program.
+            Scanner scanner = new Scanner(System.in);
+            try {
+                logger.info("Please press Enter to exit program.");
+                scanner.nextLine();
+                logger.info("Finishing");
+            } catch (IllegalStateException e) {
+                // System.in has been closed
+                logger.error("System.in was closed; exiting");
+            }
+        }
+    }
+
+    /**
+     * Example code do demonstrate using PLC4X Subcription API.
+     */
+    public static void main(String[] args) throws Exception {
+        CliOptions options = CliOptions.fromArgs(args);
+        if (options == null) {
+            CliOptions.printHelp();
+            // Could not parse.
+            System.exit(1);
+        }
+
+        HelloWebservice subscriptionApplication = new HelloWebservice(options);
+
+        subscriptionApplication.run();
+
+        System.exit(0);
+    }
+
+    private static class ValueChangeHandler implements Consumer<PlcSubscriptionEvent> {
+
+        private final String webserviceUrl;
+        private final Gson gson;
+
+        public ValueChangeHandler(String webserviceUrl) {
+            this.webserviceUrl = webserviceUrl;
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            gsonBuilder.setPrettyPrinting();
+            gson = gsonBuilder.create();
+        }
+
+        @Override
+        public void accept(PlcSubscriptionEvent plcSubscriptionEvent) {
+            logger.info("Incoming event:");
+            // Iterate over all the fields in this event and then simply output
+            // them to the console in a JSON format.
+            for (String fieldName : plcSubscriptionEvent.getFieldNames()) {
+                final PlcValue plcValue = plcSubscriptionEvent.getPlcValue(fieldName);
+
+                // Simply convert the event into a JSON object.
+                String jsonString = gson.toJson(plcValue);
+
+                // Send the the json payload to the remote webservice.
+                HttpPost post = new HttpPost(webserviceUrl);
+                try {
+                    post.setEntity(new StringEntity(jsonString));
+                } catch (UnsupportedEncodingException e) {
+                    logger.error("Error encoding json string entity", e);
+                }
+                try (CloseableHttpClient httpClient = HttpClients.createDefault();
+                     CloseableHttpResponse response = httpClient.execute(post)) {
+
+                    String result = EntityUtils.toString(response.getEntity());
+                    logger.info(String.format("Got '%s' from remote", result));
+                } catch (IOException e) {
+                    logger.error("Error sending payload to remote webservice.", e);
+                }
+            }
+        }
+    }
+
+}
diff --git a/plc4j/examples/hello-webservice/src/main/resources/logback.xml b/plc4j/examples/hello-webservice/src/main/resources/logback.xml
new file mode 100644
index 0000000..4dd05a4
--- /dev/null
+++ b/plc4j/examples/hello-webservice/src/main/resources/logback.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+-->
+<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- encoders are assigned the type
+         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <logger name="org.apache.plc4x.java.examples.hellowebservice.HelloWebservice" level="info"/>
+
+  <root level="warn">
+    <appender-ref ref="STDOUT" />
+  </root>
+
+</configuration>
\ No newline at end of file
diff --git a/plc4j/examples/pom.xml b/plc4j/examples/pom.xml
index 067f873..a5954f3 100644
--- a/plc4j/examples/pom.xml
+++ b/plc4j/examples/pom.xml
@@ -49,6 +49,7 @@
     <module>hello-opm</module>
     <module>hello-storage-elasticsearch</module>
     <module>hello-webapp</module>
+    <module>hello-webservice</module>
     <module>hello-world-plc4x</module>
     <module>hello-world-plc4x-subscription</module>
     <module>hello-world-plc4x-write</module>
diff --git a/pom.xml b/pom.xml
index a4bc0e4..eb28fd4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -461,8 +461,13 @@
       </dependency>
       <dependency>
         <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>4.5.12</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
         <artifactId>httpcore</artifactId>
-        <version>4.4.12</version>
+        <version>4.4.13</version>
       </dependency>
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>