Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java_version: [11, 17, 21]
java_version: [11, 17, 21, 24]
os: [windows-latest, ubuntu-latest]
steps:
- name: Checkout
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pom.xml.versionsBackup
/Bundle/target/
/lib/
/Server/src/logs/
/Server/src/test/resources/config/
**/.DS_Store
**/.settings
**/*.class
.metadata/*
.metadata/*
Binary file modified .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
19 changes: 18 additions & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# As2Server
The OpenAS2 application enables you to transmit and receive AS2 messages with EDI-X12, EDIFACT, XML, or binary payloads between trading partners.
The application supports Java 11 and up.


## Development
Expand All @@ -12,6 +13,9 @@ More detailed information is available in the DeveloperGuide.odt in the docs fol
## Test, Build and Package
The following commands can be used in the build process.

Updating Maven to a different version:
`./mvnw wrapper:wrapper -Dmaven=3.9.9

Checking dependency tree:
`./mvnw dependency:tree`

Expand All @@ -38,7 +42,7 @@ To deploy the released artifacts requires user ID and password for Sonatype. See
`./mvnw nexus-staging:release -Ddescription="Some release comment here"`

## Web UI for configuration
IMPORTANT: The WebUI will NOT work with Java 8 - you need Java 11 or newer
IMPORTANT: You need Java 11 or newer
Follow the instructions in the WebUI/README.md file for configuring and using it.


Expand Down
22 changes: 15 additions & 7 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
# OpenAS2 Server
# Version 4.5.2
# Version 4.6.0
# RELEASE NOTES
-----
The OpenAS2 project is pleased to announce the release of OpenAS2 4.5.2
The OpenAS2 project is pleased to announce the release of OpenAS2 4.6.0

The release download file is: OpenAS2Server-4.5.2.zip
The release download file is: OpenAS2Server-4.6.0.zip

The zip file contains a PDF document (OpenAS2HowTo.pdf) providing information on installing and using the application.
## NOTE: Testing covers Java 11 to 21.
## Java 8 is NO LONGER SUPPORTED.

Version 4.5.2 - 2025-06-12
Version 4.6.0 - 2025-08-04

This is a testing enhancement release.

1. Reworked the resource access class
2. changed tests to use the same config that is provided in the installer package
3. Optimised method to wait for files to appear on file system as part of end-to-end tests
4. Created script to generate test certificates keystore with updated certificates
5. Added maven phase to regenerate test certificates keystore prior to running tests
6. Updated Maven wrapper for project
7. Added Java 24 to test matrix

This is a bugfix release.

1. Fix database connection setup for healthcheck module.

##Upgrade Notes
See the openAS2HowTo appendix for the general process on upgrading OpenAS2.
Expand All @@ -24,7 +32,7 @@ This is a bugfix release.
**You must review all notes for the relevant intermediate versions from your version to this release version.**

### Upgrading to 4.0 or newer from any older version:
1. Ensure you implement all logging that you had configured for ealrier versions using the logback configuration or replace with another framework that works with SLF4J facade. See the OpenAS2HowTo.pdf logging section for more details.
1. Ensure you implement all logging that you had configured for earlier versions using the logback configuration or replace with another framework that works with SLF4J facade. See the OpenAS2HowTo.pdf logging section for more details.
2. The property for email configuration in the config.xml changed:
Change ALL occurrences of javax.mail.properties to jakarta.mail.properties in config.xml and the .properties file if you implemented it.
3. If using an external database for message state tracking, make sure that your configuration will work with the new Hikari JDBC pool that improves performance. See the OpenAS2HowTo.pdf message state tracking section for more details.
Expand Down
40 changes: 37 additions & 3 deletions Server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<!-- DO NOT CHANGE THIS "groupId" WITHOUT CHANGING XMLSession.getManifestAttributes.MANIFEST_VENDOR_ID_ATTRIB -->
<groupId>net.sf.openas2</groupId>
<artifactId>OpenAS2</artifactId>
<version>4.5.2</version>
<version>4.6.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -43,20 +43,54 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<systemPropertyVariables>
<OPENAS2_LOG_BASE>logs</OPENAS2_LOG_BASE>
</systemProperties>
</systemPropertyVariables>
<!-- Below will be need in the future but is crsahing for resaons unclear at this time:
https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#mockito-instrumentation
This may help resolve:
https://github.com/eclipse-m2e/m2e-core/issues/1916
<argLine>@{argLine} -javaagent:${org.mockito:mockito-core:jar}</argLine>
-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>test-resource-creation</id>
<goals>
<goal>run</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<target>
<!-- Update the test certificates on every test run to ensure they are not expired -->
<exec executable="sh" osfamily="unix">
<arg value="-c"/>
<arg line="${project.basedir}/src/bin/create_test_certificates.sh"/>
</exec>
<!-- Copy the installer config files to test resources to ensure we test the default config -->
<copy todir="${project.basedir}/src/test/resources/config"
verbose="true">
<fileset dir="${project.basedir}/src/config"/>
</copy>
</target>
</configuration>
</execution>
<execution>
<id>default-cli</id>
<goals>
Expand Down
51 changes: 51 additions & 0 deletions Server/src/bin/create_test_certificates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash

x=`basename $0`
relBinDir=`dirname $0`
binDir=`realpath $relBinDir`
srcBaseDir=`realpath $binDir/../..`
configDir=${srcBaseDir}/src/config

cd $configDir
if [ "$?" != 0 ]; then
echo "****** Failed to find the "config" directory. See errors above to correct the problem."
exit 1
fi
export IS_AUTOMATED_EXEC=1
export KEYSTORE_PASSWORD=testas2
echo "************"
echo "Deleting existing keystores..."
alias1=mycompany
alias2=partnera
alias3=partnerb
ks1=as2_certs.p12
ks2=${alias2}_certs.p12
ks3=${alias2}_certs.p12
rm -f $ks1 $ks2 $ks3
$binDir/gen_p12_key_par.sh ${ks1%.*} ${alias1} SHA256 'CN=as2.${alias1}.com, OU=QA, O=MyCompany, L=Cape Town, S=Western Cape, C=ZA'
if [ "$?" != 0 ]; then
echo "****** Failed to create as2_certs.p12 keystore. See errors above to correct the problem."
exit 1
fi
$binDir/gen_p12_key_par.sh ${ks2%.*} ${alias2} SHA256 'CN=as2.${alias2}.com, OU=QA, O=PartnerA, L=New York, S=New York, C=US'
if [ "$?" != 0 ]; then
echo "****** Failed to create ${ks2} keystore. See errors above to correct the problem."
exit 1
fi
$binDir/gen_p12_key_par.sh ${ks3%.*} ${alias3} SHA256 'CN=as2.${alias3}.com, OU=QA, O=PartnerB, L=London, S=London, C=US'
if [ "$?" != 0 ]; then
echo "****** Failed to create ${ks3} keystore. See errors above to correct the problem."
exit 1
fi
$binDir/import_alias_from_keystore.sh $ks2 ${alias2} $ks1 ${alias2}
if [ "$?" != 0 ]; then
echo "****** Failed to import ${ks2} keystorei into main keystore. See errors above to correct the problem."
exit 1
fi
$binDir/import_alias_from_keystore.sh $ks3 ${alias3} $ks1 ${alias3}
if [ "$?" != 0 ]; then
echo "****** Failed to import ${ks3} keystorei into main keystore. See errors above to correct the problem."
exit 1
fi
rm -f ${alias1}* ${alias2}* ${alias3}*
exit 0
1 change: 1 addition & 0 deletions Server/src/bin/gen_p12_key_par.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
x=`basename $0`

if test $# -ne 4; then
echo "Invalid parameter list. Expected 4 got $#: $@"
echo "Generate a certificate to a PKCS12 key store."
echo "You must supply a target key store without the extension (extension will be added as .p12) and an alias for the generated certificate."
echo "usage: ${x} <target keystore> <cert alias> <sigalg> <distinguished name> <start date>"
Expand Down
Binary file modified Server/src/config/as2_certs.p12
Binary file not shown.
4 changes: 2 additions & 2 deletions Server/src/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@
protocol="$properties.module.HealthCheckModule.protocol"
address="$properties.module.HealthCheckModule.address$"
port="$properties.module.HealthCheckModule.port$"
ssl_keystore="$properties.module.HealthCheckModule.ssl_keystore$"
ssl_keystore_password="$properties.module.HealthCheckModule.ssl_keystore_password$"/>
ssl_keystore="$properties.ssl_keystore$"
ssl_keystore_password="$properties.ssl_keystore_password$"/>
</processor>
<!-- The pollerConfigBase provides the base config for the partnership directory pollers. It must be placed at the top of the file -->
<pollerConfigBase classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
Expand Down
4 changes: 2 additions & 2 deletions Server/src/main/java/org/openas2/XMLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private void loadProperties(Node propNode) throws IOException, OpenAS2Exception
if (appPropsFile != null && appPropsFile.length() > 1) {
LOGGER.info("Processing OpenAS2 configuration properties file: {}", appPropsFile);
java.util.Properties appProps = new java.util.Properties();
// Support $ENV{some_env_var} reploacement in properties
// Support $ENV{some_env_var} replacement in properties
StringEnvVarReplacer envVarReplacer = new StringEnvVarReplacer();
envVarReplacer.setAppHomeDir(getBaseDirectory());
FileInputStream fis = null;
Expand Down Expand Up @@ -283,7 +283,7 @@ private void loadPartnerships(Node rootNode) throws OpenAS2Exception {

PartnershipFactory partnerFx = (PartnershipFactory) XMLUtil.getComponent(rootNode, this);
if (partnerFx == null) {
// Must be disable so do nothing
// Must be disabled so do nothing
return;
}
setComponent(PartnershipFactory.COMPID_PARTNERSHIP_FACTORY, partnerFx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ private void updateTracking() {
// if the file length has stayed the same, process the file
// and then stop tracking it
if (processFilesAsThreads) {
if (logger.isDebugEnabled()) {
logger.debug("Parallel processing mode handling file: " + file.getName());
}
executorService.execute(new Runnable() {
@Override
public void run() {
Expand Down
75 changes: 46 additions & 29 deletions Server/src/test/java/org/openas2/TestResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,66 @@

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Map;

/**
* A helper class for locating files and directories on the file systems.
* The main reason is to categorize static files used in tests.
* Retrieves resources used for test purposes from the file system
*
*/
public class TestResource {

/**
* An absolute path to a test specific resource.
/* Set up a map of resource files that can be generically used by all tests
* and some test specific property files that override the default behaviour
* from the standard config.xml file such as for tests using 2 AS2 server instances.
*/
private final String pathPrefix;

private TestResource(String clazzSimpleName) {
try {
URL resource = Thread.currentThread().getContextClassLoader().getResource(".");
this.pathPrefix = new File(resource.toURI()).getAbsolutePath() + File.separator + clazzSimpleName;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public static final Map<String, String[]> resources = Map.of(
"config", new String[]{"config", "config.xml"},
"partnerships", new String[]{"config", "partnerships.xml"},
"server1-props", new String[]{"custom", "server1.properties"},
"server1-partnerships", new String[]{"custom", "server1_partnerships.xml"},
"server2-props", new String[]{"custom", "server2.properties"},
"server2-partnerships", new String[]{"custom", "server2_partnerships.xml"},
"api-server-props", new String[]{"custom", "api-server.properties"}
);

static String pathPrefix = Paths.get("src","test","resources").toAbsolutePath().toString();

public static TestResource forClass(Class<?> clazz) {
return new TestResource(clazz.getSimpleName());
}

public static TestResource forGroup(String group) {
return new TestResource(group);
public static String getResource(String resourceIdentifier) throws FileNotFoundException {
/**
* Get absolute path to a file identified by the resource identifier passed in.
*
* @param resourceIdentifier - an identifier matching one of the keys in this classes resources map
* @return a file
*/
String[] resourceAttributes = resources.get(resourceIdentifier);
String filePath = get(resourceAttributes);

return filePath;
}

/**
* Get a file or directory within {@link #pathPrefix}
* Get the absolute path to a file or directory within {@link #resourceBaseFolder}
*
* @param fileName a file or directory name
* @param child a children name
* @param foldersAndFile - a list of optional folders in path with the actual file name as the last in the list
* @return a file
*/
public File get(String fileName, String... child) throws FileNotFoundException {
File file = new File(pathPrefix + File.separator + fileName + File.separator + StringUtils.join(child, File.separator));
public static String get(String... foldersAndFile) throws FileNotFoundException {
String filePath = pathPrefix + File.separator + StringUtils.join(foldersAndFile, File.separator);
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
throw new FileNotFoundException(filePath);
}
return file;
return filePath;
}

/**
* Get a File object for a file or directory within {@link #resourceBaseFolder}
*
* @param foldersAndFile - a list of optional folders in path with the actual file name as the last in the list
* @return a File object
*/
public static File getFile(String... foldersAndFile) throws FileNotFoundException {
return new File(get(foldersAndFile));
}
}
Loading
Loading