Skip to content

Commit 3531593

Browse files
author
Chris Wiechmann
authored
Merge pull request #224 from Axway-API-Management-Plus/wadl-support
Adding WADL support
2 parents 60093e5 + fb01ccf commit 3531593

11 files changed

Lines changed: 355 additions & 5 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ cache:
2020
- '$HOME/.m2/repository'
2121

2222
before_install:
23-
# Avoid installation if unit-tests fail anyway
23+
# Avoid installation if unit-tests fail anyway
2424
- mvn clean test
2525

2626
- if [ ! -f /etc/docker/daemon.json ]; then sudo cp -v .github/daemon-default.json /etc/docker/daemon.json; fi

modules/apim-adapter/src/main/java/com/axway/apim/adapter/APIManagerAdapter.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.axway.apim.adapter;
22

3+
import java.io.File;
34
import java.io.InputStream;
45
import java.net.URI;
56
import java.net.URL;
@@ -542,21 +543,26 @@ public static String getApiManagerName() throws AppException {
542543
return APIManagerAdapter.apiManagerName;
543544
}
544545

545-
public static JsonNode getCertInfoFromFile(InputStream certFile, CaCert cert) throws AppException {
546+
public static JsonNode getCertInfo(InputStream certificate, String password, CaCert cert) throws AppException {
546547
URI uri;
547548
HttpResponse httpResponse = null;
548549
try {
549550
uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(cmd.getApiBasepath() + "/certinfo").build();
550551
HttpEntity entity = MultipartEntityBuilder.create()
551-
.addBinaryBody("file", IOUtils.toByteArray(certFile), ContentType.create("application/x-x509-ca-cert"), cert.getCertFile())
552+
.addBinaryBody("file", certificate, ContentType.create("application/x-x509-ca-cert"), cert.getCertFile())
552553
.addTextBody("inbound", cert.getInbound())
553554
.addTextBody("outbound", cert.getOutbound())
555+
.addTextBody("passphrase", password)
554556
.build();
555557
POSTRequest postRequest = new POSTRequest(entity, uri);
556558
httpResponse = postRequest.execute();
557559
int statusCode = httpResponse.getStatusLine().getStatusCode();
558560
String response = EntityUtils.toString(httpResponse.getEntity());
559561
if( statusCode != 200){
562+
if(response!=null && response.contains("Bad password")) {
563+
LOG.debug("API-Manager failed to read certificate information: " + cert.getCertFile() + ". Got response: '"+response+"'.");
564+
throw new AppException("Password for keystore: '" + cert.getCertFile() + "' is wrong.", ErrorCode.WRONG_KEYSTORE_PASSWORD);
565+
}
560566
throw new AppException("API-Manager failed to read certificate information from file. Got response: '"+response+"'", ErrorCode.API_MANAGER_COMMUNICATION);
561567
}
562568
JsonNode jsonResponse = mapper.readTree(response);

modules/apim-adapter/src/main/java/com/axway/apim/api/definition/APISpecification.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public static enum APISpecType {
2828
OPEN_API_30("Open API 3.0", ".json"),
2929
OPEN_API_30_YAML("Open API 3.0 (YAML)", ".yaml"),
3030
WSDL_API ("WSDL", ".xml"),
31+
WADL_API ("Web Application Description Language (WADL)", ".wadl"),
3132
UNKNOWN ("Unknown", ".txt");
3233

3334
String niceName;

modules/apim-adapter/src/main/java/com/axway/apim/api/definition/APISpecificationFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class APISpecificationFactory {
2121
add(Swagger1xSpecification.class);
2222
add(OAS3xSpecification.class);
2323
add(WSDLSpecification.class);
24+
add(WADLSpecification.class);
2425
}};
2526

2627
public static APISpecification getAPISpecification(byte[] apiSpecificationContent, String apiDefinitionFile, String apiName) throws AppException {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.axway.apim.api.definition;
2+
3+
import java.net.MalformedURLException;
4+
import java.net.URL;
5+
6+
import com.axway.apim.lib.CoreParameters;
7+
import com.axway.apim.lib.errorHandling.AppException;
8+
import com.axway.apim.lib.errorHandling.ErrorCode;
9+
import com.axway.apim.lib.utils.Utils;
10+
11+
public class WADLSpecification extends APISpecification {
12+
13+
String wadl = null;
14+
15+
public WADLSpecification(byte[] apiSpecificationContent) throws AppException {
16+
super(apiSpecificationContent);
17+
}
18+
19+
@Override
20+
public APISpecType getAPIDefinitionType() throws AppException {
21+
return APISpecType.WADL_API;
22+
}
23+
24+
@Override
25+
public void configureBasepath(String backendBasepath) throws AppException {
26+
if(!CoreParameters.getInstance().isReplaceHostInSwagger()) return;
27+
try {
28+
if(backendBasepath!=null) {
29+
URL url = new URL(backendBasepath); // Parse it to make sure it is valid
30+
if(url.getPath()!=null && !url.getPath().equals("") && !backendBasepath.endsWith("/")) { // See issue #178
31+
backendBasepath += "/";
32+
}
33+
// The WADL has the base path configured like so: <resources base="http://customer-api.ddns.net:8099/">
34+
wadl = wadl.replaceFirst("(<resources.*base=\").*(\">)", "$1"+backendBasepath+"$2");
35+
36+
this.apiSpecificationContent = wadl.getBytes();
37+
}
38+
} catch (MalformedURLException e) {
39+
throw new AppException("The configured backendBasepath: '"+backendBasepath+"' is invalid.", ErrorCode.BACKEND_BASEPATH_IS_INVALID, e);
40+
} catch (Exception e) {
41+
LOG.error("Cannot replace host in provided Swagger-File. Continue with given host.", e);
42+
}
43+
}
44+
45+
46+
@Override
47+
public boolean configure() throws AppException {
48+
if(apiSpecificationFile.toLowerCase().endsWith(".url")) {
49+
apiSpecificationFile = Utils.getAPIDefinitionUriFromFile(apiSpecificationFile);
50+
}
51+
if(!apiSpecificationFile.toLowerCase().endsWith(".wadl") && !new String(this.apiSpecificationContent, 0, 500).contains("wadl.dev.java.net")) {
52+
LOG.debug("No WADL specification. Specification doesn't contain WADL namespace: wadl.dev.java.net in the first 500 characters.");
53+
return false;
54+
}
55+
// We going to use a cheap way - Avoid parsing & writing back the WADL-File.
56+
this.wadl = new String(this.apiSpecificationContent);
57+
return true;
58+
}
59+
}

modules/apis/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@
5858
<groupId>com.fasterxml.jackson.core</groupId>
5959
<artifactId>jackson-databind</artifactId>
6060
</dependency>
61+
<dependency>
62+
<groupId>com.fasterxml.jackson.dataformat</groupId>
63+
<artifactId>jackson-dataformat-xml</artifactId>
64+
<scope>test</scope>
65+
</dependency>
6166
<dependency>
6267
<groupId>com.consol.citrus</groupId>
6368
<artifactId>citrus-core</artifactId>

modules/apis/src/main/java/com/axway/apim/apiimport/APIImportConfigAdapter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ private void completeCaCerts(API apiConfig) throws AppException {
458458
for(CaCert cert :apiConfig.getCaCerts()) {
459459
if(cert.getCertBlob()==null) {
460460
try(InputStream is = getInputStreamForCertFile(cert)) {
461-
JsonNode certInfo = APIManagerAdapter.getCertInfoFromFile(is, cert);
461+
JsonNode certInfo = APIManagerAdapter.getCertInfo(is, null, cert);
462462
CaCert completedCert = mapper.readValue(certInfo.get(0).toString(), CaCert.class);
463463
completedCaCerts.add(completedCert);
464464
} catch (Exception e) {
@@ -829,7 +829,7 @@ private void handleOutboundSSLAuthN(AuthenticationProfile authnProfile) throws A
829829
cert.setInbound("false");
830830
cert.setOutbound("true");
831831
// This call is to validate the given password, keystore is valid
832-
APIManagerAdapter.getCertInfoFromUrl(fileData.get("data").asText(), password, cert);
832+
APIManagerAdapter.getCertInfo(new FileInputStream(clientCertFile), password, cert);
833833
String data = fileData.get("data").asText();
834834
authnProfile.getParameters().put("pfx", data);
835835
authnProfile.getParameters().remove("certFile");
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.axway.apim.api.definition;
2+
3+
import java.io.IOException;
4+
5+
import org.apache.commons.io.IOUtils;
6+
import org.testng.Assert;
7+
import org.testng.annotations.BeforeClass;
8+
import org.testng.annotations.Test;
9+
10+
import com.axway.apim.apiimport.lib.params.APIImportParams;
11+
import com.axway.apim.lib.errorHandling.AppException;
12+
import com.axway.apim.lib.errorHandling.ErrorCode;
13+
import com.fasterxml.jackson.databind.JsonNode;
14+
import com.fasterxml.jackson.databind.ObjectMapper;
15+
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
16+
17+
public class APISpecificationWADLTest {
18+
19+
XmlMapper xmlMapper = new XmlMapper();
20+
21+
@BeforeClass
22+
private void initTestIndicator() {
23+
APIImportParams params = new APIImportParams();
24+
params.setReplaceHostInSwagger(true);
25+
}
26+
27+
@Test
28+
public void testSamplePaymentsWADLAPI() throws AppException, IOException {
29+
30+
byte[] content = getAPISpecificationContent("/api_definition_1/sample-payment-api.wadl");
31+
APISpecification apiDefinition = APISpecificationFactory.getAPISpecification(content, "sample-payment-api.wadl", "Test-API");
32+
apiDefinition.configureBasepath("https://myhost.customer.com:8767/api/v1/myAPI");
33+
34+
Assert.assertTrue(apiDefinition instanceof WADLSpecification);
35+
// Check if the WADL-File has been changed based on the configured base path
36+
JsonNode wadl = xmlMapper.readTree(apiDefinition.getApiSpecificationContent());
37+
JsonNode resourcesNode = wadl.get("resources");
38+
String base = resourcesNode.get("base").asText();
39+
Assert.assertEquals(base, "https://myhost.customer.com:8767/api/v1/myAPI/");
40+
}
41+
42+
@Test
43+
public void testSampleAccoutnsWADLAPI() throws AppException, IOException {
44+
45+
byte[] content = getAPISpecificationContent("/api_definition_1/sample-accounts-api.wadl");
46+
APISpecification apiDefinition = APISpecificationFactory.getAPISpecification(content, "sample-accounts-api.wadl", "Test-API");
47+
apiDefinition.configureBasepath("https://myhost.customer.com:8767/api/v1/myAPI");
48+
49+
Assert.assertTrue(apiDefinition instanceof WADLSpecification);
50+
// Check if the WADL-File has been changed based on the configured base path
51+
JsonNode wadl = xmlMapper.readTree(apiDefinition.getApiSpecificationContent());
52+
JsonNode resourcesNode = wadl.get("resources");
53+
String base = resourcesNode.get("base").asText();
54+
Assert.assertEquals(base, "https://myhost.customer.com:8767/api/v1/myAPI/");
55+
}
56+
57+
58+
private byte[] getAPISpecificationContent(String swaggerFile) throws AppException {
59+
try {
60+
return IOUtils.toByteArray(this.getClass().getResourceAsStream(swaggerFile));
61+
} catch (IOException e) {
62+
throw new AppException("Can't read Swagger-File: '"+swaggerFile+"'", ErrorCode.CANT_READ_API_DEFINITION_FILE);
63+
}
64+
}
65+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<application xmlns="http://wadl.dev.java.net/2009/02"
2+
xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
<grammars/>
4+
<resources base="https://server1/AMB-ACCOUNTS-RS/service">
5+
<resource path="/">
6+
<resource path="info">
7+
<method name="GET">
8+
<response>
9+
<representation mediaType="*/*"/>
10+
</response>
11+
</method>
12+
</resource>
13+
</resource>
14+
<resource path="/accounts/v01">
15+
<resource path="/WGL0Check">
16+
<method name="POST">
17+
<request>
18+
<representation mediaType="application/json">
19+
<param name="request" style="plain" type="xs:string"/>
20+
</representation>
21+
</request>
22+
<response>
23+
<representation mediaType="application/json"/>
24+
</response>
25+
</method>
26+
</resource>
27+
<resource path="/callFinancialService">
28+
<method name="POST">
29+
<request>
30+
<representation mediaType="application/json">
31+
<param name="request" style="plain" type="xs:string"/>
32+
</representation>
33+
</request>
34+
<response>
35+
<representation mediaType="application/json"/>
36+
</response>
37+
</method>
38+
</resource>
39+
<resource path="/getAccountDetails">
40+
<method name="POST">
41+
<request>
42+
<representation mediaType="application/json">
43+
<param name="request" style="plain" type="xs:string"/>
44+
</representation>
45+
</request>
46+
<response>
47+
<representation mediaType="application/json"/>
48+
</response>
49+
</method>
50+
</resource>
51+
<resource path="/getDepositAccountDetails">
52+
<method name="POST">
53+
<request>
54+
<representation mediaType="application/json">
55+
<param name="request" style="plain" type="xs:string"/>
56+
</representation>
57+
</request>
58+
<response>
59+
<representation mediaType="application/json"/>
60+
</response>
61+
</method>
62+
</resource>
63+
<resource path="/getDepositAccountTransactions">
64+
<method name="POST">
65+
<request>
66+
<representation mediaType="application/json">
67+
<param name="request" style="plain" type="xs:string"/>
68+
</representation>
69+
</request>
70+
<response>
71+
<representation mediaType="application/json"/>
72+
</response>
73+
</method>
74+
</resource>
75+
<resource path="/getOverviewDetails">
76+
<method name="POST">
77+
<request>
78+
<representation mediaType="application/json">
79+
<param name="request" style="plain" type="xs:string"/>
80+
</representation>
81+
</request>
82+
<response>
83+
<representation mediaType="application/json"/>
84+
</response>
85+
</method>
86+
</resource>
87+
<resource path="/requestCurrentAccountTransactionDetail">
88+
<method name="POST">
89+
<request>
90+
<representation mediaType="application/json">
91+
<param name="request" style="plain" type="xs:string"/>
92+
</representation>
93+
</request>
94+
<response>
95+
<representation mediaType="application/json"/>
96+
</response>
97+
</method>
98+
</resource>
99+
<resource path="/requestCurrentAccountTransactionList">
100+
<method name="POST">
101+
<request>
102+
<representation mediaType="application/json">
103+
<param name="request" style="plain" type="xs:string"/>
104+
</representation>
105+
</request>
106+
<response>
107+
<representation mediaType="application/json"/>
108+
</response>
109+
</method>
110+
</resource>
111+
<resource path="/retrieveAccountsEnh">
112+
<method name="POST">
113+
<request>
114+
<representation mediaType="application/json">
115+
<param name="request" style="plain" type="xs:string"/>
116+
</representation>
117+
</request>
118+
<response>
119+
<representation mediaType="application/json"/>
120+
</response>
121+
</method>
122+
</resource>
123+
<resource path="/saveAccountNickName">
124+
<method name="POST">
125+
<request>
126+
<representation mediaType="application/json">
127+
<param name="request" style="plain" type="xs:string"/>
128+
</representation>
129+
</request>
130+
<response>
131+
<representation mediaType="application/json"/>
132+
</response>
133+
</method>
134+
</resource>
135+
<resource path="/saveAccountTransactionInternalNotes">
136+
<method name="POST">
137+
<request>
138+
<representation mediaType="application/json">
139+
<param name="request" style="plain" type="xs:string"/>
140+
</representation>
141+
</request>
142+
<response>
143+
<representation mediaType="application/json"/>
144+
</response>
145+
</method>
146+
</resource>
147+
</resource>
148+
</resources>
149+
</application>

0 commit comments

Comments
 (0)