| | |
| | | package org.openmuc.openiec61850.integrationtests; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.InetAddress; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | import javax.naming.ConfigurationException; |
| | | |
| | | import org.junit.Assert; |
| | | import org.junit.Test; |
| | | import org.openmuc.openiec61850.BasicDataAttribute; |
| | | import org.openmuc.openiec61850.BdaBoolean; |
| | | import org.openmuc.openiec61850.BdaFloat32; |
| | | import org.openmuc.openiec61850.BdaInt32; |
| | | import org.openmuc.openiec61850.BdaInt32U; |
| | | import org.openmuc.openiec61850.BdaQuality; |
| | | import org.openmuc.openiec61850.BdaQuality.Validity; |
| | | import org.openmuc.openiec61850.BdaReasonForInclusion; |
| | | import org.openmuc.openiec61850.BdaTimestamp; |
| | | import org.openmuc.openiec61850.BdaVisibleString; |
| | | 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.ModelNode; |
| | | 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 ClientServerITest extends Thread implements ServerEventListener, ClientEventListener { |
| | | |
| | | int port = 54321; |
| | | String host = "127.0.0.1"; |
| | | ClientSap clientSap = new ClientSap(); |
| | | ServerSap serverSap = null; |
| | | ClientAssociation clientAssociation = null; |
| | | ClientAssociation clientAssociation2 = null; |
| | | ServerModel serversServerModel = null; |
| | | private static int numReports = 0; |
| | | private static int numSuccess = 0; |
| | | private static int numAssociationClosed = 0; |
| | | |
| | | // Get the Java runtime |
| | | public static Runtime runtime = Runtime.getRuntime(); |
| | | |
| | | @Test |
| | | public void testClientServerCom() throws IOException, ServiceError, ConfigurationException, |
| | | javax.naming.ConfigurationException, SclParseException, InterruptedException { |
| | | |
| | | clientSap.setTSelRemote(new byte[] { 0, 1 }); |
| | | clientSap.setTSelLocal(new byte[] { 0, 0 }); |
| | | clientSap.setApTitleCalled(new int[] { 1, 1, 999, 1 }); |
| | | BdaTimestamp timestamp; |
| | | BdaVisibleString namePlateVendor; |
| | | |
| | | // --------------------------------------------------- |
| | | // ------------------1st test server------------------ |
| | | runServer("src/test/resources/openiec61850sample01.icd", port); |
| | | System.out.println("IED Server is running"); |
| | | |
| | | // ----------------------------------------------------------- |
| | | // Client |
| | | // ----------------------------------------------------------- |
| | | |
| | | System.out.println("Attempting to connect to server " + host + " on port " + port); |
| | | |
| | | clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this); |
| | | |
| | | // ServerModel serverModel = clientAssociation.retrieveModel(); |
| | | ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/openiec61850sample01.icd"); |
| | | |
| | | getAllBdas(serverModel); |
| | | |
| | | timestamp = (BdaTimestamp) serverModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX); |
| | | clientAssociation.getDataValues(timestamp); |
| | | |
| | | namePlateVendor = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/LLN0.NamPlt.vendor", Fc.DC); |
| | | namePlateVendor.setValue("Fraunhofer ISE".getBytes()); |
| | | clientAssociation.setDataValues(namePlateVendor); |
| | | namePlateVendor.setDefault(); |
| | | clientAssociation.getDataValues(namePlateVendor); |
| | | |
| | | Assert.assertEquals("Fraunhofer ISE", new String(namePlateVendor.getValue())); |
| | | |
| | | // -------------Test DataSets-Start--------------------- |
| | | |
| | | Collection<DataSet> dataSets = serverModel.getDataSets(); |
| | | Assert.assertEquals(2, dataSets.size()); |
| | | |
| | | DataSet dataSet1 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset1"); |
| | | |
| | | Assert.assertEquals("ied1lDevice1/LLN0.dataset1", dataSet1.getReferenceStr()); |
| | | |
| | | DataSet dataSet2 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset2"); |
| | | |
| | | Assert.assertEquals("ied1lDevice1/LLN0.dataset2", dataSet2.getReferenceStr()); |
| | | |
| | | for (FcModelNode dataSet2Member : dataSet2) { |
| | | ((BdaInt32) dataSet2Member).setValue(9); |
| | | } |
| | | |
| | | clientAssociation.setDataSetValues(dataSet2); |
| | | |
| | | dataSet1 = serverModel.getDataSet(dataSet1.getReferenceStr()); |
| | | |
| | | clientAssociation.getDataSetValues(dataSet1); |
| | | |
| | | List<FcModelNode> nonPersistentDataSetMembers = new ArrayList<>(2); |
| | | nonPersistentDataSetMembers.add(namePlateVendor); |
| | | nonPersistentDataSetMembers.add(timestamp); |
| | | |
| | | DataSet nonPersistentDataSet = new DataSet("@nonPersistentDataSet", nonPersistentDataSetMembers); |
| | | |
| | | clientAssociation.createDataSet(nonPersistentDataSet); |
| | | |
| | | namePlateVendor.setDefault(); |
| | | |
| | | List<ServiceError> serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet); |
| | | |
| | | for (ServiceError serviceError : serviceErrors) { |
| | | Assert.assertNull(serviceError); |
| | | } |
| | | |
| | | Assert.assertTrue("Fraunhofer ISE".equals(new String(namePlateVendor.getValue()))); |
| | | |
| | | clientAssociation.deleteDataSet(nonPersistentDataSet); |
| | | |
| | | serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet); |
| | | |
| | | Assert.assertEquals(2, serviceErrors.size()); |
| | | |
| | | for (ServiceError serviceError : serviceErrors) { |
| | | Assert.assertNotNull(serviceError); |
| | | } |
| | | |
| | | // -------------Test DataSets-End--------------------- |
| | | |
| | | serverModel.findModelNode("ied1lDevice1/MMXU1.TotW", Fc.MX); |
| | | |
| | | BdaFloat32 f = (BdaFloat32) serverModel.findModelNode("ied1lDevice1/MMXU1.W.phsA.cVal.mag.f", Fc.MX); |
| | | |
| | | f.setFloat(3.0f); |
| | | |
| | | Assert.assertEquals(f.getFloat(), 3.0f, 0.00001); |
| | | |
| | | clientAssociation.getDataSetValues(dataSet1); |
| | | |
| | | Assert.assertEquals(f.getFloat(), 0.0f, 0.00001); |
| | | |
| | | /* Test selecting a controllable Data Object */ |
| | | |
| | | BdaInt32U sboTimeout = (BdaInt32U) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.sboTimeout", Fc.CF); |
| | | sboTimeout.setValue(2000l); |
| | | |
| | | BdaVisibleString sbo = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO); |
| | | |
| | | Assert.assertNotNull(sbo); |
| | | |
| | | clientAssociation.getDataValues(sbo); |
| | | |
| | | Assert.assertTrue(sbo.getStringValue().equals("success")); |
| | | |
| | | clientAssociation.getDataValues(sbo); |
| | | |
| | | Assert.assertEquals(sbo.getStringValue(), "success"); |
| | | |
| | | /* select with second connection */ |
| | | |
| | | clientAssociation2 = clientSap.associate(InetAddress.getByName(host), port, null, this); |
| | | ServerModel serverModel2 = clientAssociation2.retrieveModel(); |
| | | |
| | | BdaVisibleString sbo2 = (BdaVisibleString) serverModel2.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO); |
| | | |
| | | clientAssociation2.getDataValues(sbo2); |
| | | Assert.assertEquals(sbo2.getStringValue(), ""); |
| | | |
| | | /* select with second connection after the sboTimeout of 1000ms should have been run out */ |
| | | |
| | | // clientAssociation.close(); |
| | | |
| | | try { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | clientAssociation2.getDataValues(sbo2); |
| | | Assert.assertEquals(sbo2.getStringValue(), "success"); |
| | | |
| | | /* select with first connnection after the second was quit */ |
| | | |
| | | clientAssociation.getDataValues(sbo); |
| | | Assert.assertEquals(sbo.getStringValue(), ""); |
| | | |
| | | clientAssociation2.close(); |
| | | |
| | | try { |
| | | Thread.sleep(100); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | clientAssociation.getDataValues(sbo); |
| | | Assert.assertEquals(sbo.getStringValue(), "success"); |
| | | |
| | | FcModelNode switchPosAFcDo = (FcModelNode) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA", Fc.CO); |
| | | |
| | | Assert.assertNotNull(switchPosAFcDo); |
| | | |
| | | clientAssociation.operate(switchPosAFcDo); |
| | | |
| | | // -------------Test Reporting-Start------------------- |
| | | |
| | | Urcb urcb1 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb101"); |
| | | Assert.assertNotNull(urcb1); |
| | | |
| | | Urcb urcb2 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb2"); |
| | | Assert.assertNotNull(urcb2); |
| | | |
| | | clientAssociation.getRcbValues(urcb1); |
| | | clientAssociation.getRcbValues(urcb2); |
| | | |
| | | BdaBoolean resv = (BdaBoolean) urcb1.getChild("Resv"); |
| | | Assert.assertNotNull(resv); |
| | | clientAssociation.getDataValues(resv); |
| | | Assert.assertFalse(resv.getValue()); |
| | | clientAssociation.reserveUrcb(urcb1); |
| | | clientAssociation.getDataValues(resv); |
| | | Assert.assertTrue(resv.getValue()); |
| | | |
| | | Assert.assertEquals("urcb1", urcb1.getRptId().getStringValue()); |
| | | Assert.assertEquals("ied1lDevice1/LLN0.urcb2", urcb2.getRptId().getStringValue()); |
| | | |
| | | Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb1.getDatSet().getStringValue()); |
| | | Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb2.getDatSet().getStringValue()); |
| | | |
| | | Assert.assertEquals(true, urcb1.getOptFlds().isDataSetName()); |
| | | Assert.assertEquals(false, urcb1.getOptFlds().isBufferOverflow()); |
| | | Assert.assertEquals(false, urcb1.getOptFlds().isConfigRevision()); |
| | | Assert.assertEquals(false, urcb1.getOptFlds().isDataReference()); |
| | | Assert.assertEquals(false, urcb1.getOptFlds().isEntryId()); |
| | | Assert.assertEquals(true, urcb1.getOptFlds().isReasonForInclusion()); |
| | | Assert.assertEquals(true, urcb1.getOptFlds().isReportTimestamp()); |
| | | Assert.assertEquals(false, urcb1.getOptFlds().isSegmentation()); |
| | | Assert.assertEquals(true, urcb1.getOptFlds().isSequenceNumber()); |
| | | |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isDataSetName()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isBufferOverflow()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isConfigRevision()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isDataReference()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isEntryId()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isReasonForInclusion()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isReportTimestamp()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isSegmentation()); |
| | | Assert.assertEquals(false, urcb2.getOptFlds().isSequenceNumber()); |
| | | |
| | | Assert.assertEquals(50L, urcb1.getBufTm().getValue()); |
| | | |
| | | Assert.assertEquals(true, urcb1.getTrgOps().isDataChange()); |
| | | Assert.assertEquals(true, urcb1.getTrgOps().isDataUpdate()); |
| | | Assert.assertEquals(true, urcb1.getTrgOps().isGeneralInterrogation()); |
| | | Assert.assertEquals(false, urcb1.getTrgOps().isIntegrity()); |
| | | Assert.assertEquals(true, urcb1.getTrgOps().isQualityChange()); |
| | | |
| | | Assert.assertEquals(false, urcb2.getTrgOps().isDataChange()); |
| | | Assert.assertEquals(false, urcb2.getTrgOps().isDataUpdate()); |
| | | Assert.assertEquals(true, urcb2.getTrgOps().isGeneralInterrogation()); |
| | | Assert.assertEquals(false, urcb2.getTrgOps().isIntegrity()); |
| | | Assert.assertEquals(false, urcb2.getTrgOps().isQualityChange()); |
| | | |
| | | Assert.assertEquals(5000L, urcb1.getIntgPd().getValue()); |
| | | |
| | | Assert.assertEquals(0, urcb1.getSqNum().getValue()); |
| | | |
| | | Assert.assertEquals(0L, urcb1.getConfRev().getValue()); |
| | | |
| | | urcb1.getRptId().setValue("myurcb1"); |
| | | urcb1.getTrgOps().setGeneralInterrogation(false); |
| | | urcb1.getTrgOps().setDataUpdate(false); |
| | | urcb1.getTrgOps().setDataChange(false); |
| | | |
| | | clientAssociation.setRcbValues(urcb1, true, true, true, true, true, true, true, true); |
| | | |
| | | urcb1.getRptId().setValue("fasdfsadf"); |
| | | |
| | | clientAssociation.getRcbValues(urcb1); |
| | | |
| | | Assert.assertEquals("myurcb1", urcb1.getRptId().getStringValue()); |
| | | |
| | | clientAssociation.reserveUrcb(urcb1); |
| | | clientAssociation.cancelUrcbReservation(urcb1); |
| | | clientAssociation.enableReporting(urcb1); |
| | | |
| | | boolean thrown = false; |
| | | try { |
| | | clientAssociation.startGi(urcb1); |
| | | } catch (ServiceError e) { |
| | | thrown = true; |
| | | } |
| | | Assert.assertTrue(thrown); |
| | | |
| | | urcb1.getTrgOps().setGeneralInterrogation(true); |
| | | urcb1.getTrgOps().setDataChange(true); |
| | | urcb1.getIntgPd().setValue(1000); |
| | | |
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false); |
| | | |
| | | Assert.assertNotNull(serviceErrors.get(0)); |
| | | clientAssociation.disableReporting(urcb1); |
| | | |
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false); |
| | | Assert.assertNull(serviceErrors.get(0)); |
| | | |
| | | clientAssociation.enableReporting(urcb1); |
| | | |
| | | clientAssociation.startGi(urcb1); |
| | | |
| | | Thread.sleep(4000); |
| | | |
| | | Assert.assertEquals(2, numReports); |
| | | Assert.assertEquals(2, numSuccess); |
| | | |
| | | clientAssociation.disableReporting(urcb1); |
| | | |
| | | urcb1.getTrgOps().setIntegrity(true); |
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, false, false, false); |
| | | Assert.assertNull(serviceErrors.get(0)); |
| | | |
| | | clientAssociation.enableReporting(urcb1); |
| | | Thread.sleep(6500); |
| | | |
| | | Assert.assertEquals(8, numReports); |
| | | Assert.assertEquals(8, numSuccess); |
| | | |
| | | clientAssociation.disableReporting(urcb1); |
| | | |
| | | // -------------Test Reporting-End--------------------- |
| | | |
| | | clientAssociation.disconnect(); |
| | | |
| | | Thread.sleep(500); |
| | | Assert.assertEquals(2, numAssociationClosed); |
| | | |
| | | serverSap.stop(); |
| | | |
| | | } |
| | | |
| | | private void getAllBdas(ServerModel serverModel) throws ServiceError, IOException { |
| | | |
| | | for (ModelNode ld : serverModel) { |
| | | for (ModelNode ln : ld) { |
| | | getDataRecursive(ln, clientAssociation); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void runServer(String sclFilePath, int port) throws SclParseException, IOException { |
| | | |
| | | List<ServerSap> serverSaps = null; |
| | | serverSaps = ServerSap.getSapsFromSclFile(sclFilePath); |
| | | |
| | | serverSap = serverSaps.get(0); |
| | | serverSap.setPort(port); |
| | | serverSap.startListening(this); |
| | | serversServerModel = serverSap.getModelCopy(); |
| | | start(); |
| | | } |
| | | |
| | | private static void getDataRecursive(ModelNode modelNode, ClientAssociation clientAssociation) |
| | | throws ServiceError, IOException { |
| | | if (modelNode.getChildren() == null) { |
| | | return; |
| | | } |
| | | for (ModelNode childNode : modelNode) { |
| | | FcModelNode fcChildNode = (FcModelNode) childNode; |
| | | if (fcChildNode.getFc() != Fc.CO) { |
| | | System.out.println("calling GetDataValues(" + childNode.getReference() + ")"); |
| | | clientAssociation.getDataValues(fcChildNode); |
| | | } |
| | | // clientAssociation.setDataValues(fcChildNode); |
| | | getDataRecursive(childNode, clientAssociation); |
| | | } |
| | | } |
| | | |
| | | public static int findArray(Byte[] array, Byte[] subArray) { |
| | | return Collections.indexOfSubList(Arrays.asList(array), Arrays.asList(subArray)); |
| | | } |
| | | |
| | | public static String getByteArrayString(byte[] byteArray) { |
| | | StringBuilder builder = new StringBuilder(); |
| | | int l = 1; |
| | | for (byte b : byteArray) { |
| | | if ((l != 1) && ((l - 1) % 8 == 0)) { |
| | | builder.append(' '); |
| | | } |
| | | if ((l != 1) && ((l - 1) % 16 == 0)) { |
| | | builder.append('\n'); |
| | | } |
| | | l++; |
| | | builder.append("0x"); |
| | | String hexString = Integer.toHexString(b & 0xff); |
| | | if (hexString.length() == 1) { |
| | | builder.append(0); |
| | | } |
| | | builder.append(hexString + " "); |
| | | } |
| | | return builder.toString(); |
| | | } |
| | | |
| | | @Override |
| | | public void serverStoppedListening(ServerSap serverSAP) { |
| | | // TODO Auto-generated method stub |
| | | } |
| | | |
| | | @Override |
| | | public List<ServiceError> write(List<BasicDataAttribute> bdas) { |
| | | System.out.println("DataSource: got write request"); |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | |
| | | BdaFloat32 totWMag = (BdaFloat32) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.mag.f", Fc.MX); |
| | | BdaQuality q = (BdaQuality) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.q", Fc.MX); |
| | | BdaTimestamp t = (BdaTimestamp) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX); |
| | | |
| | | List<BasicDataAttribute> totWBdas = new ArrayList<>(3); |
| | | totWBdas.add(totWMag); |
| | | totWBdas.add(q); |
| | | totWBdas.add(t); |
| | | |
| | | float totWMagVal = 0.0f; |
| | | q.setValidity(BdaQuality.Validity.GOOD); |
| | | |
| | | // for (int i = 0; i < 500000; i++) { |
| | | |
| | | totWMagVal += 1.0; |
| | | |
| | | System.out.println("setting totWmag to: " + totWMagVal); |
| | | totWMag.setFloat(totWMagVal); |
| | | t.setCurrentTime(); |
| | | |
| | | if (q.getValidity() == Validity.GOOD) { |
| | | q.setValidity(BdaQuality.Validity.INVALID); |
| | | } |
| | | else { |
| | | q.setValidity(BdaQuality.Validity.GOOD); |
| | | } |
| | | |
| | | try { |
| | | Thread.sleep(4000); |
| | | } catch (InterruptedException e) { |
| | | } |
| | | serverSap.setValues(totWBdas); |
| | | |
| | | // // Run the garbage collector |
| | | // runtime.gc(); |
| | | // // Calculate the used memory |
| | | // long memory = runtime.totalMemory() - runtime.freeMemory(); |
| | | // System.out.println("Used memory is bytes: " + memory); |
| | | // System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory)); |
| | | |
| | | // try { |
| | | // Thread.sleep(2000); |
| | | // } catch (InterruptedException e) { |
| | | // } |
| | | // } |
| | | |
| | | } |
| | | |
| | | private static final long MEGABYTE = 1024L * 1024L; |
| | | |
| | | public static long bytesToMegabytes(long bytes) { |
| | | return bytes / MEGABYTE; |
| | | } |
| | | |
| | | @Override |
| | | public void newReport(Report report) { |
| | | System.out.println("got report!"); |
| | | numReports++; |
| | | |
| | | if (numReports == 1) { |
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes(); |
| | | Assert.assertEquals(2, reasons.size()); |
| | | Assert.assertTrue(reasons.get(0).isGeneralInterrogation()); |
| | | Assert.assertFalse(reasons.get(0).isDataUpdate()); |
| | | } |
| | | else if (numReports == 2) { |
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes(); |
| | | Assert.assertEquals(1, reasons.size()); |
| | | Assert.assertFalse(reasons.get(0).isGeneralInterrogation()); |
| | | Assert.assertTrue(reasons.get(0).isDataChange()); |
| | | } |
| | | else if (numReports >= 3) { |
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes(); |
| | | Assert.assertEquals(2, reasons.size()); |
| | | Assert.assertTrue(reasons.get(0).isIntegrity()); |
| | | Assert.assertTrue(reasons.get(1).isIntegrity()); |
| | | } |
| | | |
| | | numSuccess++; |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void associationClosed(IOException e) { |
| | | System.out.println("Association closed!"); |
| | | if (e != null) { |
| | | System.out.println(e.getMessage()); |
| | | } |
| | | numAssociationClosed++; |
| | | } |
| | | } |
| | | package org.openmuc.openiec61850.integrationtests;
|
| | |
|
| | | import java.io.IOException;
|
| | | import java.net.InetAddress;
|
| | | import java.util.ArrayList;
|
| | | import java.util.Arrays;
|
| | | import java.util.Collection;
|
| | | import java.util.Collections;
|
| | | import java.util.List;
|
| | |
|
| | | import javax.naming.ConfigurationException;
|
| | |
|
| | | import org.junit.Assert;
|
| | | import org.junit.Test;
|
| | | import org.openmuc.openiec61850.BasicDataAttribute;
|
| | | import org.openmuc.openiec61850.BdaBoolean;
|
| | | import org.openmuc.openiec61850.BdaFloat32;
|
| | | import org.openmuc.openiec61850.BdaInt32;
|
| | | import org.openmuc.openiec61850.BdaInt32U;
|
| | | import org.openmuc.openiec61850.BdaQuality;
|
| | | import org.openmuc.openiec61850.BdaQuality.Validity;
|
| | | import org.openmuc.openiec61850.BdaReasonForInclusion;
|
| | | import org.openmuc.openiec61850.BdaTimestamp;
|
| | | import org.openmuc.openiec61850.BdaVisibleString;
|
| | | 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.ModelNode;
|
| | | 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 ClientServerITest extends Thread implements ServerEventListener, ClientEventListener {
|
| | |
|
| | | int port = 54321;
|
| | | String host = "127.0.0.1";
|
| | | ClientSap clientSap = new ClientSap();
|
| | | ServerSap serverSap = null;
|
| | | ClientAssociation clientAssociation = null;
|
| | | ClientAssociation clientAssociation2 = null;
|
| | | ServerModel serversServerModel = null;
|
| | | private static int numReports = 0;
|
| | | private static int numSuccess = 0;
|
| | | private static int numAssociationClosed = 0;
|
| | |
|
| | | // Get the Java runtime
|
| | | public static Runtime runtime = Runtime.getRuntime();
|
| | |
|
| | | @Test
|
| | | public void testClientServerCom() throws IOException, ServiceError, ConfigurationException,
|
| | | javax.naming.ConfigurationException, SclParseException, InterruptedException {
|
| | |
|
| | | clientSap.setTSelRemote(new byte[] { 0, 1 });
|
| | | clientSap.setTSelLocal(new byte[] { 0, 0 });
|
| | | clientSap.setApTitleCalled(new int[] { 1, 1, 999, 1 });
|
| | | BdaTimestamp timestamp;
|
| | | BdaVisibleString namePlateVendor;
|
| | |
|
| | | // ---------------------------------------------------
|
| | | // ------------------1st test server------------------
|
| | | runServer("src/test/resources/openiec61850sample01.icd", port);
|
| | | System.out.println("IED Server is running");
|
| | |
|
| | | // -----------------------------------------------------------
|
| | | // Client
|
| | | // -----------------------------------------------------------
|
| | |
|
| | | System.out.println("Attempting to connect to server " + host + " on port " + port);
|
| | |
|
| | | clientAssociation = clientSap.associate(InetAddress.getByName(host), port, null, this);
|
| | |
|
| | | // ServerModel serverModel = clientAssociation.retrieveModel();
|
| | | ServerModel serverModel = clientAssociation.getModelFromSclFile("src/test/resources/openiec61850sample01.icd");
|
| | |
|
| | | getAllBdas(serverModel);
|
| | |
|
| | | timestamp = (BdaTimestamp) serverModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
|
| | | clientAssociation.getDataValues(timestamp);
|
| | |
|
| | | namePlateVendor = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/LLN0.NamPlt.vendor", Fc.DC);
|
| | | namePlateVendor.setValue("Fraunhofer ISE".getBytes());
|
| | | clientAssociation.setDataValues(namePlateVendor);
|
| | | namePlateVendor.setDefault();
|
| | | clientAssociation.getDataValues(namePlateVendor);
|
| | |
|
| | | Assert.assertEquals("Fraunhofer ISE", new String(namePlateVendor.getValue()));
|
| | |
|
| | | // -------------Test DataSets-Start---------------------
|
| | |
|
| | | Collection<DataSet> dataSets = serverModel.getDataSets();
|
| | | Assert.assertEquals(2, dataSets.size());
|
| | |
|
| | | DataSet dataSet1 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset1");
|
| | |
|
| | | Assert.assertEquals("ied1lDevice1/LLN0.dataset1", dataSet1.getReferenceStr());
|
| | |
|
| | | DataSet dataSet2 = serverModel.getDataSet("ied1lDevice1/LLN0.dataset2");
|
| | |
|
| | | Assert.assertEquals("ied1lDevice1/LLN0.dataset2", dataSet2.getReferenceStr());
|
| | |
|
| | | for (FcModelNode dataSet2Member : dataSet2) {
|
| | | ((BdaInt32) dataSet2Member).setValue(9);
|
| | | }
|
| | |
|
| | | clientAssociation.setDataSetValues(dataSet2);
|
| | |
|
| | | dataSet1 = serverModel.getDataSet(dataSet1.getReferenceStr());
|
| | |
|
| | | clientAssociation.getDataSetValues(dataSet1);
|
| | |
|
| | | List<FcModelNode> nonPersistentDataSetMembers = new ArrayList<>(2);
|
| | | nonPersistentDataSetMembers.add(namePlateVendor);
|
| | | nonPersistentDataSetMembers.add(timestamp);
|
| | |
|
| | | DataSet nonPersistentDataSet = new DataSet("@nonPersistentDataSet", nonPersistentDataSetMembers);
|
| | |
|
| | | clientAssociation.createDataSet(nonPersistentDataSet);
|
| | |
|
| | | namePlateVendor.setDefault();
|
| | |
|
| | | List<ServiceError> serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
|
| | |
|
| | | for (ServiceError serviceError : serviceErrors) {
|
| | | Assert.assertNull(serviceError);
|
| | | }
|
| | |
|
| | | Assert.assertTrue("Fraunhofer ISE".equals(new String(namePlateVendor.getValue())));
|
| | |
|
| | | clientAssociation.deleteDataSet(nonPersistentDataSet);
|
| | |
|
| | | serviceErrors = clientAssociation.getDataSetValues(nonPersistentDataSet);
|
| | |
|
| | | Assert.assertEquals(2, serviceErrors.size());
|
| | |
|
| | | for (ServiceError serviceError : serviceErrors) {
|
| | | Assert.assertNotNull(serviceError);
|
| | | }
|
| | |
|
| | | // -------------Test DataSets-End---------------------
|
| | |
|
| | | serverModel.findModelNode("ied1lDevice1/MMXU1.TotW", Fc.MX);
|
| | |
|
| | | BdaFloat32 f = (BdaFloat32) serverModel.findModelNode("ied1lDevice1/MMXU1.W.phsA.cVal.mag.f", Fc.MX);
|
| | |
|
| | | f.setFloat(3.0f);
|
| | |
|
| | | Assert.assertEquals(f.getFloat(), 3.0f, 0.00001);
|
| | |
|
| | | clientAssociation.getDataSetValues(dataSet1);
|
| | |
|
| | | Assert.assertEquals(f.getFloat(), 0.0f, 0.00001);
|
| | |
|
| | | /* Test selecting a controllable Data Object */
|
| | |
|
| | | BdaInt32U sboTimeout = (BdaInt32U) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.sboTimeout", Fc.CF);
|
| | | sboTimeout.setValue(2000l);
|
| | |
|
| | | BdaVisibleString sbo = (BdaVisibleString) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
|
| | |
|
| | | Assert.assertNotNull(sbo);
|
| | |
|
| | | clientAssociation.getDataValues(sbo);
|
| | |
|
| | | Assert.assertTrue(sbo.getStringValue().equals("success"));
|
| | |
|
| | | clientAssociation.getDataValues(sbo);
|
| | |
|
| | | Assert.assertEquals(sbo.getStringValue(), "success");
|
| | |
|
| | | /* select with second connection */
|
| | |
|
| | | clientAssociation2 = clientSap.associate(InetAddress.getByName(host), port, null, this);
|
| | | ServerModel serverModel2 = clientAssociation2.retrieveModel();
|
| | |
|
| | | BdaVisibleString sbo2 = (BdaVisibleString) serverModel2.findModelNode("ied1lDevice1/CSWI1.PosA.SBO", Fc.CO);
|
| | |
|
| | | clientAssociation2.getDataValues(sbo2);
|
| | | Assert.assertEquals(sbo2.getStringValue(), "");
|
| | |
|
| | | /* select with second connection after the sboTimeout of 1000ms should have been run out */
|
| | |
|
| | | // clientAssociation.close();
|
| | |
|
| | | try {
|
| | | Thread.sleep(1000);
|
| | | } catch (InterruptedException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | |
|
| | | clientAssociation2.getDataValues(sbo2);
|
| | | Assert.assertEquals(sbo2.getStringValue(), "success");
|
| | |
|
| | | /* select with first connnection after the second was quit */
|
| | |
|
| | | clientAssociation.getDataValues(sbo);
|
| | | Assert.assertEquals(sbo.getStringValue(), "");
|
| | |
|
| | | clientAssociation2.close();
|
| | |
|
| | | try {
|
| | | Thread.sleep(100);
|
| | | } catch (InterruptedException e) {
|
| | | e.printStackTrace();
|
| | | }
|
| | |
|
| | | clientAssociation.getDataValues(sbo);
|
| | | Assert.assertEquals(sbo.getStringValue(), "success");
|
| | |
|
| | | FcModelNode switchPosAFcDo = (FcModelNode) serverModel.findModelNode("ied1lDevice1/CSWI1.PosA", Fc.CO);
|
| | |
|
| | | Assert.assertNotNull(switchPosAFcDo);
|
| | |
|
| | | clientAssociation.operate(switchPosAFcDo);
|
| | |
|
| | | // -------------Test Reporting-Start-------------------
|
| | |
|
| | | Urcb urcb1 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb101");
|
| | | Assert.assertNotNull(urcb1);
|
| | |
|
| | | Urcb urcb2 = serverModel.getUrcb("ied1lDevice1/LLN0.urcb2");
|
| | | Assert.assertNotNull(urcb2);
|
| | |
|
| | | clientAssociation.getRcbValues(urcb1);
|
| | | clientAssociation.getRcbValues(urcb2);
|
| | |
|
| | | BdaBoolean resv = (BdaBoolean) urcb1.getChild("Resv");
|
| | | Assert.assertNotNull(resv);
|
| | | clientAssociation.getDataValues(resv);
|
| | | Assert.assertFalse(resv.getValue());
|
| | | clientAssociation.reserveUrcb(urcb1);
|
| | | clientAssociation.getDataValues(resv);
|
| | | Assert.assertTrue(resv.getValue());
|
| | |
|
| | | Assert.assertEquals("urcb1", urcb1.getRptId().getStringValue());
|
| | | Assert.assertEquals("ied1lDevice1/LLN0.urcb2", urcb2.getRptId().getStringValue());
|
| | |
|
| | | Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb1.getDatSet().getStringValue());
|
| | | Assert.assertEquals("ied1lDevice1/LLN0$dataset1", urcb2.getDatSet().getStringValue());
|
| | |
|
| | | Assert.assertEquals(true, urcb1.getOptFlds().isDataSetName());
|
| | | Assert.assertEquals(false, urcb1.getOptFlds().isBufferOverflow());
|
| | | Assert.assertEquals(false, urcb1.getOptFlds().isConfigRevision());
|
| | | Assert.assertEquals(false, urcb1.getOptFlds().isDataReference());
|
| | | Assert.assertEquals(false, urcb1.getOptFlds().isEntryId());
|
| | | Assert.assertEquals(true, urcb1.getOptFlds().isReasonForInclusion());
|
| | | Assert.assertEquals(true, urcb1.getOptFlds().isReportTimestamp());
|
| | | Assert.assertEquals(false, urcb1.getOptFlds().isSegmentation());
|
| | | Assert.assertEquals(true, urcb1.getOptFlds().isSequenceNumber());
|
| | |
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isDataSetName());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isBufferOverflow());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isConfigRevision());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isDataReference());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isEntryId());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isReasonForInclusion());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isReportTimestamp());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isSegmentation());
|
| | | Assert.assertEquals(false, urcb2.getOptFlds().isSequenceNumber());
|
| | |
|
| | | Assert.assertEquals(50L, urcb1.getBufTm().getValue());
|
| | |
|
| | | Assert.assertEquals(true, urcb1.getTrgOps().isDataChange());
|
| | | Assert.assertEquals(true, urcb1.getTrgOps().isDataUpdate());
|
| | | Assert.assertEquals(true, urcb1.getTrgOps().isGeneralInterrogation());
|
| | | Assert.assertEquals(false, urcb1.getTrgOps().isIntegrity());
|
| | | Assert.assertEquals(true, urcb1.getTrgOps().isQualityChange());
|
| | |
|
| | | Assert.assertEquals(false, urcb2.getTrgOps().isDataChange());
|
| | | Assert.assertEquals(false, urcb2.getTrgOps().isDataUpdate());
|
| | | Assert.assertEquals(true, urcb2.getTrgOps().isGeneralInterrogation());
|
| | | Assert.assertEquals(false, urcb2.getTrgOps().isIntegrity());
|
| | | Assert.assertEquals(false, urcb2.getTrgOps().isQualityChange());
|
| | |
|
| | | Assert.assertEquals(5000L, urcb1.getIntgPd().getValue());
|
| | |
|
| | | Assert.assertEquals(0, urcb1.getSqNum().getValue());
|
| | |
|
| | | Assert.assertEquals(0L, urcb1.getConfRev().getValue());
|
| | |
|
| | | urcb1.getRptId().setValue("myurcb1");
|
| | | urcb1.getTrgOps().setGeneralInterrogation(false);
|
| | | urcb1.getTrgOps().setDataUpdate(false);
|
| | | urcb1.getTrgOps().setDataChange(false);
|
| | |
|
| | | clientAssociation.setRcbValues(urcb1, true, true, true, true, true, true, true, true);
|
| | |
|
| | | urcb1.getRptId().setValue("fasdfsadf");
|
| | |
|
| | | clientAssociation.getRcbValues(urcb1);
|
| | |
|
| | | Assert.assertEquals("myurcb1", urcb1.getRptId().getStringValue());
|
| | |
|
| | | clientAssociation.reserveUrcb(urcb1);
|
| | | clientAssociation.cancelUrcbReservation(urcb1);
|
| | | clientAssociation.enableReporting(urcb1);
|
| | |
|
| | | boolean thrown = false;
|
| | | try {
|
| | | clientAssociation.startGi(urcb1);
|
| | | } catch (ServiceError e) {
|
| | | thrown = true;
|
| | | }
|
| | | Assert.assertTrue(thrown);
|
| | |
|
| | | urcb1.getTrgOps().setGeneralInterrogation(true);
|
| | | urcb1.getTrgOps().setDataChange(true);
|
| | | urcb1.getIntgPd().setValue(1000);
|
| | |
|
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
|
| | |
|
| | | Assert.assertNotNull(serviceErrors.get(0));
|
| | | clientAssociation.disableReporting(urcb1);
|
| | |
|
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, true, false, false);
|
| | | Assert.assertNull(serviceErrors.get(0));
|
| | |
|
| | | clientAssociation.enableReporting(urcb1);
|
| | |
|
| | | clientAssociation.startGi(urcb1);
|
| | |
|
| | | Thread.sleep(4000);
|
| | |
|
| | | Assert.assertEquals(2, numReports);
|
| | | Assert.assertEquals(2, numSuccess);
|
| | |
|
| | | clientAssociation.disableReporting(urcb1);
|
| | |
|
| | | urcb1.getTrgOps().setIntegrity(true);
|
| | | serviceErrors = clientAssociation.setRcbValues(urcb1, false, false, false, false, true, false, false, false);
|
| | | Assert.assertNull(serviceErrors.get(0));
|
| | |
|
| | | clientAssociation.enableReporting(urcb1);
|
| | | Thread.sleep(6500);
|
| | |
|
| | | Assert.assertEquals(8, numReports);
|
| | | Assert.assertEquals(8, numSuccess);
|
| | |
|
| | | clientAssociation.disableReporting(urcb1);
|
| | |
|
| | | // -------------Test Reporting-End---------------------
|
| | |
|
| | | clientAssociation.disconnect();
|
| | |
|
| | | Thread.sleep(500);
|
| | | Assert.assertEquals(2, numAssociationClosed);
|
| | |
|
| | | serverSap.stop();
|
| | |
|
| | | }
|
| | |
|
| | | private void getAllBdas(ServerModel serverModel) throws ServiceError, IOException {
|
| | |
|
| | | for (ModelNode ld : serverModel) {
|
| | | for (ModelNode ln : ld) {
|
| | | getDataRecursive(ln, clientAssociation);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | private void runServer(String sclFilePath, int port) throws SclParseException, IOException {
|
| | |
|
| | | List<ServerSap> serverSaps = null;
|
| | | serverSaps = ServerSap.getSapsFromSclFile(sclFilePath);
|
| | |
|
| | | serverSap = serverSaps.get(0);
|
| | | serverSap.setPort(port);
|
| | | serverSap.startListening(this);
|
| | | serversServerModel = serverSap.getModelCopy();
|
| | | start();
|
| | | }
|
| | |
|
| | | private static void getDataRecursive(ModelNode modelNode, ClientAssociation clientAssociation)
|
| | | throws ServiceError, IOException {
|
| | | if (modelNode.getChildren() == null) {
|
| | | return;
|
| | | }
|
| | | for (ModelNode childNode : modelNode) {
|
| | | FcModelNode fcChildNode = (FcModelNode) childNode;
|
| | | if (fcChildNode.getFc() != Fc.CO) {
|
| | | System.out.println("calling GetDataValues(" + childNode.getReference() + ")");
|
| | | clientAssociation.getDataValues(fcChildNode);
|
| | | }
|
| | | // clientAssociation.setDataValues(fcChildNode);
|
| | | getDataRecursive(childNode, clientAssociation);
|
| | | }
|
| | | }
|
| | |
|
| | | public static int findArray(Byte[] array, Byte[] subArray) {
|
| | | return Collections.indexOfSubList(Arrays.asList(array), Arrays.asList(subArray));
|
| | | }
|
| | |
|
| | | public static String getByteArrayString(byte[] byteArray) {
|
| | | StringBuilder builder = new StringBuilder();
|
| | | int l = 1;
|
| | | for (byte b : byteArray) {
|
| | | if ((l != 1) && ((l - 1) % 8 == 0)) {
|
| | | builder.append(' ');
|
| | | }
|
| | | if ((l != 1) && ((l - 1) % 16 == 0)) {
|
| | | builder.append('\n');
|
| | | }
|
| | | l++;
|
| | | builder.append("0x");
|
| | | String hexString = Integer.toHexString(b & 0xff);
|
| | | if (hexString.length() == 1) {
|
| | | builder.append(0);
|
| | | }
|
| | | builder.append(hexString + " ");
|
| | | }
|
| | | return builder.toString();
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void serverStoppedListening(ServerSap serverSAP) {
|
| | | // TODO Auto-generated method stub
|
| | | }
|
| | |
|
| | | @Override
|
| | | public List<ServiceError> write(List<BasicDataAttribute> bdas) {
|
| | | System.out.println("DataSource: got write request");
|
| | | return null;
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void run() {
|
| | |
|
| | | BdaFloat32 totWMag = (BdaFloat32) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.mag.f", Fc.MX);
|
| | | BdaQuality q = (BdaQuality) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.q", Fc.MX);
|
| | | BdaTimestamp t = (BdaTimestamp) serversServerModel.findModelNode("ied1lDevice1/MMXU1.TotW.t", Fc.MX);
|
| | |
|
| | | List<BasicDataAttribute> totWBdas = new ArrayList<>(3);
|
| | | totWBdas.add(totWMag);
|
| | | totWBdas.add(q);
|
| | | totWBdas.add(t);
|
| | |
|
| | | float totWMagVal = 0.0f;
|
| | | q.setValidity(BdaQuality.Validity.GOOD);
|
| | |
|
| | | // for (int i = 0; i < 500000; i++) {
|
| | |
|
| | | totWMagVal += 1.0;
|
| | |
|
| | | System.out.println("setting totWmag to: " + totWMagVal);
|
| | | totWMag.setFloat(totWMagVal);
|
| | | t.setCurrentTime();
|
| | |
|
| | | if (q.getValidity() == Validity.GOOD) {
|
| | | q.setValidity(BdaQuality.Validity.INVALID);
|
| | | }
|
| | | else {
|
| | | q.setValidity(BdaQuality.Validity.GOOD);
|
| | | }
|
| | |
|
| | | try {
|
| | | Thread.sleep(4000);
|
| | | } catch (InterruptedException e) {
|
| | | }
|
| | | serverSap.setValues(totWBdas);
|
| | |
|
| | | // // Run the garbage collector
|
| | | // runtime.gc();
|
| | | // // Calculate the used memory
|
| | | // long memory = runtime.totalMemory() - runtime.freeMemory();
|
| | | // System.out.println("Used memory is bytes: " + memory);
|
| | | // System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
|
| | |
|
| | | // try {
|
| | | // Thread.sleep(2000);
|
| | | // } catch (InterruptedException e) {
|
| | | // }
|
| | | // }
|
| | |
|
| | | }
|
| | |
|
| | | private static final long MEGABYTE = 1024L * 1024L;
|
| | |
|
| | | public static long bytesToMegabytes(long bytes) {
|
| | | return bytes / MEGABYTE;
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void newReport(Report report) {
|
| | | System.out.println("got report!");
|
| | | numReports++;
|
| | |
|
| | | if (numReports == 1) {
|
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes();
|
| | | Assert.assertEquals(2, reasons.size());
|
| | | Assert.assertTrue(reasons.get(0).isGeneralInterrogation());
|
| | | Assert.assertFalse(reasons.get(0).isDataUpdate());
|
| | | }
|
| | | else if (numReports == 2) {
|
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes();
|
| | | Assert.assertEquals(1, reasons.size());
|
| | | Assert.assertFalse(reasons.get(0).isGeneralInterrogation());
|
| | | Assert.assertTrue(reasons.get(0).isDataChange());
|
| | | }
|
| | | else if (numReports >= 3) {
|
| | | List<BdaReasonForInclusion> reasons = report.getReasonCodes();
|
| | | Assert.assertEquals(2, reasons.size());
|
| | | Assert.assertTrue(reasons.get(0).isIntegrity());
|
| | | Assert.assertTrue(reasons.get(1).isIntegrity());
|
| | | }
|
| | |
|
| | | numSuccess++;
|
| | |
|
| | | }
|
| | |
|
| | | @Override
|
| | | public void associationClosed(IOException e) {
|
| | | System.out.println("Association closed!");
|
| | | if (e != null) {
|
| | | System.out.println(e.getMessage());
|
| | | }
|
| | | numAssociationClosed++;
|
| | | }
|
| | | }
|