From 0200a86cb1bc895a876c6a63ef118b0e6a948592 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Tue, 10 Jul 2018 11:16:01 +0200 Subject: [PATCH 1/9] SclParser now returns list of ServerModels instead of ServerSaps --- .../openiec61850/ClientAssociation.java | 25 +++++++----------- .../org/openmuc/openiec61850/LogicalNode.java | 6 +++++ .../org/openmuc/openiec61850/SclParser.java | 25 +++++++++++------- .../org/openmuc/openiec61850/ServerSap.java | 26 +------------------ .../openiec61850/app/ConsoleClient.java | 5 +++- .../openiec61850/app/ConsoleServer.java | 7 ++--- .../integrationtests/ClientServerITest.java | 9 +++---- .../integrationtests/ClientServerITest2.java | 9 +++---- .../integrationtests/ReportingTest.java | 9 ++----- .../integrationtests/SclTests.java | 6 ++--- 10 files changed, 53 insertions(+), 74 deletions(-) diff --git a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java index 975489f..18cc4c7 100644 --- a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java @@ -692,22 +692,13 @@ public final class ClientAssociation { } /** - * Parses the given SCL File and returns the server model that is described by it. This function can be used instead - * of retrieveModel in order to get the server model that is needed to call the other ACSI services. - * - * @param sclFilePath - * the path to the SCL file that is to be parsed. - * @return The ServerNode that is the root node of the complete server model. - * @throws SclParseException - * if any kind of fatal error occurs in the parsing process. + * Set the server model instead of retrieving it from the server device. + * + * @param model + * the server model */ - public ServerModel getModelFromSclFile(String sclFilePath) throws SclParseException { - List serverSaps = ServerSap.getSapsFromSclFile(sclFilePath); - if (serverSaps == null || serverSaps.size() == 0) { - throw new SclParseException("No AccessPoint found in SCL file."); - } - serverModel = serverSaps.get(0).serverModel; - return serverModel; + public void setServerModel(ServerModel model) { + this.serverModel = model; } /** @@ -2010,6 +2001,10 @@ public final class ClientAssociation { setDataValues(oper); } + public boolean isOpen() { + return !closed; + } + /** * Will close the connection simply by closing the TCP socket. */ diff --git a/src/main/java/org/openmuc/openiec61850/LogicalNode.java b/src/main/java/org/openmuc/openiec61850/LogicalNode.java index 9b819bf..5f00394 100644 --- a/src/main/java/org/openmuc/openiec61850/LogicalNode.java +++ b/src/main/java/org/openmuc/openiec61850/LogicalNode.java @@ -114,6 +114,12 @@ public final class LogicalNode extends ModelNode { if (fc != null) { return fcDataObjects.get(fc).get(childName); } + for (Map map : fcDataObjects.values()) { + FcDataObject fcDataObject = map.get(childName); + if (fcDataObject != null) { + return fcDataObject; + } + } return null; } diff --git a/src/main/java/org/openmuc/openiec61850/SclParser.java b/src/main/java/org/openmuc/openiec61850/SclParser.java index 3dd6249..5d066b6 100644 --- a/src/main/java/org/openmuc/openiec61850/SclParser.java +++ b/src/main/java/org/openmuc/openiec61850/SclParser.java @@ -45,31 +45,36 @@ import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -final class SclParser { +public class SclParser { private TypeDefinitions typeDefinitions; private final Map dataSetsMap = new HashMap<>(); private Document doc; private String iedName; - private List serverSaps = null; + private List serverModels = null; private boolean useResvTmsAttributes = false; private final List dataSetDefs = new ArrayList<>(); - public List getServerSaps() { - return serverSaps; + public static List parse(InputStream is) throws SclParseException { + SclParser sclParser = new SclParser(); + sclParser.parseStream(is); + return sclParser.serverModels; } - public void parse(String icdFile) throws SclParseException { + public static List parse(String sclFilePath) throws SclParseException { try { - parse(new FileInputStream(icdFile)); + return parse(new FileInputStream(sclFilePath)); } catch (FileNotFoundException e) { throw new SclParseException(e); } } - public void parse(InputStream icdFileStream) throws SclParseException { + private SclParser() { + } + + private void parseStream(InputStream icdFileStream) throws SclParseException { typeDefinitions = new TypeDefinitions(); @@ -104,12 +109,12 @@ final class SclParser { NodeList iedElements = iedList.item(0).getChildNodes(); - serverSaps = new ArrayList<>(iedElements.getLength()); + serverModels = new ArrayList<>(iedElements.getLength()); for (int i = 0; i < iedElements.getLength(); i++) { Node element = iedElements.item(i); String nodeName = element.getNodeName(); if ("AccessPoint".equals(nodeName)) { - serverSaps.add(createAccessPoint(element)); + serverModels.add(createAccessPoint(element).serverModel); } else if ("Services".equals(nodeName)) { NodeList servicesElements = element.getChildNodes(); @@ -174,7 +179,7 @@ final class SclParser { throw new SclParseException("AccessPoint has no name attribute!"); } String name = namedItem.getNodeValue(); - serverSap = new ServerSap(102, 0, null, server, name, null); + serverSap = new ServerSap(102, 0, null, server, null); break; } diff --git a/src/main/java/org/openmuc/openiec61850/ServerSap.java b/src/main/java/org/openmuc/openiec61850/ServerSap.java index cc33027..512c58f 100644 --- a/src/main/java/org/openmuc/openiec61850/ServerSap.java +++ b/src/main/java/org/openmuc/openiec61850/ServerSap.java @@ -17,7 +17,6 @@ package org.openmuc.openiec61850; import java.io.IOException; -import java.io.InputStream; import java.net.InetAddress; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -53,7 +52,6 @@ public final class ServerSap { ServerEventListener serverEventListener; private ServerAcseSap acseSap; - private final String name; private int port = 102; private int backlog = 0; private InetAddress bindAddr = null; @@ -66,18 +64,6 @@ public final class ServerSap { final ServerModel serverModel; - public static List getSapsFromSclFile(String sclFilePath) throws SclParseException { - SclParser sclParserObject = new SclParser(); - sclParserObject.parse(sclFilePath); - return sclParserObject.getServerSaps(); - } - - public static List getSapsFromSclFile(InputStream sclFileStream) throws SclParseException { - SclParser sclParserObject = new SclParser(); - sclParserObject.parse(sclFileStream); - return sclParserObject.getServerSaps(); - } - /** * Creates a ServerSap. * @@ -94,13 +80,12 @@ public final class ServerSap { * default * */ - ServerSap(int port, int backlog, InetAddress bindAddr, ServerModel serverModel, String name, + public ServerSap(int port, int backlog, InetAddress bindAddr, ServerModel serverModel, ServerSocketFactory serverSocketFactory) { this.port = port; this.backlog = backlog; this.bindAddr = bindAddr; this.serverSocketFactory = serverSocketFactory; - this.name = name; this.serverModel = serverModel; } @@ -148,15 +133,6 @@ public final class ServerSap { return bindAddr; } - /** - * Returns the name of the ServerSap / AccessPoint as specified in the SCL file. - * - * @return the name. - */ - public String getName() { - return name; - } - /** * Sets the factory class to generate the ServerSocket. The ServerSocketFactory could be used to create * SSLServerSockets. Set to null to use ServerSocketFactory.getDefault(). diff --git a/src/main/java/org/openmuc/openiec61850/app/ConsoleClient.java b/src/main/java/org/openmuc/openiec61850/app/ConsoleClient.java index ef76f32..697aae4 100644 --- a/src/main/java/org/openmuc/openiec61850/app/ConsoleClient.java +++ b/src/main/java/org/openmuc/openiec61850/app/ConsoleClient.java @@ -17,6 +17,7 @@ import org.openmuc.openiec61850.FcModelNode; import org.openmuc.openiec61850.ModelNode; import org.openmuc.openiec61850.Report; import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.SclParser; import org.openmuc.openiec61850.ServerModel; import org.openmuc.openiec61850.ServiceError; import org.openmuc.openiec61850.Urcb; @@ -374,12 +375,14 @@ public class ConsoleClient { System.out.println("reading model from file..."); try { - serverModel = association.getModelFromSclFile(modelFileParam.getValue()); + serverModel = SclParser.parse(modelFileParam.getValue()).get(0); } catch (SclParseException e1) { System.out.println("Error parsing SCL file: " + e1.getMessage()); return; } + association.setServerModel(serverModel); + System.out.println("successfully read model"); } diff --git a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java index fb73c9a..8afe5e5 100644 --- a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java +++ b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java @@ -17,6 +17,7 @@ import org.openmuc.openiec61850.BdaInt8U; import org.openmuc.openiec61850.Fc; import org.openmuc.openiec61850.ModelNode; import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.SclParser; import org.openmuc.openiec61850.ServerEventListener; import org.openmuc.openiec61850.ServerModel; import org.openmuc.openiec61850.ServerSap; @@ -212,15 +213,15 @@ public class ConsoleServer { System.exit(1); } - List serverSaps = null; + List serverModels = null; try { - serverSaps = ServerSap.getSapsFromSclFile(modelFileParam.getValue()); + serverModels = SclParser.parse(modelFileParam.getValue()); } catch (SclParseException e) { System.out.println("Error parsing SCL/ICD file: " + e.getMessage()); return; } - serverSap = serverSaps.get(0); + serverSap = new ServerSap(102, 0, null, serverModels.get(0), null); serverSap.setPort(portParam.getValue()); Runtime.getRuntime().addShutdownHook(new Thread() { diff --git a/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest.java b/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest.java index fd0e505..66c0f88 100644 --- a/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest.java +++ b/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest.java @@ -31,6 +31,7 @@ import org.openmuc.openiec61850.FcModelNode; import org.openmuc.openiec61850.ModelNode; import org.openmuc.openiec61850.Report; import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.SclParser; import org.openmuc.openiec61850.ServerEventListener; import org.openmuc.openiec61850.ServerModel; import org.openmuc.openiec61850.ServerSap; @@ -77,7 +78,8 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this); // ServerModel serverModel = clientAssociation.retrieveModel(); - ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/openiec61850sample01.icd"); + ServerModel serverModel = SclParser.parse("src/test/resources/openiec61850sample01.icd").get(0); + clientAssociation.setServerModel(serverModel); getAllBdas(serverModel); @@ -366,10 +368,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl private void runServer(String sclFilePath, int port) throws SclParseException, IOException { - List serverSaps = null; - serverSaps = ServerSap.getSapsFromSclFile(sclFilePath); - - serverSap = serverSaps.get(0); + serverSap = new ServerSap(port, 0, null, SclParser.parse(sclFilePath).get(0), null); serverSap.setPort(port); serverSap.startListening(this); serversServerModel = serverSap.getModelCopy(); diff --git a/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest2.java b/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest2.java index 5887d0c..7686f09 100644 --- a/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest2.java +++ b/src/test/java/org/openmuc/openiec61850/integrationtests/ClientServerITest2.java @@ -20,6 +20,7 @@ import org.openmuc.openiec61850.FcModelNode; import org.openmuc.openiec61850.ModelNode; import org.openmuc.openiec61850.Report; import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.SclParser; import org.openmuc.openiec61850.ServerEventListener; import org.openmuc.openiec61850.ServerModel; import org.openmuc.openiec61850.ServerSap; @@ -60,8 +61,8 @@ public class ClientServerITest2 extends Thread implements ServerEventListener, C clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this); - ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/testModel2.icd"); - // ServerModel serverModel = clientAssociation.retrieveModel(); + ServerModel serverModel = SclParser.parse("src/test/resources/testModel2.icd").get(0); + clientAssociation.setServerModel(serverModel); getAllBdas(serverModel); @@ -86,10 +87,8 @@ public class ClientServerITest2 extends Thread implements ServerEventListener, C private void runServer(String sclFilePath, int port) throws SclParseException, IOException { - List serverSaps = null; - serverSaps = ServerSap.getSapsFromSclFile(sclFilePath); + serverSap = new ServerSap(port, 0, null, SclParser.parse(sclFilePath).get(0), null); - serverSap = serverSaps.get(0); serverSap.setPort(port); serverSap.startListening(this); serversServerModel = serverSap.getModelCopy(); diff --git a/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java b/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java index 94246ce..5f9150c 100644 --- a/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java +++ b/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java @@ -22,6 +22,7 @@ import org.openmuc.openiec61850.Fc; import org.openmuc.openiec61850.FcModelNode; import org.openmuc.openiec61850.Report; import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.SclParser; import org.openmuc.openiec61850.ServerEventListener; import org.openmuc.openiec61850.ServerModel; import org.openmuc.openiec61850.ServerSap; @@ -57,14 +58,8 @@ public class ReportingTest implements ClientEventListener { } private void startServer() throws SclParseException, IOException { - final List sapsFromSclFile = ServerSap.getSapsFromSclFile(ICD_FILE); - if (sapsFromSclFile.isEmpty()) { - throw new IllegalArgumentException("Could not create server sap from '" + ICD_FILE + "'."); - } - - this.serverSap = sapsFromSclFile.get(0); - this.serverSap.setPort(PORT); + serverSap = new ServerSap(PORT, 0, null, SclParser.parse(ICD_FILE).get(0), null); this.serverSap.startListening(new ServerEventListener() { diff --git a/src/test/java/org/openmuc/openiec61850/integrationtests/SclTests.java b/src/test/java/org/openmuc/openiec61850/integrationtests/SclTests.java index e7fb7ad..6fcb773 100644 --- a/src/test/java/org/openmuc/openiec61850/integrationtests/SclTests.java +++ b/src/test/java/org/openmuc/openiec61850/integrationtests/SclTests.java @@ -2,7 +2,7 @@ package org.openmuc.openiec61850.integrationtests; import org.junit.Test; import org.openmuc.openiec61850.SclParseException; -import org.openmuc.openiec61850.ServerSap; +import org.openmuc.openiec61850.SclParser; public class SclTests { @@ -12,8 +12,8 @@ public class SclTests { @Test public void testClientServerCom() throws SclParseException { - ServerSap.getSapsFromSclFile(SCL_FILE_PATH_1); - ServerSap.getSapsFromSclFile(SCL_FILE_PATH_2); + SclParser.parse(SCL_FILE_PATH_1); + SclParser.parse(SCL_FILE_PATH_2); } } From 1d5b09e0fc93573765b998fb7df1ea1506c5c5ee Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Thu, 12 Jul 2018 12:35:27 +0200 Subject: [PATCH 2/9] scl parser can now handle multiple IEDs in a single scl file --- .../openiec61850/ClientAssociation.java | 2 +- .../org/openmuc/openiec61850/SclParser.java | 52 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java index 18cc4c7..e7e80e1 100644 --- a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java @@ -568,7 +568,7 @@ public final class ClientAssociation { if (decodedResponsePdu.getConfirmedRequestPDU() != null) { incomingResponses.add(decodedResponsePdu); - throw clientReceiver.getLastIOException(); + throw new IOException("connection was closed", clientReceiver.getLastIOException()); } testForInitiateErrorResponse(decodedResponsePdu); diff --git a/src/main/java/org/openmuc/openiec61850/SclParser.java b/src/main/java/org/openmuc/openiec61850/SclParser.java index 5d066b6..fd4c804 100644 --- a/src/main/java/org/openmuc/openiec61850/SclParser.java +++ b/src/main/java/org/openmuc/openiec61850/SclParser.java @@ -52,7 +52,7 @@ public class SclParser { private Document doc; private String iedName; - private List serverModels = null; + private List serverModels = new ArrayList<>(); private boolean useResvTmsAttributes = false; private final List dataSetDefs = new ArrayList<>(); @@ -100,29 +100,37 @@ public class SclParser { throw new SclParseException("No IED section found!"); } - Node nameAttribute = iedList.item(0).getAttributes().getNamedItem("name"); + for (int z = 0; z < iedList.getLength(); z++) { + Node iedNode = iedList.item(z); - iedName = nameAttribute.getNodeValue(); - if ((iedName == null) || (iedName.length() == 0)) { - throw new SclParseException("IED must have a name!"); - } + useResvTmsAttributes = false; - NodeList iedElements = iedList.item(0).getChildNodes(); + Node nameAttribute = iedNode.getAttributes().getNamedItem("name"); - serverModels = new ArrayList<>(iedElements.getLength()); - for (int i = 0; i < iedElements.getLength(); i++) { - Node element = iedElements.item(i); - String nodeName = element.getNodeName(); - if ("AccessPoint".equals(nodeName)) { - serverModels.add(createAccessPoint(element).serverModel); + iedName = nameAttribute.getNodeValue(); + if ((iedName == null) || (iedName.length() == 0)) { + throw new SclParseException("IED must have a name!"); } - else if ("Services".equals(nodeName)) { - NodeList servicesElements = element.getChildNodes(); - for (int j = 0; j < servicesElements.getLength(); j++) { - if ("ReportSettings".equals(servicesElements.item(j).getNodeName())) { - Node resvTmsAttribute = servicesElements.item(j).getAttributes().getNamedItem("resvTms"); - if (resvTmsAttribute != null) { - useResvTmsAttributes = resvTmsAttribute.getNodeValue().equalsIgnoreCase("true"); + + NodeList iedElements = iedNode.getChildNodes(); + + for (int i = 0; i < iedElements.getLength(); i++) { + Node element = iedElements.item(i); + String nodeName = element.getNodeName(); + if ("AccessPoint".equals(nodeName)) { + ServerSap serverSap = createAccessPoint(element); + if (serverSap != null) { + serverModels.add(serverSap.serverModel); + } + } + else if ("Services".equals(nodeName)) { + NodeList servicesElements = element.getChildNodes(); + for (int j = 0; j < servicesElements.getLength(); j++) { + if ("ReportSettings".equals(servicesElements.item(j).getNodeName())) { + Node resvTmsAttribute = servicesElements.item(j).getAttributes().getNamedItem("resvTms"); + if (resvTmsAttribute != null) { + useResvTmsAttributes = resvTmsAttribute.getNodeValue().equalsIgnoreCase("true"); + } } } } @@ -185,10 +193,6 @@ public class SclParser { } } - if (serverSap == null) { - throw new SclParseException("AccessPoint has no server!"); - } - return serverSap; } From ca47659ebea75c06f5774061f462b2d50dd7701d Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Thu, 12 Jul 2018 12:36:04 +0200 Subject: [PATCH 3/9] set version to 1.6.1 --- configuration.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.gradle b/configuration.gradle index 9f248db..4b95557 100644 --- a/configuration.gradle +++ b/configuration.gradle @@ -1,7 +1,7 @@ project.ext { - cfgVersion = "1.6.1-SNAPSHOT" + cfgVersion = "1.6.1" cfgGroup = "org.openmuc" From aad176e43925f506c852b3d242a840311eef1002 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Thu, 12 Jul 2018 12:40:52 +0200 Subject: [PATCH 4/9] set version to 1.6.2-SNAPSHOT --- configuration.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.gradle b/configuration.gradle index 4b95557..387420c 100644 --- a/configuration.gradle +++ b/configuration.gradle @@ -1,7 +1,7 @@ project.ext { - cfgVersion = "1.6.1" + cfgVersion = "1.6.2-SNAPSHOT" cfgGroup = "org.openmuc" From 0641743072ebacf70658ded00ecebbb7810abe97 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Tue, 21 Aug 2018 13:23:00 +0200 Subject: [PATCH 5/9] sample server now supports writing booleans --- .../java/org/openmuc/openiec61850/app/ConsoleServer.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java index 8afe5e5..36cf13a 100644 --- a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java +++ b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import org.openmuc.openiec61850.BasicDataAttribute; +import org.openmuc.openiec61850.BdaBoolean; import org.openmuc.openiec61850.BdaFloat32; import org.openmuc.openiec61850.BdaFloat64; import org.openmuc.openiec61850.BdaInt16; @@ -182,6 +183,10 @@ public class ConsoleServer { long value = Long.parseLong(valueString); ((BdaInt64) bda).setValue(value); } + else if (bda instanceof BdaBoolean) { + boolean value = Boolean.parseBoolean(valueString); + ((BdaBoolean) bda).setValue(value); + } else { throw new IllegalArgumentException(); } From 484152d1bafd4cac84f280e693225d258b56108b Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Fri, 21 Sep 2018 13:12:00 +0200 Subject: [PATCH 6/9] changed jasn1 dependency to jasn1-iec61850mod so that boolean true values are coded as 0x01 instead of 0xff because it is need by some devices --- configuration.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.gradle b/configuration.gradle index 387420c..a98fb57 100644 --- a/configuration.gradle +++ b/configuration.gradle @@ -83,7 +83,7 @@ def projectName = 'OpenIEC61850' dependencies { compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' - compile group: 'org.openmuc', name: 'jasn1', version: '1.10.0' + compile group: 'org.openmuc', name: 'jasn1-iec61850mod', version: '1.10.0' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' compile group: 'com.toedter', name: 'jcalendar', version: '1.4' } From 648d839df7689710ea1a9859eeaa37b2b2e17e1d Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Tue, 6 Nov 2018 09:31:02 +0100 Subject: [PATCH 7/9] fixed typo in console server --- src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java index 36cf13a..c022f2b 100644 --- a/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java +++ b/src/main/java/org/openmuc/openiec61850/app/ConsoleServer.java @@ -90,9 +90,7 @@ public class ConsoleServer { break; case WRITE_VALUE_KEY: - System.out.println("** Reading model from file."); - - System.out.println("Enter reference to read (e.g. myld/MYLN0.do.da.bda): "); + System.out.println("Enter reference to write (e.g. myld/MYLN0.do.da.bda): "); String reference = actionProcessor.getReader().readLine(); System.out.println("Enter functional constraint of referenced node: "); String fcString = actionProcessor.getReader().readLine(); From 1c24852d77792f7c2f420558285e2e0cd163d8c3 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Tue, 6 Nov 2018 14:42:45 +0100 Subject: [PATCH 8/9] fixed correct shutdown of server thread pools --- .../openmuc/jositransport/ServerThread.java | 4 ++- .../openiec61850/ServerAssociation.java | 4 ++- .../internal/NamedDefaultThreadFactory.java | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/openmuc/openiec61850/internal/NamedDefaultThreadFactory.java diff --git a/src/main/java/org/openmuc/jositransport/ServerThread.java b/src/main/java/org/openmuc/jositransport/ServerThread.java index 27aff2b..aa11ce0 100644 --- a/src/main/java/org/openmuc/jositransport/ServerThread.java +++ b/src/main/java/org/openmuc/jositransport/ServerThread.java @@ -16,6 +16,8 @@ */ package org.openmuc.jositransport; +import org.openmuc.openiec61850.internal.NamedDefaultThreadFactory; + import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; @@ -88,7 +90,7 @@ final class ServerThread extends Thread { @Override public void run() { - ExecutorService executor = Executors.newCachedThreadPool(); + ExecutorService executor = Executors.newCachedThreadPool(new NamedDefaultThreadFactory("openiec61850-osi-server")); try { Socket clientSocket = null; diff --git a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java index e8da14c..da33a12 100644 --- a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java @@ -40,6 +40,7 @@ import org.openmuc.jasn1.ber.types.string.BerVisibleString; import org.openmuc.josistack.AcseAssociation; import org.openmuc.josistack.ByteBufferInputStream; import org.openmuc.josistack.DecodingException; +import org.openmuc.openiec61850.internal.NamedDefaultThreadFactory; import org.openmuc.openiec61850.internal.mms.asn1.AccessResult; import org.openmuc.openiec61850.internal.mms.asn1.ConfirmedErrorPDU; import org.openmuc.openiec61850.internal.mms.asn1.ConfirmedRequestPDU; @@ -118,7 +119,7 @@ final class ServerAssociation { public ServerAssociation(ServerSap serverSap) { this.serverSap = serverSap; serverModel = serverSap.serverModel; - executor = Executors.newScheduledThreadPool(2); + executor = Executors.newScheduledThreadPool(2, new NamedDefaultThreadFactory("openiec61850-server-connection")); } public void handleNewAssociation(AcseAssociation acseAssociation, ByteBuffer associationRequest) { @@ -1635,6 +1636,7 @@ final class ServerAssociation { void close() { cleanUpConnection(); + executor.shutdown(); if (acseAssociation != null) { acseAssociation.disconnect(); } diff --git a/src/main/java/org/openmuc/openiec61850/internal/NamedDefaultThreadFactory.java b/src/main/java/org/openmuc/openiec61850/internal/NamedDefaultThreadFactory.java new file mode 100644 index 0000000..dbbe307 --- /dev/null +++ b/src/main/java/org/openmuc/openiec61850/internal/NamedDefaultThreadFactory.java @@ -0,0 +1,30 @@ +package org.openmuc.openiec61850.internal; + +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +public class NamedDefaultThreadFactory implements ThreadFactory { + + private static final AtomicInteger factoryCounter = new AtomicInteger(1); + private final AtomicInteger threadCounter = new AtomicInteger(1); + private final String namePrefix; + private ThreadFactory backingDefaultThreadFactory = Executors.defaultThreadFactory(); + + public NamedDefaultThreadFactory(String namePrefix) { + this.namePrefix = namePrefix; + } + + @Override + public Thread newThread(Runnable r) { + Thread thread = backingDefaultThreadFactory.newThread(r); + String threadName = + namePrefix + + "-" + + factoryCounter.getAndIncrement() + + "-thread-" + + threadCounter.getAndIncrement(); + thread.setName(threadName); + return thread; + } +} From 56fee3cf1984c856346eaa0c86456aeccb10e070 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Tue, 6 Nov 2018 14:43:05 +0100 Subject: [PATCH 9/9] made values of BDAs volatile so they are thread save --- src/main/java/org/openmuc/openiec61850/BdaBitString.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaBoolean.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaEntryTime.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaFloat32.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaFloat64.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt128.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt16.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt16U.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt32.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt32U.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt64.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt8.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaInt8U.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaOctetString.java | 2 +- src/main/java/org/openmuc/openiec61850/BdaTimestamp.java | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/openmuc/openiec61850/BdaBitString.java b/src/main/java/org/openmuc/openiec61850/BdaBitString.java index e1e1244..34217df 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaBitString.java +++ b/src/main/java/org/openmuc/openiec61850/BdaBitString.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.TypeDescription; abstract public class BdaBitString extends BasicDataAttribute { - byte[] value; + volatile byte[] value; final int maxNumBits; public BdaBitString(ObjectReference objectReference, Fc fc, String sAddr, int maxNumBits, boolean dchg, diff --git a/src/main/java/org/openmuc/openiec61850/BdaBoolean.java b/src/main/java/org/openmuc/openiec61850/BdaBoolean.java index 996e478..0f2189c 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaBoolean.java +++ b/src/main/java/org/openmuc/openiec61850/BdaBoolean.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.TypeDescription; public final class BdaBoolean extends BasicDataAttribute { - private boolean value; + volatile private boolean value; public BdaBoolean(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaEntryTime.java b/src/main/java/org/openmuc/openiec61850/BdaEntryTime.java index f34ba7b..4fad5c1 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaEntryTime.java +++ b/src/main/java/org/openmuc/openiec61850/BdaEntryTime.java @@ -30,7 +30,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.TypeDescription; */ public final class BdaEntryTime extends BasicDataAttribute { - private byte[] value; + volatile private byte[] value; public BdaEntryTime(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaFloat32.java b/src/main/java/org/openmuc/openiec61850/BdaFloat32.java index 451d74d..b96e146 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaFloat32.java +++ b/src/main/java/org/openmuc/openiec61850/BdaFloat32.java @@ -25,7 +25,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaFloat32 extends BasicDataAttribute { - private byte[] value; + volatile private byte[] value; public BdaFloat32(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaFloat64.java b/src/main/java/org/openmuc/openiec61850/BdaFloat64.java index 580672f..e5637b3 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaFloat64.java +++ b/src/main/java/org/openmuc/openiec61850/BdaFloat64.java @@ -25,7 +25,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaFloat64 extends BasicDataAttribute { - private byte[] value = new byte[] { 11, 0, 0, 0, 0, 0, 0, 0, 0 }; + volatile private byte[] value = new byte[] { 11, 0, 0, 0, 0, 0, 0, 0, 0 }; public BdaFloat64(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt128.java b/src/main/java/org/openmuc/openiec61850/BdaInt128.java index 489577f..3b59c0d 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt128.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt128.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt128 extends BasicDataAttribute { - private long value; + volatile private long value; public BdaInt128(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt16.java b/src/main/java/org/openmuc/openiec61850/BdaInt16.java index 4e15123..c14d44b 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt16.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt16.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt16 extends BasicDataAttribute { - private short value; + volatile private short value; public BdaInt16(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt16U.java b/src/main/java/org/openmuc/openiec61850/BdaInt16U.java index 2b2508d..ac1bf22 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt16U.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt16U.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt16U extends BasicDataAttribute { - private int value; + volatile private int value; public BdaInt16U(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt32.java b/src/main/java/org/openmuc/openiec61850/BdaInt32.java index 2ee7b5b..c9ebec7 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt32.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt32.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt32 extends BasicDataAttribute { - private int value; + volatile private int value; public BdaInt32(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt32U.java b/src/main/java/org/openmuc/openiec61850/BdaInt32U.java index 956a75d..7f84330 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt32U.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt32U.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt32U extends BasicDataAttribute { - private long value; + volatile private long value; public BdaInt32U(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt64.java b/src/main/java/org/openmuc/openiec61850/BdaInt64.java index d1b2eea..c8669f7 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt64.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt64.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt64 extends BasicDataAttribute { - private long value; + volatile private long value; public BdaInt64(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt8.java b/src/main/java/org/openmuc/openiec61850/BdaInt8.java index 81f833a..44234fe 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt8.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt8.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt8 extends BasicDataAttribute { - private byte value; + volatile private byte value; public BdaInt8(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaInt8U.java b/src/main/java/org/openmuc/openiec61850/BdaInt8U.java index 5f94a38..e313de3 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaInt8U.java +++ b/src/main/java/org/openmuc/openiec61850/BdaInt8U.java @@ -23,7 +23,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.Unsigned8; public final class BdaInt8U extends BasicDataAttribute { - private short value; + volatile private short value; public BdaInt8U(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd); diff --git a/src/main/java/org/openmuc/openiec61850/BdaOctetString.java b/src/main/java/org/openmuc/openiec61850/BdaOctetString.java index 91232a0..bab086e 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaOctetString.java +++ b/src/main/java/org/openmuc/openiec61850/BdaOctetString.java @@ -25,7 +25,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.TypeDescription; public final class BdaOctetString extends BasicDataAttribute { - private byte[] value; + volatile private byte[] value; private final int maxLength; public BdaOctetString(ObjectReference objectReference, Fc fc, String sAddr, int maxLength, boolean dchg, diff --git a/src/main/java/org/openmuc/openiec61850/BdaTimestamp.java b/src/main/java/org/openmuc/openiec61850/BdaTimestamp.java index 782dfed..db6c7c0 100644 --- a/src/main/java/org/openmuc/openiec61850/BdaTimestamp.java +++ b/src/main/java/org/openmuc/openiec61850/BdaTimestamp.java @@ -26,7 +26,7 @@ import org.openmuc.openiec61850.internal.mms.asn1.UtcTime; public final class BdaTimestamp extends BasicDataAttribute { - private byte[] value; + volatile private byte[] value; public BdaTimestamp(ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) { super(objectReference, fc, sAddr, dchg, dupd);