From ba7023d39a1919309881d49917a668b56b5a0854 Mon Sep 17 00:00:00 2001 From: Anuprakash Moothedath Date: Wed, 28 Aug 2024 14:02:24 +0530 Subject: [PATCH 1/4] Added TSQ manager and its IVT program Signed-off-by: Anuprakash Moothedath --- .../java/dev/galasa/cicsts/ICicsRegion.java | 1 + .../java/dev/galasa/cicsts/ITsqHandler.java | 54 ++++ .../java/dev/galasa/cicsts/TsqException.java | 30 ++ .../galasa/cicsts/TsqManagerException.java | 31 ++ .../cicsts/internal/CicstsManagerImpl.java | 17 ++ .../internal/properties/ExtraBundles.java | 11 +- .../dev/galasa/cicsts/spi/BaseCicsImpl.java | 20 +- .../galasa/cicsts/spi/ICicstsManagerSpi.java | 24 +- .../dev/galasa/cicsts/spi/ITsqProvider.java | 31 ++ .../dev.galasa.cicsts.tsq.manager.ivt/bnd.bnd | 5 + .../build.gradle | 27 ++ .../settings.gradle | 2 + .../cicsts/tsq/manager/ivt/TsqManagerIVT.java | 142 +++++++++ .../dev.galasa.cicsts.tsq.manager/bnd.bnd | 5 + .../build.gradle | 28 ++ .../settings.gradle | 2 + .../galasa/cicsts/tsq/internal/TsqImpl.java | 285 ++++++++++++++++++ .../cicsts/tsq/internal/TsqManagerField.java | 22 ++ .../cicsts/tsq/internal/TsqManagerImpl.java | 99 ++++++ .../cicsts/tsq/internal/package-info.java | 9 + .../properties/TsqPropertiesSingleton.java | 51 ++++ .../tsq/internal/properties/package-info.java | 13 + .../galasa/cicsts/tsq/spi/ITsqManagerSpi.java | 13 + .../galasa/cicsts/tsq/spi/package-info.java | 9 + .../tsq_manager_codesnippet.md | 84 ++++++ galasa-managers-parent/settings.gradle | 2 + 26 files changed, 1002 insertions(+), 15 deletions(-) create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/bnd.bnd create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/settings.gradle create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/bnd.bnd create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/build.gradle create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/settings.gradle create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/package-info.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/TsqPropertiesSingleton.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/package-info.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/ITsqManagerSpi.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/package-info.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java index 74e26173a..65e719420 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java @@ -52,6 +52,7 @@ public interface ICicsRegion { ICemt cemt() throws CicstsManagerException; ICeda ceda() throws CicstsManagerException; ICeci ceci() throws CicstsManagerException; + ITsqHandler tsq() throws CicstsManagerException; /** * Provides a CICS resource instance that can then be used to create a specific CICS resource diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java new file mode 100644 index 000000000..774bfd07f --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts; + +import javax.validation.constraints.NotNull; + +public interface ITsqHandler { + + /** + * Set TSQ name + * @param queueName TSQ name + * @throws TsqException if there is a problem in setting the TSQ name + */ + public void setQName(@NotNull String queueName) throws TsqException; + + /** + * Get TSQ name + * @return TSQ name + * @throws TsqException if there is a problem in setting the TSQ name + */ + public String getQName() throws TsqException; + + /** + * Read Data from TSQ. TSQ name is set using setName() method. + * TSQ item number to be read is passed as parm to this method. + * @param item Item number of the TSQ to be read + * @return Data read from TSQ as String + * @throws TsqException if there is a problem in reading from the TSQ + */ + public String readQ(@NotNull int item) throws TsqException; + + /** + * Write inputData to TSQ. TSQ name is set using setName() method. + * @param inputData The string to be written to the TSQ + * @throws TsqException if there is a problem in writing to the TSQ + */ + public void writeQ(@NotNull String inputData) throws TsqException; + + /** + * Delete TSQ. TSQ name is set using setName() method. + * @throws TsqException if there is a problem in deleting the TSQ + */ + public void deleteQ() throws TsqException; + + /** + * Make TSQ Recoverable. TSQ name is set using setName() method. + * @throws TsqException if there is a problem in making the TSQ recoverable + */ + public void makeRecoverable() throws TsqException; + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java new file mode 100644 index 000000000..44744b735 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java @@ -0,0 +1,30 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts; + +public class TsqException extends TsqManagerException { + private static final long serialVersionUID = 1L; + + public TsqException() { + } + + public TsqException(String message) { + super(message); + } + + public TsqException(Throwable cause) { + super(cause); + } + + public TsqException(String message, Throwable cause) { + super(message, cause); + } + + public TsqException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java new file mode 100644 index 000000000..df23ff8b9 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java @@ -0,0 +1,31 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts; + +public class TsqManagerException extends CicstsManagerException { + private static final long serialVersionUID = 1L; + + public TsqManagerException() { + } + + public TsqManagerException(String message) { + super(message); + } + + public TsqManagerException(Throwable cause) { + super(cause); + } + + public TsqManagerException(String message, Throwable cause) { + super(message, cause); + } + + public TsqManagerException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/CicstsManagerImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/CicstsManagerImpl.java index a91823646..e15abec64 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/CicstsManagerImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/CicstsManagerImpl.java @@ -35,6 +35,7 @@ import dev.galasa.cicsts.spi.ICeciProvider; import dev.galasa.cicsts.spi.ICedaProvider; import dev.galasa.cicsts.spi.ICemtProvider; +import dev.galasa.cicsts.spi.ITsqProvider; import dev.galasa.cicsts.spi.ICicsRegionLogonProvider; import dev.galasa.cicsts.spi.ICicsRegionProvisioned; import dev.galasa.cicsts.spi.ICicsRegionProvisioner; @@ -80,6 +81,7 @@ public class CicstsManagerImpl extends AbstractManager implements ICicstsManager private ICeciProvider ceciProvider; private ICedaProvider cedaProvider; private ICemtProvider cemtProvider; + private ITsqProvider tsqProvider; private ICicsResourceProvider cicsResourceProvider; @Override @@ -361,6 +363,11 @@ public void registerCedaProvider(@NotNull ICedaProvider cedaProvider) { this.cedaProvider = cedaProvider; } + @Override + public void registerTsqProvider(@NotNull ITsqProvider tsqProvider) { + this.tsqProvider = tsqProvider; + } + @Override public void registerCemtProvider(@NotNull ICemtProvider cemtProvider) { this.cemtProvider = cemtProvider; @@ -390,6 +397,16 @@ public ICedaProvider getCedaProvider() throws CicstsManagerException { return this.cedaProvider; } + + @Override + @NotNull + public ITsqProvider getTsqProvider() throws CicstsManagerException { + if (this.tsqProvider == null) { + throw new CicstsManagerException("No TSQ provider has been registered"); + } + + return this.tsqProvider; + } @Override @NotNull diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/properties/ExtraBundles.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/properties/ExtraBundles.java index 80212006f..5dc2b4421 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/properties/ExtraBundles.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/internal/properties/ExtraBundles.java @@ -1,8 +1,8 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ package dev.galasa.cicsts.internal.properties; import java.util.ArrayList; @@ -42,6 +42,7 @@ public static List get() throws CicstsManagerException { list.add("dev.galasa.cicsts.ceci.manager"); list.add("dev.galasa.cicsts.ceda.manager"); list.add("dev.galasa.cicsts.cemt.manager"); + list.add("dev.galasa.cicsts.tsq.manager"); list.add("dev.galasa.cicsts.resource.manager"); list.add("dev.galasa.zosliberty.manager"); list.add("dev.galasa.textscan.manager"); diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java index b94673d6f..a5bef8437 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java @@ -1,14 +1,15 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ package dev.galasa.cicsts.spi; import dev.galasa.cicsts.CicstsManagerException; import dev.galasa.cicsts.ICeci; import dev.galasa.cicsts.ICeda; import dev.galasa.cicsts.ICemt; +import dev.galasa.cicsts.ITsqHandler; import dev.galasa.cicsts.MasType; import dev.galasa.cicsts.cicsresource.CicsJvmserverResourceException; import dev.galasa.cicsts.cicsresource.ICicsResource; @@ -29,6 +30,7 @@ public abstract class BaseCicsImpl implements ICicsRegionProvisioned { private ICeci ceci; private ICeda ceda; private ICemt cemt; + private ITsqHandler tsq; private ICicsResource cicsResource; private IZosUNIXFile runTemporaryUNIXPath; @@ -93,6 +95,14 @@ public ICeda ceda() throws CicstsManagerException { return this.ceda; } + @Override + public ITsqHandler tsq() throws CicstsManagerException { + if (this.tsq == null) { + this.tsq = this.cicstsManager.getTsqProvider().getTsq(this, this.cicstsManager); + } + return this.tsq; + } + @Override public ICemt cemt() throws CicstsManagerException { if (this.cemt == null) { diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java index 3b6c79737..a9bc74377 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java @@ -1,8 +1,8 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ package dev.galasa.cicsts.spi; import java.util.List; @@ -44,6 +44,13 @@ public interface ICicstsManagerSpi { * @param cedaProvider - the new provider */ void registerCedaProvider(@NotNull ICedaProvider cedaProvider); + + /** + * Register the a ITsqHandler instance provider with the CICS TS Manager + * + * @param tsqProvider - the new provider + */ + void registerTsqProvider(@NotNull ITsqProvider tsqProvider); /** * Register the a ICicsResource instance provider with the CICS TS Manager @@ -73,6 +80,13 @@ public interface ICicstsManagerSpi { @NotNull public ICedaProvider getCedaProvider() throws CicstsManagerException; + /** + * @return The registered TSQ provider + * @throws CicstsManagerException + */ + @NotNull + public ITsqProvider getTsqProvider() throws CicstsManagerException; + /** * @return The registered CICS Resource provider * @throws CicstsManagerException diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java new file mode 100644 index 000000000..bae723f81 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.spi; + +import javax.validation.constraints.NotNull; + +import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.TsqManagerException; +import dev.galasa.cicsts.ICicsRegion; + +/** + * Provides CICS Region related TSQ objects + * + */ +public interface ITsqProvider { + + /** + * Returns a unique instance of the ICemt per CICS region + * + * @param cicsRegion + * @param cicstsManager + * @return ITsqHandler object for this CICS region, will a different instance for different regions + * @throws TsqManagerException if getTsq() fails + */ + @NotNull + ITsqHandler getTsq(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException; + +} \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/bnd.bnd b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/bnd.bnd new file mode 100644 index 000000000..d418344c5 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/bnd.bnd @@ -0,0 +1,5 @@ +-snapshot: ${tstamp} +Bundle-Name: Galasa TSQ Manager IVTs +Export-Package: dev.galasa.cicsts.tsq.manager.ivt +Import-Package: !javax.validation.constraints, \ + * diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle new file mode 100644 index 000000000..27f8b8b73 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle @@ -0,0 +1,27 @@ +plugins { + id 'galasa.manager.ivt' +} + +description = 'Galasa TSQ Manager IVTs' + +version = '0.1.0' + +dependencies { + implementation project (':galasa-managers-core-parent:dev.galasa.core.manager') + implementation project (':galasa-managers-cicsts-parent:dev.galasa.cicsts.tsq.manager') + implementation project (':galasa-managers-zos-parent:dev.galasa.zos3270.manager') +} + + +// Note: These values are consumed by the parent build process +// They indicate which packages of functionality this OSGi bundle should be delivered inside, +// or referenced from. +// The settings here are gathered together by the build process to create a release.yaml file +// which gathers-up all the packaging metadata about all the OSGi bundles in this component. +ext.projectName=project.name +ext.includeInOBR = true +ext.includeInMVP = true +ext.includeInBOM = false +ext.includeInIsolated = true +ext.includeInCodeCoverage = false +ext.includeInJavadoc = false diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/settings.gradle b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/settings.gradle new file mode 100644 index 000000000..f2ef69561 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'dev.galasa.cicsts.tsq.manager.ivt' + diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java new file mode 100644 index 000000000..8163152c2 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java @@ -0,0 +1,142 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package dev.galasa.cicsts.tsq.manager.ivt; + +import dev.galasa.BeforeClass; +import dev.galasa.Test; +import dev.galasa.core.manager.Logger; +import org.apache.commons.logging.Log; + +import dev.galasa.cicsts.CicsRegion; +import dev.galasa.cicsts.CicsTerminal; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.ITsqHandler; + +import dev.galasa.zos3270.FieldNotFoundException; +import dev.galasa.zos3270.KeyboardLockedException; +import dev.galasa.zos3270.TerminalInterruptedException; +import dev.galasa.zos3270.spi.NetworkException; +import dev.galasa.zos3270.TimeoutException; + +import static org.assertj.core.api.Assertions.assertThat; + +@Test +public class TsqManagerIVT { + + @Logger + public Log logger; + + @CicsRegion(cicsTag="A") + public ICicsRegion cicsRegionA; + + @CicsTerminal(cicsTag="A") + public ICicsTerminal cemtTerminalA; + + public ITsqHandler tsqA; + + /** + * Validate if the ITsqHandler object is not NULL + * + * @throws CicstsManagerException + */ + @BeforeClass + public void checkTsqLoaded() throws CicstsManagerException { + tsqA = cicsRegionA.tsq(); + assertThat(tsqA).isNotNull(); + } + + /** + * Set the TSQ name for performing ITsqHandler methods + * + * @throws CicstsManagerException + */ + @BeforeClass + public void setTsqName() throws CicstsManagerException { + // Set the TSQ name as GALASAQ for readQ(), writeQ() and deleteQ() methods. + tsqA.setQName("GALASAQ"); + } + + /** + * Check if getQName() returns the TSQ name + * + * @throws CicstsManagerException + */ + @Test + public void getTsqName() throws CicstsManagerException { + // Set the TSQ name as GALASAQ for readQ(), writeQ() and deleteQ() methods. + assertThat(tsqA.getQName()).isEqualTo("GALASAQ"); + } + + /** + * Tests that the Text is written to TSQ and read from TSQ + * + * @throws CicstsManagerException + */ + @Test + public void testTsqWriteRead() throws CicstsManagerException { + String writeMessage = "This message is written from Galasa to the TSQ named GALASAQ."; + // Write message to TSQ - GALASAQ + tsqA.writeQ(writeMessage); + logger.info("Text written to TSQ GALASAQ : " + writeMessage); + + //Read message from TSQ - GALASAQ + String readMessage = tsqA.readQ(1); + logger.info("Text read from TSQ GALASAQ : " + readMessage); + + // Validate if the message read from TSQ is same as the message written + assertThat(readMessage).isEqualTo(writeMessage); + } + + /** + * Tests that the TSQ is made recoverable + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + */ + @Test + public void testTsqMakeRevoverable() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + // Make the TSQ named GALASAQ recoverable + tsqA.makeRecoverable(); + + // Inquire the CICS TSMODEL resource GALASAQM + String tsModelProps = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSMODEL(GALASAQM)").enter().waitForKeyboard().tab().type("s").enter().waitForKeyboard().retrieveScreen(); + // Validate if the TSMODEL sets the recover status to recoverable + assertThat(tsModelProps).contains("Tsmodel(GALASAQM)","Prefix(GALASAQ)","Recovstatus(Recoverable)"); + } + + /** + * Tests that the TSQ is deleted + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + */ + @Test + public void testTsqDeleteQ() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + String tsqPropsBeforeDelete = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSQUEUE(GALASAQ)").enter().waitForKeyboard().retrieveScreen(); + // Validate if the TSQ - GALASAQ is existing + assertThat(tsqPropsBeforeDelete).contains("Tsq(GALASAQ ","NORMAL"); + assertThat(tsqPropsBeforeDelete).doesNotContain("NOT FOUND"); + + // Delete the TSQ GALASAQ + tsqA.deleteQ(); + + // Inquire the CICS TSMODEL resource GALASAQM + String tsqPropsAfterDelete = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSQUEUE(GALASAQ)").enter().waitForKeyboard().retrieveScreen(); + // Validate if the TSQ - GALASAQ is deleted + assertThat(tsqPropsAfterDelete).contains("Tsq(GALASAQ ","NOT FOUND","ERROR"); + } +} \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/bnd.bnd b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/bnd.bnd new file mode 100644 index 000000000..001335e5a --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/bnd.bnd @@ -0,0 +1,5 @@ +-snapshot: ${tstamp} +Bundle-Name: Galasa CICS/TS TSQ Manager +Export-Package: dev.galasa.cicsts.tsq.spi +Import-Package: !javax.validation.constraints, \ + * diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/build.gradle b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/build.gradle new file mode 100644 index 000000000..76c669010 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/build.gradle @@ -0,0 +1,28 @@ +plugins { + id 'galasa.manager' +} + +description = 'Galasa CICS/TS TSQ Manager' + +version = '0.1.0' + +dependencies { + api project (':galasa-managers-cicsts-parent:dev.galasa.cicsts.manager') + implementation project (':galasa-managers-zos-parent:dev.galasa.zos3270.manager') +} + + +// Note: These values are consumed by the parent build process +// They indicate which packages of functionality this OSGi bundle should be delivered inside, +// or referenced from. +// The settings here are gathered together by the build process to create a release.yaml file +// which gathers-up all the packaging metadata about all the OSGi bundles in this component. +ext.projectName=project.name +ext.includeInOBR = true +ext.includeInMVP = true +ext.includeInBOM = true +ext.includeInIsolated = true +ext.includeInCodeCoverage = true +ext.includeInJavadoc = true + + diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/settings.gradle b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/settings.gradle new file mode 100644 index 000000000..ae20d3c38 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'dev.galasa.cicsts.tsq.manager' + diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java new file mode 100644 index 000000000..1fd040ed4 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java @@ -0,0 +1,285 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.internal; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.validation.constraints.NotNull; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import dev.galasa.cicsts.TsqException; +import dev.galasa.cicsts.TsqManagerException; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.IExecInterfaceBlock; +import dev.galasa.cicsts.ICeci; +import dev.galasa.cicsts.ICeda; +import dev.galasa.cicsts.ICeciResponse; +import dev.galasa.cicsts.CeciException; +import dev.galasa.cicsts.CedaException; +import dev.galasa.cicsts.spi.ICicstsManagerSpi; +import dev.galasa.zos3270.FieldNotFoundException; +import dev.galasa.zos3270.KeyboardLockedException; +import dev.galasa.zos3270.TerminalInterruptedException; +import dev.galasa.zos3270.TimeoutException; +import dev.galasa.zos3270.spi.NetworkException; + + +/** + * Implementation of {@link ITsqHandler} + */ +public class TsqImpl implements ITsqHandler { + + private static final Log logger = LogFactory.getLog(TsqImpl.class); + + private final ICicsRegion cicsRegion; + private final ICicsTerminal ceciTerminal; + private final ICicsTerminal cedaTerminal; + private final ICicstsManagerSpi cicstsManager; + private final ICeci ceci; + private final ICeda ceda; + private String queueName; + + public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqException { + this.cicsRegion = cicsRegion; + this.cicstsManager = cicstsManager; + try { + this.ceci = cicsRegion.ceci(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CECI instance for CICS region", e); + } + try { + this.ceda = cicsRegion.ceda(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEDA instance for CICS region", e); + } + try { + this.ceciTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); + this.ceciTerminal.connectToCicsRegion(); + this.ceciTerminal.resetAndClear(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CECI terminal for CICS region", e); + } + try { + this.cedaTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); + this.cedaTerminal.connectToCicsRegion(); + this.cedaTerminal.resetAndClear(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEDA terminal for CICS region", e); + } + } + + /* + * To set the TSQ name used for readQ(), writeQ(), deleteQ() and makeRecoverable() methods + */ + @Override + public void setQName(@NotNull String queueName) throws TsqException{ + this.queueName = queueName; + // Check if queueName is blank + if (this.queueName.trim().length() == 0){ + throw new TsqException("TSQ queue name cannot be blanks in setName() method."); + } + logger.info("TSQ name set to: " + queueName); + return; + } + + /* + * To get the TSQ name used for readQ(), writeQ(), deleteQ() and makeRecoverable() methods + */ + @Override + public String getQName() throws TsqException{ + return this.queueName ; + } + + /* + * To read the TSQ with name set using setName() method + */ + @Override + public String readQ(@NotNull int item) throws TsqException{ + // Check if queueName is set + this.checkQueueName(); + String outData = ""; + + // Create READQ command to execute using CECI + String command = "READQ TS INTO(&OUTDATA)"; + if(this.queueName.length() > 8) { + // Use QNAME where the TSQ name is greater than 8 characters. + command += " QNAME(" + this.queueName + ")"; + } else { + // Otherwise use QUEUE to avoid potentially breaking existing tests. + command += " QUEUE(" + this.queueName + ")"; + } + command += " ITEM(" + item + ")"; + + try { + //Start CECI session in the terminal + this.ceci.startCECISession(this.ceciTerminal); + // Read TSQ using CECI command + ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); + if (resp.isNormal()) { + try { + // Retrieve the text read from TSQ + outData = this.ceci.retrieveVariableText(this.ceciTerminal, "&OUTDATA"); + } catch (CeciException e) { + throw new TsqException("Read TSQ failed while trying to retrieve the data. ", e); + } + } else { + throw new TsqException("TSQ read failed for queue : " + this.queueName + ". CICS response : " + resp.getResponse()); + } + } catch (CeciException e) { + throw new TsqException("Failed to read TSQ Data " + this.queueName + ".", e); + } + + // Delete the &OUTDATA variable after reading the TSQ + try{ + this.ceci.deleteVariable(this.ceciTerminal, "&OUTDATA"); + } catch (CeciException e) { + throw new TsqException("Failed to delete variable used to read TSQ : " + this.queueName + ".", e); + } + return outData; + } + + /* + * To write to the TSQ with name set using setName() method + */ + @Override + public void writeQ(String inputData) throws TsqException { + // Check if queueName is set + this.checkQueueName(); + + // Check if inputData to write to TSQ is empty + if (inputData.trim().length() == 0){ + throw new TsqException("Data written to TSQ cannot be empty. "); + } + + // Create WRITEQ command to execute using CECI + String command = "WRITEQ TS FROM(&INPUTDATA)"; + if(this.queueName.length() > 8) { + // Use QNAME where the TSQ name is greater than 8 characters. + command += " QNAME(" + this.queueName + ")"; + } else { + // Otherwise use QUEUE to avoid potentially breaking existing tests. + command += " QUEUE(" + this.queueName + ")"; + } + + try { + // Start CECI session in the terminal + this.ceci.startCECISession(this.ceciTerminal); + + // Create variable to write data to TSQ + int varLength = this.ceci.defineVariableText(this.ceciTerminal, "&INPUTDATA", inputData); + logger.info("Message length written to variable is : " + varLength); + logger.info("Message written is : " + inputData); + + } catch (CeciException e) { + throw new TsqException("Failed to create variable for input data to write to TSQ : " + this.queueName + ".", e); + } + + try { + // Write to TSQ using using CECI command + ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); + if (!resp.isNormal()) { + throw new TsqException("Write to TSQ failed for queue " + this.queueName + ". CICS response: " + resp.getResponse()); + } else { + logger.info(String.format("Written '%s' to TSQ - %s successful.",inputData , this.queueName )); + } + } catch (CeciException e) { + throw new TsqException("Failed to write to TSQ : " + this.queueName + ".", e); + } + + // Delete the &INPUTDATA variable after writing to TSQ + try{ + this.ceci.deleteVariable(this.ceciTerminal, "&INPUTDATA"); + } catch (CeciException e) { + throw new TsqException("Failed to delete variable used to write to TSQ : " + this.queueName + ".", e); + } + return; + } + + /* + * To delete the TSQ with name set using setName() method + */ + @Override + public void deleteQ() throws TsqException { + // Check if queueName is set + this.checkQueueName(); + + // Create DELETEQ command to execute using CECI + String command = "DELETEQ TS"; + if(this.queueName.length() > 8) { + // Use QNAME where the TSQ name is greater than 8 characters. + command += " QNAME(" + this.queueName + ")"; + } else { + // Otherwise use QUEUE to avoid potentially breaking existing tests. + command += " QUEUE(" + this.queueName + ")"; + } + + try { + //Start CECI session in the terminal + this.ceci.startCECISession(this.ceciTerminal); + + // Delete TSQ using using CECI command + ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); + if (!resp.isNormal()) { + throw new TsqException("Delete TSQ failed for queue " + this.queueName + ". CICS response: " + resp.getResponse()); + } + } catch(CeciException e) { + throw new TsqException("Failed to delete TSQ " + this.queueName + ".", e); + } + return; + } + + /* + * Make recoverable the TSQ with name set using setName() method + */ + @Override + public void makeRecoverable() throws TsqException { + // Generate model name + String modelName = resolveModelName(); + try { + // Run CEDA TSMODEL command to make TSQ recoverable + this.ceda.createResource(this.cedaTerminal, "TSMODEL", modelName, modelName, String.format("PREFIX(%s) RECOVERY(YES)", this.queueName)); + // Install CEDA TSMODEL to make TSQ recoverable + this.ceda.installResource(this.cedaTerminal, "TSMODEL", modelName, modelName); + } catch(CedaException e) { + throw new TsqException("Failed to make TSQ : " + this.queueName + " recoverable.", e); + } + return; + } + + /** + * Check if the queue name is empty and throw error if empty. + */ + public void checkQueueName() throws TsqException { + if (this.queueName.trim().length() == 0){ + throw new TsqException("TSQ queue name cannot be blanks. Set queue name using setName() method. "); + } + return; + } + + /** + * Generates a TS model based on the TSQ name. If the TSQ name is less than 8 characters long, it is appened with 'M'. Otherwise the 8th character is changed to be an 'M'. + *

+ * If the TSQ name is: 'QUEUE ', then the model name is: 'QUEUEM '. + *
+ * If the TSQ name is: 'FEATUREQ', then the model name is: 'FEATUREM'. + */ + private String resolveModelName() { + if(this.queueName.length() < 8) { + return this.queueName + "M"; + } else { + return this.queueName.substring(0,7) + "M"; + } + } + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java new file mode 100644 index 000000000..4ce09596f --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java @@ -0,0 +1,22 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to annotate annotations that are to be used for Test Class fields. To be + * populated by the Manager. + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +public @interface TsqManagerField { + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java new file mode 100644 index 000000000..89e95dd86 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java @@ -0,0 +1,99 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.internal; + +import java.util.HashMap; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.osgi.service.component.annotations.Component; + +import dev.galasa.ManagerException; +import dev.galasa.cicsts.TsqException; +import dev.galasa.cicsts.TsqManagerException; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.tsq.internal.properties.TsqPropertiesSingleton; +import dev.galasa.cicsts.tsq.spi.ITsqManagerSpi; +import dev.galasa.cicsts.spi.ITsqProvider; +import dev.galasa.cicsts.spi.ICicstsManagerSpi; +import dev.galasa.framework.spi.AbstractManager; +import dev.galasa.framework.spi.ConfigurationPropertyStoreException; +import dev.galasa.framework.spi.IFramework; +import dev.galasa.framework.spi.IManager; +import dev.galasa.framework.spi.ResourceUnavailableException; +import dev.galasa.framework.spi.language.GalasaTest; + +@Component(service = { IManager.class }) +public class TsqManagerImpl extends AbstractManager implements ITsqManagerSpi, ITsqProvider { + + protected static final String NAMESPACE = "tsq"; + private ICicstsManagerSpi cicstsManager; + + protected HashMap regionTsqs = new HashMap<>(); + + /* (non-Javadoc) + * @see dev.galasa.framework.spi.AbstractManager#initialise(dev.galasa.framework.spi.IFramework, java.util.List, java.util.List, java.lang.Class) + */ + @Override + public void initialise(@NotNull IFramework framework, @NotNull List allManagers, @NotNull List activeManagers, @NotNull GalasaTest galasaTest) throws ManagerException { + super.initialise(framework, allManagers, activeManagers, galasaTest); + try { + TsqPropertiesSingleton.setCps(framework.getConfigurationPropertyService(NAMESPACE)); + } catch (ConfigurationPropertyStoreException e) { + throw new TsqManagerException("Unable to request framework services", e); + } + + if(galasaTest.isJava()) { + youAreRequired(allManagers, activeManagers, galasaTest); + } + } + + /* (non-Javadoc) + * @see dev.galasa.framework.spi.AbstractManager#provisionGenerate() + */ + @Override + public void provisionGenerate() throws ManagerException, ResourceUnavailableException { + generateAnnotatedFields(TsqManagerField.class); + } + + + /* (non-Javadoc) + * @see dev.galasa.framework.spi.AbstractManager#youAreRequired() + */ + @Override + public void youAreRequired(@NotNull List allManagers, @NotNull List activeManagers, @NotNull GalasaTest galasaTest) throws ManagerException { + if (activeManagers.contains(this)) { + return; + } + + activeManagers.add(this); + + cicstsManager = addDependentManager(allManagers, activeManagers, galasaTest, ICicstsManagerSpi.class); + if(cicstsManager == null) { + throw new CicstsManagerException("CICS Manager is not available"); + } + + cicstsManager.registerTsqProvider(this); + + } + + @Override + public @NotNull ITsqHandler getTsq(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException{ + ITsqHandler tsq = this.regionTsqs.get(cicsRegion); + if (tsq == null) { + try{ + tsq = new TsqImpl(this, cicsRegion, cicstsManager); + this.regionTsqs.put(cicsRegion, tsq); + } catch (TsqException e) { + throw new TsqManagerException("TSQ instance implemenation failed. ", e); + } + } + return tsq; + } +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/package-info.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/package-info.java new file mode 100644 index 000000000..14c82443f --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/package-info.java @@ -0,0 +1,9 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +/** + * CICS/TS TSQ Manager - Internal Implementation + */ +package dev.galasa.cicsts.tsq.internal; \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/TsqPropertiesSingleton.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/TsqPropertiesSingleton.java new file mode 100644 index 000000000..18f93e090 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/TsqPropertiesSingleton.java @@ -0,0 +1,51 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.internal.properties; + +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; + +import dev.galasa.cicsts.TsqManagerException; +import dev.galasa.framework.spi.IConfigurationPropertyStoreService; + +@Component(service=TsqPropertiesSingleton.class, immediate=true) +public class TsqPropertiesSingleton { + + private static TsqPropertiesSingleton singletonInstance; + private static void setInstance(TsqPropertiesSingleton instance) { + singletonInstance = instance; + } + + private IConfigurationPropertyStoreService cps; + + @Activate + public void activate() { + setInstance(this); + } + + @Deactivate + public void deacivate() { + setInstance(null); + } + + public static IConfigurationPropertyStoreService cps() throws TsqManagerException { + if (singletonInstance != null) { + return singletonInstance.cps; + } + + throw new TsqManagerException("Attempt to access manager CPS before it has been initialised"); + } + + public static void setCps(IConfigurationPropertyStoreService cps) throws TsqManagerException { + if (singletonInstance != null) { + singletonInstance.cps = cps; + return; + } + + throw new TsqManagerException("Attempt to set manager CPS before instance created"); + } +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/package-info.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/package-info.java new file mode 100644 index 000000000..9da2a516b --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/properties/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +/** + * CICS/TS TSQ Manager - CPS Properties + * + *

+ * The following properties are used by the CICS/TS TSQ Manager:-
+ *

+ */ +package dev.galasa.cicsts.tsq.internal.properties; \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/ITsqManagerSpi.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/ITsqManagerSpi.java new file mode 100644 index 000000000..d5ce45c8e --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/ITsqManagerSpi.java @@ -0,0 +1,13 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.spi; + +/** + * Provides the SPI access to the CICS/TS TSQ Manager + */ +public interface ITsqManagerSpi { + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/package-info.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/package-info.java new file mode 100644 index 000000000..7162cb8d8 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/spi/package-info.java @@ -0,0 +1,9 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +/** + * zOSMF Batch Manager - Internal SPI + */ +package dev.galasa.cicsts.tsq.spi; \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md new file mode 100644 index 000000000..8a0a38740 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md @@ -0,0 +1,84 @@ +
Request a TSQ Handler instance + +The following snippet shows the code that is required to request a TSQ instance in a Galasa test: + +``` +@CicsRegion() +public ICicsRegion cicsRegion; + +... + +ITsqHandler tsq = cicsRegion.tsq(); +``` + +The code creates a CICS/TS TSQ instance. + +
+ +
Issue a TSQ WRITEQ command + +The following snippet shows the code required to issue the a TSQ WRITEQ command. + +In this case, the test will write a message to the TSQ named GALASAQ from the variable writeMessage: + +``` +tsq.setQName("GALASAQ"); + +String writeMessage = "Write this message to TSQ name GALASAQ"; +tsq.writeQ(writeMessage); + +``` +
+ +
Issue a TSQ READQ command + +The following snippet shows the code required to issue the a TSQ READQ command. + +In this case, the test will read a message from the TSQ named GALASAQ based in the item number passed into the variable readMessage: + +``` +tsq.setName("GALASAQ"); + +int itemNum = 1; +String readMessage = tsq.readQ(itemNum); + +``` +
+ +
Issue a TSQ DELETEQ command + +The following snippet shows the code required to issue the a TSQ DELETEQ command. + +In this case, the test will delete the TSQ named GALASAQ: + +``` +tsq.setName("GALASAQ"); + +String readMessage = tsq.deleteQ(); + +``` +
+ +
Make a TSQ recoverable + +The following snippet shows the code required to make a TSQ recoverable. + +In this case, the test will make the TSQ named GALASAQ recoverable: + +``` +tsq.setName("GALASAQ"); + +String readMessage = tsq.makeRecoverable(); + +``` +
+ +
To get TSQ name + +The following snippet shows the code required to get the TSQ name. + +``` +String tsqName = tsq.getQName(); + +``` +
\ No newline at end of file diff --git a/galasa-managers-parent/settings.gradle b/galasa-managers-parent/settings.gradle index 767ec2472..59374a9fa 100644 --- a/galasa-managers-parent/settings.gradle +++ b/galasa-managers-parent/settings.gradle @@ -60,10 +60,12 @@ include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.manager.ivt' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.ceci.manager' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.cemt.manager' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.ceda.manager' +include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.tsq.manager' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.resource.manager' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.ceda.manager.ivt' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.cemt.manager.ivt' include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.ceci.manager.ivt' +include 'galasa-managers-cicsts-parent:dev.galasa.cicsts.tsq.manager.ivt' // galasa-managers-unix-parent include 'galasa-managers-unix-parent:dev.galasa.linux.manager' include 'galasa-managers-unix-parent:dev.galasa.linux.manager.ivt' From 2b2a0827d03b93c1deb5516760d7bc12bc405ff7 Mon Sep 17 00:00:00 2001 From: Anuprakash Moothedath Date: Fri, 30 Aug 2024 22:26:04 +0530 Subject: [PATCH 2/4] Updated TSQ manager methods Signed-off-by: Anuprakash Moothedath --- .../java/dev/galasa/cicsts/ICicsRegion.java | 2 +- .../src/main/java/dev/galasa/cicsts/ITsq.java | 64 ++++ .../java/dev/galasa/cicsts/ITsqHandler.java | 54 --- .../dev/galasa/cicsts/spi/BaseCicsImpl.java | 6 +- .../galasa/cicsts/spi/ICicstsManagerSpi.java | 2 +- .../dev/galasa/cicsts/spi/ITsqProvider.java | 8 +- .../cicsts/tsq/manager/ivt/TsqManagerIVT.java | 142 -------- .../galasa/cicsts/tsq/internal/TsqImpl.java | 312 +++++++++++------- .../cicsts/tsq/internal/TsqManagerImpl.java | 8 +- .../galasa/cicsts/tsq/spi/package-info.java | 2 +- .../tsq_manager_codesnippet.md | 81 +++-- 11 files changed, 323 insertions(+), 358 deletions(-) create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java delete mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java delete mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java index 65e719420..9a24c1666 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java @@ -52,7 +52,7 @@ public interface ICicsRegion { ICemt cemt() throws CicstsManagerException; ICeda ceda() throws CicstsManagerException; ICeci ceci() throws CicstsManagerException; - ITsqHandler tsq() throws CicstsManagerException; + ITsq tsq() throws CicstsManagerException; /** * Provides a CICS resource instance that can then be used to create a specific CICS resource diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java new file mode 100644 index 000000000..eee566802 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java @@ -0,0 +1,64 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts; + +import javax.validation.constraints.NotNull; +public interface ITsq { + + /** + * Create a new TSQ and write data to the TSQ. + * @param queueName TSQ name + * @param data data to be written to the queue + * @param recoverable true for recoverable and false for non-recoverable + * @return "OK" - for successful TSQ creation and data written to TSQ, + * "ALREADY_EXISTING" - if TSQ already exiting and data written to existing TSQ + * @throws TsqException if there is a problem in creating the TSQ name + */ + public String createQueue(@NotNull String queueName, @NotNull String data, @NotNull boolean recoverable) throws TsqException; + + /** + * Create a new TSQ and write data to the TSQ. + * @param queueName TSQ name + * @param data data to be written to the queue + * @return "OK" - for successful TSQ creation and data written to TSQ, + * "ALREADY_EXISTING" - if TSQ already exiting and data written to existing TSQ + * @throws TsqException if there is a problem in creating the TSQ name + */ + public String createQueue(@NotNull String queueName, @NotNull String data) throws TsqException; + + /** + * Read Data from TSQ based on item number. + * @param queueName TSQ name + * @param item Item number of the TSQ to be read + * @return Data read from TSQ as String + * @throws TsqException if there is a problem in reading from the TSQ + */ + public String readQueue(@NotNull String queueName, @NotNull int item) throws TsqException; + + /** + * Read next from TSQ. + * @param queueName TSQ name + * @return Data read from TSQ as String + * @throws TsqException if there is a problem in reading from the TSQ + */ + public String readQueueNext(String queueName) throws TsqException; + + /** + * Write data to TSQ. + * @param queueName TSQ name + * @param data The data to be written to the TSQ + * @throws TsqException if there is a problem in writing to the TSQ + */ + public void writeQueue(@NotNull String queueName, @NotNull String data) throws TsqException; + + /** + * Delete TSQ. + * @param queueName TSQ name + * @throws TsqException if there is a problem in deleting the TSQ + */ + public void deleteQueue(@NotNull String queueName) throws TsqException; + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java deleted file mode 100644 index 774bfd07f..000000000 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ -package dev.galasa.cicsts; - -import javax.validation.constraints.NotNull; - -public interface ITsqHandler { - - /** - * Set TSQ name - * @param queueName TSQ name - * @throws TsqException if there is a problem in setting the TSQ name - */ - public void setQName(@NotNull String queueName) throws TsqException; - - /** - * Get TSQ name - * @return TSQ name - * @throws TsqException if there is a problem in setting the TSQ name - */ - public String getQName() throws TsqException; - - /** - * Read Data from TSQ. TSQ name is set using setName() method. - * TSQ item number to be read is passed as parm to this method. - * @param item Item number of the TSQ to be read - * @return Data read from TSQ as String - * @throws TsqException if there is a problem in reading from the TSQ - */ - public String readQ(@NotNull int item) throws TsqException; - - /** - * Write inputData to TSQ. TSQ name is set using setName() method. - * @param inputData The string to be written to the TSQ - * @throws TsqException if there is a problem in writing to the TSQ - */ - public void writeQ(@NotNull String inputData) throws TsqException; - - /** - * Delete TSQ. TSQ name is set using setName() method. - * @throws TsqException if there is a problem in deleting the TSQ - */ - public void deleteQ() throws TsqException; - - /** - * Make TSQ Recoverable. TSQ name is set using setName() method. - * @throws TsqException if there is a problem in making the TSQ recoverable - */ - public void makeRecoverable() throws TsqException; - -} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java index a5bef8437..2fae8108d 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java @@ -9,7 +9,7 @@ import dev.galasa.cicsts.ICeci; import dev.galasa.cicsts.ICeda; import dev.galasa.cicsts.ICemt; -import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ITsq; import dev.galasa.cicsts.MasType; import dev.galasa.cicsts.cicsresource.CicsJvmserverResourceException; import dev.galasa.cicsts.cicsresource.ICicsResource; @@ -30,7 +30,7 @@ public abstract class BaseCicsImpl implements ICicsRegionProvisioned { private ICeci ceci; private ICeda ceda; private ICemt cemt; - private ITsqHandler tsq; + private ITsq tsq; private ICicsResource cicsResource; private IZosUNIXFile runTemporaryUNIXPath; @@ -96,7 +96,7 @@ public ICeda ceda() throws CicstsManagerException { } @Override - public ITsqHandler tsq() throws CicstsManagerException { + public ITsq tsq() throws CicstsManagerException { if (this.tsq == null) { this.tsq = this.cicstsManager.getTsqProvider().getTsq(this, this.cicstsManager); } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java index a9bc74377..e2882d905 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ICicstsManagerSpi.java @@ -46,7 +46,7 @@ public interface ICicstsManagerSpi { void registerCedaProvider(@NotNull ICedaProvider cedaProvider); /** - * Register the a ITsqHandler instance provider with the CICS TS Manager + * Register the a ITsq instance provider with the CICS TS Manager * * @param tsqProvider - the new provider */ diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java index bae723f81..4449e8afd 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java @@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull; -import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ITsq; import dev.galasa.cicsts.TsqManagerException; import dev.galasa.cicsts.ICicsRegion; @@ -18,14 +18,14 @@ public interface ITsqProvider { /** - * Returns a unique instance of the ICemt per CICS region + * Returns a unique instance of the ITsq per CICS region * * @param cicsRegion * @param cicstsManager - * @return ITsqHandler object for this CICS region, will a different instance for different regions + * @return ITsq object for this CICS region, will a different instance for different regions * @throws TsqManagerException if getTsq() fails */ @NotNull - ITsqHandler getTsq(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException; + ITsq getTsq(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException; } \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java deleted file mode 100644 index 8163152c2..000000000 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package dev.galasa.cicsts.tsq.manager.ivt; - -import dev.galasa.BeforeClass; -import dev.galasa.Test; -import dev.galasa.core.manager.Logger; -import org.apache.commons.logging.Log; - -import dev.galasa.cicsts.CicsRegion; -import dev.galasa.cicsts.CicsTerminal; -import dev.galasa.cicsts.CicstsManagerException; -import dev.galasa.cicsts.ICicsRegion; -import dev.galasa.cicsts.ICicsTerminal; -import dev.galasa.cicsts.ITsqHandler; - -import dev.galasa.zos3270.FieldNotFoundException; -import dev.galasa.zos3270.KeyboardLockedException; -import dev.galasa.zos3270.TerminalInterruptedException; -import dev.galasa.zos3270.spi.NetworkException; -import dev.galasa.zos3270.TimeoutException; - -import static org.assertj.core.api.Assertions.assertThat; - -@Test -public class TsqManagerIVT { - - @Logger - public Log logger; - - @CicsRegion(cicsTag="A") - public ICicsRegion cicsRegionA; - - @CicsTerminal(cicsTag="A") - public ICicsTerminal cemtTerminalA; - - public ITsqHandler tsqA; - - /** - * Validate if the ITsqHandler object is not NULL - * - * @throws CicstsManagerException - */ - @BeforeClass - public void checkTsqLoaded() throws CicstsManagerException { - tsqA = cicsRegionA.tsq(); - assertThat(tsqA).isNotNull(); - } - - /** - * Set the TSQ name for performing ITsqHandler methods - * - * @throws CicstsManagerException - */ - @BeforeClass - public void setTsqName() throws CicstsManagerException { - // Set the TSQ name as GALASAQ for readQ(), writeQ() and deleteQ() methods. - tsqA.setQName("GALASAQ"); - } - - /** - * Check if getQName() returns the TSQ name - * - * @throws CicstsManagerException - */ - @Test - public void getTsqName() throws CicstsManagerException { - // Set the TSQ name as GALASAQ for readQ(), writeQ() and deleteQ() methods. - assertThat(tsqA.getQName()).isEqualTo("GALASAQ"); - } - - /** - * Tests that the Text is written to TSQ and read from TSQ - * - * @throws CicstsManagerException - */ - @Test - public void testTsqWriteRead() throws CicstsManagerException { - String writeMessage = "This message is written from Galasa to the TSQ named GALASAQ."; - // Write message to TSQ - GALASAQ - tsqA.writeQ(writeMessage); - logger.info("Text written to TSQ GALASAQ : " + writeMessage); - - //Read message from TSQ - GALASAQ - String readMessage = tsqA.readQ(1); - logger.info("Text read from TSQ GALASAQ : " + readMessage); - - // Validate if the message read from TSQ is same as the message written - assertThat(readMessage).isEqualTo(writeMessage); - } - - /** - * Tests that the TSQ is made recoverable - * - * @throws CicstsManagerException - * @throws FieldNotFoundException - * @throws KeyboardLockedException - * @throws NetworkException - * @throws TerminalInterruptedException - * @throws TimeoutException - */ - @Test - public void testTsqMakeRevoverable() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { - // Make the TSQ named GALASAQ recoverable - tsqA.makeRecoverable(); - - // Inquire the CICS TSMODEL resource GALASAQM - String tsModelProps = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSMODEL(GALASAQM)").enter().waitForKeyboard().tab().type("s").enter().waitForKeyboard().retrieveScreen(); - // Validate if the TSMODEL sets the recover status to recoverable - assertThat(tsModelProps).contains("Tsmodel(GALASAQM)","Prefix(GALASAQ)","Recovstatus(Recoverable)"); - } - - /** - * Tests that the TSQ is deleted - * - * @throws CicstsManagerException - * @throws FieldNotFoundException - * @throws KeyboardLockedException - * @throws NetworkException - * @throws TerminalInterruptedException - * @throws TimeoutException - */ - @Test - public void testTsqDeleteQ() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { - String tsqPropsBeforeDelete = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSQUEUE(GALASAQ)").enter().waitForKeyboard().retrieveScreen(); - // Validate if the TSQ - GALASAQ is existing - assertThat(tsqPropsBeforeDelete).contains("Tsq(GALASAQ ","NORMAL"); - assertThat(tsqPropsBeforeDelete).doesNotContain("NOT FOUND"); - - // Delete the TSQ GALASAQ - tsqA.deleteQ(); - - // Inquire the CICS TSMODEL resource GALASAQM - String tsqPropsAfterDelete = cemtTerminalA.resetAndClear().waitForKeyboard().type("CEMT INQUIRE TSQUEUE(GALASAQ)").enter().waitForKeyboard().retrieveScreen(); - // Validate if the TSQ - GALASAQ is deleted - assertThat(tsqPropsAfterDelete).contains("Tsq(GALASAQ ","NOT FOUND","ERROR"); - } -} \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java index 1fd040ed4..5fffb027b 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java @@ -18,37 +18,41 @@ import dev.galasa.cicsts.TsqException; import dev.galasa.cicsts.TsqManagerException; import dev.galasa.cicsts.CicstsManagerException; -import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ITsq; import dev.galasa.cicsts.ICicsRegion; import dev.galasa.cicsts.ICicsTerminal; import dev.galasa.cicsts.IExecInterfaceBlock; import dev.galasa.cicsts.ICeci; import dev.galasa.cicsts.ICeda; +import dev.galasa.cicsts.ICemt; import dev.galasa.cicsts.ICeciResponse; import dev.galasa.cicsts.CeciException; import dev.galasa.cicsts.CedaException; +import dev.galasa.cicsts.CemtException; import dev.galasa.cicsts.spi.ICicstsManagerSpi; import dev.galasa.zos3270.FieldNotFoundException; import dev.galasa.zos3270.KeyboardLockedException; import dev.galasa.zos3270.TerminalInterruptedException; import dev.galasa.zos3270.TimeoutException; import dev.galasa.zos3270.spi.NetworkException; - +import dev.galasa.cicsts.CicstsHashMap; /** - * Implementation of {@link ITsqHandler} + * Implementation of {@link ITsq} */ -public class TsqImpl implements ITsqHandler { +public class TsqImpl implements ITsq { private static final Log logger = LogFactory.getLog(TsqImpl.class); private final ICicsRegion cicsRegion; private final ICicsTerminal ceciTerminal; private final ICicsTerminal cedaTerminal; + private final ICicsTerminal cemtTerminal; private final ICicstsManagerSpi cicstsManager; private final ICeci ceci; private final ICeda ceda; - private String queueName; + private final ICemt cemt; + private String queueName; public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqException { this.cicsRegion = cicsRegion; @@ -63,63 +67,143 @@ public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi } catch (CicstsManagerException e) { throw new TsqException("Unable to get CEDA instance for CICS region", e); } + try { + this.cemt = cicsRegion.cemt(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEMT instance for CICS region", e); + } try { this.ceciTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); this.ceciTerminal.connectToCicsRegion(); - this.ceciTerminal.resetAndClear(); - } catch (CicstsManagerException e) { + this.ceciTerminal.clear(); + } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { throw new TsqException("Unable to get CECI terminal for CICS region", e); } try { this.cedaTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); this.cedaTerminal.connectToCicsRegion(); - this.cedaTerminal.resetAndClear(); - } catch (CicstsManagerException e) { + this.cedaTerminal.clear(); + } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { throw new TsqException("Unable to get CEDA terminal for CICS region", e); } + try { + this.cemtTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); + this.cemtTerminal.connectToCicsRegion(); + this.cemtTerminal.clear(); + } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { + throw new TsqException("Unable to get CEMT terminal for CICS region", e); + } } /* - * To set the TSQ name used for readQ(), writeQ(), deleteQ() and makeRecoverable() methods + * Create the TSQ and write data. Make the TSQ recoverable based on recoverable param. */ @Override - public void setQName(@NotNull String queueName) throws TsqException{ + public String createQueue(String queueName, String data, boolean recoverable) throws TsqException { this.queueName = queueName; - // Check if queueName is blank - if (this.queueName.trim().length() == 0){ - throw new TsqException("TSQ queue name cannot be blanks in setName() method."); + String response = ""; + // If recoverable is true create a TSMODEL to set TSQ as recoverable + if (recoverable) { + this.setRecoverable(queueName); } - logger.info("TSQ name set to: " + queueName); - return; - } + + // Create TSQ and write to TSQ + try { + response = this.createQueue(queueName, data); + } catch (TsqException e) { + throw new TsqException(String.format("Failed to create TSQ : (%s)", queueName), e); + } + + return response; + } /* - * To get the TSQ name used for readQ(), writeQ(), deleteQ() and makeRecoverable() methods + * Create the TSQ and write data. + */ + @Override + public String createQueue(String queueName, String data) throws TsqException { + this.queueName = queueName; + String response = "OK"; + + // Check if TSQ is already exiting. + try { + CicstsHashMap cemtInquireTSQ = this.cemt.inquireResource(this.cemtTerminal, "TSQUEUE", queueName); + + if( cemtInquireTSQ != null ) { + logger.warn(String.format("TSQ is already existing. The data will be written to existing TSQ : (%s).", queueName)); + response = "ALREADY_EXISTING"; + } + } catch ( CemtException e ) { + throw new TsqException("Failed to inquire the existence of TSQ : " + queueName, e); + } + try { + this.writeQueue(queueName, data); + } catch (TsqException e) { + throw new TsqException("Failed to write to TSQ : " + queueName, e); + } + return response; + } + + /* + * Write to the TSQ */ @Override - public String getQName() throws TsqException{ - return this.queueName ; - } + public void writeQueue(String queueName, String data) throws TsqException { + this.queueName = queueName; + // Check if queueName is set + this.checkQueueName(); + // Check if data to write to TSQ is blank or not + this.checkData(data); + + // Create WRITEQ command to execute using CECI + String command = String.format("WRITEQ TS FROM(&INPUTDATA) %s", this.setQueueNameforCECI()); + + try { + // Start CECI session in the terminal + this.ceci.startCECISession(this.ceciTerminal); + + // Create variable to write data to TSQ + int varLength = this.ceci.defineVariableText(this.ceciTerminal, "&INPUTDATA", data); + logger.info(String.format("Message length written to variable is : %s", varLength)); + logger.info(String.format("Message written is : %s", data)); + + } catch (CeciException e) { + throw new TsqException(String.format("Failed to create variable for input data to write to TSQ : (%s).", queueName), e); + } + + try { + // Write to TSQ using using CECI command + ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); + if (!resp.isNormal()) { + throw new TsqException(String.format("Write failed for TSQ : (%s). CICS response: %s", queueName, resp.getResponse())); + } else { + logger.info(String.format("Written '%s' to TSQ - %s successful.",data , queueName )); + } + } catch (CeciException e) { + throw new TsqException(String.format("Failed to write to TSQ : (%s).", queueName) , e); + } + + // Delete the &INPUTDATA variable after writing to TSQ + try{ + this.ceci.deleteVariable(this.ceciTerminal, "&INPUTDATA"); + } catch (CeciException e) { + throw new TsqException(String.format("Failed to delete variable used to write to TSQ : (%s).", queueName), e); + } + return; + } /* - * To read the TSQ with name set using setName() method + * Read the TSQ based on the item number */ @Override - public String readQ(@NotNull int item) throws TsqException{ + public String readQueue(String queueName, int item) throws TsqException{ + this.queueName = queueName; // Check if queueName is set this.checkQueueName(); - String outData = ""; + String data = ""; // Create READQ command to execute using CECI - String command = "READQ TS INTO(&OUTDATA)"; - if(this.queueName.length() > 8) { - // Use QNAME where the TSQ name is greater than 8 characters. - command += " QNAME(" + this.queueName + ")"; - } else { - // Otherwise use QUEUE to avoid potentially breaking existing tests. - command += " QUEUE(" + this.queueName + ")"; - } - command += " ITEM(" + item + ")"; + String command = String.format("READQ TS INTO(&OUTDATA) %s ITEM(%s)", this.setQueueNameforCECI(), item); try { //Start CECI session in the terminal @@ -129,101 +213,71 @@ public String readQ(@NotNull int item) throws TsqException{ if (resp.isNormal()) { try { // Retrieve the text read from TSQ - outData = this.ceci.retrieveVariableText(this.ceciTerminal, "&OUTDATA"); + data = this.ceci.retrieveVariableText(this.ceciTerminal, "&OUTDATA"); } catch (CeciException e) { throw new TsqException("Read TSQ failed while trying to retrieve the data. ", e); } - } else { - throw new TsqException("TSQ read failed for queue : " + this.queueName + ". CICS response : " + resp.getResponse()); + } else if (resp.getResponse().equals("ITEMERR")) { + data = "READ_ERROR"; + logger.error(String.format("There is no item (%s) to read from TSQ : (%s). CICS response : %s ", item, queueName, resp.getResponse())); + } else { + throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", queueName, resp.getResponse())); } } catch (CeciException e) { - throw new TsqException("Failed to read TSQ Data " + this.queueName + ".", e); - } - - // Delete the &OUTDATA variable after reading the TSQ - try{ - this.ceci.deleteVariable(this.ceciTerminal, "&OUTDATA"); - } catch (CeciException e) { - throw new TsqException("Failed to delete variable used to read TSQ : " + this.queueName + ".", e); + throw new TsqException(String.format("Failed to read TSQ : (%s).", queueName), e); } - return outData; + return data; } /* - * To write to the TSQ with name set using setName() method + * Read next entry in TSQ */ @Override - public void writeQ(String inputData) throws TsqException { + public String readQueueNext(String queueName) throws TsqException{ + this.queueName = queueName; // Check if queueName is set this.checkQueueName(); + String data = ""; - // Check if inputData to write to TSQ is empty - if (inputData.trim().length() == 0){ - throw new TsqException("Data written to TSQ cannot be empty. "); - } + // Create READQ command to execute using CECI + String command = String.format("READQ TS INTO(&OUTDATA) %s NEXT", this.setQueueNameforCECI()); - // Create WRITEQ command to execute using CECI - String command = "WRITEQ TS FROM(&INPUTDATA)"; - if(this.queueName.length() > 8) { - // Use QNAME where the TSQ name is greater than 8 characters. - command += " QNAME(" + this.queueName + ")"; - } else { - // Otherwise use QUEUE to avoid potentially breaking existing tests. - command += " QUEUE(" + this.queueName + ")"; - } - try { - // Start CECI session in the terminal + //Start CECI session in the terminal this.ceci.startCECISession(this.ceciTerminal); - - // Create variable to write data to TSQ - int varLength = this.ceci.defineVariableText(this.ceciTerminal, "&INPUTDATA", inputData); - logger.info("Message length written to variable is : " + varLength); - logger.info("Message written is : " + inputData); - - } catch (CeciException e) { - throw new TsqException("Failed to create variable for input data to write to TSQ : " + this.queueName + ".", e); - } - - try { - // Write to TSQ using using CECI command - ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); - if (!resp.isNormal()) { - throw new TsqException("Write to TSQ failed for queue " + this.queueName + ". CICS response: " + resp.getResponse()); - } else { - logger.info(String.format("Written '%s' to TSQ - %s successful.",inputData , this.queueName )); - } - } catch (CeciException e) { - throw new TsqException("Failed to write to TSQ : " + this.queueName + ".", e); - } - - // Delete the &INPUTDATA variable after writing to TSQ - try{ - this.ceci.deleteVariable(this.ceciTerminal, "&INPUTDATA"); + // Read TSQ using CECI command + ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); + if (resp.isNormal()) { + try { + // Retrieve the text read from TSQ + data = this.ceci.retrieveVariableText(this.ceciTerminal, "&OUTDATA"); + } catch (CeciException e) { + throw new TsqException("Read TSQ failed while trying to retrieve the data. ", e); + } + } else if (resp.getResponse().equals("ITEMERR")) { + data = "READ_ERROR"; + logger.error(String.format("There is no item to read from TSQ : (%s). CICS response : %s ", queueName, resp.getResponse())); + } + else { + throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", queueName, resp.getResponse())); + } } catch (CeciException e) { - throw new TsqException("Failed to delete variable used to write to TSQ : " + this.queueName + ".", e); + throw new TsqException(String.format("Failed to read TSQ : (%s).", queueName), e); } - return; - } + return data; + } /* - * To delete the TSQ with name set using setName() method + * To delete TSQ */ @Override - public void deleteQ() throws TsqException { + public void deleteQueue(String queueName) throws TsqException { // Check if queueName is set this.checkQueueName(); // Create DELETEQ command to execute using CECI - String command = "DELETEQ TS"; - if(this.queueName.length() > 8) { - // Use QNAME where the TSQ name is greater than 8 characters. - command += " QNAME(" + this.queueName + ")"; - } else { - // Otherwise use QUEUE to avoid potentially breaking existing tests. - command += " QUEUE(" + this.queueName + ")"; - } - + String command = String.format("DELETEQ TS %s", this.setQueueNameforCECI()); + try { //Start CECI session in the terminal this.ceci.startCECISession(this.ceciTerminal); @@ -231,43 +285,45 @@ public void deleteQ() throws TsqException { // Delete TSQ using using CECI command ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); if (!resp.isNormal()) { - throw new TsqException("Delete TSQ failed for queue " + this.queueName + ". CICS response: " + resp.getResponse()); + throw new TsqException(String.format("Delete failed for TSQ : (%s). CICS response: %s", queueName, resp.getResponse())); } } catch(CeciException e) { - throw new TsqException("Failed to delete TSQ " + this.queueName + ".", e); + throw new TsqException(String.format("Failed to delete TSQ : (%s).", queueName), e); } return; } /* - * Make recoverable the TSQ with name set using setName() method + * Create TSMODEL to make TSQ recoverable */ - @Override - public void makeRecoverable() throws TsqException { + private void setRecoverable(String queueName) throws TsqException { // Generate model name String modelName = resolveModelName(); try { // Run CEDA TSMODEL command to make TSQ recoverable - this.ceda.createResource(this.cedaTerminal, "TSMODEL", modelName, modelName, String.format("PREFIX(%s) RECOVERY(YES)", this.queueName)); + this.ceda.createResource(this.cedaTerminal, "TSMODEL", modelName, modelName, String.format("PREFIX(%s) RECOVERY(YES)", queueName)); // Install CEDA TSMODEL to make TSQ recoverable this.ceda.installResource(this.cedaTerminal, "TSMODEL", modelName, modelName); } catch(CedaException e) { - throw new TsqException("Failed to make TSQ : " + this.queueName + " recoverable.", e); + throw new TsqException(String.format("Failed to make TSQ : (%s) recoverable.", queueName), e); } return; } - /** - * Check if the queue name is empty and throw error if empty. - */ - public void checkQueueName() throws TsqException { - if (this.queueName.trim().length() == 0){ - throw new TsqException("TSQ queue name cannot be blanks. Set queue name using setName() method. "); - } - return; - } + // Set Queue name for CECI commands + private String setQueueNameforCECI() { + StringBuilder command = new StringBuilder(); + if(this.queueName.length() > 8) { + // Use QNAME where the TSQ name is greater than 8 characters. + command.append(String.format("QNAME(%s)", this.queueName)); + } else { + // Otherwise use QUEUE to avoid potentially breaking existing tests. + command.append(String.format("QUEUE(%s)", this.queueName)); + } + return command.toString(); + } - /** + /** * Generates a TS model based on the TSQ name. If the TSQ name is less than 8 characters long, it is appened with 'M'. Otherwise the 8th character is changed to be an 'M'. *

* If the TSQ name is: 'QUEUE ', then the model name is: 'QUEUEM '. @@ -281,5 +337,23 @@ private String resolveModelName() { return this.queueName.substring(0,7) + "M"; } } - + + /** + * Check if the queue name is empty and throw error if empty. + */ + public void checkQueueName() throws TsqException { + if (this.queueName.trim().length() == 0){ + throw new TsqException("TSQ queue name cannot be blank."); + } + return; + } + /** + * Check if the data is empty and throw error if empty. + */ + public void checkData(String data) throws TsqException { + if (data.trim().length() == 0){ + throw new TsqException(String.format("Data cannot be blank to write to TSQ : (%s)", this.queueName)); + } + return; + } } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java index 89e95dd86..c558176e2 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java @@ -16,7 +16,7 @@ import dev.galasa.cicsts.TsqException; import dev.galasa.cicsts.TsqManagerException; import dev.galasa.cicsts.CicstsManagerException; -import dev.galasa.cicsts.ITsqHandler; +import dev.galasa.cicsts.ITsq; import dev.galasa.cicsts.ICicsRegion; import dev.galasa.cicsts.tsq.internal.properties.TsqPropertiesSingleton; import dev.galasa.cicsts.tsq.spi.ITsqManagerSpi; @@ -35,7 +35,7 @@ public class TsqManagerImpl extends AbstractManager implements ITsqManagerSpi, I protected static final String NAMESPACE = "tsq"; private ICicstsManagerSpi cicstsManager; - protected HashMap regionTsqs = new HashMap<>(); + protected HashMap regionTsqs = new HashMap<>(); /* (non-Javadoc) * @see dev.galasa.framework.spi.AbstractManager#initialise(dev.galasa.framework.spi.IFramework, java.util.List, java.util.List, java.lang.Class) @@ -84,8 +84,8 @@ public void youAreRequired(@NotNull List allManagers, @NotNull List

Request a TSQ Handler instance +
Request a TSQ instance The following snippet shows the code that is required to request a TSQ instance in a Galasa test: @@ -8,77 +8,100 @@ public ICicsRegion cicsRegion; ... -ITsqHandler tsq = cicsRegion.tsq(); +ITsq tsq = cicsRegion.tsq(); ``` The code creates a CICS/TS TSQ instance.
-
Issue a TSQ WRITEQ command +
Create and write to TSQ -The following snippet shows the code required to issue the a TSQ WRITEQ command. +The following snippet shows the code required to create and write to a TSQ. -In this case, the test will write a message to the TSQ named GALASAQ from the variable writeMessage: +In this case, the test will create a TSQ named GALASAQ and write data in the variable writeMessage. + +Response will be: +- OK : if new TSQ is created and data is written +- ALREADY_EXISTING : if TSQ is already existing and data is written ``` -tsq.setQName("GALASAQ"); -String writeMessage = "Write this message to TSQ name GALASAQ"; -tsq.writeQ(writeMessage); +String queueName = "GALASAQ"; +String writeMessage = "Write this message to TSQ named GALASAQ"; +String response = tsq.createQueue(queueName, writeMessage); ``` -
-
Issue a TSQ READQ command +The following snippet shows the code required to create and write to a recoverable TSQ. -The following snippet shows the code required to issue the a TSQ READQ command. +In this case, the test will create a recoverable TSQ named GALASAQ (if not already existing) and write data from the variable writeMessage. -In this case, the test will read a message from the TSQ named GALASAQ based in the item number passed into the variable readMessage: +Response will be: +- OK : if new TSQ is created and data is written +- ALREADY_EXISTING : if TSQ is already exiting and data is written ``` -tsq.setName("GALASAQ"); -int itemNum = 1; -String readMessage = tsq.readQ(itemNum); +String queueName = "GALASAQ"; +String writeMessage = "Write this message to TSQ named GALASAQ"; +boolean recoverable = true; +String response = tsq.createQueue(queueName, writeMessage, recoverable); ``` +Note: If TSQ is already existing and is non-recoverable, then the TSQ needs to be deleted and then created with recoverable option to make it recoverable. Otherwise the TSQ will continue to be non-recoverable. +
-
Issue a TSQ DELETEQ command +
Write to TSQ -The following snippet shows the code required to issue the a TSQ DELETEQ command. +The following snippet shows the code required to write data to a TSQ. -In this case, the test will delete the TSQ named GALASAQ: +In this case, the test will write the data contained in the variable named writeMessage to the TSQ named GALASAQ: ``` -tsq.setName("GALASAQ"); -String readMessage = tsq.deleteQ(); +String queueName = "GALASAQ"; +String writeMessage = "Write this message to TSQ named GALASAQ"; +tsq.writeQueue(queueName, writeMessage); ```
-
Make a TSQ recoverable +
Read from TSQ + +The following snippet shows the code required to read data from a TSQ. + +In this case, the test will read a message into the variable named readMessage, from the TSQ named GALASAQ based on the item number passed : + +``` + +String queueName = "GALASAQ"; +int itemNum = 1; +String readMessage = tsq.readQueue(queueName, itemNum); -The following snippet shows the code required to make a TSQ recoverable. +``` -In this case, the test will make the TSQ named GALASAQ recoverable: +In this case, the test will read the next message from the TSQ named GALASAQ into the variable named readMessage: ``` -tsq.setName("GALASAQ"); -String readMessage = tsq.makeRecoverable(); +String queueName = "GALASAQ"; +String readMessage = tsq.readQueueNext(queueName); ```
-
To get TSQ name +
Delete a TSQ -The following snippet shows the code required to get the TSQ name. +The following snippet shows the code required to delete a TSQ. + +In this case, the test will delete the TSQ named GALASAQ: ``` -String tsqName = tsq.getQName(); + +String queueName = "GALASAQ"; +tsq.deleteQueue(queueName); ``` -
\ No newline at end of file +
From 21cb88fd194576e1539e847dbf059f894d66908b Mon Sep 17 00:00:00 2001 From: Anuprakash Moothedath Date: Tue, 3 Sep 2024 17:54:25 +0530 Subject: [PATCH 3/4] Updated the implementations of TSQ manger methods Signed-off-by: Anuprakash Moothedath --- .../java/dev/galasa/cicsts/ICicsRegion.java | 2 +- .../src/main/java/dev/galasa/cicsts/ITsq.java | 41 ++- .../java/dev/galasa/cicsts/ITsqFactory.java | 28 +++ .../dev/galasa/cicsts/spi/BaseCicsImpl.java | 8 +- .../dev/galasa/cicsts/spi/ITsqProvider.java | 10 +- .../build.gradle | 2 +- .../cicsts/tsq/manager/ivt/TsqManagerIVT.java | 235 ++++++++++++++++++ .../cicsts/tsq/internal/TsqFactoryImpl.java | 192 ++++++++++++++ .../galasa/cicsts/tsq/internal/TsqImpl.java | 172 +++++-------- .../cicsts/tsq/internal/TsqManagerField.java | 22 -- .../cicsts/tsq/internal/TsqManagerImpl.java | 12 +- .../tsq_manager_codesnippet.md | 110 ++++---- 12 files changed, 612 insertions(+), 222 deletions(-) create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java create mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java delete mode 100644 galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java index 9a24c1666..321a9c73e 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java @@ -52,7 +52,7 @@ public interface ICicsRegion { ICemt cemt() throws CicstsManagerException; ICeda ceda() throws CicstsManagerException; ICeci ceci() throws CicstsManagerException; - ITsq tsq() throws CicstsManagerException; + ITsqFactory getTSQFactory() throws CicstsManagerException; /** * Provides a CICS resource instance that can then be used to create a specific CICS resource diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java index eee566802..8ed2629e2 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java @@ -9,56 +9,45 @@ public interface ITsq { /** - * Create a new TSQ and write data to the TSQ. - * @param queueName TSQ name - * @param data data to be written to the queue - * @param recoverable true for recoverable and false for non-recoverable - * @return "OK" - for successful TSQ creation and data written to TSQ, - * "ALREADY_EXISTING" - if TSQ already exiting and data written to existing TSQ - * @throws TsqException if there is a problem in creating the TSQ name + * Chect the existence of a TSQ. + * @throws TsqException if there is a problem in checking the TSQ existence + * @return boolean based on if TSQ is existing or not */ - public String createQueue(@NotNull String queueName, @NotNull String data, @NotNull boolean recoverable) throws TsqException; - + public boolean exists() throws TsqException; + /** - * Create a new TSQ and write data to the TSQ. - * @param queueName TSQ name - * @param data data to be written to the queue - * @return "OK" - for successful TSQ creation and data written to TSQ, - * "ALREADY_EXISTING" - if TSQ already exiting and data written to existing TSQ - * @throws TsqException if there is a problem in creating the TSQ name + * Check if a TSQ is recoverable. + * @throws TsqException if there is a problem in checking if the TSQ is recoverable or not + * @return boolean based on if TSQ is recoverable or not */ - public String createQueue(@NotNull String queueName, @NotNull String data) throws TsqException; + public boolean isRecoverable() throws TsqException; /** * Read Data from TSQ based on item number. - * @param queueName TSQ name * @param item Item number of the TSQ to be read * @return Data read from TSQ as String * @throws TsqException if there is a problem in reading from the TSQ */ - public String readQueue(@NotNull String queueName, @NotNull int item) throws TsqException; + public String readQueue(@NotNull int item) throws TsqException; /** * Read next from TSQ. - * @param queueName TSQ name * @return Data read from TSQ as String - * @throws TsqException if there is a problem in reading from the TSQ + * @throws TsqException if there is a problem in reading next from the TSQ */ - public String readQueueNext(String queueName) throws TsqException; + public String readQueueNext() throws TsqException; /** * Write data to TSQ. - * @param queueName TSQ name * @param data The data to be written to the TSQ * @throws TsqException if there is a problem in writing to the TSQ */ - public void writeQueue(@NotNull String queueName, @NotNull String data) throws TsqException; + public void writeQueue(@NotNull String data) throws TsqException; /** - * Delete TSQ. - * @param queueName TSQ name + * Delete non-recoverable TSQ. * @throws TsqException if there is a problem in deleting the TSQ */ - public void deleteQueue(@NotNull String queueName) throws TsqException; + public void deleteQueue() throws TsqException; } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java new file mode 100644 index 000000000..f5306c390 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts; + +import javax.validation.constraints.NotNull; +public interface ITsqFactory { + + /** + * Create a new ITsq object with recoverable status + * @param queueName TSQ name + * @param recoverable true for recoverable and false for non-recoverable + * @return ITsq object + * @throws TsqException if there is a problem in creating the ITsq object + */ + public ITsq createQueue(@NotNull String queueName, @NotNull boolean recoverable) throws TsqException; + + /** + * Create a new ITsq object without recoverable status. Default recoverable status is NonRecoverable + * @param queueName TSQ name + * @return ITsq object + * @throws TsqException if there is a problem in creating the ITsq object + */ + public ITsq createQueue(@NotNull String queueName) throws TsqException; + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java index 2fae8108d..8bf22193f 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java @@ -9,7 +9,7 @@ import dev.galasa.cicsts.ICeci; import dev.galasa.cicsts.ICeda; import dev.galasa.cicsts.ICemt; -import dev.galasa.cicsts.ITsq; +import dev.galasa.cicsts.ITsqFactory; import dev.galasa.cicsts.MasType; import dev.galasa.cicsts.cicsresource.CicsJvmserverResourceException; import dev.galasa.cicsts.cicsresource.ICicsResource; @@ -30,7 +30,7 @@ public abstract class BaseCicsImpl implements ICicsRegionProvisioned { private ICeci ceci; private ICeda ceda; private ICemt cemt; - private ITsq tsq; + private ITsqFactory tsq; private ICicsResource cicsResource; private IZosUNIXFile runTemporaryUNIXPath; @@ -96,9 +96,9 @@ public ICeda ceda() throws CicstsManagerException { } @Override - public ITsq tsq() throws CicstsManagerException { + public ITsqFactory getTSQFactory() throws CicstsManagerException { if (this.tsq == null) { - this.tsq = this.cicstsManager.getTsqProvider().getTsq(this, this.cicstsManager); + this.tsq = this.cicstsManager.getTsqProvider().getTsqFactory(this, this.cicstsManager); } return this.tsq; } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java index 4449e8afd..c8a533a14 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/ITsqProvider.java @@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull; -import dev.galasa.cicsts.ITsq; +import dev.galasa.cicsts.ITsqFactory; import dev.galasa.cicsts.TsqManagerException; import dev.galasa.cicsts.ICicsRegion; @@ -18,14 +18,14 @@ public interface ITsqProvider { /** - * Returns a unique instance of the ITsq per CICS region + * Returns a unique instance of the ITsqFactory per CICS region * * @param cicsRegion * @param cicstsManager - * @return ITsq object for this CICS region, will a different instance for different regions - * @throws TsqManagerException if getTsq() fails + * @return ITsqFactory object for this CICS region, will have a different instance for different regions + * @throws TsqManagerException if getTsqFactory() fails */ @NotNull - ITsq getTsq(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException; + ITsqFactory getTsqFactory(ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqManagerException; } \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle index 27f8b8b73..8e9453055 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/build.gradle @@ -21,7 +21,7 @@ dependencies { ext.projectName=project.name ext.includeInOBR = true ext.includeInMVP = true -ext.includeInBOM = false +ext.includeInBOM = true ext.includeInIsolated = true ext.includeInCodeCoverage = false ext.includeInJavadoc = false diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java new file mode 100644 index 000000000..c2fde8990 --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java @@ -0,0 +1,235 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.manager.ivt; + +import dev.galasa.BeforeClass; +import dev.galasa.Test; +import dev.galasa.core.manager.Logger; +import org.apache.commons.logging.Log; + +import dev.galasa.cicsts.CicsRegion; +import dev.galasa.cicsts.CicsTerminal; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.ITsq; +import dev.galasa.cicsts.ITsqFactory; + +import dev.galasa.zos3270.FieldNotFoundException; +import dev.galasa.zos3270.KeyboardLockedException; +import dev.galasa.zos3270.TerminalInterruptedException; +import dev.galasa.zos3270.spi.NetworkException; +import dev.galasa.zos3270.TimeoutException; + +import static org.assertj.core.api.Assertions.assertThat; + +@Test +public class TsqManagerIVT { + + @Logger + public Log logger; + + @CicsRegion(cicsTag="A") + public ICicsRegion cicsRegionA; + + @CicsTerminal(cicsTag="A") + public ICicsTerminal cemtTerminalA; + + public ITsqFactory tsqFactoryA; + public ITsq tsqRecoverable; + public ITsq tsqNonRecoverable; + + /** + * Create TSQ Factory instance and ITsq objects + * @throws CicstsManagerException + */ + @BeforeClass + public void createTsqInstance() throws CicstsManagerException { + this.tsqFactoryA = cicsRegionA.getTSQFactory(); + // Create ITsq object for recoverable TSQ + tsqRecoverable = this.tsqFactoryA.createQueue("GALASAR", true); + // Create ITsq object for non-recoverable TSQ + tsqNonRecoverable = this.tsqFactoryA.createQueue("GALASAN", false); + } + + /** + * Check if recoverable TSQ exists + * + * @throws CicstsManagerException + **/ + @Test + public void testRecoverableTsqNotExists() throws CicstsManagerException { + boolean response = tsqRecoverable.exists(); + assertThat(response).as("Recoverable TSQ (GALASAR) is existing.").isEqualTo(false); + } + + /** + * Check if non-recoverable TSQ exists + * + * @throws CicstsManagerException + **/ + @Test + public void testNonRecoverableTsqNotExists() throws CicstsManagerException { + boolean response = tsqNonRecoverable.exists(); + assertThat(response).as("Non Recoverable TSQ (GALASAN) is existing.").isEqualTo(false); + } + + /** + * Tests that the recoverable TSQ is created and data is written + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + **/ + @Test + public void testCreateRecoverableTsq() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + String writeMessage = "001 - This message is written from Galasa to the recoverable TSQ named GALASAR."; + // Create and write message to TSQ - GALASAR with recoverable status as true + tsqRecoverable.writeQueue(writeMessage); + + // Check if the CICS TSQUEUE - GALASAR is recoverable + boolean response = tsqRecoverable.isRecoverable(); + assertThat(response).as("TSQ (GALASAR) is not recoverable.").isEqualTo(true); + + // Read message from TSQ and validate + String readMessage = tsqRecoverable.readQueue(1); + assertThat(readMessage).as("TSQ (GALASAR) message read is not equal to the message written.").isEqualTo(writeMessage); + } + + /** + * Tests that the data is written if TSQ is existing and recoverable status is not updated + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + **/ + @Test + public void testCreateNonRecoverableTsqForExisting() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + String writeMessage = "002 - This message is written from Galasa to the recoverable TSQ named GALASAR."; + // Create and write message to TSQ - GALASAR with recoverable as false + tsqRecoverable = tsqFactoryA.createQueue("GALASAR", false); + + // Write second message to TSQ - GALASAR + tsqRecoverable.writeQueue(writeMessage); + + // Check if the CICS TSQUEUE - GALASAR is still recoverable + boolean response = tsqRecoverable.isRecoverable(); + assertThat(response).as("TSQ (GALASAR) is not recoverable.").isEqualTo(true); + + + // Read second message from TSQ and validate + String readMessage = tsqRecoverable.readQueue(2); + assertThat(readMessage).as("TSQ (GALASAR) message read is not equal to the message written.").isEqualTo(writeMessage); + } + + /** + * Check if Recoverable TSQ exists + * + * @throws CicstsManagerException + **/ + @Test + public void testRecoverableTsqExists() throws CicstsManagerException { + boolean response = tsqRecoverable.exists(); + assertThat(response).as("Recoverable TSQ (GALASAR) is not existing.").isEqualTo(true); + } + + /** + * Tests that if non recoverable TSQ is created and data is written + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + **/ + @Test + public void testCreateNonRecoverableTsq() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + String writeMessage = "001 - This message is written from Galasa to the non-recoverable TSQ named GALASAN."; + + // Create and write message to TSQ - GALASAN + tsqNonRecoverable.writeQueue(writeMessage); + + // Check if the CICS TSQUEUE - GALASAN is non recoverable + boolean response = tsqNonRecoverable.isRecoverable(); + assertThat(response).as("TSQ (GALASAN) is recoverable.").isEqualTo(false); + + // Read message from non-recoverable TSQ and validate + String readMessage = tsqNonRecoverable.readQueue(1); + assertThat(readMessage).as("TSQ (GALASAN) message read is not equal to the message written.").isEqualTo(writeMessage); + } + + /** + * Check if NonRecoverable exists + * + * @throws CicstsManagerException + **/ + @Test + public void testNonRecoverableTsqExists() throws CicstsManagerException { + boolean response = tsqNonRecoverable.exists(); + assertThat(response).as("Non Recoverable TSQ (GALASAN) is not existing.").isEqualTo(true); + } + /** + * Tests that the non recoverable TSQ is deleted + * + * @throws CicstsManagerException + * @throws FieldNotFoundException + * @throws KeyboardLockedException + * @throws NetworkException + * @throws TerminalInterruptedException + * @throws TimeoutException + **/ + @Test + public void testTsqDelete() throws CicstsManagerException, FieldNotFoundException, KeyboardLockedException, NetworkException, TerminalInterruptedException, TimeoutException { + + // Delete TSQ + tsqNonRecoverable.deleteQueue(); + + // Check if the TSQ - GALASAN is not existing after deleteQueue + boolean response = tsqNonRecoverable.exists(); + assertThat(response).as("Non Recoverable TSQ (GALASAN) is existing.").isEqualTo(false); + } + + /** + * Tests that the non-recoverable TSQ is created and data is written. + * Validate if the readQueueNext() works as expected. + * + * @throws CicstsManagerException + */ + @Test + public void testTsqReadNext() throws CicstsManagerException { + + // Write 4 messages to TSQ - GALASAN + String writeMessage1 = "01) This message is written from Galasa to the TSQ named GALASAN."; + tsqNonRecoverable.writeQueue(writeMessage1); + String writeMessage2 = "02) This message is written from Galasa to the TSQ named GALASAN."; + tsqNonRecoverable.writeQueue(writeMessage2); + String writeMessage3 = "03) This message is written from Galasa to the TSQ named GALASAN."; + tsqNonRecoverable.writeQueue(writeMessage3); + String writeMessage4 = "04) This message is written from Galasa to the TSQ named GALASAN."; + tsqNonRecoverable.writeQueue(writeMessage4); + + // Read next and validate the messages starting from item 1 + String readMessage = tsqNonRecoverable.readQueue(1); + assertThat(readMessage).as("Error in reading the first data.").isEqualTo(writeMessage1); + readMessage = tsqNonRecoverable.readQueueNext(); + assertThat(readMessage).as("Error in reading the second data.").isEqualTo(writeMessage2); + readMessage = tsqNonRecoverable.readQueueNext(); + assertThat(readMessage).as("Error in reading the third data.").isEqualTo(writeMessage3); + readMessage = tsqNonRecoverable.readQueueNext(); + assertThat(readMessage).as("Error in reading the fourth data.").isEqualTo(writeMessage4); + + // READ_ERROR when no more items to read. + readMessage = tsqNonRecoverable.readQueueNext(); + assertThat(readMessage).as("Non Recoverable TSQ (GALASAN) contains more data.").isEqualTo("READ_ERROR"); + } +} \ No newline at end of file diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java new file mode 100644 index 000000000..48184b1eb --- /dev/null +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java @@ -0,0 +1,192 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.cicsts.tsq.internal; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.validation.constraints.NotNull; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import dev.galasa.cicsts.TsqException; +import dev.galasa.cicsts.TsqManagerException; +import dev.galasa.cicsts.CicstsManagerException; +import dev.galasa.cicsts.ITsqFactory; +import dev.galasa.cicsts.ITsq; +import dev.galasa.cicsts.ICicsRegion; +import dev.galasa.cicsts.ICicsTerminal; +import dev.galasa.cicsts.IExecInterfaceBlock; +import dev.galasa.cicsts.ICeci; +import dev.galasa.cicsts.ICeda; +import dev.galasa.cicsts.ICemt; +import dev.galasa.cicsts.ICeciResponse; +import dev.galasa.cicsts.CeciException; +import dev.galasa.cicsts.CedaException; +import dev.galasa.cicsts.CemtException; +import dev.galasa.cicsts.spi.ICicstsManagerSpi; +import dev.galasa.zos3270.FieldNotFoundException; +import dev.galasa.zos3270.KeyboardLockedException; +import dev.galasa.zos3270.TerminalInterruptedException; +import dev.galasa.zos3270.TimeoutException; +import dev.galasa.zos3270.spi.NetworkException; +import dev.galasa.cicsts.CicstsHashMap; + +/** + * Implementation of {@link ITsq} + */ +public class TsqFactoryImpl implements ITsqFactory { + + private static final Log logger = LogFactory.getLog(TsqFactoryImpl.class); + + private final ICicsRegion cicsRegion; + private final ICicsTerminal cedaTerminal; + private final ICicsTerminal cemtTerminal; + private final ICicstsManagerSpi cicstsManager; + private final TsqManagerImpl tsqManager; + private final ICeda ceda; + private final ICemt cemt; + private String queueName; + + public TsqFactoryImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqException { + this.cicsRegion = cicsRegion; + this.cicstsManager = cicstsManager; + this.tsqManager = manager; + try { + this.ceda = cicsRegion.ceda(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEDA instance for CICS region", e); + } + try { + this.cemt = cicsRegion.cemt(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEMT instance for CICS region", e); + } + try { + this.cedaTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); + this.cedaTerminal.connectToCicsRegion(); + this.cedaTerminal.clear(); + } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { + throw new TsqException("Unable to get CEDA terminal for CICS region", e); + } + try { + this.cemtTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); + this.cemtTerminal.connectToCicsRegion(); + this.cemtTerminal.resetAndClear(); + } catch (CicstsManagerException e) { + throw new TsqException("Unable to get CEMT terminal for CICS region", e); + } + } + + /* + * Create the CICS resource TSMODEL if TSQ is recoverable. + * Create and return the ITsq object for the queueName provided. + */ + @Override + public ITsq createQueue(String queueName, boolean recoverable) throws TsqException { + this.queueName = queueName; + checkQueueName(); + + // If recoverable is true create a TSMODEL to make the TSQ as recoverable + if (recoverable) { + this.setRecoverable(queueName); + } + + // Create new ITsq object for the queueName + try { + ITsq response = this.createQueue(queueName); + return response; + } catch (TsqException e) { + throw new TsqException(String.format("Failed to create TSQ : (%s)", queueName), e); + } + } + + /* + * Create and return the ITsq object for the queueName provided. + */ + @Override + public ITsq createQueue(String queueName) throws TsqException { + this.queueName = queueName; + checkQueueName(); + + // Check if TSQ is already exiting. + try { + CicstsHashMap cemtInquireTSQ = this.cemt.inquireResource(this.cemtTerminal, "TSQUEUE", queueName); + // Issue WARNING if TSQ is already existing + if( cemtInquireTSQ != null ) { + logger.warn(String.format("TSQ is already existing. Recoverable status will be based on existing TSQ : (%s).", queueName)); + } + } catch ( CemtException e ) { + throw new TsqException("Failed to inquire the existence of TSQ : " + queueName, e); + } + + // Create new ITsq object for the queueName + try { + ITsq response = new TsqImpl(tsqManager, cicsRegion, cicstsManager, queueName); + return response; + } catch (TsqException e) { + throw new TsqException("Failed to write to TSQ : " + queueName, e); + } + } + + /* + * Create TSMODEL to make TSQ recoverable + */ + private void setRecoverable(String queueName) throws TsqException { + // Generate model name + String modelName = resolveModelName(); + + // Check if TSMODEL is already exiting. + try { + CicstsHashMap cemtInquireTSModel = this.cemt.inquireResource(this.cemtTerminal, "TSMODEL", modelName); + // Issue a warning if TSMODEL is already existing + if( cemtInquireTSModel != null ) { + logger.warn(String.format("TSQMODEL (%s) is already existing for TSQ (%s). Recoverable status will be based on existing TSMODEL.", modelName, queueName)); + } else { + try { + // Create TSMODEL using CEDA command to make TSQ recoverable + this.ceda.createResource(this.cedaTerminal, "TSMODEL", modelName, modelName, String.format("PREFIX(%s) RECOVERY(YES)", queueName)); + // Install TSMODEL using CEDA command to make TSQ recoverable + this.ceda.installResource(this.cedaTerminal, "TSMODEL", modelName, modelName); + } catch(CedaException e) { + throw new TsqException(String.format("Failed to make TSQ : (%s) recoverable.", queueName), e); + } + } + } catch ( CemtException e ) { + throw new TsqException("Failed to inquire the existence of TSMODEL : " + modelName, e); + } + return; + } + + /** + * Generates a TS model name based on the TSQ name. + * If the TSQ name is less than 8 characters long, it is appened with 'M'. Otherwise the 8th character is changed to be an 'M'. + * + * If the TSQ name is: 'QUEUE ', then the model name is: 'QUEUEM '. + * If the TSQ name is: 'FEATUREQ', then the model name is: 'FEATUREM'. + */ + private String resolveModelName() { + if(this.queueName.length() < 8) { + return this.queueName + "M"; + } else { + return this.queueName.substring(0,7) + "M"; + } + } + + /** + * Check if the queue name is empty and throw error if empty. + */ + public void checkQueueName() throws TsqException { + if (this.queueName.trim().length() == 0){ + throw new TsqException("TSQ queue name cannot be blank."); + } + return; + } + +} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java index 5fffb027b..32a31db1d 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqImpl.java @@ -46,27 +46,21 @@ public class TsqImpl implements ITsq { private final ICicsRegion cicsRegion; private final ICicsTerminal ceciTerminal; - private final ICicsTerminal cedaTerminal; private final ICicsTerminal cemtTerminal; private final ICicstsManagerSpi cicstsManager; private final ICeci ceci; - private final ICeda ceda; private final ICemt cemt; private String queueName; - public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager) throws TsqException { + public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi cicstsManager, String queueName) throws TsqException { this.cicsRegion = cicsRegion; this.cicstsManager = cicstsManager; + this.queueName = queueName; try { this.ceci = cicsRegion.ceci(); } catch (CicstsManagerException e) { throw new TsqException("Unable to get CECI instance for CICS region", e); } - try { - this.ceda = cicsRegion.ceda(); - } catch (CicstsManagerException e) { - throw new TsqException("Unable to get CEDA instance for CICS region", e); - } try { this.cemt = cicsRegion.cemt(); } catch (CicstsManagerException e) { @@ -78,81 +72,64 @@ public TsqImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsManagerSpi this.ceciTerminal.clear(); } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { throw new TsqException("Unable to get CECI terminal for CICS region", e); - } - try { - this.cedaTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); - this.cedaTerminal.connectToCicsRegion(); - this.cedaTerminal.clear(); - } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { - throw new TsqException("Unable to get CEDA terminal for CICS region", e); - } + } try { this.cemtTerminal = cicstsManager.generateCicsTerminal(cicsRegion.getTag()); this.cemtTerminal.connectToCicsRegion(); - this.cemtTerminal.clear(); - } catch (CicstsManagerException | KeyboardLockedException | NetworkException | TerminalInterruptedException e) { + this.cemtTerminal.resetAndClear(); + } catch (CicstsManagerException e) { throw new TsqException("Unable to get CEMT terminal for CICS region", e); } } - - /* - * Create the TSQ and write data. Make the TSQ recoverable based on recoverable param. - */ - @Override - public String createQueue(String queueName, String data, boolean recoverable) throws TsqException { - this.queueName = queueName; - String response = ""; - // If recoverable is true create a TSMODEL to set TSQ as recoverable - if (recoverable) { - this.setRecoverable(queueName); - } - // Create TSQ and write to TSQ + /* + * Check the exitence of TSQ + */ + @Override + public boolean exists() throws TsqException { + boolean response = true; try { - response = this.createQueue(queueName, data); - } catch (TsqException e) { - throw new TsqException(String.format("Failed to create TSQ : (%s)", queueName), e); + // Check if TSQ is already exiting. + CicstsHashMap cemtInquireTSQ = this.cemt.inquireResource(this.cemtTerminal, "TSQUEUE", this.queueName); + if( cemtInquireTSQ == null ) { + response = false; + } + } catch ( CemtException e ) { + throw new TsqException("Failed to inquire the existence of TSQ : " + queueName, e); } - return response; } - /* - * Create the TSQ and write data. + /* + * Check if the TSQ is recoverable */ - @Override - public String createQueue(String queueName, String data) throws TsqException { - this.queueName = queueName; - String response = "OK"; - - // Check if TSQ is already exiting. + @Override + public boolean isRecoverable() throws TsqException { + boolean response = false; try { - CicstsHashMap cemtInquireTSQ = this.cemt.inquireResource(this.cemtTerminal, "TSQUEUE", queueName); - + CicstsHashMap cemtInquireTSQ = this.cemt.inquireResource(this.cemtTerminal, "TSQUEUE", this.queueName); if( cemtInquireTSQ != null ) { - logger.warn(String.format("TSQ is already existing. The data will be written to existing TSQ : (%s).", queueName)); - response = "ALREADY_EXISTING"; + // Check if TSQ is recoverable + if (cemtInquireTSQ.get("recovstatus").equals("Recoverable")) { + response = true; + } + } else { + throw new TsqException(String.format("The TSQ (%s) does not exist, so cannot check if it is recoverable.", queueName)); } } catch ( CemtException e ) { throw new TsqException("Failed to inquire the existence of TSQ : " + queueName, e); } - try { - this.writeQueue(queueName, data); - } catch (TsqException e) { - throw new TsqException("Failed to write to TSQ : " + queueName, e); - } return response; - } + } /* * Write to the TSQ */ @Override - public void writeQueue(String queueName, String data) throws TsqException { - this.queueName = queueName; - // Check if queueName is set + public void writeQueue(String data) throws TsqException { + // Check if queueName is not empty this.checkQueueName(); - // Check if data to write to TSQ is blank or not + // Check if data to write to TSQ is not blank this.checkData(data); // Create WRITEQ command to execute using CECI @@ -168,26 +145,26 @@ public void writeQueue(String queueName, String data) throws TsqException { logger.info(String.format("Message written is : %s", data)); } catch (CeciException e) { - throw new TsqException(String.format("Failed to create variable for input data to write to TSQ : (%s).", queueName), e); + throw new TsqException(String.format("Failed to create variable for input data to write to TSQ : (%s).", this.queueName), e); } try { // Write to TSQ using using CECI command ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); if (!resp.isNormal()) { - throw new TsqException(String.format("Write failed for TSQ : (%s). CICS response: %s", queueName, resp.getResponse())); + throw new TsqException(String.format("Write failed for TSQ : (%s). CICS response: %s", this.queueName, resp.getResponse())); } else { - logger.info(String.format("Written '%s' to TSQ - %s successful.",data , queueName )); + logger.info(String.format("Written '%s' to TSQ - %s successful.",data , this.queueName )); } } catch (CeciException e) { - throw new TsqException(String.format("Failed to write to TSQ : (%s).", queueName) , e); + throw new TsqException(String.format("Failed to write to TSQ : (%s).", this.queueName) , e); } - // Delete the &INPUTDATA variable after writing to TSQ + // Delete the &INPUTDATA variable after writing to TSQ for next WRITEQ command try{ this.ceci.deleteVariable(this.ceciTerminal, "&INPUTDATA"); } catch (CeciException e) { - throw new TsqException(String.format("Failed to delete variable used to write to TSQ : (%s).", queueName), e); + throw new TsqException(String.format("Failed to delete variable used to write to TSQ : (%s).", this.queueName), e); } return; } @@ -196,9 +173,8 @@ public void writeQueue(String queueName, String data) throws TsqException { * Read the TSQ based on the item number */ @Override - public String readQueue(String queueName, int item) throws TsqException{ - this.queueName = queueName; - // Check if queueName is set + public String readQueue(int item) throws TsqException{ + // Check if queueName is not empty this.checkQueueName(); String data = ""; @@ -218,13 +194,14 @@ public String readQueue(String queueName, int item) throws TsqException{ throw new TsqException("Read TSQ failed while trying to retrieve the data. ", e); } } else if (resp.getResponse().equals("ITEMERR")) { + // If invalid ITEM number in READQ command data = "READ_ERROR"; - logger.error(String.format("There is no item (%s) to read from TSQ : (%s). CICS response : %s ", item, queueName, resp.getResponse())); + logger.error(String.format("There is no item (%s) to read from TSQ : (%s). CICS response : %s ", item, this.queueName, resp.getResponse())); } else { - throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", queueName, resp.getResponse())); + throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", this.queueName, resp.getResponse())); } } catch (CeciException e) { - throw new TsqException(String.format("Failed to read TSQ : (%s).", queueName), e); + throw new TsqException(String.format("Failed to read TSQ : (%s).", this.queueName), e); } return data; } @@ -233,9 +210,8 @@ public String readQueue(String queueName, int item) throws TsqException{ * Read next entry in TSQ */ @Override - public String readQueueNext(String queueName) throws TsqException{ - this.queueName = queueName; - // Check if queueName is set + public String readQueueNext() throws TsqException{ + // Check if queueName is not empty this.checkQueueName(); String data = ""; @@ -255,14 +231,15 @@ public String readQueueNext(String queueName) throws TsqException{ throw new TsqException("Read TSQ failed while trying to retrieve the data. ", e); } } else if (resp.getResponse().equals("ITEMERR")) { + // If no more data in TSQ data = "READ_ERROR"; - logger.error(String.format("There is no item to read from TSQ : (%s). CICS response : %s ", queueName, resp.getResponse())); + logger.error(String.format("There is no item to read from TSQ : (%s). CICS response : %s ", this.queueName, resp.getResponse())); } else { - throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", queueName, resp.getResponse())); + throw new TsqException(String.format("TSQ read failed for queue : (%s). CICS response : %s.", this.queueName, resp.getResponse())); } } catch (CeciException e) { - throw new TsqException(String.format("Failed to read TSQ : (%s).", queueName), e); + throw new TsqException(String.format("Failed to read TSQ : (%s).", this.queueName), e); } return data; } @@ -271,45 +248,28 @@ public String readQueueNext(String queueName) throws TsqException{ * To delete TSQ */ @Override - public void deleteQueue(String queueName) throws TsqException { - // Check if queueName is set + public void deleteQueue() throws TsqException { + // Check if queueName is not empty this.checkQueueName(); // Create DELETEQ command to execute using CECI String command = String.format("DELETEQ TS %s", this.setQueueNameforCECI()); try { - //Start CECI session in the terminal + // Start CECI session in the terminal this.ceci.startCECISession(this.ceciTerminal); // Delete TSQ using using CECI command ICeciResponse resp = this.ceci.issueCommand(this.ceciTerminal, command); if (!resp.isNormal()) { - throw new TsqException(String.format("Delete failed for TSQ : (%s). CICS response: %s", queueName, resp.getResponse())); + throw new TsqException(String.format("Delete failed for TSQ : (%s). CICS response: %s", this.queueName, resp.getResponse())); } } catch(CeciException e) { - throw new TsqException(String.format("Failed to delete TSQ : (%s).", queueName), e); + throw new TsqException(String.format("Failed to delete TSQ : (%s).", this.queueName), e); } return; } - /* - * Create TSMODEL to make TSQ recoverable - */ - private void setRecoverable(String queueName) throws TsqException { - // Generate model name - String modelName = resolveModelName(); - try { - // Run CEDA TSMODEL command to make TSQ recoverable - this.ceda.createResource(this.cedaTerminal, "TSMODEL", modelName, modelName, String.format("PREFIX(%s) RECOVERY(YES)", queueName)); - // Install CEDA TSMODEL to make TSQ recoverable - this.ceda.installResource(this.cedaTerminal, "TSMODEL", modelName, modelName); - } catch(CedaException e) { - throw new TsqException(String.format("Failed to make TSQ : (%s) recoverable.", queueName), e); - } - return; - } - // Set Queue name for CECI commands private String setQueueNameforCECI() { StringBuilder command = new StringBuilder(); @@ -317,27 +277,12 @@ private String setQueueNameforCECI() { // Use QNAME where the TSQ name is greater than 8 characters. command.append(String.format("QNAME(%s)", this.queueName)); } else { - // Otherwise use QUEUE to avoid potentially breaking existing tests. + // Use QUEUE where the TSQ name is less than or equal to 8 characters. command.append(String.format("QUEUE(%s)", this.queueName)); } return command.toString(); } - /** - * Generates a TS model based on the TSQ name. If the TSQ name is less than 8 characters long, it is appened with 'M'. Otherwise the 8th character is changed to be an 'M'. - *

- * If the TSQ name is: 'QUEUE ', then the model name is: 'QUEUEM '. - *
- * If the TSQ name is: 'FEATUREQ', then the model name is: 'FEATUREM'. - */ - private String resolveModelName() { - if(this.queueName.length() < 8) { - return this.queueName + "M"; - } else { - return this.queueName.substring(0,7) + "M"; - } - } - /** * Check if the queue name is empty and throw error if empty. */ @@ -347,6 +292,7 @@ public void checkQueueName() throws TsqException { } return; } + /** * Check if the data is empty and throw error if empty. */ diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java deleted file mode 100644 index 4ce09596f..000000000 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerField.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ -package dev.galasa.cicsts.tsq.internal; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Used to annotate annotations that are to be used for Test Class fields. To be - * populated by the Manager. - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface TsqManagerField { - -} diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java index c558176e2..8a85ae7e8 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqManagerImpl.java @@ -16,7 +16,7 @@ import dev.galasa.cicsts.TsqException; import dev.galasa.cicsts.TsqManagerException; import dev.galasa.cicsts.CicstsManagerException; -import dev.galasa.cicsts.ITsq; +import dev.galasa.cicsts.ITsqFactory; import dev.galasa.cicsts.ICicsRegion; import dev.galasa.cicsts.tsq.internal.properties.TsqPropertiesSingleton; import dev.galasa.cicsts.tsq.spi.ITsqManagerSpi; @@ -35,7 +35,7 @@ public class TsqManagerImpl extends AbstractManager implements ITsqManagerSpi, I protected static final String NAMESPACE = "tsq"; private ICicstsManagerSpi cicstsManager; - protected HashMap regionTsqs = new HashMap<>(); + protected HashMap regionTsqs = new HashMap<>(); /* (non-Javadoc) * @see dev.galasa.framework.spi.AbstractManager#initialise(dev.galasa.framework.spi.IFramework, java.util.List, java.util.List, java.lang.Class) @@ -59,7 +59,6 @@ public void initialise(@NotNull IFramework framework, @NotNull List al */ @Override public void provisionGenerate() throws ManagerException, ResourceUnavailableException { - generateAnnotatedFields(TsqManagerField.class); } @@ -83,12 +82,13 @@ public void youAreRequired(@NotNull List allManagers, @NotNull List

Request a TSQ instance +
Request a TSQ Factory instance -The following snippet shows the code that is required to request a TSQ instance in a Galasa test: +The following snippet shows the code that is required to request a TSQ Factory instance in a Galasa test: ``` @CicsRegion() public ICicsRegion cicsRegion; +public ITsqFactory tsqFactory; ... -ITsq tsq = cicsRegion.tsq(); -``` +this.tsqFactory = cicsRegion.getTSQFactory(); -The code creates a CICS/TS TSQ instance. +```
-
Create and write to TSQ +
Create a new ITsq object with a queue name -The following snippet shows the code required to create and write to a TSQ. +The following snippets show the code required to create a new ITsq object. -In this case, the test will create a TSQ named GALASAQ and write data in the variable writeMessage. - -Response will be: -- OK : if new TSQ is created and data is written -- ALREADY_EXISTING : if TSQ is already existing and data is written +In this case, the test will create an ITsq object with queue named GALASAR. The TSQ created using this object will be a recoverable queue. ``` +public ITsq tsqRecoverable; -String queueName = "GALASAQ"; -String writeMessage = "Write this message to TSQ named GALASAQ"; -String response = tsq.createQueue(queueName, writeMessage); - -``` +... -The following snippet shows the code required to create and write to a recoverable TSQ. +// Create ITsq object for recoverable TSQ +String queueName = "GALASAR"; +boolean recoverable = true; +tsqRecoverable = this.tsqFactoryA.createQueue(queueName, recoverable); -In this case, the test will create a recoverable TSQ named GALASAQ (if not already existing) and write data from the variable writeMessage. +``` -Response will be: -- OK : if new TSQ is created and data is written -- ALREADY_EXISTING : if TSQ is already exiting and data is written +In this case, the test will create an ITsq object with queue named GALASAN. The TSQ created using this object will be a non-recoverable queue. ``` +public ITsq tsqNonRecoverable; -String queueName = "GALASAQ"; -String writeMessage = "Write this message to TSQ named GALASAQ"; -boolean recoverable = true; -String response = tsq.createQueue(queueName, writeMessage, recoverable); +... + +// Create ITsq object for non-recoverable TSQ +String queueName = "GALASAN"; +boolean recoverable = false; +tsqNonRecoverable = this.tsqFactoryA.createQueue(queueName, recoverable); ``` -Note: If TSQ is already existing and is non-recoverable, then the TSQ needs to be deleted and then created with recoverable option to make it recoverable. Otherwise the TSQ will continue to be non-recoverable. +Note: If TSQ is already existing then the recoverable status will not change.
@@ -57,51 +54,76 @@ Note: If TSQ is already existing and is non-recoverable, then the TSQ needs to b The following snippet shows the code required to write data to a TSQ. -In this case, the test will write the data contained in the variable named writeMessage to the TSQ named GALASAQ: +In this case, the test will write the data contained in the variable named writeMessage to the TSQ named GALASAN: ``` +// Note: Here ITsq object - tsqNonRecoverable is created with queueName = "GALASAN" -String queueName = "GALASAQ"; -String writeMessage = "Write this message to TSQ named GALASAQ"; -tsq.writeQueue(queueName, writeMessage); +String writeMessage = "Write this message to TSQ named GALASAN."; +tsqNonRecoverable.writeQueue(writeMessage); ``` +
Read from TSQ The following snippet shows the code required to read data from a TSQ. -In this case, the test will read a message into the variable named readMessage, from the TSQ named GALASAQ based on the item number passed : +In this case, the test will read a message into the variable named readMessage, from the TSQ named GALASAN based on the item number passed : ``` - -String queueName = "GALASAQ"; -int itemNum = 1; -String readMessage = tsq.readQueue(queueName, itemNum); +// Note: Here ITsq object - tsqNonRecoverable is created with queueName = "GALASAN" +int itemNumber = 1; +String readMessage =tsqNonRecoverable.readQueue(itemNumber); ``` -In this case, the test will read the next message from the TSQ named GALASAQ into the variable named readMessage: +In this case, the test will read the next message from the TSQ named GALASAN. Here the variable - readMessage2 will have item number 2 and variable - readMessage3 will have item number 3 : ``` - -String queueName = "GALASAQ"; -String readMessage = tsq.readQueueNext(queueName); +String readMessage2 = tsqNonRecoverable.readQueueNext(); +String readMessage3 = tsqNonRecoverable.readQueueNext(); ```
Delete a TSQ -The following snippet shows the code required to delete a TSQ. +The following snippet shows the code required to delete a non-recoverable TSQ. -In this case, the test will delete the TSQ named GALASAQ: +In this case, the test will delete the TSQ named GALASAN: ``` +// Note: Here ITsq object - tsqNonRecoverable is created with queueName = "GALASAN" +tsqNonRecoverable.deleteQueue(); -String queueName = "GALASAQ"; -tsq.deleteQueue(queueName); +``` +
+ +
Check if a TSQ is existing + +The following snippet shows the code required to check the existence of a TSQ. + +In this case, the test will check the existence of the TSQ named GALASAN. The variable - response will be true if the TSQ is existing else it will be false: + +``` +// Note: Here ITsq object - tsqNonRecoverable is created with queueName = "GALASAN" +boolean response = tsqNonRecoverable.exists(); ```
+ + +
Check if a TSQ is recoverable + +The following snippet shows the code required to check if a TSQ is recoverable. + +In this case, the test will check the TSQ named GALASAN if it is recoverable or not. The variable - response will be true if the TSQ is recoverable else it will be false: + +``` +// Note: Here ITsq object - tsqNonRecoverable is created with queueName = "GALASAN" +boolean response = tsqNonRecoverable.isRecoverable(); + +``` +
\ No newline at end of file From f0f11d88b5c23b0acb292316fe938ea6b8c3cd47 Mon Sep 17 00:00:00 2001 From: Anuprakash Moothedath Date: Thu, 5 Sep 2024 10:46:01 +0530 Subject: [PATCH 4/4] Updated the multiple review comments Signed-off-by: Anuprakash Moothedath --- .../src/main/java/dev/galasa/cicsts/ICicsRegion.java | 2 +- .../src/main/java/dev/galasa/cicsts/ITsq.java | 4 ++-- .../src/main/java/dev/galasa/cicsts/ITsqFactory.java | 10 ++++++---- .../src/main/java/dev/galasa/cicsts/TsqException.java | 3 +++ .../java/dev/galasa/cicsts/TsqManagerException.java | 3 +++ .../main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java | 2 +- .../galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java | 2 +- .../dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java | 4 ++-- .../tsq_manager_codesnippet.md | 10 +++++----- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java index 321a9c73e..58729c8a7 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ICicsRegion.java @@ -52,7 +52,7 @@ public interface ICicsRegion { ICemt cemt() throws CicstsManagerException; ICeda ceda() throws CicstsManagerException; ICeci ceci() throws CicstsManagerException; - ITsqFactory getTSQFactory() throws CicstsManagerException; + ITsqFactory getTsqFactory() throws CicstsManagerException; /** * Provides a CICS resource instance that can then be used to create a specific CICS resource diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java index 8ed2629e2..f37fb42ab 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsq.java @@ -9,7 +9,7 @@ public interface ITsq { /** - * Chect the existence of a TSQ. + * Check the existence of a TSQ. * @throws TsqException if there is a problem in checking the TSQ existence * @return boolean based on if TSQ is existing or not */ @@ -28,7 +28,7 @@ public interface ITsq { * @return Data read from TSQ as String * @throws TsqException if there is a problem in reading from the TSQ */ - public String readQueue(@NotNull int item) throws TsqException; + public String readQueue(int item) throws TsqException; /** * Read next from TSQ. diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java index f5306c390..af836b625 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/ITsqFactory.java @@ -11,16 +11,18 @@ public interface ITsqFactory { /** * Create a new ITsq object with recoverable status * @param queueName TSQ name - * @param recoverable true for recoverable and false for non-recoverable - * @return ITsq object + * @param isRecoverable true for recoverable and false for non-recoverable + * @return ITsq object. The existence of the ITsq object does not have any correlation to whether + * the queue actually exists underneath it. It is used to access or create the ITsq. * @throws TsqException if there is a problem in creating the ITsq object */ - public ITsq createQueue(@NotNull String queueName, @NotNull boolean recoverable) throws TsqException; + public ITsq createQueue(@NotNull String queueName, boolean isRecoverable) throws TsqException; /** * Create a new ITsq object without recoverable status. Default recoverable status is NonRecoverable * @param queueName TSQ name - * @return ITsq object + * @return ITsq object. The existence of the ITsq object does not have any correlation to whether + * the queue actually exists underneath it. It is used to access or create the ITsq. * @throws TsqException if there is a problem in creating the ITsq object */ public ITsq createQueue(@NotNull String queueName) throws TsqException; diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java index 44744b735..318ed5516 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqException.java @@ -5,6 +5,9 @@ */ package dev.galasa.cicsts; +/* + * TsqException happens for errors in the TSQ manager methods. + */ public class TsqException extends TsqManagerException { private static final long serialVersionUID = 1L; diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java index df23ff8b9..06edafb51 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/TsqManagerException.java @@ -5,6 +5,9 @@ */ package dev.galasa.cicsts; +/* + * TsqManagerException happens for errors in TSQ manager provisioning + */ public class TsqManagerException extends CicstsManagerException { private static final long serialVersionUID = 1L; diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java index 8bf22193f..3e7f90844 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.manager/src/main/java/dev/galasa/cicsts/spi/BaseCicsImpl.java @@ -96,7 +96,7 @@ public ICeda ceda() throws CicstsManagerException { } @Override - public ITsqFactory getTSQFactory() throws CicstsManagerException { + public ITsqFactory getTsqFactory() throws CicstsManagerException { if (this.tsq == null) { this.tsq = this.cicstsManager.getTsqProvider().getTsqFactory(this, this.cicstsManager); } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java index c2fde8990..5fedaf803 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager.ivt/src/main/java/dev/galasa/cicsts/tsq/manager/ivt/TsqManagerIVT.java @@ -48,7 +48,7 @@ public class TsqManagerIVT { */ @BeforeClass public void createTsqInstance() throws CicstsManagerException { - this.tsqFactoryA = cicsRegionA.getTSQFactory(); + this.tsqFactoryA = cicsRegionA.getTsqFactory(); // Create ITsq object for recoverable TSQ tsqRecoverable = this.tsqFactoryA.createQueue("GALASAR", true); // Create ITsq object for non-recoverable TSQ diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java index 48184b1eb..8e2ae859d 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/src/main/java/dev/galasa/cicsts/tsq/internal/TsqFactoryImpl.java @@ -89,12 +89,12 @@ public TsqFactoryImpl(TsqManagerImpl manager, ICicsRegion cicsRegion, ICicstsMan * Create and return the ITsq object for the queueName provided. */ @Override - public ITsq createQueue(String queueName, boolean recoverable) throws TsqException { + public ITsq createQueue(String queueName, boolean isRecoverable) throws TsqException { this.queueName = queueName; checkQueueName(); // If recoverable is true create a TSMODEL to make the TSQ as recoverable - if (recoverable) { + if (isRecoverable) { this.setRecoverable(queueName); } diff --git a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md index 87fa02357..18853e953 100644 --- a/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md +++ b/galasa-managers-parent/galasa-managers-cicsts-parent/dev.galasa.cicsts.tsq.manager/tsq_manager_codesnippet.md @@ -9,7 +9,7 @@ public ITsqFactory tsqFactory; ... -this.tsqFactory = cicsRegion.getTSQFactory(); +this.tsqFactory = cicsRegion.getTsqFactory(); ``` @@ -28,8 +28,8 @@ public ITsq tsqRecoverable; // Create ITsq object for recoverable TSQ String queueName = "GALASAR"; -boolean recoverable = true; -tsqRecoverable = this.tsqFactoryA.createQueue(queueName, recoverable); +boolean isRecoverable = true; +tsqRecoverable = this.tsqFactoryA.createQueue(queueName, isRecoverable); ``` @@ -42,8 +42,8 @@ public ITsq tsqNonRecoverable; // Create ITsq object for non-recoverable TSQ String queueName = "GALASAN"; -boolean recoverable = false; -tsqNonRecoverable = this.tsqFactoryA.createQueue(queueName, recoverable); +boolean isRecoverable = false; +tsqNonRecoverable = this.tsqFactoryA.createQueue(queueName, isRecoverable); ``` Note: If TSQ is already existing then the recoverable status will not change.