diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/pom.xml b/plc4j/integrations/apache-hop/plc4x-hop-actions/pom.xml index ee58270dbcc..ddc11edb5b6 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/pom.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/pom.xml @@ -142,5 +142,10 @@ provided --> + + org.netbeans.api + org-openide-util-lookup + RELEASE170 + \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java index 67145901ab6..dca33626910 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java @@ -27,7 +27,7 @@ @HopMetadata( key = "Xplc4xaction", name = "PLC4x Action", - description = "A shared PLC4x connection to a PLC", + description = "A shared PLC4x connection to a PLC_Borrar", image = "plc4x_toddy.svg", documentationUrl = "/metadata-types/neo4j/neo4j-connection.html") public class ActionSampleMetaData extends HopMetadataBase implements IHopMetadata { diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java index c2aac428f52..53ffb309a41 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java @@ -31,22 +31,26 @@ import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import org.apache.hop.core.Const; import org.apache.hop.core.exception.HopException; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; -import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +import org.openide.util.Lookup; import org.w3c.dom.Node; - +/* +* The purpose of this "Action" is firstly to verify the connection to +* the PLC and secondly to create a connection that will be shared by +* the Hop environment. +*/ @Action( id = "CHECK_PLC4X_CONNECTIONS", name = "i18n::Plc4xActionConnections.Name", description = "i18n::Plc4xActionConnections.Description", - image = "plc4x_toddy.svg", + image = "plc4x_toddy_play.svg", categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.Conditions", keywords = "i18n::Plc4xActionConnections.keyword", documentationUrl = "/workflow/actions/plc4x.html") @@ -56,7 +60,13 @@ public class Plc4xCheckConnections extends ActionBase implements Cloneable, IAct private Plc4xConnection[] connections; private boolean connected = false; + private Plc4xWrapperConnection connwrapper = null; private PlcConnection plcconn = null; + private ActionBase actionbase = null; + + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result lkresult = null; protected static final String[] unitTimeDesc = new String[] { @@ -79,7 +89,7 @@ public class Plc4xCheckConnections extends ActionBase implements Cloneable, IAct private long timeStart; private long now; - public Plc4xCheckConnections( String name) { + public Plc4xCheckConnections(String name) { super(name, ""); //connections = null; waitfors = null; @@ -170,8 +180,6 @@ private static int getWaitTimeByCode(String tt) { return 0; } - - /** * * Save values to XML @@ -247,63 +255,84 @@ public void loadXml( Node entrynode, IHopMetadataProvider metadataProvider, IVar } } - /** - * Execute this action and return the result. - * In this case it means, just set the result boolean in the Result - * class. - * Check all conections metadata from the dialog. - * @param prevResult The result of the previous execution - * @return The Result of the execution. - */ - @Override - public Result execute( Result prevResult, int nr ) { - Result result = prevResult; - result.setNrErrors(0); - connected = true; - for (Plc4xConnection connmeta:connections) { - try { - plcconn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(01) - if (!plcconn.isConnected()) { - logBasic("Cant connect to: " + connmeta.getUrl()); - connected = false; - plcconn = null; - //break; + /** + * Execute this action and return the result. + * In this case it means, just set the result boolean in the Result class. + * + * Check all conections metadata from the dialog (really only one). + * @param prevResult The result of the previous execution + * @return The Result of the execution. + */ + @Override + public Result execute( Result prevResult, int nr ) { + + Result result = prevResult; + result.setNrErrors(0); + connected = true; + + actionbase = null; + + for (Plc4xConnection connmeta:connections) { + + if (null == connwrapper) { //(01) + template = new Lookup.Template<>(Plc4xWrapperConnection.class, connmeta.getName(), null); + lkresult = lookup.lookup(template); + if (!lkresult.allItems().isEmpty()) { + connwrapper = (Plc4xWrapperConnection) lkresult.allInstances().toArray()[0]; //(02) + if (connwrapper != null) connwrapper.retain(); //(03) + } + }; + + if (null == connwrapper) { //(04) + try { + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(05) + if (conn.isConnected()) { + connwrapper = new Plc4xWrapperConnection(conn, connmeta.getName()); + lookup.add(connwrapper); //(06) + } else { + connected = false; + plcconn = null; + } + } catch (Exception ex) { + connected = false; + plcconn = null; + } + + } else { + if (!connwrapper.getConnection().isConnected()) { //(07) + connected = false; + plcconn = null; + } + } + + if (null == connwrapper) { //(08) + try { + + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(09) + + if (conn.isConnected()) { + conn.close(); //(10) + plcconn = null; + } else { + connected = false; + plcconn = null; + } + } catch (Exception ex){ + connected = false; + plcconn = null; + } + } - plcconn.close(); - plcconn = null; - } catch (Exception ex) { - Logger.getLogger(Plc4xCheckConnections.class.getName()).log(Level.SEVERE, null, ex); - connected = false; - plcconn = null; - //break; - } finally { - } - - } result.setResult(connected); return result; } - /** - * - * Add checks to report warnings - * - * @param remarks - * @param workflowMeta - * @param variables - * @param metadataProvider - */ - @Override - public void check( List remarks, WorkflowMeta workflowMeta, IVariables variables, - IHopMetadataProvider metadataProvider ) { - } - - @Override - public boolean resetErrorsBeforeExecution() { - return false; - } + @Override + public boolean resetErrorsBeforeExecution() { + return false; + } @Override public boolean isEvaluation() { @@ -313,9 +342,6 @@ public boolean isEvaluation() { @Override public boolean isUnconditional() { return false; - } - - - + } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java index d4f3f5e2538..d92da3f85ab 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java @@ -33,23 +33,45 @@ import java.util.List; import org.apache.hop.core.Const; import org.apache.hop.core.exception.HopException; +import org.apache.hop.pipeline.PipelineMeta; +import org.apache.hop.pipeline.engine.IPipelineEngine; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; +import org.openide.util.Lookup; import org.w3c.dom.Node; - +/* +* The purpose of this "Action" is to release the driver resource +* within a "workflow", in case the number of accounts reaches zero, +* the wrapper will close the connection. +* The work pattern must be within the "workflow": +* +* Start -> Create connection -> Run pipeline -> Close connection -> Finish. +* +* It should always be taken into account that the connections to +* the PLCs are limited resources. +*/ @Action( id = "CHECK_PLC4X_DISCONNECTIONS", name = "i18n::Plc4xActionDisConnections.Name", description = "i18n::Plc4xActionDisConnections.Description", - image = "plc4x_toddy.svg", + image = "plc4x_toddy_stop.svg", categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.Conditions", keywords = "i18n::Plc4xActionDisConnections.keyword", documentationUrl = "/workflow/actions/checkdbconnection.html") public class Plc4xCheckDisConnections extends ActionBase implements Cloneable, IAction { - private static final Class PKG = Plc4xCheckDisConnections.class; // Needed by Translator + + private static final Class PKG = Plc4xCheckDisConnections.class; // Needed by Translator - private Plc4xConnection[] connections; + private Plc4xConnection[] connections; + private Plc4xWrapperConnection connwrapper = null; + private ActionBase actionbase = null; + + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result lkresult = null; protected static final String[] unitTimeDesc = new String[] { @@ -240,32 +262,31 @@ public void loadXml( Node entrynode, IHopMetadataProvider metadataProvider, IVar } } - /** - * Execute this action and return the result. In this case it means, just set the result boolean in the Result - * class. - * - * @param result The result of the previous execution - * @return The Result of the execution. - */ - @Override - public Result execute( Result result, int nr ) { - result.setResult(true); - System.out.println("NR: " + nr); + /** + * Execute this action and return the result. In this case it means, + * just set the result boolean in the Result class. + * + * @param result The result of the previous execution + * @return The Result of the execution. + */ + @Override + public Result execute( Result result, int nr ) { + result.setResult(true); + + for (Plc4xConnection connmeta:connections) { + template = new Lookup.Template<>(Plc4xWrapperConnection.class, connmeta.getName(), null); + lkresult = lookup.lookup(template); + if (!lkresult.allItems().isEmpty()) { + connwrapper = (Plc4xWrapperConnection) lkresult.allInstances().toArray()[0]; + if (connwrapper != null) { + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); + } + } + }; return result; } - /** - * - * Add checks to report warnings - * - * @param remarks - * @param workflowMeta - * @param variables - * @param metadataProvider - */ - @Override - public void check( List remarks, WorkflowMeta workflowMeta, IVariables variables, - IHopMetadataProvider metadataProvider ) { - } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_play.svg b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_play.svg new file mode 100644 index 00000000000..b0683725109 --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_play.svg @@ -0,0 +1,1490 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_stop.svg b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_stop.svg new file mode 100644 index 00000000000..844057852b6 --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/plc4x_toddy_stop.svg @@ -0,0 +1,1513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml b/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml index 84000a4fbe5..7d718f1492c 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml @@ -141,5 +141,15 @@ + + io.netty + netty-common + ${netty.version} + + + org.netbeans.api + org-openide-util-lookup + RELEASE170 + \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/Plc4xConnectionEditor.java b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/Plc4xConnectionEditor.java index 43fb6a9befe..75db5ca921c 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/Plc4xConnectionEditor.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/Plc4xConnectionEditor.java @@ -120,7 +120,7 @@ public Button[] createButtonsForButtonBar(Composite parent) { Button wbTest = new Button(parent, SWT.PUSH | SWT.CENTER); props.setLook(wbTest); - wbTest.setText("Test connection"); + wbTest.setText("Test connection."); wbTest.addListener(SWT.Selection, e -> test_connection()); return new Button[] {wbTest}; diff --git a/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xLookup.java b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xLookup.java new file mode 100644 index 00000000000..fac064e6fcc --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xLookup.java @@ -0,0 +1,92 @@ + /* + * 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.hop.metadata.util; + +import org.apache.plc4x.java.api.PlcConnection; +import org.openide.util.lookup.AbstractLookup; +import org.openide.util.lookup.InstanceContent; +import org.openide.util.lookup.InstanceContent.Convertor; + +/* +* Plc4xLookup is the main repository for sharing connections within a +* Hop pipeline/workflow instance. +* It's static nature limits its use within a JVM instance, +* however this is not a limitation since in general the connections to +* the PLCs are limited resources. +* A "Convertor" is included for the "Plc4xWrapperConnection" types +* to facilitate their use, without limiting their use as a container +* for other types of objects. +*/ +public class Plc4xLookup extends AbstractLookup { + private InstanceContent content = null; + private static Plc4xLookup def = new Plc4xLookup (); + + public Plc4xLookup(InstanceContent content) { + super(content); + this.content = content; + } + + public Plc4xLookup() { + this(new InstanceContent()); + } + + public void add(Object obj) { + if (obj instanceof Plc4xWrapperConnection) + content.add((Plc4xWrapperConnection) obj, Plc4xConvertor); + else + content.add(obj); + } + + public void remove(Object obj) { + if (obj instanceof Plc4xWrapperConnection) + content.remove((Plc4xWrapperConnection) obj, Plc4xConvertor); + else + content.remove(obj); + } + + public static Plc4xLookup getDefault(){ + return def; + } + + private static final Convertor Plc4xConvertor = + new InstanceContent.Convertor() { + + @Override + public Plc4xWrapperConnection convert(Plc4xWrapperConnection obj) { + return obj; + } + + @Override + public Class type(Plc4xWrapperConnection obj) { + return Plc4xWrapperConnection.class; + } + + @Override + public String id(Plc4xWrapperConnection obj) { + return obj.getId(); + } + + @Override + public String displayName(Plc4xWrapperConnection obj) { + return obj.getConnection().toString(); + } + + }; + +} diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xWrapperConnection.java b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xWrapperConnection.java similarity index 85% rename from plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xWrapperConnection.java rename to plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xWrapperConnection.java index 6c6ea3602aa..f16e6a4259f 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xWrapperConnection.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-metadata/src/main/java/org/apache/plc4x/hop/metadata/util/Plc4xWrapperConnection.java @@ -1,4 +1,4 @@ - /* + /* * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.plc4x.hop.transforms.util; +package org.apache.plc4x.hop.metadata.util; import io.netty.util.AbstractReferenceCounted; import io.netty.util.ReferenceCounted; @@ -27,15 +27,17 @@ * Its goal is for it to be shared between the different transform that * may be running simultaneously on the local or remote Hop engine. * Its use with other kind of engines must be certified. - * The concept is very simple, the last to leave closes the connection. + * The concept is very simple, "the last to leave closes the connection". */ public class Plc4xWrapperConnection extends AbstractReferenceCounted { private final PlcConnection connection; + private final String id; - public Plc4xWrapperConnection(PlcConnection connection){ + public Plc4xWrapperConnection(PlcConnection connection, String id){ super(); this.connection = connection; + this.id = id; } public PlcConnection getConnection(){ @@ -51,10 +53,13 @@ protected void deallocate() { } } - @Override public ReferenceCounted touch(Object hint) { return this; } + public String getId() { + return id; + } + } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml b/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml index 961b83f0c2c..1091369b0a1 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml @@ -122,7 +122,7 @@ ${project.groupId} - hop-plc4x-metadata + plc4x-hop-metadata ${project.version} @@ -155,5 +155,10 @@ jackson-datatype-jsr310 ${jackson.version} + + org.netbeans.api + org-openide-util-lookup + RELEASE170 + \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java index 243aa0120b7..099dc1de1fc 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java @@ -49,8 +49,10 @@ import org.apache.hop.pipeline.transform.ITransform; import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; -import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.transforms.plc4xinput.Plc4xRead; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.PlcReadRequest; @@ -65,6 +67,7 @@ import org.apache.plc4x.java.s7.events.S7SysEvent; import org.apache.plc4x.java.s7.events.S7UserEvent; import org.apache.plc4x.java.s7.readwrite.ModeTransitionType; +import org.openide.util.Lookup; /** * This transform receives an event from the S7 driver, of type MODE, SYS, @@ -73,87 +76,93 @@ */ public class Plc4xEvent extends BaseTransform { - public static String FIELD_MODE_EVENT = "MODE"; - public static String FIELD_USER_EVENT = "USR"; - public static String FIELD_SYS_EVENT = "SYS"; - public static String FIELD_ALARM_EVENT = "ALM"; + public static String FIELD_MODE_EVENT = "MODE"; + public static String FIELD_USER_EVENT = "USR"; + public static String FIELD_SYS_EVENT = "SYS"; + public static String FIELD_ALARM_EVENT = "ALM"; - - private static final Class PKG = Plc4xEvent.class; // Needed by Translator - - private Plc4xConnection connmeta = null; - private Plc4xWrapperConnection connwrapper = null; - private PlcReadRequest readRequest = null; - private PlcConsumerRegistration registerMode = null; - private PlcConsumerRegistration registerUser = null; - private PlcConsumerRegistration registerSys = null; - private PlcConsumerRegistration registerAlarm = null; - private PlcSubscriptionRequest subsbuild = null; - private PlcSubscriptionResponse subresponse = null; - - private List remarks = new ArrayList<>(); // stores the errors... - - /* - * The transfer of events is done from the driver tasks. A delay can be added - * for the execution of this transformer. - */ - private ObjectMapper mapper = new ObjectMapper(); - private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); - private boolean stopBundle = false; - private int index = 0; - - private static final ReentrantLock lock = new ReentrantLock(); - - private static final String dummy = "dummy"; - public Plc4xEvent(TransformMeta transformMeta, Plc4xEventMeta meta, Plc4xEventData data, int copyNr, PipelineMeta pipelineMeta, + private static final Class PKG = Plc4xEvent.class; // Needed by Translator + + private Plc4xConnection connmeta = null; + private Plc4xWrapperConnection connwrapper = null; + private PlcReadRequest readRequest = null; + private PlcConsumerRegistration registerMode = null; + private PlcConsumerRegistration registerUser = null; + private PlcConsumerRegistration registerSys = null; + private PlcConsumerRegistration registerAlarm = null; + private PlcSubscriptionRequest subsbuild = null; + private PlcSubscriptionResponse subresponse = null; + + private List remarks = new ArrayList<>(); // stores the errors... + + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result result = null; + + + /* + * The transfer of events is done from the driver tasks. A delay can be added + * for the execution of this transformer. + */ + private ObjectMapper mapper = new ObjectMapper(); + private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); + private boolean stopBundle = false; + private int index = 0; + + private static final ReentrantLock lock = new ReentrantLock(); + + private static final String dummy = "dummy"; + + public Plc4xEvent(TransformMeta transformMeta, Plc4xEventMeta meta, Plc4xEventData data, int copyNr, PipelineMeta pipelineMeta, Pipeline pipeline ) { super( transformMeta, meta, data, copyNr, pipelineMeta, pipeline ); - } + } - /* - * Including Date and Time field for every row - * - * @param meta Meta data from user dialog - * @param remarks Error registers - * @param origin transform instance name - */ - public static final RowMetaAndData buildRow(Plc4xEventMeta meta, + /* + * Including Date and Time field for every row + * + * @param meta Meta data from user dialog + * @param remarks Error registers + * @param origin transform instance name + */ + public static final RowMetaAndData buildRow(Plc4xEventMeta meta, List remarks, String origin) throws HopPluginException { - IRowMeta rowMeta = new RowMeta(); - Object[] rowData = RowDataUtil.allocateRowData(2); - int index = 0; - - ArrayList fields = new ArrayList(); - - if (meta.isModeEvent()) { - for (S7ModeEvent.Fields field:S7ModeEvent.Fields.values()) { - fields.add(field.name()); + + IRowMeta rowMeta = new RowMeta(); + Object[] rowData = RowDataUtil.allocateRowData(2); + int index = 0; + + ArrayList fields = new ArrayList(); + + if (meta.isModeEvent()) { + for (S7ModeEvent.Fields field:S7ModeEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isSysEvent()) { + for (S7SysEvent.Fields field:S7SysEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isUserEvent()) { + for (S7UserEvent.Fields field:S7UserEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isAlarmEvent()) { + fields.add("ALARM"); } - } else if (meta.isSysEvent()) { - for (S7SysEvent.Fields field:S7SysEvent.Fields.values()) { - fields.add(field.name()); - } - } else if (meta.isUserEvent()) { - for (S7UserEvent.Fields field:S7UserEvent.Fields.values()) { - fields.add(field.name()); - } - } else if (meta.isAlarmEvent()) { - fields.add("ALARM"); - } - - for (String field : fields) { - IValueMeta valueMeta = - ValueMetaFactory.createValueMeta(field, IValueMeta.TYPE_STRING); // build a - rowData[index] = StringUtil.EMPTY_STRING; - // Now add value to the row! - // This is in fact a copy from the fields row, but now with data. - rowMeta.addValueMeta(valueMeta); - index++; - } - - return new RowMetaAndData(rowMeta, rowData); + + for (String field : fields) { + IValueMeta valueMeta = + ValueMetaFactory.createValueMeta(field, IValueMeta.TYPE_STRING); // build a + rowData[index] = StringUtil.EMPTY_STRING; + // Now add value to the row! + // This is in fact a copy from the fields row, but now with data. + rowMeta.addValueMeta(valueMeta); + index++; + } + + return new RowMetaAndData(rowMeta, rowData); } /* @@ -198,7 +207,7 @@ public boolean processRow() throws HopException { try{ PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) if (conn.isConnected()) { - connwrapper = new Plc4xWrapperConnection(conn); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); getPipeline().getExtensionDataMap().put(meta.getConnection(), connwrapper); //(04) } } catch (Exception ex){ @@ -319,62 +328,68 @@ public boolean processRow() throws HopException { } - @Override - public boolean init() { - try { - if(super.init()){ - // Determine the number of rows to generate... - data.rowLimit = Const.toLong(resolve(meta.getRowLimit()), -1L); + @Override + public boolean init() { + try { + if(super.init()){ + // Determine the number of rows to generate... + data.rowLimit = Const.toLong(resolve(meta.getRowLimit()), -1L); - if (data.rowLimit < 0L) { // Unable to parse - logError(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Wrong.RowLimit.Number")); - return false; // fail - } - - // Create a row (constants) with all the values in it... - List remarks = new ArrayList<>(); // stores the errors... - RowMetaAndData outputRow = buildRow(meta, remarks, getTransformName()); - if (!remarks.isEmpty()) { - for (int i = 0; i < remarks.size(); i++) { - CheckResult cr = (CheckResult) remarks.get(i); - logError(cr.getText()); - } - return false; - } + if (data.rowLimit < 0L) { // Unable to parse + logError(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Wrong.RowLimit.Number")); + return false; // fail + } - data.outputRowData = outputRow.getData(); - data.outputRowMeta = outputRow.getRowMeta(); - - mapper.findAndRegisterModules(); + // Create a row (constants) with all the values in it... + List remarks = new ArrayList<>(); // stores the errors... + RowMetaAndData outputRow = buildRow(meta, remarks, getTransformName()); + if (!remarks.isEmpty()) { + for (int i = 0; i < remarks.size(); i++) { + CheckResult cr = (CheckResult) remarks.get(i); + logError(cr.getText()); + } + return false; + } + + data.outputRowData = outputRow.getData(); + data.outputRowMeta = outputRow.getRowMeta(); - return true; + mapper.findAndRegisterModules(); + + getPlcConnection(); + + return true; + } + + return false; + + } catch (Exception ex){ + setErrors(1L); + logError("Error initializing transform", ex); + return false; } - return false; - } catch (Exception ex){ - setErrors(1L); - logError("Error initializing transform", ex); - return false; } - } - /* - * Here, must perform the cleaning of any resource, main of the connection to - * the associated PLC. - */ + /* + * Here, must perform the cleaning of any resource, main of the connection to + * the associated PLC. + */ @Override public void cleanup() { + System.out.println("*************** CLEANUP *****************"); super.cleanup(); logBasic("Cleanup. Release connection."); if (null != connwrapper) { if (null != registerMode ) registerMode.unregister(); if (null != registerUser) registerUser.unregister(); if (null != registerSys) registerSys.unregister(); - if (null != registerAlarm) registerAlarm.unregister(); - connwrapper.release(); + if (null != registerAlarm) registerAlarm.unregister(); + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); } } - - + /* * Here, must perform the cleaning of any resource. * 1. Check if we have reference to wrapper. @@ -384,14 +399,14 @@ public void cleanup() { */ @Override public void dispose() { + System.out.println("*************** DISPOSE *****************"); super.dispose(); if (connwrapper != null) { logBasic("Dispose. Release connection: " + connwrapper.refCnt()); - connwrapper.release(); - if (!connwrapper.getConnection().isConnected()){ - getPipeline().getExtensionDataMap().remove(meta.getConnection()); - } - connwrapper = null; + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); + connwrapper = null; readRequest = null; registerMode = null; registerUser = null; @@ -407,7 +422,55 @@ public void stopRunning() throws HopException { stopBundle = true; } - + private void getPlcConnection() { + lock.lock(); //(01) + try { + + IHopMetadataProvider metaprovider = getMetadataProvider(); + connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); + + if (connwrapper == null) { + template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); + result = lookup.lookup(template); + if (!result.allItems().isEmpty()) { + System.out.println("Aqui encontro la conexion: " + meta.getConnection()); + connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; + if (connwrapper != null) connwrapper.retain(); + } + }; + + if (connmeta == null){ + logError( + BaseMessages.getString( + PKG, + "Plc4x.Read.Meta.Log.SetMetadata", + meta.getConnection())); + } + + if ((connmeta != null) && (connwrapper == null)){ + readRequest = null; + try{ + System.out.println("Creo una nueva conexión..."); + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) + + if (conn.isConnected()) { + System.out.println("**** Agrego la segunda conexion. ****"); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); + lookup.add(connwrapper); + } + + } catch (Exception ex){ + setErrors(1L); + logError("Unable to create connection to PLC. " + ex.getMessage()); + } + } + + } catch (HopException ex) { + logError("Unable to create connection to PLC. " + ex.getMessage()); + } finally { + lock.unlock(); + } + } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java index 5e9302da020..0d8332d4ffb 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java @@ -24,6 +24,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.CheckResult; import org.apache.hop.core.Const; @@ -49,13 +51,15 @@ import org.apache.hop.pipeline.transform.ITransform; import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; -import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; +import org.openide.util.Lookup; /** * Transform That contains the basic skeleton needed to create your own plugin @@ -68,7 +72,12 @@ public class Plc4xRead extends BaseTransform { private Plc4xConnection connmeta = null; private Plc4xWrapperConnection connwrapper = null; private PlcReadRequest readRequest = null; - private PlcReadResponse readResponse = null; + private PlcReadResponse readResponse = null; + + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result result = null; + private int maxwait = 0; private static final ReentrantLock lock = new ReentrantLock(); @@ -231,27 +240,30 @@ public static final RowMetaAndData buildRow(Plc4xReadMeta meta, return new RowMetaAndData(rowMeta, rowData); } - /* - * 1. Block the other instances by means of a lock. - * 2. Try to locate an existing connection. - * 3. If it doesn't exist, it tries to take control of the routine to - * create an instance of PlcConnection and his wrapper. - * 4. Register the connection wrapper for global access. - * 5. If the connection to the PLC is made, then it creates the query - * and executes it. - * TODO: Field validation. - */ - @Override - public boolean processRow() throws HopException { - - Object[] r = getRow(); // Get row from input rowset & set row busy! - setLogLevel(LogLevel.DEBUG); + /* + * 1. Block the other instances by means of a lock. + * 2. Try to locate an existing connection. + * 3. If it doesn't exist, it tries to take control of the routine to + * create an instance of PlcConnection and his wrapper. + * 4. Register the connection wrapper for global access. + * 5. If the connection to the PLC is made, then it creates the query + * and executes it. + * TODO: Field validation. + */ + @Override + public boolean processRow() throws HopException { + System.out.println("*************** PROCESSROW *****************"); + Object[] r = getRow(); // Get row from input rowset & set row busy! + setLogLevel(LogLevel.DEBUG); if ((!meta.isNeverEnding() && data.rowsWritten >= data.rowLimit) && !isStopped()) { setOutputDone(); // signal end to receiver(s) return false; } + System.out.println("Nombre del transform: " + getName() + " : " + getPipeline().getFilename()); + System.out.println("Plc4xRead Objetos registrados: " + getPipeline().getExtensionDataMap().size()); + if (first) { index.clear(); plcfields.clear(); @@ -263,41 +275,51 @@ public boolean processRow() throws HopException { first = false; } - lock.lock(); //(01) - try { - IHopMetadataProvider metaprovider = getMetadataProvider(); - connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); - if (connwrapper == null) { - connwrapper = (Plc4xWrapperConnection) getPipeline().getExtensionDataMap().get(meta.getConnection()); //(02) - if (connwrapper != null) connwrapper.retain(); - }; - - if (connmeta == null){ - logError( - BaseMessages.getString( - PKG, - "Plc4x.Read.Meta.Log.SetMetadata", - meta.getConnection())); - } - - if ((connmeta != null) && (connwrapper == null)){ - readRequest = null; - try{ - PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) - - if (conn.isConnected()) { - connwrapper = new Plc4xWrapperConnection(conn); - getPipeline().getExtensionDataMap().put(meta.getConnection(), connwrapper); //(04) - } - - } catch (Exception ex){ - setErrors(1L); - logError("Unable to create connection to PLC. " + ex.getMessage()); - } - } - } finally { - lock.unlock(); - } +// lock.lock(); //(01) +// try { +// +// IHopMetadataProvider metaprovider = getMetadataProvider(); +// connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); +// +// if (connwrapper == null) { +// template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); +// result = lookup.lookup(template); +// if (!result.allItems().isEmpty()) { +// System.out.println("Aqui encontro la conexion: " + meta.getConnection()); +// connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; +// if (connwrapper != null) connwrapper.retain(); +// } +// }; +// +// if (connmeta == null){ +// logError( +// BaseMessages.getString( +// PKG, +// "Plc4x.Read.Meta.Log.SetMetadata", +// meta.getConnection())); +// } +// +// if ((connmeta != null) && (connwrapper == null)){ +// readRequest = null; +// try{ +// System.out.println("Creo una nueva conexión..."); +// PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) +// +// if (conn.isConnected()) { +// System.out.println("**** Agrego la segunda conexion. ****"); +// connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); +// lookup.add(connwrapper); +// } +// +// } catch (Exception ex){ +// setErrors(1L); +// logError("Unable to create connection to PLC. " + ex.getMessage()); +// } +// } +// +// } finally { +// lock.unlock(); +// } if ((connmeta != null) && (connwrapper != null)){ if (connwrapper.getConnection().isConnected()){ @@ -350,12 +372,15 @@ public boolean processRow() throws HopException { data.prevDate = data.rowDate; data.rowDate = new Date(); int index = 0; + if (!Utils.isEmpty(meta.getRowTimeField())) { r[index++] = data.rowDate; } + if (!Utils.isEmpty(meta.getLastTimeField())) { r[index++] = data.prevDate; } + for (Plc4xGeneratorField field: meta.getFields()){ if (field.getType().equalsIgnoreCase("Boolean")){ r[index++] = Boolean.parseBoolean(field.getValue()); @@ -372,42 +397,45 @@ public boolean processRow() throws HopException { @Override - public boolean init() { - try { - if(super.init()){ - // Determine the number of rows to generate... - data.rowLimit = Const.toLong(resolve(meta.getRowLimit()), -1L); - data.rowsWritten = 0L; - data.delay = Const.toLong(resolve(meta.getIntervalInMs()), -1L); - - if (data.rowLimit < 0L) { // Unable to parse - logError(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Wrong.RowLimit.Number")); - return false; // fail - } - - // Create a row (constants) with all the values in it... - List remarks = new ArrayList<>(); // stores the errors... - RowMetaAndData outputRow = buildRow(meta, remarks, getTransformName()); - if (!remarks.isEmpty()) { - for (int i = 0; i < remarks.size(); i++) { - CheckResult cr = (CheckResult) remarks.get(i); - logError(cr.getText()); - } - return false; - } + public boolean init() { + System.out.println("*************** INIT *****************"); + try { + if(super.init()){ + // Determine the number of rows to generate... + data.rowLimit = Const.toLong(resolve(meta.getRowLimit()), -1L); + data.rowsWritten = 0L; + data.delay = Const.toLong(resolve(meta.getIntervalInMs()), -1L); + + if (data.rowLimit < 0L) { // Unable to parse + logError(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Wrong.RowLimit.Number")); + return false; // fail + } + + // Create a row (constants) with all the values in it... + List remarks = new ArrayList<>(); // stores the errors... + RowMetaAndData outputRow = buildRow(meta, remarks, getTransformName()); + if (!remarks.isEmpty()) { + for (int i = 0; i < remarks.size(); i++) { + CheckResult cr = (CheckResult) remarks.get(i); + logError(cr.getText()); + } + return false; + } - data.outputRowData = outputRow.getData(); - data.outputRowMeta = outputRow.getRowMeta(); + data.outputRowData = outputRow.getData(); + data.outputRowMeta = outputRow.getRowMeta(); - return true; + getPlcConnection(); + + return true; + } + return false; + } catch (Exception ex){ + setErrors(1L); + logError("Error initializing transform", ex); + return false; } - return false; - } catch (Exception ex){ - setErrors(1L); - logError("Error initializing transform", ex); - return false; } - } /* * Here, must perform the cleaning of any resource, main of the connection to @@ -415,10 +443,14 @@ public boolean init() { */ @Override public void cleanup() { + System.out.println("*************** CLEANUP *****************"); super.cleanup(); logBasic("Cleanup. Release connection."); - if (connwrapper != null) - connwrapper.release(); + if (connwrapper != null) { + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); + } } @@ -431,20 +463,68 @@ public void cleanup() { */ @Override public void dispose() { + System.out.println("*************** DISPOSE *****************"); super.dispose(); if (connwrapper != null) { logBasic("Dispose. Release connection: " + connwrapper.refCnt()); - connwrapper.release(); - if (!connwrapper.getConnection().isConnected()){ - getPipeline().getExtensionDataMap().remove(meta.getConnection()); - } + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); connwrapper = null; readRequest = null; } } - + private void getPlcConnection() { + lock.lock(); //(01) + try { + + IHopMetadataProvider metaprovider = getMetadataProvider(); + connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); + + if (connwrapper == null) { + template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); + result = lookup.lookup(template); + if (!result.allItems().isEmpty()) { + System.out.println("Aqui encontro la conexion: " + meta.getConnection()); + connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; + if (connwrapper != null) connwrapper.retain(); + } + }; + + if (connmeta == null){ + logError( + BaseMessages.getString( + PKG, + "Plc4x.Read.Meta.Log.SetMetadata", + meta.getConnection())); + } + + if ((connmeta != null) && (connwrapper == null)){ + readRequest = null; + try{ + System.out.println("Creo una nueva conexión..."); + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) + + if (conn.isConnected()) { + System.out.println("**** Agrego la segunda conexion. ****"); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); + lookup.add(connwrapper); + } + + } catch (Exception ex){ + setErrors(1L); + logError("Unable to create connection to PLC. " + ex.getMessage()); + } + } + + } catch (HopException ex) { + Logger.getLogger(Plc4xRead.class.getName()).log(Level.SEVERE, null, ex); + } finally { + lock.unlock(); + } + } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java index 2f2b718a083..bf71bf6efd4 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java @@ -23,6 +23,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.CheckResult; import org.apache.hop.core.Const; @@ -48,13 +50,15 @@ import org.apache.hop.pipeline.transform.ITransform; import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; -import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.PlcWriteRequest; import org.apache.plc4x.java.api.messages.PlcWriteResponse; +import org.openide.util.Lookup; /** * Transform That contains the basic skeleton needed to create your own plugin @@ -70,6 +74,10 @@ public class Plc4xWrite extends BaseTransform { private PlcWriteRequest.Builder builder = null; private PlcWriteResponse writeResponse = null; + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result result = null; + private static final ReentrantLock lock = new ReentrantLock(); private static final String dummy = "dummy"; @@ -275,39 +283,51 @@ public boolean processRow() throws HopException { return false; } - lock.lock(); //(01) - try { - IHopMetadataProvider metaprovider = getMetadataProvider(); - connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); - if (connwrapper == null) { - connwrapper = (Plc4xWrapperConnection) getPipeline().getExtensionDataMap().get(meta.getConnection()); //(02) - if (connwrapper != null) connwrapper.retain(); - }; - - if (connmeta == null){ - logError( - BaseMessages.getString( - PKG, - "Plc4x.Read.Meta.Log.SetMetadata", - meta.getConnection())); - } - - if ((connmeta != null) && (connwrapper == null)){ - writeRequest = null; - try{ - PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) - if (conn.isConnected()) { - connwrapper = new Plc4xWrapperConnection(conn); - getPipeline().getExtensionDataMap().put(meta.getConnection(), connwrapper); //(04) - } - } catch (Exception ex){ - setErrors(1L); - logError("Unable to create connection to PLC. " + ex.getMessage()); - } - } - } finally { - lock.unlock(); - } +// lock.lock(); //(02) +// try { +// +// IHopMetadataProvider metaprovider = getMetadataProvider(); +// connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); +// +// if (connwrapper == null) { +// template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); //(03) +// result = lookup.lookup(template); +// if (!result.allItems().isEmpty()) { +// System.out.println("Aqui encontro la conexion: " + meta.getConnection()); +// connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; +// if (connwrapper != null) connwrapper.retain(); +// } +// }; +// +// if (connmeta == null){ +// logError( +// BaseMessages.getString( +// PKG, +// "Plc4x.Read.Meta.Log.SetMetadata", +// meta.getConnection())); +// } +// +// if ((connmeta != null) && (connwrapper == null)){ +// writeRequest = null; +// try{ +// System.out.println("Creo una nueva conexión..."); +// PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(04) +// +// if (conn.isConnected()) { +// System.out.println("**** Agrego la segunda conexion. ****"); +// connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); +// lookup.add(connwrapper); //(05) +// } +// +// } catch (Exception ex){ +// setErrors(1L); +// logError("Unable to create connection to PLC. " + ex.getMessage()); +// } +// } +// +// } finally { +// lock.unlock(); +// } if ((connmeta != null) && (connwrapper != null)){ if (connwrapper.getConnection().isConnected()){ @@ -416,7 +436,7 @@ public boolean processRow() throws HopException { @Override public boolean init() { - + System.out.println("*************** INIT *****************"); try { if(super.init()){ // Determine the number of rows to generate... @@ -443,7 +463,9 @@ public boolean init() { data.outputRowData = outputRow.getData(); data.outputRowMeta = outputRow.getRowMeta(); - return true; + getPlcConnection(); + + return true; } return false; } catch (Exception ex){ @@ -460,10 +482,14 @@ public boolean init() { */ @Override public void cleanup() { + System.out.println("*************** CLEANUP *****************"); super.cleanup(); logBasic("Cleanup. Release connection."); - if (connwrapper != null) - connwrapper.release(); + if (connwrapper != null) { + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); + } } @@ -476,20 +502,68 @@ public void cleanup() { */ @Override public void dispose() { + System.out.println("*************** DISPOSE *****************"); super.dispose(); if (connwrapper != null) { logBasic("Dispose. Release connection: " + connwrapper.refCnt()); - connwrapper.release(); - if (!connwrapper.getConnection().isConnected()){ - getPipeline().getExtensionDataMap().remove(meta.getConnection()); - } + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); connwrapper = null; writeRequest = null; } } - + private void getPlcConnection() { + lock.lock(); //(01) + try { + + IHopMetadataProvider metaprovider = getMetadataProvider(); + connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); + + if (connwrapper == null) { + template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); + result = lookup.lookup(template); + if (!result.allItems().isEmpty()) { + System.out.println("Aqui encontro la conexion: " + meta.getConnection()); + connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; + if (connwrapper != null) connwrapper.retain(); + } + }; + + if (connmeta == null){ + logError( + BaseMessages.getString( + PKG, + "Plc4x.Read.Meta.Log.SetMetadata", + meta.getConnection())); + } + + if ((connmeta != null) && (connwrapper == null)){ + writeRequest = null; + try{ + System.out.println("Creo una nueva conexión..."); + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) + + if (conn.isConnected()) { + System.out.println("**** Agrego la segunda conexion. ****"); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); + lookup.add(connwrapper); + } + + } catch (Exception ex){ + setErrors(1L); + logError("Unable to create connection to PLC. " + ex.getMessage()); + } + } + + } catch (HopException ex) { + Logger.getLogger(Plc4xWrite.class.getName()).log(Level.SEVERE, null, ex); + } finally { + lock.unlock(); + } + } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java index 67003bf3b5e..5ed2513993d 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java @@ -27,6 +27,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.CheckResult; import org.apache.hop.core.Const; @@ -52,10 +54,12 @@ import org.apache.hop.pipeline.transform.ITransform; import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xLookup; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; import org.apache.plc4x.hop.transforms.util.Plc4xPlcSubscriptionTag; -import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.metadata.util.Plc4xWrapperConnection; +import org.apache.plc4x.hop.transforms.plc4xinput.Plc4xRead; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.PlcReadRequest; @@ -64,6 +68,7 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest; import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse; import org.apache.plc4x.java.s7.events.S7Event; +import org.openide.util.Lookup; /** * Transform That contains the basic skeleton needed to create your own plugin @@ -71,27 +76,31 @@ */ public class Plc4xSubs extends BaseTransform { - private static final Class PKG = Plc4xSubs.class; // Needed by Translator - - private Plc4xConnection connmeta = null; - private Plc4xWrapperConnection connwrapper = null; - private PlcSubscriptionRequest subsRequest = null; - private PlcSubscriptionResponse subsResponse = null; - private int maxwait = 0; - private static final ReentrantLock lock = new ReentrantLock(); - - private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); - private boolean stopBundle = false; - - private static final String dummy = "dummy"; - - private Map index = new HashMap(); - private Map plctags = new HashMap(); + private static final Class PKG = Plc4xSubs.class; // Needed by Translator + + private Plc4xConnection connmeta = null; + private Plc4xWrapperConnection connwrapper = null; + private PlcSubscriptionRequest subsRequest = null; + private PlcSubscriptionResponse subsResponse = null; + private int maxwait = 0; + private static final ReentrantLock lock = new ReentrantLock(); + + private Plc4xLookup lookup = Plc4xLookup.getDefault(); + private Lookup.Template template = null; + private Lookup.Result result = null; + + private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); + private boolean stopBundle = false; - public Plc4xSubs(TransformMeta transformMeta, Plc4xSubsMeta meta, Plc4xSubsData data, int copyNr, PipelineMeta pipelineMeta, + private static final String dummy = "dummy"; + + private Map index = new HashMap(); + private Map plctags = new HashMap(); + + public Plc4xSubs(TransformMeta transformMeta, Plc4xSubsMeta meta, Plc4xSubsData data, int copyNr, PipelineMeta pipelineMeta, Pipeline pipeline ) { super( transformMeta, meta, data, copyNr, pipelineMeta, pipeline ); - } + } /* * Including Date and Time field for every row @@ -295,7 +304,7 @@ public boolean processRow() throws HopException { try{ PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) if (conn.isConnected()) { - connwrapper = new Plc4xWrapperConnection(conn); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); getPipeline().getExtensionDataMap().put(meta.getConnection(), connwrapper); //(04) } } catch (Exception ex){ @@ -391,6 +400,7 @@ public boolean processRow() throws HopException { @Override public boolean init() { + System.out.println("*************** INIT *****************"); try { if(super.init()){ // Determine the number of rows to generate... @@ -433,10 +443,15 @@ public boolean init() { */ @Override public void cleanup() { + System.out.println("*************** CLEANUP *****************"); + super.cleanup(); super.cleanup(); logBasic("Cleanup. Release connection."); - if (connwrapper != null) - connwrapper.release(); + if (connwrapper != null) { + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); + } } @@ -449,13 +464,13 @@ public void cleanup() { */ @Override public void dispose() { + System.out.println("*************** DISPOSE *****************"); super.dispose(); if (connwrapper != null) { - logBasic("Dispose. Release connection: " + connwrapper.refCnt()); - connwrapper.release(); - if (!connwrapper.getConnection().isConnected()){ - getPipeline().getExtensionDataMap().remove(meta.getConnection()); - } + logBasic("Dispose. Release connection: " + connwrapper.refCnt()); + connwrapper.release(); + if (connwrapper.refCnt() <= 0) + lookup.remove(connwrapper); connwrapper = null; subsRequest = null; } @@ -467,6 +482,56 @@ public void stopRunning() throws HopException { super.stopRunning(); stopBundle = true; } - + + private void getPlcConnection() { + lock.lock(); //(01) + try { + + IHopMetadataProvider metaprovider = getMetadataProvider(); + connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); + + if (connwrapper == null) { + template = new Lookup.Template<>(Plc4xWrapperConnection.class, meta.getConnection(), null); + result = lookup.lookup(template); + if (!result.allItems().isEmpty()) { + System.out.println("Aqui encontro la conexion: " + meta.getConnection()); + connwrapper = (Plc4xWrapperConnection) result.allInstances().toArray()[0]; + if (connwrapper != null) connwrapper.retain(); + } + }; + + if (connmeta == null){ + logError( + BaseMessages.getString( + PKG, + "Plc4x.Read.Meta.Log.SetMetadata", + meta.getConnection())); + } + + if ((connmeta != null) && (connwrapper == null)){ + subsRequest = null; + try{ + System.out.println("Creo una nueva conexión..."); + PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) + + if (conn.isConnected()) { + System.out.println("**** Agrego la segunda conexion. ****"); + connwrapper = new Plc4xWrapperConnection(conn, meta.getConnection()); + lookup.add(connwrapper); + } + + } catch (Exception ex){ + setErrors(1L); + logError("Unable to create connection to PLC. " + ex.getMessage()); + } + } + + } catch (HopException ex) { + Logger.getLogger(Plc4xRead.class.getName()).log(Level.SEVERE, null, ex); + } finally { + lock.unlock(); + } + } + } diff --git a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xRequestType.java b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xRequestType.java index 4e118f5bd43..712be6fdf5e 100644 --- a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xRequestType.java +++ b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xRequestType.java @@ -45,7 +45,7 @@ public enum Plc4xRequestType { } } - private short value; + private final short value; Plc4xRequestType(short value) { this.value = value; diff --git a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xResponseCode.java b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xResponseCode.java index 36b32de966a..03cef96a869 100644 --- a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xResponseCode.java +++ b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xResponseCode.java @@ -44,7 +44,7 @@ public enum Plc4xResponseCode { } } - private short value; + private final short value; Plc4xResponseCode(short value) { this.value = value; diff --git a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xSubscriptionType.java b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xSubscriptionType.java index 9340c3c5547..60f730b3991 100644 --- a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xSubscriptionType.java +++ b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xSubscriptionType.java @@ -36,7 +36,7 @@ public enum Plc4xSubscriptionType { } } - private short value; + private final short value; Plc4xSubscriptionType(short value) { this.value = value; diff --git a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xValueType.java b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xValueType.java index 78ae46a27fb..58e6216e8dc 100644 --- a/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xValueType.java +++ b/plc4j/tools/plc4x-server/src/main/generated/org/apache/plc4x/java/plc4x/readwrite/Plc4xValueType.java @@ -64,7 +64,7 @@ public enum Plc4xValueType { } } - private short value; + private final short value; Plc4xValueType(short value) { this.value = value;