-
Notifications
You must be signed in to change notification settings - Fork 684
Implement extensible architecture for Federated API Discovery #13550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 25 commits
754b522
4d3af77
970cf52
51d64fb
9829528
9be6347
9fa4708
e9cf7fe
75b7e79
ff54e72
8c84050
18556eb
3f27527
3987e44
cfd56ee
8179b2c
e577028
8534f95
27abaa6
35094dc
d25c378
6fdac53
b4895e2
0e21bd6
7327209
3065b18
2bd6bd7
b171396
c52cceb
e47357e
d6d03f5
71b2af3
4998f7d
20770c3
269a42b
488e993
e35ee32
545a7b5
f4c50cb
2b13fd0
16be663
e9820f4
78cb3a3
b7731c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| /* | ||
| * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). | ||
| * | ||
| * WSO2 LLC. 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. | ||
| */ | ||
|
|
||
| package org.wso2.carbon.apimgt.api; | ||
|
|
||
| import org.wso2.carbon.apimgt.api.model.API; | ||
| import org.wso2.carbon.apimgt.api.model.APIIdentifier; | ||
| import org.wso2.carbon.apimgt.api.model.Environment; | ||
|
|
||
| /** | ||
| * Abstract builder for creating WSO2 API objects from external API contracts (federated discovery). | ||
| * | ||
| * @param <T> The type of the raw data/contract from the external gateway (e.g. Azure API object, Kong API object). | ||
| */ | ||
| public abstract class FederatedAPIBuilder<T> { | ||
|
|
||
| /** | ||
| * Builds a WSO2 API object from the raw external data. | ||
| * | ||
| * @param sourceApi The raw data object from the external gateway. | ||
| * @param env The environment where the API is discovered. | ||
| * @param org The organization context. | ||
| * @return The constructed API object. | ||
| * @throws APIManagementException If an error occurs during building. | ||
| */ | ||
| public API build(T sourceApi, Environment env, String org) throws APIManagementException { | ||
| // 1. Basic Identification | ||
| String provider = org; // Usually defaults to the organization name | ||
| APIIdentifier apiId = new APIIdentifier(provider, getName(sourceApi), getVersion(sourceApi)); | ||
|
|
||
| API api = new API(apiId); | ||
|
|
||
| // 2. Map Common Properties | ||
| api.setContext(getContext(sourceApi)); | ||
| api.setContextTemplate(getContextTemplate(sourceApi)); | ||
| api.setUuid(getGatewayId(sourceApi)); // Important for mapping updates later | ||
| api.setDescription(getDescription(sourceApi)); | ||
|
|
||
| // 3. Set Standard WSO2 Flags | ||
| api.setOrganization(org); | ||
| if (env != null) { | ||
| api.setGatewayType(env.getGatewayType()); | ||
| } | ||
| api.setInitiatedFromGateway(true); | ||
| api.setRevision(false); | ||
| api.setGatewayVendor("external"); | ||
|
|
||
| // 4. Specific Mapping (Delegated to subclasses) | ||
| mapSpecificDetails(api, sourceApi, env); | ||
|
|
||
| return api; | ||
| } | ||
|
|
||
| /** | ||
| * Extracts the name of the API from the raw data. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The API name. | ||
| */ | ||
| protected abstract String getName(T sourceApi); | ||
|
|
||
| /** | ||
| * Extracts the version of the API from the raw data. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The API version. | ||
| */ | ||
| protected abstract String getVersion(T sourceApi); | ||
|
|
||
| /** | ||
| * Extracts the context/path of the API from the raw data. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The API context. | ||
| */ | ||
| protected abstract String getContext(T sourceApi); | ||
|
|
||
| /** | ||
| * Extracts the context/path of the API from the raw data. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The API context template. | ||
| */ | ||
| protected abstract String getContextTemplate(T sourceApi); | ||
|
|
||
| /** | ||
| * Extracts the unique ID (UUID) from the external gateway. | ||
| * This is used to link the WSO2 API to the External API for updates. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The unique gateway ID. | ||
| */ | ||
| protected abstract String getGatewayId(T sourceApi); | ||
|
|
||
| /** | ||
| * Extracts the description of the API from the raw data. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return The API description. | ||
| */ | ||
| protected abstract String getDescription(T sourceApi); | ||
|
|
||
| /** | ||
| * Maps type-specific details (protocol, endpoints, definitions, etc.) to the API object. | ||
| * | ||
| * @param api The WSO2 API object to populate. | ||
| * @param sourceApi The raw data object. | ||
| * @throws APIManagementException If an error occurs during mapping. | ||
| */ | ||
| protected abstract void mapSpecificDetails(API api, T sourceApi, Environment env) throws APIManagementException; | ||
|
|
||
| /** | ||
| * Checks if this builder can handle the given raw data object. | ||
| * | ||
| * @param sourceApi The raw data object. | ||
| * @return True if this builder can handle the object, false otherwise. | ||
| */ | ||
| public abstract boolean canHandle(T sourceApi); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,119 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Copyright (c) 2025 WSO2 LLC. (http://www.wso2.org) All Rights Reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * WSO2 LLC. 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. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package org.wso2.carbon.apimgt.api; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Abstract factory for creating and managing FederatedAPIBuilder instances. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * This provides a gateway-agnostic way to select the appropriate builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * for different API types (REST, WebSocket, GraphQL, etc.). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Gateway-specific implementations (AzureBuilderFactory, AWSBuilderFactory, etc.) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * should extend this class and register their specific builders. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param <T> The type of raw API data from the gateway (e.g., ApiContract for Azure, RestApi for AWS) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public abstract class FederatedBuilderFactory<T> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final List<FederatedAPIBuilder<T>> builders; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Constructor initializes the builders list. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Subclasses should call this and then register their builders. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public FederatedBuilderFactory() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.builders = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Gets the appropriate builder for the given raw API data. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Uses the Strategy pattern - iterates through registered builders | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * and returns the first one that can handle the API type. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param sourceApi The raw API data from the gateway | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return The builder that can handle this API type, or null if unsupported | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public FederatedAPIBuilder<T> getBuilder(T sourceApi) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (FederatedAPIBuilder<T> builder : builders) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (builder.canHandle(sourceApi)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return builder; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new IllegalStateException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "No registered builder can handle the given API data"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Checks if the given API type is supported by any registered builder. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param sourceApi The raw API data from the gateway | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @return true if a builder can handle this API type, false otherwise | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public boolean isSupported(T sourceApi) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return getBuilder(sourceApi) != null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (IllegalStateException e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | |
| * Gets the appropriate builder for the given raw API data. | |
| * Uses the Strategy pattern - iterates through registered builders | |
| * and returns the first one that can handle the API type. | |
| * | |
| * @param sourceApi The raw API data from the gateway | |
| * @return The builder that can handle this API type, or null if unsupported | |
| */ | |
| public FederatedAPIBuilder<T> getBuilder(T sourceApi) { | |
| for (FederatedAPIBuilder<T> builder : builders) { | |
| if (builder.canHandle(sourceApi)) { | |
| return builder; | |
| } | |
| } | |
| throw new IllegalStateException( | |
| "No registered builder can handle the given API data"); | |
| } | |
| /** | |
| * Checks if the given API type is supported by any registered builder. | |
| * | |
| * @param sourceApi The raw API data from the gateway | |
| * @return true if a builder can handle this API type, false otherwise | |
| */ | |
| public boolean isSupported(T sourceApi) { | |
| try { | |
| return getBuilder(sourceApi) != null; | |
| } catch (IllegalStateException e) { | |
| return false; | |
| } | |
| } | |
| /** | |
| * Gets the appropriate builder for the given raw API data. | |
| * Uses the Strategy pattern - iterates through registered builders | |
| * and returns the first one that can handle the API type. | |
| * | |
| * `@param` sourceApi The raw API data from the gateway | |
| * `@return` The builder that can handle this API type, or null if unsupported | |
| */ | |
| private FederatedAPIBuilder<T> findBuilder(T sourceApi) { | |
| for (FederatedAPIBuilder<T> builder : builders) { | |
| if (builder.canHandle(sourceApi)) { | |
| return builder; | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * Gets the appropriate builder for the given raw API data. | |
| * Uses the Strategy pattern - iterates through registered builders | |
| * and returns the first one that can handle the API type. | |
| * | |
| * `@param` sourceApi The raw API data from the gateway | |
| * `@return` The builder that can handle this API type, or null if unsupported | |
| */ | |
| public FederatedAPIBuilder<T> getBuilder(T sourceApi) { | |
| FederatedAPIBuilder<T> builder = findBuilder(sourceApi); | |
| if (builder != null) { | |
| return builder; | |
| } | |
| throw new IllegalStateException( | |
| "No registered builder can handle the given API data"); | |
| } | |
| /** | |
| * {`@inheritDoc`} | |
| */ | |
| public boolean isSupported(T sourceApi) { | |
| return findBuilder(sourceApi) != null; | |
| } |
🤖 Prompt for AI Agents
In
`@components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/FederatedBuilderFactory.java`
around lines 46 - 76, The Javadoc and control flow are inconsistent: create a
private helper method (e.g., findBuilder or lookupBuilder) in
FederatedBuilderFactory that iterates the builders collection and returns the
first FederatedAPIBuilder<T> that canHandle(sourceApi) or null if none found;
change getBuilder(T sourceApi) to call that helper and throw the
IllegalStateException only when the helper returns null (and update the `@return`
Javadoc to match), and change isSupported(T sourceApi) to call the same helper
and return (helper(...) != null) instead of relying on exception-based flow.
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -292,10 +292,26 @@ private void processDiscoveredAPIs(List<DiscoveredAPI> apisToDeployInGatewayEnv, | |||||||
| JsonObject apiJson = (JsonObject) new Gson().toJsonTree(apidto); | ||||||||
| apiJson = CommonUtil.addTypeAndVersionToFile(ImportExportConstants.TYPE_API, | ||||||||
| ImportExportConstants.APIM_VERSION, apiJson); | ||||||||
| String definition; | ||||||||
| if (api.isAsync()) { | ||||||||
| definition = api.getAsyncApiDefinition(); | ||||||||
| } else { | ||||||||
| definition = api.getSwaggerDefinition(); | ||||||||
| } | ||||||||
|
|
||||||||
| if (definition == null || StringUtils.isBlank(definition)) { | ||||||||
| log.warn("API definition is empty for: " + apidto.getName() + " version: " | ||||||||
| + apidto.getVersion()); | ||||||||
| if (log.isDebugEnabled()) { | ||||||||
| log.debug("API type: " + apidto.getType() + ", API object: " + api.toString()); | ||||||||
| } | ||||||||
| continue; | ||||||||
| } | ||||||||
|
|
||||||||
| InputStream apiZip = FederatedGatewayUtil.createZipAsInputStream( | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Log Improvement Suggestion No: 3
Suggested change
|
||||||||
| apiJson.toString(), api.getSwaggerDefinition(), | ||||||||
| apiJson.toString(), definition, | ||||||||
| FederatedGatewayUtil.createDeploymentYaml(environment), | ||||||||
| apidto.getName()); | ||||||||
| apidto.getName(), api.isAsync()); | ||||||||
|
|
||||||||
| ImportExportAPI importExportAPI = APIImportExportUtil.getImportExportAPI(); | ||||||||
|
|
||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1338,7 +1338,7 @@ private void validateKeyManagers(API api, List<String> existingKeyManagers) thro | |||||||||||||||||
| .forEach(validKeyManagers::add); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| if (validKeyManagers.isEmpty()) { | ||||||||||||||||||
| if (validKeyManagers.isEmpty() && !api.isInitiatedFromGateway()) { | ||||||||||||||||||
| throw new APIManagementException( | ||||||||||||||||||
|
Comment on lines
1340
to
1342
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Log Improvement Suggestion No: 7
Suggested change
|
||||||||||||||||||
| "API must have at least one valid and enabled key manager configured", | ||||||||||||||||||
| ExceptionCodes.KEY_MANAGER_NOT_FOUND); | ||||||||||||||||||
|
|
@@ -2623,7 +2623,8 @@ public API createNewAPIVersion(String existingApiId, String newVersion, Boolean | |||||||||||||||||
|
|
||||||||||||||||||
| existingAPI.setOrganization(organization); | ||||||||||||||||||
| APIIdentifier existingAPIId = existingAPI.getId(); | ||||||||||||||||||
| String existingAPISwaggerDefinition = existingAPI.getSwaggerDefinition(); | ||||||||||||||||||
| String existingApiDefinition = existingAPI.isAsync() ? existingAPI.getAsyncApiDefinition() | ||||||||||||||||||
| : existingAPI.getSwaggerDefinition(); | ||||||||||||||||||
| String existingAPICreatedTime = existingAPI.getCreatedTime(); | ||||||||||||||||||
| String existingAPIStatus = existingAPI.getStatus(); | ||||||||||||||||||
| boolean isExsitingAPIdefaultVersion = existingAPI.isDefaultVersion(); | ||||||||||||||||||
|
|
@@ -2646,7 +2647,7 @@ public API createNewAPIVersion(String existingApiId, String newVersion, Boolean | |||||||||||||||||
| List<OperationPolicy> apiLevelPolicies = extractAndDropAPILevelPoliciesFromAPI(existingAPI); | ||||||||||||||||||
| updateMCPServerBackends(existingAPI, existingApiId, organization); | ||||||||||||||||||
| //update swagger definition with version | ||||||||||||||||||
| APIUtil.updateAPISwaggerWithVersion(existingAPI); | ||||||||||||||||||
| APIUtil.updateAPIDefinitionWithVersion(existingAPI); | ||||||||||||||||||
| API newAPI = addAPI(existingAPI); | ||||||||||||||||||
| String newAPIId = newAPI.getUuid(); | ||||||||||||||||||
| cloneAPIPoliciesForNewAPIVersion(existingApiId, newAPI, operationPoliciesMap, apiLevelPolicies); | ||||||||||||||||||
|
|
@@ -2703,7 +2704,11 @@ public API createNewAPIVersion(String existingApiId, String newVersion, Boolean | |||||||||||||||||
| existingAPI.setId(existingAPIId); | ||||||||||||||||||
| existingAPI.setContext(existingContext); | ||||||||||||||||||
| existingAPI.setCreatedTime(existingAPICreatedTime); | ||||||||||||||||||
| existingAPI.setSwaggerDefinition(existingAPISwaggerDefinition); | ||||||||||||||||||
| if (existingAPI.isAsync()) { | ||||||||||||||||||
| existingAPI.setAsyncApiDefinition(existingApiDefinition); | ||||||||||||||||||
| } else { | ||||||||||||||||||
| existingAPI.setSwaggerDefinition(existingApiDefinition); | ||||||||||||||||||
| } | ||||||||||||||||||
| // update existing api with the original timestamp | ||||||||||||||||||
| existingAPI.setVersionTimestamp(existingVersionTimestamp); | ||||||||||||||||||
| if (isDefaultVersion) { | ||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Javadoc for
getContextTemplateis a copy-paste ofgetContext.The
@returntag says "The API context template" (correct), but the method description still reads "Extracts the context/path of the API" — same asgetContext. Clarify that this returns the template (e.g., with{version}placeholder).📝 Proposed Javadoc fix
🤖 Prompt for AI Agents