From 6ed7849a1a5b86531ab821fea8701cdc7a6f2245 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Thu, 14 Sep 2017 10:11:11 +0200 Subject: [PATCH] added test for reporting of dynamically created datasets, fixed bugs to get test running --- .../openiec61850/ServerAssociation.java | 8 +- .../org/openmuc/openiec61850/ServerModel.java | 2 +- .../integrationtests/ReportingTest.java | 182 ++++++++++++++++++ 3 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java diff --git a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java index 55c1731..9030930 100644 --- a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java @@ -696,7 +696,8 @@ final class ServerAssociation { + getVariableAccessAttributesRequest.getName() .getDomainSpecific() .getDomainID() - + " and ItemID " + getVariableAccessAttributesRequest.getName() + + " and ItemID " + + getVariableAccessAttributesRequest.getName() .getDomainSpecific() .getItemID() + " was found."); @@ -1304,7 +1305,7 @@ final class ServerAssociation { } else if (nodeName.equals("DatSet")) { if ((urcb.reserved == null || urcb.reserved == this) && !urcb.enabled) { - String dataSetRef = ((BdaVisibleString) fcModelNodeCopy).getStringValue(); + String dataSetRef = ((BdaVisibleString) fcModelNodeCopy).getStringValue().replace('$', '.'); if (dataSetRef.isEmpty()) { urcb.dataSet = null; ((BasicDataAttribute) modelNode).setValueFrom((BasicDataAttribute) fcModelNodeCopy); @@ -1313,6 +1314,9 @@ final class ServerAssociation { } else { DataSet dataSet = serverModel.getDataSet(dataSetRef); + if (dataSet == null) { + dataSet = nonPersistentDataSets.get(dataSetRef); + } if (dataSet != null) { urcb.dataSet = dataSet; ((BasicDataAttribute) modelNode).setValueFrom((BasicDataAttribute) fcModelNodeCopy); diff --git a/src/main/java/org/openmuc/openiec61850/ServerModel.java b/src/main/java/org/openmuc/openiec61850/ServerModel.java index 0c26bd9..e394988 100644 --- a/src/main/java/org/openmuc/openiec61850/ServerModel.java +++ b/src/main/java/org/openmuc/openiec61850/ServerModel.java @@ -91,7 +91,7 @@ public final class ServerModel extends ModelNode { } void addDataSet(DataSet dataSet) { - dataSets.put(dataSet.getReferenceStr(), dataSet); + dataSets.put(dataSet.getReferenceStr().replace('$', '.'), dataSet); for (ModelNode ld : children.values()) { for (ModelNode ln : ld.getChildren()) { for (Urcb urcb : ((LogicalNode) ln).getUrcbs()) { diff --git a/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java b/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java new file mode 100644 index 0000000..94246ce --- /dev/null +++ b/src/test/java/org/openmuc/openiec61850/integrationtests/ReportingTest.java @@ -0,0 +1,182 @@ +package org.openmuc.openiec61850.integrationtests; + +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmuc.openiec61850.BasicDataAttribute; +import org.openmuc.openiec61850.BdaFloat32; +import org.openmuc.openiec61850.ClientAssociation; +import org.openmuc.openiec61850.ClientEventListener; +import org.openmuc.openiec61850.ClientSap; +import org.openmuc.openiec61850.DataSet; +import org.openmuc.openiec61850.Fc; +import org.openmuc.openiec61850.FcModelNode; +import org.openmuc.openiec61850.Report; +import org.openmuc.openiec61850.SclParseException; +import org.openmuc.openiec61850.ServerEventListener; +import org.openmuc.openiec61850.ServerModel; +import org.openmuc.openiec61850.ServerSap; +import org.openmuc.openiec61850.ServiceError; +import org.openmuc.openiec61850.Urcb; + +public class ReportingTest implements ClientEventListener { + + private static final String PREEXISTING_DATASET_REFERENCE = "ied1lDevice1/LLN0$dataset1"; + private static final String CREATED_DATASET_REFERENCE = "ied1lDevice1/LLN0$datasetnew"; + private static final String CHANGING_SERVER_DA_REFERENCE_1 = "ied1lDevice1/MMXU1.W.phsA.cVal.mag.f"; + private static final String CHANGING_SERVER_DA_REFERENCE_2 = "ied1lDevice1/DSCH1.SchdAbsTm.sptestval1"; + private static final int PORT = 54321; + private static final String ICD_FILE = "src/test/resources/openiec61850sample01.icd"; + private static final String URCB1_REFERENCE = "ied1lDevice1/LLN0.urcb101"; + + private ServerSap serverSap; + private ServerModel serverModel; + private ServerModel clientModel; + ClientAssociation clientAssociation; + private int reportCounter = 0; + + @Before + public void startServerAndClient() throws SclParseException, UnknownHostException, IOException, ServiceError { + startServer(); + startClient(); + } + + private void startClient() throws IOException, UnknownHostException, ServiceError { + ClientSap clientSap = new ClientSap(); + this.clientAssociation = clientSap.associate(InetAddress.getByName("localhost"), PORT, "", this); + this.clientModel = this.clientAssociation.retrieveModel(); + } + + 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); + + this.serverSap.startListening(new ServerEventListener() { + + @Override + public List write(List arg0) { + return null; + } + + @Override + public void serverStoppedListening(ServerSap arg0) { + } + }); + + this.serverModel = this.serverSap.getModelCopy(); + } + + @Test + public void reportingTest() throws ServiceError, IOException, InterruptedException { + Urcb urcb = this.clientModel.getUrcb(URCB1_REFERENCE); + assertNotNull(urcb); + + this.clientAssociation.getRcbValues(urcb); + this.clientAssociation.reserveUrcb(urcb); + this.clientAssociation.enableReporting(urcb); + + Thread.sleep(500); + + BdaFloat32 mag = (BdaFloat32) this.serverModel.findModelNode(CHANGING_SERVER_DA_REFERENCE_1, Fc.MX); + Assert.assertNotNull(mag); + Assert.assertEquals(0, this.reportCounter); + + mag.setFloat(new Float(3.0)); + List bdas = new ArrayList<>(); + bdas.add(mag); + this.serverSap.setValues(bdas); + + Thread.sleep(500); + + Assert.assertEquals(1, this.reportCounter); + + } + + @Test + public void reportingWithCreatedDataSetTest() throws ServiceError, IOException, InterruptedException { + // BdaFloat32 clientMag = (BdaFloat32)this.clientModel.findModelNode(CHANGING_SERVER_DA_REFERENCE, Fc.MX); + + FcModelNode clientMag = (FcModelNode) this.clientModel.findModelNode(CHANGING_SERVER_DA_REFERENCE_1, Fc.MX); + assertNotNull(clientMag); + List dataSetMembers = new ArrayList<>(); + dataSetMembers.add(clientMag); + + DataSet dataSet = new DataSet(CREATED_DATASET_REFERENCE, dataSetMembers); + this.clientAssociation.createDataSet(dataSet); + + Urcb urcb = this.clientModel.getUrcb(URCB1_REFERENCE); + assertNotNull(urcb); + + this.clientAssociation.getRcbValues(urcb); + + Assert.assertEquals(PREEXISTING_DATASET_REFERENCE, urcb.getDatSet().getStringValue()); + + System.out.println("dataset: " + urcb.getDatSet().getStringValue()); + + this.clientAssociation.reserveUrcb(urcb); + + urcb.getDatSet().setValue(CREATED_DATASET_REFERENCE); + List serviceErrors = this.clientAssociation.setRcbValues(urcb, false, true, false, false, false, + false, false, false); + + Assert.assertNull(serviceErrors.get(0)); + + this.clientAssociation.getRcbValues(urcb); + + Assert.assertEquals(CREATED_DATASET_REFERENCE, urcb.getDatSet().getStringValue()); + + this.clientAssociation.enableReporting(urcb); + + Thread.sleep(500); + + BdaFloat32 mag = (BdaFloat32) this.serverModel.findModelNode(CHANGING_SERVER_DA_REFERENCE_1, Fc.MX); + Assert.assertNotNull(mag); + Assert.assertEquals(0, this.reportCounter); + + mag.setFloat(new Float(3.0)); + List bdas = new ArrayList<>(); + bdas.add(mag); + this.serverSap.setValues(bdas); + + Thread.sleep(1_000); + + Assert.assertEquals(1, this.reportCounter); + + } + + @After + public void disconnectAndStopServer() throws Exception { + if (this.serverSap != null) { + this.serverSap.stop(); + } + + } + + @Override + public void associationClosed(IOException arg0) { + } + + @Override + public void newReport(Report arg0) { + System.out.println("got a report."); + synchronized (this) { + this.reportCounter++; + } + } + +}