Skip to content

Commit

Permalink
Enhance template creation to include api methods and inbound per meth…
Browse files Browse the repository at this point in the history
…od override
  • Loading branch information
rathnapandi committed Nov 22, 2024
1 parent 07f414d commit 05c9e73
Show file tree
Hide file tree
Showing 7 changed files with 420 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.axway.apim.api.API;
import com.axway.apim.api.model.*;
import com.axway.apim.config.model.APISecurity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@JsonPropertyOrder({"name", "path", "state", "version", "organization", "apiSpecification", "summary", "descriptionType", "descriptionManual", "vhost", "remoteHost",
"backendBasepath", "image", "inboundProfiles", "outboundProfiles", "securityProfiles", "authenticationProfiles", "tags", "customProperties",
Expand All @@ -16,12 +18,10 @@ public class APIConfig {
public static final String DEFAULT = "_default";
private final API api;
private final String apiDefinition;
private final Map<String, Object> securityProfiles;

public APIConfig(API api, String apiDefinition, Map<String, Object> securityProfiles) {
public APIConfig(API api, String apiDefinition) {
this.api = api;
this.apiDefinition = apiDefinition;
this.securityProfiles = securityProfiles;
}

public Map<String, OutboundProfile> getOutboundProfiles() {
Expand All @@ -46,15 +46,11 @@ public Map<String, OutboundProfile> getOutboundProfiles() {
}


public List<Map<String, Object>> getSecurityProfiles() {
if (securityProfiles.size() == 1) {
List<APISecurity> apiSecurities = (List<APISecurity>) securityProfiles.get("devices");
if (apiSecurities.get(0).getType().equals(DeviceType.passThrough.getName()))
return Collections.emptyList();
public List<SecurityProfile> getSecurityProfiles() {
if (api.getSecurityProfiles().size() == 1) {
return Collections.emptyList();
}
List<Map<String, Object>> list = new ArrayList<>();
list.add(securityProfiles);
return list;
return api.getSecurityProfiles();
}

public String getPath() {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public void addOptions() {
addOption(option);


option = new Option("includeMethods", false, "Include API Methods");
option.setRequired(false);
addOption(option);

option = new Option("inboundPerMethodOverride", false, "Include Inbound per Methods overrides");
option.setRequired(false);
addOption(option);


}

@Override
Expand Down Expand Up @@ -90,6 +99,8 @@ public Parameters getParams() {
frontendAuthType = "passThrough";
}
params.setFrontendAuthType(frontendAuthType);
params.setInboundPerMethodOverride(hasOption("inboundPerMethodOverride"));
params.setIncludeMethods(hasOption("includeMethods"));
return params;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public class GenerateTemplateParameters extends StandardExportParams implements
private String config;
private String backendAuthType;
private String frontendAuthType;
private boolean includeMethods;
private boolean inboundPerMethodOverride;

public String getApiDefinition() {
return apiDefinition;
Expand Down Expand Up @@ -41,4 +43,20 @@ public String getFrontendAuthType() {
public void setFrontendAuthType(String frontendAuthType) {
this.frontendAuthType = frontendAuthType;
}

public boolean isIncludeMethods() {
return includeMethods;
}

public void setIncludeMethods(boolean includeMethods) {
this.includeMethods = includeMethods;
}

public boolean isInboundPerMethodOverride() {
return inboundPerMethodOverride;
}

public void setInboundPerMethodOverride(boolean inboundPerMethodOverride) {
this.inboundPerMethodOverride = inboundPerMethodOverride;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

import com.axway.apim.adapter.jackson.CustomYamlFactory;
import com.axway.apim.api.API;
import com.axway.apim.api.model.APIMethod;
import com.axway.apim.api.model.InboundProfile;
import com.axway.apim.api.model.SecurityProfile;
import com.axway.apim.lib.error.AppException;
import com.axway.apim.lib.error.ErrorCode;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.servlet.ServletHandler;
Expand All @@ -25,6 +37,10 @@
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

public class GenerateTemplateTest {
Expand All @@ -36,24 +52,25 @@ public class GenerateTemplateTest {
private void init() throws URISyntaxException {
URI uri = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI();
resourcePath = Paths.get(uri).toString();
apimCliHome = resourcePath + File.separator + "apimcli";
apimCliHome = resourcePath + File.separator + "apimcli";

}

Server server = new Server();

@BeforeClass
public void start() throws InterruptedException {
Executors.newSingleThreadExecutor().execute(() -> {
try(ServerConnector connector = new ServerConnector(server)) {
try (ServerConnector connector = new ServerConnector(server)) {
connector.setPort(7070);
HttpConfiguration https_config = getHttpConfiguration();
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(resourcePath + File.separator + "keystore.jks");
sslContextFactory.setKeyStorePassword("changeit");
sslContextFactory.setKeyManagerPassword("changeit");
try (ServerConnector https = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config))) {
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config))) {

https.setPort(8443);
https.setHost("0.0.0.0");
Expand Down Expand Up @@ -91,9 +108,10 @@ private static HttpConfiguration getHttpConfiguration() {
public void stop() throws Exception {
server.stop();
}

@Test
public void testDownloadCertificates() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, KeyManagementException {
HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
GenerateTemplate generateTemplate = new GenerateTemplate();
API api = new API();
String filePath = generateTemplate.downloadCertificatesAndContent(api, "config.json", "https://localhost:8443/openapi.json");
Expand All @@ -104,7 +122,7 @@ public void testDownloadCertificates() throws IOException, CertificateEncodingEx
@Test
public void testDownloadContent() throws IOException {
GenerateTemplate generateTemplate = new GenerateTemplate();
String filePath = generateTemplate.downloadContent( "config.json", "http://localhost:7070/openapi.json");
String filePath = generateTemplate.downloadContent("config.json", "http://localhost:7070/openapi.json");
Assert.assertNotNull(filePath);
}

Expand Down Expand Up @@ -179,5 +197,49 @@ public void testWithFrontendAuthAlternateName() throws IOException {
Assert.assertEquals("passThrough", documentContext.read("$.securityProfiles[0].devices[0].type"));
}

@Test
public void generateApiMethods() throws IOException {

OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/methods.yaml");
GenerateTemplate generateTemplate = new GenerateTemplate();
List<APIMethod> apiMethods = generateTemplate.addMethods(openAPI);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(apiMethods));
// System.out.println(openAPI);

}

@Test
public void includeInboundPerMethodOverride() throws IOException {

OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/methods.yaml");
GenerateTemplate generateTemplate = new GenerateTemplate();
List<SecurityProfile> securityProfiles = new ArrayList<>();
API api = new API();
generateTemplate.addInboundPerMethodOverride(openAPI, api, securityProfiles);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
FilterProvider filters = new SimpleFilterProvider()

.addFilter("ProfileFilter",
SimpleBeanPropertyFilter.serializeAllExcept("apiMethodId"))
.setDefaultFilter(SimpleBeanPropertyFilter.serializeAllExcept());
objectMapper.setFilterProvider(filters);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(api.getInboundProfiles()));
}


@Test
public void testInboundOverride() throws IOException {
String[] args = {"template", "generate", "-c", "api-config.yaml", "-a", "src/test/resources/methods.yaml", "-frontendAuthType", "apiKey", "-inboundPerMethodOverride", "-o", "yaml"};
GenerateTemplate.generate(args);
// DocumentContext documentContext = JsonPath.parse(Files.newInputStream(Paths.get("api-config.json")));
// Assert.assertEquals("Swagger Petstore - OpenAPI 3.0", documentContext.read("$.name"));
// Assert.assertEquals("published", documentContext.read("$.state"));
// Assert.assertEquals("/api/v3", documentContext.read("$.path"));
// Assert.assertEquals("passThrough", documentContext.read("$.securityProfiles[0].devices[0].type"));
}


}
106 changes: 106 additions & 0 deletions modules/spectoconfig/src/test/resources/methods.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
openapi: 3.0.3
info:
title: Sample API
description: This is a sample API demonstrating OAuth 2.0 client credentials flow with scopes defined at the service and path levels.
version: 1.0.0

servers:
- url: https://api.example.com/v1

components:
securitySchemes:
oauth2ClientCredentials:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://auth.example.com/oauth2/token
scopes:
read: Grants read access
write: Grants write access
admin: Grants admin access

schemas:
SampleResponse:
type: object
properties:
message:
type: string

security:
- oauth2ClientCredentials:
- read
- write
tags:
- name: public
description: public desc
externalDocs:
url: http://docs.my-api.com/pet-operations.htm
- name: data
description: data desc
externalDocs:
url: http://docs.my-api.com/store-orders.htm
- name: admin
description: admin desc
externalDocs:
url: http://docs.my-api.com/store-orders.htm


paths:
/public:
get:
summary: Public endpoint
tags:
- public
description: This endpoint is public and does not require authentication.
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/SampleResponse'

/secure-data:
get:
summary: Secure data endpoint
tags:
- data
description: This endpoint requires OAuth with 'read' scope.
security:
- oauth2ClientCredentials:
- read
responses:
'200':
description: Secured data retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SampleResponse'

/admin:
post:
summary: Admin-only endpoint
tags:
- admin
description: This endpoint requires OAuth with 'admin' scope.
security:
- oauth2ClientCredentials:
- admin
requestBody:
description: Request payload for admin operation
required: true
content:
application/json:
schema:
type: object
properties:
action:
type: string
example: "update"
responses:
'201':
description: Admin operation successful
content:
application/json:
schema:
$ref: '#/components/schemas/SampleResponse'

0 comments on commit 05c9e73

Please sign in to comment.