diff --git a/.github/daemon-default.json b/.github/daemon-default.json
deleted file mode 100644
index d226ade7e..000000000
--- a/.github/daemon-default.json
+++ /dev/null
@@ -1 +0,0 @@
-{"insecure-registries": ["docker-registry.demo.axway.com"], "debug": true}
diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml
index b63be69c0..408dc1b99 100644
--- a/.github/workflows/integration-test.yml
+++ b/.github/workflows/integration-test.yml
@@ -8,10 +8,10 @@ env:
CACHE_FILE_APIM: api-manager_7_7_20240530.cache.tar
CACHE_FILE_CASSANDRA: cassandra_4_0_13.cache.tar
FED_FILE: swagger-promote-7.7-20240530.fed
- LOG_LEVEL: info
+ LOG_LEVEL: debug
jobs:
- build:
+ integration-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -58,9 +58,9 @@ jobs:
run: |
mkdir licenses
echo ${{ secrets.APIM_LIC }} | base64 -di > licenses/apim.lic
- docker-compose run --rm start_cassandra
- docker-compose run --rm start_apimgmt
- docker-compose logs --tail 30 apimgmt
+ docker compose run --rm start_cassandra
+ docker compose run --rm start_apimgmt
+ docker compose logs --tail 30 apimgmt
- name: Maven APIM Integration Test
run: mvn verify -P integration-tests
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9878338ce..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-language: java
-# Run integration tests only, as Unit-Tests ran before installation of the API-Manager test instance
-script: "mvn verify -P integration-tests"
-
-services:
- - docker
-
-env:
- global:
- - CACHE_DIR=$HOME/docker
- - APIM_DOCKER_IMAGE=docker-registry.demo.axway.com/swagger-promote/api-mgr-with-policies:7.7-20220830
- - CASSANDRA_DOCKER_IMAGE=cassandra:2.2.12
- - CACHE_FILE_APIM=$CACHE_DIR/api-manager_7_7_20220830.cache.tar.gz
- - CACHE_FILE_CASSANDRA=$CACHE_DIR/cassandra_2_2_12.cache.tar.gz
- - CACHE_FILE_WAIT_FOR_DEPENDENCIES=$CACHE_DIR/wait-for-dependencies.cache.tar.gz
- - counter=0
- # Variable to test the OS-Environment variable replace
- - OS=TravisCI
-
-cache:
- directories:
- - $CACHE_DIR
- - '$HOME/.m2/repository'
-
-before_install:
- # Avoid installation if unit-tests fail anyway
- - mvn clean test
-
- - if [ ! -f /etc/docker/daemon.json ]; then sudo cp -v .github/daemon-default.json /etc/docker/daemon.json; fi
- - if [ ! -f $CACHE_FILE_APIM ]; then sudo cat /etc/default/docker; fi
- - if [ ! -f $CACHE_FILE_APIM ]; then echo \"Restarting Docker-Daemon\"; sudo service docker restart; sudo systemctl status docker.service; sudo journalctl -xe; fi
-
- #- sudo apt-get update
- #- sudo apt-get install curl
- # All files in this folder will be cached for the next build
- - mkdir -p $CACHE_DIR
- # Downloading the APIM-Docker-Image takes too long (Timeout 10 minutes) - Externalized to make use of travis_wait
- # In this script, we are either using the cached version or download a new Docker-Image
- - travis_wait build/pull_apim_docker_image.sh
- # Now it's time to safe the downloaded API-Management Docker-Image into the cache folder
- - if [ ! -f $CACHE_FILE_APIM ]; then docker save $APIM_DOCKER_IMAGE | gzip > $CACHE_FILE_APIM; fi
- # Pull Cassandra Image or use the cache
- - travis_wait build/pull_cassandra_docker_image.sh
- # Safe Cassandra image inc cache file
- - if [ ! -f $CACHE_FILE_CASSANDRA ]; then docker save $CASSANDRA_DOCKER_IMAGE | gzip > $CACHE_FILE_CASSANDRA; fi
- # Pull wait-for-dependencies or use the cache
- - travis_wait build/pull_wait_for_dependencies.sh
- # Wait dadarek/wait-for-dependencies to avoid docker pull limit
- - if [ ! -f $CACHE_FILE_WAIT_FOR_DEPENDENCIES ]; then docker save dadarek/wait-for-dependencies | gzip > $CACHE_FILE_WAIT_FOR_DEPENDENCIES; fi
-
-install:
- # Start Cassandra and wait that port 9042 is reachable
- - docker-compose run --rm start_cassandra
- # Start the API-Gateway + API-Manager
- - docker-compose run --rm start_apimgmt
- # Give API-Manager a moment to start
- - docker-compose logs --tail 30 apimgmt
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2019ba61f..bfb83fd75 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+# [1.14.6] In progress
+## Fixed
+- Importing SOAP API with different endpoints (for import and for runtime calls) (See issue [#501](https://github.com/Axway-API-Management-Plus/apim-cli/issues/501))
+- -returnCodeMapping option does not work on apim-cli org import (See issue [#496](https://github.com/Axway-API-Management-Plus/apim-cli/issues/496))
+- The output of command 'apim api get' is not containing the complete list of client applications (array) of the api (See issue [#495](https://github.com/Axway-API-Management-Plus/apim-cli/issues/495))
+- Update API with Assigned Quota (See issue [#499](https://github.com/Axway-API-Management-Plus/apim-cli/issues/499))
+
+### Added
+- Force APIM-cli to download the latest Trusted Certificates in a Frontend API (See issue [#494](https://github.com/Axway-API-Management-Plus/apim-cli/issues/494))
+
+### Changed
+- Updated libs to fix security vulnerabilities
+ - com.graphql-java:graphql-java from 21.3 to 21.5
+ - commons-io:commons-io from 2.11.0 to 2.14.0
+
+
# [1.14.5] 2024-07-12
## Fixed
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index dfa8485bd..63b071eac 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -19,50 +19,11 @@ are ready for the next version. This means that the develop branch is actually s
- GnuPG for Code-Signing (e.g. https://gnupg.org/)
- Apache Maven 3.6.3 or higher
-#### Maven settings.xml
+### Maven pgp usage
+- https://maven.apache.org/plugins/maven-gpg-plugin/usage.html
-A server configuration for GitHub write access by Maven using your personal access token.
-```xml
-
- github
- cwiechmann@axway.com
- YOUR_GITHUB_PAT
-
-```
-The Code must be signed to be published to Maven-Central. A Signing-Key must be created and published:
-Learn more: https://central.sonatype.org/publish/requirements/gpg/
-
-Confguration required for the Sonatype communication:
-Learn more: https://github.com/chhh/sonatype-ossrh-parent/blob/master/publishing-to-maven-central.md
-
-A profile Sonatype servers used by Sonatype maven plugin.
-
-```xml
-
- ossrh
- YOUR_OSSRH_USERNAME
- YOUR_OSSRH_PASSWORD
-
-```
-
-A profile for GPG which is used by the `maven-gpg-plugin` plugin.
-
-```xml
-
- ossrh
-
- true
-
-
- gpg
- axway
-
-
-```
-Learn more: https://maven.apache.org/plugins/maven-gpg-plugin/usage.html
-
-### Create a new release
+## Create a new release
For the release, develop is merged into Master and the release is generated on Master with Maven.
@@ -85,47 +46,12 @@ git commit
git push
```
-### 4. Create Pre-Release with Maven
+### 4. Create Release with Maven
-```sh
-mvn -Darguments=-DskipTests release:prepare -P release
-
-# Set the version number following [Semantic Versioning](https://semver.org/)
-# Git-Label version should be for example: 1.11.0
-# Next SNAPSHOT Version: 1.12.0-SNAPSHOT
-```
-
-### 5. Validate the Pre-Release
-
-- Use the Pre-Release to manually perform some smoke tests
-`apim-cli\distribution\target`
- - If you are not happy with the actual build for any reason, you need to rollback the actual release prepare:
- ```sh
- mvn release:rollback
- # Sometimes the created tag isn't removed automatically. You need to delete it to re-execute release:prepare:
- git tag -d 1.11.0
- git push origin :refs/tags/1.11.0
- ```
-
-### 6. Create the release
-
-```sh
-# This uploads the release artifacts to Maven-Central automatically
-mvn -Darguments=-DskipTests release:perform -P release
-```
-
-### 7. Create a release on GitHub
+- Run Github action Release API CLI on github and Maven repository
-- Select the tag created by Maven
-- Use the description from the previous release and modify it
-- It also pushes the Chocolately package
-- upload the created release files to GitHub:
- ```
- target/checkout/distribution/target/axway-apimcli-1.11.0.zip
- target/checkout/distribution/target/axway-apimcli-1.11.0.tar.gz
- ```
-### 8. Commit all changes and merge master into develop
+### 5. Commit all changes and merge master into develop
```
git checkout develop
git merge master
diff --git a/ROTATE_PGP_KEY.md b/ROTATE_PGP_KEY.md
new file mode 100644
index 000000000..5448c3e60
--- /dev/null
+++ b/ROTATE_PGP_KEY.md
@@ -0,0 +1,43 @@
+# Rotate PGP Keys.
+
+PGP key comes with expiry date.
+
+
+## Create new key
+
+```bash
+➜ apim-cli git:(master) gpg --gen-key
+gpg (GnuPG) 2.4.5; Copyright (C) 2024 g10 Code GmbH
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
+
+GnuPG needs to construct a user ID to identify your key.
+
+Real name: Rathna
+Email address: rathnapandi.n@gmail.com
+You selected this USER-ID:
+ "Rathna "
+
+Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
+```
+
+## Push the key to Key server
+
+Use the pgp id to upload it key server
+
+```bash
+ gpg --keyserver keyserver.ubuntu.com --send-keys 5D8F776E941F2D1D91EB2875212961A21019826F
+```
+
+## Store the key password and private key to Github action secrets and variables.
+
+- Secret names
+ - GPG_PASSPHRASE
+ - GPG_PRIVATE_KEY
+
+### Export private key
+```bash
+gpg --output private.pgp --armor --export-secret-key 5D8F776E941F2D1D91EB2875212961A21019826F
+```
diff --git a/build/base_apim_setup.sh b/build/base_apim_setup.sh
deleted file mode 100755
index 2f2382bb7..000000000
--- a/build/base_apim_setup.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-# Create an API-Development Organisation!
-curl --insecure -u apiadmin:changeme -X POST \
- https://localhost:8075/api/portal/v1.3/organizations \
- -H 'Content-Type: application/json' \
- -d '{
- "name": "API Development",
- "description": "Test Org",
- "enabled": true,
- "development": true
-}'
-echo "Created organization: 'API Development'"
\ No newline at end of file
diff --git a/build/pull_apim_docker_image.sh b/build/pull_apim_docker_image.sh
deleted file mode 100755
index 224549ca5..000000000
--- a/build/pull_apim_docker_image.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-echo "CACHE_FILE_APIM: $CACHE_FILE_APIM"
-echo "SKIP_CACHE: $SKIP_CACHE"
-
-echo "Listing $CACHE_DIR"
-ls -l $CACHE_DIR
-
-if [ -f $CACHE_FILE_APIM -a "$SKIP_CACHE" != "true" ]
-then
- echo "Using cached API-Manager docker image: $APIM_DOCKER_IMAGE from $CACHE_FILE_APIM"
- gunzip -c $CACHE_FILE_APIM | docker load
-else
- echo "Pulling APIM docker from registry, this will take a while"
- docker login --username $AXWAY_DOCKER_REG_USER --password $AXWAY_DOCKER_REG_PASS docker-registry.demo.axway.com
- docker pull $APIM_DOCKER_IMAGE
-fi
diff --git a/build/pull_cassandra_docker_image.sh b/build/pull_cassandra_docker_image.sh
deleted file mode 100755
index 72bbba9c2..000000000
--- a/build/pull_cassandra_docker_image.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-if [ -f $CACHE_FILE_CASSANDRA ]
-then
- echo "Loading docker image: $CASSANDRA_DOCKER_IMAGE from $CACHE_FILE_CASSANDRA"
- gunzip -c $CACHE_FILE_CASSANDRA | docker load
-else
- echo "Pulling CASSANDRA docker from registry, this will take a while"
- docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASS
- docker pull $CASSANDRA_DOCKER_IMAGE
-fi
-
-
diff --git a/build/pull_wait_for_dependencies.sh b/build/pull_wait_for_dependencies.sh
deleted file mode 100755
index cf932c62d..000000000
--- a/build/pull_wait_for_dependencies.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-if [ -f $CACHE_FILE_WAIT_FOR_DEPENDENCIES ]
-then
- echo "Loading docker image: dadarek/wait-for-dependencies from $CACHE_FILE_WAIT_FOR_DEPENDENCIES"
- gunzip -c $CACHE_FILE_WAIT_FOR_DEPENDENCIES | docker load
-else
- echo "Pulling dadarek/wait-for-dependencies docker from Docker-Hub"
- docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASS
- docker pull dadarek/wait-for-dependencies
-fi
-
-
diff --git a/distribution/pom.xml b/distribution/pom.xml
index b2efa7cd3..985476191 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -12,7 +12,6 @@
distribution
pom
Distribution
-
com.github.axway-api-management-plus.apim-cli
@@ -52,6 +51,7 @@
+ axway-apimcli-1.14.5.1-SNAPSHOT
maven-assembly-plugin
diff --git a/docker-compose.yml b/docker-compose.yml
index 9b8efab20..c09c214c8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,13 +2,14 @@ version: "2"
services:
cassandra:
+ # image: cassandra:4.0.13
image: ${CASSANDRA_DOCKER_IMAGE}
ports:
- 9042:9042 # Cassandra listen socket
hostname: cassandra
apimgmt:
- # image: docker-registry.demo.axway.com/swagger-promote/api-mgr-with-policies:7.7
+ # image: docker.repository.axway.com/apigateway-docker-prod/7.7/gateway:7.7.0.20240530-2-BN0004-ubi9
image: ${APIM_DOCKER_IMAGE}
volumes:
- ${GITHUB_WORKSPACE}/licenses:/opt/Axway/apigateway/conf/licenses
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIFilter.java b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIFilter.java
index 931ceca63..dabc79e0b 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIFilter.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIFilter.java
@@ -200,12 +200,9 @@ public void setApiPath(String apiPath) {
op = "like";
apiPath = apiPath.replace("*", "");
}
- // Only from version 7.7 on we can query for the path directly.
- if (APIManagerAdapter.hasAPIManagerVersion("7.7")) {
- filters.add(new BasicNameValuePair(FIELD, "path"));
- filters.add(new BasicNameValuePair(OP, op));
- filters.add(new BasicNameValuePair(VALUE, apiPath));
- }
+ filters.add(new BasicNameValuePair(FIELD, "path"));
+ filters.add(new BasicNameValuePair(OP, op));
+ filters.add(new BasicNameValuePair(VALUE, apiPath));
}
public String getQueryStringVersion() {
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIAdapter.java b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIAdapter.java
index 23ae4eb81..05cd7b57b 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIAdapter.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIAdapter.java
@@ -417,7 +417,7 @@ public void translateMethodIdsToName(APIQuota apiQuota, String apiId) throws App
APIManagerAPIMethodAdapter methodAdapter = APIManagerAdapter.getInstance().getMethodAdapter();
List quotaRestrictions = apiQuota.getRestrictions();
for (QuotaRestriction quotaRestriction : quotaRestrictions) {
- APIMethod apiMethod = methodAdapter.getMethodForId(apiId, quotaRestriction.getApiId());
+ APIMethod apiMethod = methodAdapter.getMethodForId(apiId, quotaRestriction.getMethod());
if (apiMethod != null)
quotaRestriction.setMethod(apiMethod.getName());
}
@@ -605,7 +605,7 @@ public API updateAPIProxy(API api) throws AppException {
}
}
- private String[] getSerializeAllExcept() throws AppException {
+ public String[] getSerializeAllExcept() throws AppException {
String[] serializeAllExcept;
// queryStringPassThrough added in inboundProfiles on API manager version 7.7.20220530
if (queryStringPassThroughBreakingVersion.contains(APIManagerAdapter.getInstance().getApiManagerVersion())) {
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIMethodAdapter.java b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIMethodAdapter.java
index 69a8dce7a..4c9b300b9 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIMethodAdapter.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/apis/APIManagerAPIMethodAdapter.java
@@ -83,6 +83,8 @@ public APIMethod getMethodForName(String apiId, String methodName) throws AppExc
}
public APIMethod getMethodForId(String apiId, String methodId) throws AppException {
+ if(methodId.equals("*"))
+ return null;
List apiMethods = getAllMethodsForAPI(apiId);
if (apiMethods.isEmpty()) {
LOG.warn("No operations found for API with id: {}", apiId);
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/jackson/QuotaRestrictionSerializer.java b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/jackson/QuotaRestrictionSerializer.java
index 6c7a19697..8697db642 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/adapter/jackson/QuotaRestrictionSerializer.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/adapter/jackson/QuotaRestrictionSerializer.java
@@ -15,42 +15,42 @@ public class QuotaRestrictionSerializer extends StdSerializer
public static final String METHOD = "method";
public QuotaRestrictionSerializer() {
- this(null);
- }
-
- public QuotaRestrictionSerializer(Class t) {
- super(t);
- }
-
- @Override
- public void serialize(QuotaRestriction quotaRestriction, JsonGenerator jgen, SerializerProvider provider) throws IOException {
- jgen.writeStartObject();
- if(quotaRestriction.getRestrictedAPI()==null) {
- jgen.writeObjectField("api", "*");
- jgen.writeObjectField(METHOD, "*");
- } else { // API-Specific quota
- // Don't write the API-Name as it's confusing it is ignored during import when the API-Path is given.
- jgen.writeObjectField("apiPath", quotaRestriction.getRestrictedAPI().getPath());
- if(quotaRestriction.getRestrictedAPI().getVhost()!=null) {
- jgen.writeObjectField("vhost", quotaRestriction.getRestrictedAPI().getVhost());
- }
- if(quotaRestriction.getRestrictedAPI().getApiRoutingKey()!=null) {
- jgen.writeObjectField("apiRoutingKey", quotaRestriction.getRestrictedAPI().getApiRoutingKey());
- }
- if(quotaRestriction.getMethod()==null || "*".equals(quotaRestriction.getMethod())) {
- jgen.writeObjectField(METHOD, "*");
- } else {
- APIMethod method = APIManagerAdapter.getInstance().getMethodAdapter().getMethodForId(quotaRestriction.getApiId(), quotaRestriction.getMethod());
- jgen.writeObjectField(METHOD, method.getName());
- }
- }
- jgen.writePOJOField("type",quotaRestriction.getType());
- jgen.writePOJOField("config",quotaRestriction.getConfig());
- jgen.writeEndObject();
- }
-
- @Override
- public Class handledType() {
- return QuotaRestriction.class;
- }
+ this(null);
+ }
+
+ public QuotaRestrictionSerializer(Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(QuotaRestriction quotaRestriction, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ jgen.writeStartObject();
+ if (quotaRestriction.getRestrictedAPI() == null) {
+ jgen.writeObjectField("api", "*");
+ jgen.writeObjectField(METHOD, "*");
+ } else { // API-Specific quota
+ // Don't write the API-Name as it's confusing it is ignored during import when the API-Path is given.
+ jgen.writeObjectField("apiPath", quotaRestriction.getRestrictedAPI().getPath());
+ if (quotaRestriction.getRestrictedAPI().getVhost() != null) {
+ jgen.writeObjectField("vhost", quotaRestriction.getRestrictedAPI().getVhost());
+ }
+ if (quotaRestriction.getRestrictedAPI().getApiRoutingKey() != null) {
+ jgen.writeObjectField("apiRoutingKey", quotaRestriction.getRestrictedAPI().getApiRoutingKey());
+ }
+ if (quotaRestriction.getMethod() == null || "*".equals(quotaRestriction.getMethod())) {
+ jgen.writeObjectField(METHOD, "*");
+ } else {
+ APIMethod method = APIManagerAdapter.getInstance().getMethodAdapter().getMethodForId(quotaRestriction.getApiId(), quotaRestriction.getMethod());
+ jgen.writeObjectField(METHOD, method.getName());
+ }
+ }
+ jgen.writePOJOField("type", quotaRestriction.getType());
+ jgen.writePOJOField("config", quotaRestriction.getConfig());
+ jgen.writeEndObject();
+ }
+
+ @Override
+ public Class handledType() {
+ return QuotaRestriction.class;
+ }
}
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WADLSpecification.java b/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WADLSpecification.java
index fc1505a5e..7940462f9 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WADLSpecification.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WADLSpecification.java
@@ -1,6 +1,7 @@
package com.axway.apim.api.specification;
import com.axway.apim.api.API;
+import com.axway.apim.lib.CoreParameters;
import com.axway.apim.lib.error.AppException;
import com.axway.apim.lib.error.ErrorCode;
import com.axway.apim.lib.utils.Utils;
@@ -33,6 +34,7 @@ public void updateBasePath(String basePath, String host) {
@Override
public void configureBasePath(String backendBasePath, API api) throws AppException {
try {
+ CoreParameters.getInstance().setOverrideSpecBasePath(false); // Not allowing override base path for WADL, hence changing it to false.
if (backendBasePath != null) {
URL url = new URL(backendBasePath); // Parse it to make sure it is valid
if (url.getPath() != null && !url.getPath().isEmpty() && !backendBasePath.endsWith("/")) { // See issue #178
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WSDLSpecification.java b/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WSDLSpecification.java
index 3bdab49e9..faa55b40f 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WSDLSpecification.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/api/specification/WSDLSpecification.java
@@ -2,6 +2,7 @@
import com.axway.apim.api.API;
import com.axway.apim.api.model.ServiceProfile;
+import com.axway.apim.lib.CoreParameters;
import com.axway.apim.lib.error.AppException;
import com.axway.apim.lib.utils.Utils;
import org.slf4j.Logger;
@@ -61,6 +62,7 @@ public boolean parse(byte[] apiSpecificationContent) throws AppException {
return true;
}
try {
+ CoreParameters.getInstance().setOverrideSpecBasePath(false); // Not allowing override base path for WSDL, hence changing it to false.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
// to be compliant, completely disable DOCTYPE declaration:
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/lib/EnvironmentProperties.java b/modules/apim-adapter/src/main/java/com/axway/apim/lib/EnvironmentProperties.java
index e7a649260..ac34495cf 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/lib/EnvironmentProperties.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/lib/EnvironmentProperties.java
@@ -22,6 +22,7 @@ public class EnvironmentProperties implements Map {
public static final String FALSE = "false";
public static final boolean RETAIN_BACKEND_URL = Boolean.parseBoolean(System.getenv().getOrDefault("retain.backend.url", FALSE));
public static final boolean PRINT_CONFIG_CONSOLE = Boolean.parseBoolean(System.getenv().getOrDefault("print_console", FALSE));
+ public static final boolean OVERRIDE_CERTIFICATES = Boolean.parseBoolean(System.getenv().getOrDefault("override_certificates", FALSE));
public static final boolean CHECK_CATALOG = Boolean.parseBoolean(System.getenv().getOrDefault("check_catalog", FALSE));
private static final Logger LOG = LoggerFactory.getLogger(EnvironmentProperties.class);
diff --git a/modules/apim-adapter/src/main/java/com/axway/apim/lib/error/ErrorCode.java b/modules/apim-adapter/src/main/java/com/axway/apim/lib/error/ErrorCode.java
index af3d8f1ba..6c51cb875 100644
--- a/modules/apim-adapter/src/main/java/com/axway/apim/lib/error/ErrorCode.java
+++ b/modules/apim-adapter/src/main/java/com/axway/apim/lib/error/ErrorCode.java
@@ -11,7 +11,7 @@ public enum ErrorCode {
MISSING_PARAMETER(5, "There is a missing parameter.", false),
INVALID_PARAMETER(6, "There is an invalid parameter.", false),
API_ALREADY_EXISTS(7, "The API already exists for another organization.", false),
- BACKEND_API_DEF_NA(8, "The API already exists for another organization.", false),
+ BACKEND_API_DEF_NA(8, "Backend API definition is not available.", false),
NO_CHANGE(10, "No change between desired and actual API has been detected.", false, LogLevel.WARN),
EXPORT_FOLDER_EXISTS(12, "Export failed Export-Folder already exists.", false),
UPDATE_ONLY_IS_SET(13, "Creating of a new API fails, when flag updateOnly is set.", false),
diff --git a/modules/apim-adapter/src/test/java/com/axway/apim/adapter/apis/APIManagerAPIAdapterTest.java b/modules/apim-adapter/src/test/java/com/axway/apim/adapter/apis/APIManagerAPIAdapterTest.java
index 72531374b..7f7d454e3 100644
--- a/modules/apim-adapter/src/test/java/com/axway/apim/adapter/apis/APIManagerAPIAdapterTest.java
+++ b/modules/apim-adapter/src/test/java/com/axway/apim/adapter/apis/APIManagerAPIAdapterTest.java
@@ -3,6 +3,7 @@
import com.axway.apim.WiremockWrapper;
import com.axway.apim.adapter.APIManagerAdapter;
import com.axway.apim.adapter.client.apps.ClientAppFilter;
+import com.axway.apim.adapter.jackson.QuotaRestrictionDeserializer;
import com.axway.apim.api.API;
import com.axway.apim.api.model.*;
import com.axway.apim.api.model.apps.ClientApplication;
@@ -11,7 +12,15 @@
import com.axway.apim.lib.CoreParameters;
import com.axway.apim.lib.error.AppException;
import com.axway.apim.lib.utils.Utils;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.FilterProvider;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -786,4 +795,28 @@ public boolean parse(byte[] apiSpecificationContent) throws AppException {
}
+ @Test
+ public void updateAPIProxyWithBasicAuthEmptyPassword() throws IOException {
+ String testConfig = this.getClass().getResource("/com/axway/apim/adapter/conf/outbound_basic_auth_empty_password.json").getPath();
+ File file = new File(testConfig);
+ ObjectMapper mapper = Utils.createObjectMapper(new File(testConfig));
+ SimpleModule module = new SimpleModule();
+ module.addDeserializer(QuotaRestriction.class, new QuotaRestrictionDeserializer(QuotaRestrictionDeserializer.DeserializeMode.configFile, false));
+ // We would like to get back the original AppExcepption instead of a JsonMappingException
+ mapper.disable(DeserializationFeature.WRAP_EXCEPTIONS);
+ mapper.registerModule(module);
+ ObjectReader reader = mapper.reader();
+ API baseConfig = reader.forType(API.class).readValue(file);
+ System.out.println(baseConfig.getAuthenticationProfiles());
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ String[] serializeAllExcept = apiManagerAPIAdapter.getSerializeAllExcept();
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ FilterProvider filter = new SimpleFilterProvider().setDefaultFilter(
+ SimpleBeanPropertyFilter.serializeAllExcept(serializeAllExcept));
+ objectMapper.setFilterProvider(filter);
+
+ System.out.println(objectMapper.writeValueAsString(baseConfig));
+ }
+
}
diff --git a/modules/apim-adapter/src/test/java/com/axway/apim/api/model/AuthenticationProfileTest.java b/modules/apim-adapter/src/test/java/com/axway/apim/api/model/AuthenticationProfileTest.java
index e4cf2fcf5..ce2e4f6df 100644
--- a/modules/apim-adapter/src/test/java/com/axway/apim/api/model/AuthenticationProfileTest.java
+++ b/modules/apim-adapter/src/test/java/com/axway/apim/api/model/AuthenticationProfileTest.java
@@ -1,6 +1,9 @@
package com.axway.apim.api.model;
import com.axway.apim.lib.utils.Utils;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -173,6 +176,24 @@ public void compareBasicAuthProfilesWithDifferentPassword(){
Assert.assertNotEquals(authenticationProfileFromGateway, authenticationProfile);
}
+ @Test
+ public void checkBasicAuthProfilesWithEmptyPassword() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ String authProfile = "{\n" +
+ " \"name\":\"HTTP Basic Auth\",\n" +
+ " \"parameters\":{\n" +
+ " \"username\":\"usernameabc\",\n" +
+ " \"password\":\"\"\n" +
+ " },\n" +
+ " \"type\":\"http_basic\"\n" +
+ " }";
+ AuthenticationProfile authenticationProfile = mapper.readValue(authProfile, AuthenticationProfile.class);
+ Assert.assertTrue(authenticationProfile.getParameters().get("password").equals(""));
+ }
+
+
@Test
public void compareBasicAuthProfilesWithSamePassword(){
AuthenticationProfile authenticationProfile = new AuthenticationProfile();
diff --git a/modules/apim-adapter/src/test/resources/apimanager/README.md b/modules/apim-adapter/src/test/resources/apimanager/README.md
index 01692efc0..c3a5b4336 100644
--- a/modules/apim-adapter/src/test/resources/apimanager/README.md
+++ b/modules/apim-adapter/src/test/resources/apimanager/README.md
@@ -1,45 +1,62 @@
# Not used - Migrated to official docker image
# Purpose
The project is using Integration-Tests to simulate tasks the API-Developer is doing. That means, creating the API for the first time, doing frequent changes, subscribe with applications, etc.
-For that TravisCI is using, which is starting an API-Manager V7.x Docker-Container to perform these integration tests. This document describes the steps needed to build the Docker-Image.
+For that Github Action is using, which is starting an API-Manager V7.x Docker-Container to perform these integration tests. This document describes the steps needed to build the Docker-Image.
## Steps
-Download the API-Gateway/API-Manager release from support.axway.com you want to test with and have the following ready:
-- APIGateway_x.x.x_xxx_Install_linux-x86-64_BNxxxxxx.run
-- APIGateway_x.x.x-x_ScriptsPackageDocker_linux-x86-64_BNxxxxxxx.tar.gz
-- a license without hostname binding
-Copy everything to a system having docker installed.
-Perform the following steps:
-```
- cd $HOME
- git clone https://github.com/Axway-API-Management-Plus/apim-cli.git
- mkdir apim-cli-dockerimage
- cp APIGateway_x.x.x_xxx_Install_linux-x86-64_BNxxxxxx.run apim-cli-dockerimage
- cp APIGateway_7.7.20200130-1_DockerScripts.tar.gz apim-cli-dockerimage
- cp multiple.lic apim-cli-dockerimage
- $HOME/apim-cli/modules/apim-adapter/src/test/resources/apimanager/buildDockerImage.sh 7.7-20200930
+Integration test Github action uses APIM V7 docker image to run the integration tests.
+- Update latest docker image with tag
+- Update supported Cassandra version
+- Update the docker cahes
+
+Github workflow file integration-test.yaml
+
+```yaml
+ name: APIM CLI Integration Tests
+
+ on: [push]
+
+ env:
+ CASSANDRA_DOCKER_IMAGE: cassandra:4.0.13
+ APIM_DOCKER_IMAGE: docker.repository.axway.com/apigateway-docker-prod/7.7/gateway:7.7.0.20240530-2-BN0004-ubi9
+ CACHE_FILE_APIM: api-manager_7_7_20240530.cache.tar
+ CACHE_FILE_CASSANDRA: cassandra_4_0_13.cache.tar
+ FED_FILE: swagger-promote-7.7-20240530.fed
+ LOG_LEVEL: info
```
-### Added Untrusted Docker-Registry
+
+## Update fed file to newer version.
+
+### Upgrade fed file
+
+- Run upgradeconfig CLI command to update fed file to newer version
+
+```bash
+docker run -it -v /home/axway/apim-cli/modules/apim-adapter/src/test/resources/apimanager:/opt/Axway/apiprojects docker.repository.axway.com/apigateway-docker-prod/7.7/gateway:7.7.0.20240530-1-BN0092-ubi9 /bin/sh /opt/Axway/apigateway/posix/bin/upgradeconfig -f /opt/Axway/apiprojects/swagger-promote-7.7-20240228.fed -o /opt/Axway/apiprojects/new
```
-vi /etc/docker/daemon.json
+
+Above command creates new folder named **new** under modules/apim-adapter/src/test/resources/apimanager and files (suffix with .fed, .pol, .env)
+
+- Rename fed folder
+```bash
+mv e4b134f7-905b-4c56-ab40-221db6c931c9.fed swagger-promote-7.7-20240530.fed
```
-Add the following
-```json
-{
- "insecure-registries" : ["docker-registry.demo.axway.com"]
-}
-systemctl restart dockerd
+
+- Update fed file name in workflow file integration-test.yaml
+```yaml
+env:
+ FED_FILE: swagger-promote-7.7-20240530.fed
```
-Please note, that you need Write-Permissions to the Docker-Repository to push the image!
+## Update APIM license
-To enable the image, please adjust the image referred in the Travis-CI configuration file:
+- Create base64 encoded version of license.
+```bash
+base64 -i ~/Downloads/API-7.7-Docker-Temp.lic
```
-edit .github/workflows/integration-test.yml
-and change:
-Add/register your new Docker-Image and reference it in the following environment variables:
-- DOCKER_IMAGE_TO_USE=docker-registry.demo.axway.com/swagger-promote/api-mgr-with-policies:7.7-20221130
-- CACHE_FILE_APIM=api-manager_7_7_20221130.cache.tar
-```
-After checkin & commit a Github Action build is started using the provided Docker-Image.
+- Copy the base64 content and update Github Secrets and Variables
+
+Secret name - APIM_LIC
+
+## Push all changes to git, it will trigger the integration test.
diff --git a/modules/apim-adapter/src/test/resources/com/axway/apim/adapter/conf/outbound_basic_auth_empty_password.json b/modules/apim-adapter/src/test/resources/com/axway/apim/adapter/conf/outbound_basic_auth_empty_password.json
new file mode 100644
index 000000000..2071e6536
--- /dev/null
+++ b/modules/apim-adapter/src/test/resources/com/axway/apim/adapter/conf/outbound_basic_auth_empty_password.json
@@ -0,0 +1,18 @@
+{
+ "name": "test",
+ "path": "/test",
+ "state": "Published",
+ "version": "1.0.0",
+ "organization": "orga",
+ "authenticationProfiles": [
+ {
+ "name": "_default",
+ "isDefault": true,
+ "parameters": {
+ "username": "daskdjaskldjaskljdklasjdl",
+ "password": ""
+ },
+ "type": "http_basic"
+ }
+ ]
+}
diff --git a/modules/apis/src/main/java/com/axway/apim/api/export/ExportAPI.java b/modules/apis/src/main/java/com/axway/apim/api/export/ExportAPI.java
index fa776d86b..1dd3bd0e7 100644
--- a/modules/apis/src/main/java/com/axway/apim/api/export/ExportAPI.java
+++ b/modules/apis/src/main/java/com/axway/apim/api/export/ExportAPI.java
@@ -292,10 +292,11 @@ public List getClientOrganizations() throws AppException {
public List