feat(distro-wildfly): add Apiman developer portal to the WildFly distribution
Closes:
MODIFY
.github/workflows/release.yaml
.github/workflows/release.yaml
@@ -64,7 +64,7 @@ jobs:
git config --global user.name "apiman-ci"
git config --global user.email "ci.apiman@gmail.com"
git remote add origin "https://apiman-ci:${{ secrets.ACCESS_TOKEN }}@github.com/$GITHUB_REPOSITORY.git"
- git fetch
+ git fetch --recurse-submodules
git checkout master
git branch --set-upstream-to=origin/master
git pull

MODIFY
.github/workflows/trigger-docs-rebuild-redeploy.yml
.github/workflows/trigger-docs-rebuild-redeploy.yml
@@ -2,7 +2,7 @@ name: Trigger rebuild and redeployment of Apiman docs website
on:
push:
- branches: [ 2.x ] # Put all branches we want to track docs for here.
+ branches: [ master, 2.x ] # Put all branches we want to track docs for here.
paths:
- 'docs/**'
workflow_dispatch:

MODIFY
.github/workflows/verify.yaml
.github/workflows/verify.yaml
@@ -50,6 +50,7 @@ jobs:
- name: Checkout Code
uses: actions/checkout@v3
with:
+ submodules: true
fetch-depth: 0
- name: Set up `mvnd`

ADD
.gitmodules
+[submodule "developer-portal"]
+ path = developer-portal
+ url = https://github.com/apiman/apiman-developer-portal
+ branch = main

MODIFY
common/config/src/main/java/io/apiman/common/config/ConfigFactory.java
common/config/src/main/java/io/apiman/common/config/ConfigFactory.java
@@ -34,8 +34,9 @@ public class ConfigFactory {
private ConfigFactory() {
}
- public static final CompositeConfiguration createConfig() {
+ public static CompositeConfiguration createConfig() {
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
+ compositeConfiguration.addConfiguration(new EnvConfigurationWithSynonyms());
compositeConfiguration.addConfiguration(new SystemPropertiesConfiguration());
compositeConfiguration.addConfiguration(ConfigFileConfiguration.create("apiman.properties", "apiman.config.url")); //$NON-NLS-1$ //$NON-NLS-2$
return compositeConfiguration;

ADD
common/config/src/main/java/io/apiman/common/config/EnvConfigurationWithSynonyms.java
+/*
+ * Copyright 2022, Black Parrot Labs Ltd.
+ *
+ * Licensed 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.
+ */
+
+package io.apiman.common.config;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.configuration.AbstractConfiguration;
+
+/**
+ * Look up value from environment, but also look up common env var 'synonyms', with upper case and underscores instead of kebab/dot.
+ * <p>
+ * For example, <code>apiman.manager.api = APIMAN_MANAGER_API</code> or <code>apiman-manager-ui.api = APIMAN_MANAGER_UI_API</code>.
+ *
+ * @author Marc Savy {@literal <marc@blackparrotlabs.io>}
+ */
+public class EnvConfigurationWithSynonyms extends AbstractConfiguration {
+
+ public EnvConfigurationWithSynonyms() {
+ }
+
+ @Override
+ protected void addPropertyDirect(String key, Object value) {
+ throw new IllegalArgumentException("Environment is read-only. Can't add a new property.");
+ }
+
+ private static List<String> synonyms(String key) {
+ String dotToUnderscore = key.replace(".", "_").replace("-", "_");
+ String upperCase = dotToUnderscore.toUpperCase();
+ return List.of(key, dotToUnderscore, upperCase);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public boolean containsKey(String key) {
+ return getProperty(key) != null;
+ }
+
+ @Override
+ public Object getProperty(String key) {
+ for (String s : synonyms(key)) {
+ Object result = System.getenv(s);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterator<String> getKeys() {
+ return System.getenv().keySet().iterator();
+ }
+}

MODIFY
common/config/src/main/java/io/apiman/common/config/EnvLookup.java
common/config/src/main/java/io/apiman/common/config/EnvLookup.java
*/
package io.apiman.common.config;
+import java.util.List;
+
import org.apache.commons.lang.text.StrLookup;
/**
@@ -29,12 +31,19 @@ public class EnvLookup extends StrLookup {
*/
@Override
public String lookup(String key) {
- String value = System.getenv(key);
- if (value == null) {
- return ""; //$NON-NLS-1$
- } else {
- return value;
+ // Emulates Microprofile prop -> env lookup
+ for (String s : synonyms(key)) {
+ if (s != null) {
+ return s;
+ }
}
+ return "";
+ }
+
+ private List<String> synonyms(String key) {
+ String dotToUnderscore = key.replace(".", "_").replace("-", "_");
+ String upperCase = dotToUnderscore.toUpperCase();
+ return List.of(System.getenv(dotToUnderscore), System.getenv(upperCase));
}
}

MODIFY
distro/wildfly/pom.xml
distro/wildfly/pom.xml
</dependency>
<!-- Apiman WildFly WAR deps -->
+ <dependency>
+ <groupId>io.apiman</groupId>
+ <artifactId>apiman-developer-portal</artifactId>
+ <type>war</type>
+ </dependency>
<dependency>
<groupId>io.apiman</groupId>
<artifactId>apiman-manager-api-war-wildfly8</artifactId>

MODIFY
distro/wildfly/src/main/assembly/overlay.xml
distro/wildfly/src/main/assembly/overlay.xml
<directoryMode>0755</directoryMode>
<fileMode>0755</fileMode>
</dependencySet>
+ <!-- apiman portal -->
+ <dependencySet>
+ <outputDirectory>standalone/deployments</outputDirectory>
+ <includes>
+ <include>*:apiman-developer-portal:war</include>
+ </includes>
+ <outputFileNameMapping>portal.war</outputFileNameMapping>
+ <useProjectArtifact>false</useProjectArtifact>
+ <useProjectAttachments>false</useProjectAttachments>
+ <useTransitiveDependencies>false</useTransitiveDependencies>
+ <useTransitiveFiltering>false</useTransitiveFiltering>
+ <directoryMode>0755</directoryMode>
+ <fileMode>0755</fileMode>
+ </dependencySet>
<!-- apiman -->
<dependencySet>
<outputDirectory>standalone/deployments</outputDirectory>

MODIFY
distro/wildfly/src/main/resources/overlay/standalone/configuration/apiman.properties
distro/wildfly/src/main/resources/overlay/standalone/configuration/apiman.properties
@@ -50,7 +50,10 @@ apiman-manager-ui.allowed-cors-origins=*
# For services such as notifications we generate links so that the user can click through directly to the UI.
# Set this to whatever your valid public endpoint would be for accessing the main Apiman UI.
-apiman-manager.ui.endpoint=http://localhost:8080/apimanui/api-manager/
+apiman-manager-ui.endpoint=http://localhost:8080/apimanui/api-manager/
+
+# Where is the Apiman API backend?
+apiman-manager-ui.api.endpoint=http://localhost:8080/apiman
# Security context settings.
apiman-manager.security-context.type=keycloak

MODIFY
distro/wildfly/src/main/resources/overlay/standalone/configuration/standalone-apiman.xml
distro/wildfly/src/main/resources/overlay/standalone/configuration/standalone-apiman.xml
<property name="hibernate.types.print.banner" value="false"/>
<property name="apiman.hibernate.dialect" value="${env.APIMAN_DB_DRIVER, apiman.db.driver:h2}"/>
<property name="apiman-gateway.initializers.jdbc.datasource.type" value="${env.APIMAN_DB_DRIVER, apiman.db.driver:h2}"/>
+ <property name="apiman.auth.realm" value="${env.APIMAN_AUTH_REALM, apiman.auth.realm:apiman}"/>
</system-properties>
<management>
<security-realms>

MODIFY
manager/api/beans/src/main/java/io/apiman/manager/api/beans/search/SearchCriteriaBean.java
manager/api/beans/src/main/java/io/apiman/manager/api/beans/search/SearchCriteriaBean.java
@@ -18,6 +18,7 @@ package io.apiman.manager.api.beans.search;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import java.util.StringJoiner;
/**
* Generic search criteria used when searching for beans.
@@ -178,4 +179,12 @@ public class SearchCriteriaBean implements Serializable {
}
}
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", SearchCriteriaBean.class.getSimpleName() + "[", "]")
+ .add("filters=" + filters)
+ .add("orderBy=" + orderBy)
+ .add("paging=" + paging)
+ .toString();
+ }
}

MODIFY
manager/api/beans/src/main/java/io/apiman/manager/api/beans/search/SearchCriteriaFilterBean.java
manager/api/beans/src/main/java/io/apiman/manager/api/beans/search/SearchCriteriaFilterBean.java
package io.apiman.manager.api.beans.search;
import java.io.Serializable;
+import java.util.StringJoiner;
/**
* Represents a single filter or search criteria. This is used when searching
@@ -125,4 +126,12 @@ public class SearchCriteriaFilterBean implements Serializable {
return true;
}
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", SearchCriteriaFilterBean.class.getSimpleName() + "[", "]")
+ .add("name='" + name + "'")
+ .add("value='" + value + "'")
+ .add("operator=" + operator)
+ .toString();
+ }
}

MODIFY
manager/api/core/src/main/java/io/apiman/manager/api/core/config/ApiManagerConfig.java
manager/api/core/src/main/java/io/apiman/manager/api/core/config/ApiManagerConfig.java
@@ -85,7 +85,7 @@ public abstract class ApiManagerConfig {
/* -------------------------------------------------------
* Endpoint-related
* ------------------------------------------------------- */
- public static final String APIMAN_MANAGER_UI_ENDPOINT = "apiman-manager.ui.endpoint";
+ public static final String APIMAN_MANAGER_UI_ENDPOINT = "apiman-manager-ui.endpoint"; // TODO(msavy): same key is in UIConfig
private final Configuration config;

feat(distro-wildfly): add Apiman developer portal to the WildFly distribution

Closes: #2230