Skip to content

Commit

Permalink
Fix issue #511 and code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
rathnapandi committed Oct 28, 2024
1 parent 9b017f3 commit 4e214cc
Show file tree
Hide file tree
Showing 27 changed files with 277 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -15,25 +16,15 @@ public class APIStatusManager {

private static final Logger LOG = LoggerFactory.getLogger(APIStatusManager.class);

private static final String PUBLISHED = "published";
private static final String UNPUBLISHED = "unpublished";

private static final String DELETED = "deleted";
private static final String DEPRECATED = "deprecated";
private static final String UNDEPRECATED = "undeprecated";


private final APIManagerAdapter apimAdapter;

private boolean updateVHostRequired = false;

private enum StatusChangeMap {
unpublished(new String[]{APIStatusManager.PUBLISHED, APIStatusManager.DELETED}),
published(new String[]{APIStatusManager.UNPUBLISHED, APIStatusManager.DEPRECATED}),
unpublished(new String[]{Constants.API_PUBLISHED, Constants.API_DELETED}),
published(new String[]{Constants.API_UNPUBLISHED, Constants.API_DEPRECATED}),
deleted(new String[]{}),
deprecated(new String[]{APIStatusManager.UNPUBLISHED, APIStatusManager.UNDEPRECATED}),
undeprecated(new String[]{APIStatusManager.PUBLISHED, APIStatusManager.UNPUBLISHED}),
pending(new String[]{APIStatusManager.DELETED});
deprecated(new String[]{Constants.API_UNPUBLISHED, Constants.API_UNDEPRECATED}),
undeprecated(new String[]{Constants.API_PUBLISHED, Constants.API_UNPUBLISHED}),
pending(new String[]{Constants.API_DELETED});

private final String[] possibleStates;

Expand All @@ -43,8 +34,8 @@ private enum StatusChangeMap {
}

private enum StatusChangeRequiresEnforce {
published(new String[]{APIStatusManager.UNPUBLISHED, APIStatusManager.DELETED}),
deprecated(new String[]{APIStatusManager.UNPUBLISHED, APIStatusManager.DELETED});
published(new String[]{Constants.API_UNPUBLISHED, Constants.API_DELETED}),
deprecated(new String[]{Constants.API_UNPUBLISHED, Constants.API_DELETED});

private final List<String> enforceRequired;

Expand All @@ -61,10 +52,6 @@ public static StatusChangeRequiresEnforce getEnum(String value) {
}
}

public APIStatusManager() throws AppException {
this.apimAdapter = APIManagerAdapter.getInstance();
}

public void update(API apiToUpdate, String desiredState, boolean enforceBreakingChange) throws AppException {
update(apiToUpdate, desiredState, null, enforceBreakingChange);
}
Expand All @@ -90,8 +77,8 @@ public void update(API apiToUpdate, String desiredState, String vhost, boolean e
+ "is breaking. Enforce change with option: -force", ErrorCode.BREAKING_CHANGE_DETECTED);

}

try {
APIManagerAdapter apimAdapter = APIManagerAdapter.getInstance();
String[] possibleStatus = StatusChangeMap.valueOf(apiToUpdate.getState()).possibleStates;
String intermediateState = null;
boolean statusMovePossible = false;
Expand Down Expand Up @@ -125,7 +112,7 @@ public void update(API apiToUpdate, String desiredState, String vhost, boolean e
throw new AppException("The status change from: '" + apiToUpdate.getState() + "' to '" + desiredState + "' is not possible!", ErrorCode.CANT_UPDATE_API_STATUS);
}
apiToUpdate.setState(desiredState);
if (desiredState.equals(API.STATE_DELETED)) {
if (desiredState.equals(Constants.API_DELETED)) {
// If an API in state unpublished or pending, also an orgAdmin can delete it
if (apiAdapter.isFrontendApiExists(apiToUpdate))
apiAdapter.deleteAPIProxy(apiToUpdate);
Expand All @@ -134,18 +121,18 @@ public void update(API apiToUpdate, String desiredState, String vhost, boolean e
apiAdapter.deleteBackendAPI(apiToUpdate);
} else {
apiAdapter.updateAPIStatus(apiToUpdate, desiredState, vhost);
if (vhost != null && desiredState.equals(API.STATE_UNPUBLISHED)) {
if (vhost != null && desiredState.equals(Constants.API_UNPUBLISHED)) {
this.updateVHostRequired = true; // Flag to control update of the VHost
}
}
// Take over the status, as it has been updated now
apiToUpdate.setState(desiredState);
// When deprecation or undeprecation is requested, we have to set the actual API accordingly!
if (desiredState.equals(APIStatusManager.UNDEPRECATED)) {
if (desiredState.equals(Constants.API_UNDEPRECATED)) {
apiToUpdate.setDeprecated("false");
apiToUpdate.setState(API.STATE_PUBLISHED);
} else if (desiredState.equals(APIStatusManager.DEPRECATED)) {
apiToUpdate.setState(API.STATE_PUBLISHED);
apiToUpdate.setState(Constants.API_PUBLISHED);
} else if (desiredState.equals(Constants.API_DEPRECATED)) {
apiToUpdate.setState(Constants.API_PUBLISHED);
apiToUpdate.setDeprecated("true");
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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.Constants;
import com.axway.apim.lib.utils.URLParser;
import com.axway.apim.lib.utils.Utils;
import com.axway.apim.lib.utils.rest.*;
Expand Down Expand Up @@ -191,11 +192,24 @@ public API getUniqueAPI(List<API> foundAPIs, APIFilter filter) throws AppExcepti
if (apisPerKey.get(filterKey) != null && apisPerKey.get(filterKey).size() == 1) {
return apisPerKey.get(filterKey).get(0);
}
throw new AppException("No unique API found. Found " + foundAPIs.size() + " APIs based on filter: " + filter, ErrorCode.UNKNOWN_API);
LOG.debug("More than one API found based on filter path: {}, vhost : {} and version : {}", filter.getApiPath(), filter.getVhost(), filter.getVersion());
return filterApiBasedOnState(foundAPIs, filter);
// If more than one api exists with different api state
}
return foundAPIs.get(0);
}

public API filterApiBasedOnState(List<API> foundAPIs, APIFilter filter) throws AppException {
LOG.debug("Filtering based on state published");
for (API api : foundAPIs) {
if (api.getState().equals(Constants.API_PUBLISHED) && api.getPath().equals(filter.getApiPath()) && Objects.equals(api.getVhost(), filter.getVhost())) {
LOG.debug("Found an api with published state : {} - {}", api.getName(), api.getId());
return api;
}
}
throw new AppException("No unique API found. Found " + foundAPIs.size() + " APIs based on filter: " + filter, ErrorCode.UNKNOWN_API);
}

public String getVersion(API api) {
return api.getApiRoutingKey() != null ? api.getApiRoutingKey() : api.getVersion();
}
Expand Down Expand Up @@ -672,11 +686,11 @@ public boolean isFrontendApiExists(API api) {
}

public void publishAPI(API api, String vhost) throws AppException {
if (API.STATE_PUBLISHED.equals(api.getState())) {
if (Constants.API_PUBLISHED.equals(api.getState())) {
LOG.info("API is already published");
return;
}
updateAPIStatus(api, API.STATE_PUBLISHED, vhost);
updateAPIStatus(api, Constants.API_PUBLISHED, vhost);
}

public byte[] getAPIDatFile(API api, String password) throws AppException {
Expand Down Expand Up @@ -724,7 +738,7 @@ public void updateAPIStatus(API api, String desiredState, String vhost) throws A
.setPath(cmd.getApiBasepath() + PROXIES + api.getId() + "/" + StatusEndpoint.valueOf(desiredState).endpoint)
.build();
HttpEntity entity;
if (vhost != null && desiredState.equals(API.STATE_PUBLISHED)) { // During publish, it might be required to also set the VHost (See issue: #98)
if (vhost != null && desiredState.equals(Constants.API_PUBLISHED)) { // During publish, it might be required to also set the VHost (See issue: #98)
entity = new StringEntity("vhost=" + vhost, ContentType.APPLICATION_FORM_URLENCODED);
} else {
entity = new StringEntity("", ContentType.APPLICATION_FORM_URLENCODED);
Expand Down Expand Up @@ -760,7 +774,7 @@ public void updateRetirementDate(API api, Long retirementDate) throws AppExcepti
try {
if (retirementDate == null || retirementDate == 0) return;
// Ignore the retirementDate if desiredState is not deprecated as it's used nowhere
if (!api.getState().equals(API.STATE_DEPRECATED)) {
if (!api.getState().equals(Constants.API_DEPRECATED)) {
LOG.info("Ignoring given retirementDate as API-Status is not set to deprecated");
return;
}
Expand Down Expand Up @@ -956,7 +970,7 @@ public List<NameValuePair> addParam(API apiToUpgradeAccess, boolean deprecateRef
}

public boolean upgradeAccessToNewerAPI(API apiToUpgradeAccess, API referenceAPI, boolean deprecateRefApi, boolean retireRefApi, long retirementDateRefAPI) throws AppException {
if (apiToUpgradeAccess.getState().equals(API.STATE_UNPUBLISHED)) {
if (apiToUpgradeAccess.getState().equals(Constants.API_UNPUBLISHED)) {
LOG.info("API to upgrade access has state unpublished.");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.axway.apim.adapter.jackson;

import com.axway.apim.api.API;
import com.axway.apim.lib.utils.Constants;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
Expand All @@ -24,8 +24,8 @@ public void serializeAsField(Object bean,
SerializerProvider prov) throws Exception {
Object value = writer.get(bean);
if (value instanceof String) {
if(value.equals(API.STATE_DEPRECATED)) {
gen.writeStringField(writer.getName(), API.STATE_PUBLISHED);
if(value.equals(Constants.API_DEPRECATED)) {
gen.writeStringField(writer.getName(), Constants.API_PUBLISHED);
} else {
gen.writeStringField(writer.getName(), (String)value);
}
Expand Down
61 changes: 28 additions & 33 deletions modules/apim-adapter/src/main/java/com/axway/apim/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.axway.apim.api.model.TagMap;
import com.axway.apim.api.model.apps.ClientApplication;
import com.axway.apim.lib.APIPropertyAnnotation;
import com.axway.apim.lib.utils.Constants;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
Expand All @@ -49,12 +50,6 @@
@JsonFilter("APIFilter")
public class API implements CustomPropertiesEntity {

public static final String STATE_PUBLISHED = "published";
public static final String STATE_UNPUBLISHED = "unpublished";
public static final String STATE_DEPRECATED = "deprecated";
public static final String STATE_DELETED = "deleted";
public static final String STATE_PENDING = "pending";

JsonNode apiConfiguration;

@JsonIgnore
Expand All @@ -63,97 +58,97 @@ public class API implements CustomPropertiesEntity {
@APIPropertyAnnotation(isBreaking = true, writableStates = {}, isRecreate = true)
protected APISpecification apiDefinition = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
protected List<CaCert> caCerts = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected String descriptionType = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected String descriptionManual = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected String descriptionMarkdown = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected String descriptionUrl = null;

@JsonDeserialize(using = MarkdownLocalDeserializer.class)
protected List<String> markdownLocal = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
@JsonSetter(nulls = Nulls.SKIP)
protected List<SecurityProfile> securityProfiles = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
@JsonSetter(nulls = Nulls.SKIP)
protected List<AuthenticationProfile> authenticationProfiles = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED})
protected TagMap tags = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
protected Map<String, OutboundProfile> outboundProfiles = null;

@APIPropertyAnnotation(copyProp = false, isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(copyProp = false, isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
protected Map<String, ServiceProfile> serviceProfiles = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
protected Map<String, InboundProfile> inboundProfiles = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED})
protected List<CorsProfile> corsProfiles;

@APIPropertyAnnotation(copyProp = false, writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(copyProp = false, writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected List<Organization> clientOrganizations;

@APIPropertyAnnotation(copyProp = false,
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
@JsonSetter(nulls = Nulls.SKIP)
protected List<ClientApplication> applications = null;

@APIPropertyAnnotation(isBreaking = true, writableStates = {})
protected String path = null;

@APIPropertyAnnotation(copyProp = false,
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected String state = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED})
protected String version;

@APIPropertyAnnotation(isBreaking = true, writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED}, ignoreNull = false)
@APIPropertyAnnotation(isBreaking = true, writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED}, ignoreNull = false)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
protected String vhost = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED})
protected String name = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED, API.STATE_DEPRECATED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED, Constants.API_DEPRECATED})
protected String summary = null;

protected Long createdOn = null;

protected String createdBy = null;

@APIPropertyAnnotation(
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected Image image = null;

@APIPropertyAnnotation(
writableStates = {API.STATE_UNPUBLISHED})
writableStates = {Constants.API_UNPUBLISHED})
protected Map<String, String> customProperties = null;

@APIPropertyAnnotation(copyProp = false,
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected APIQuota applicationQuota = null;

@APIPropertyAnnotation(copyProp = false,
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected APIQuota systemQuota = null;

@APIPropertyAnnotation(isBreaking = true,
writableStates = {API.STATE_UNPUBLISHED})
writableStates = {Constants.API_UNPUBLISHED})
protected String apiRoutingKey = null;

@APIPropertyAnnotation(writableStates = {}, isRecreate = true)
Expand All @@ -175,13 +170,13 @@ public class API implements CustomPropertiesEntity {
protected String resourcePath = null;

@APIPropertyAnnotation(copyProp = false,
writableStates = {API.STATE_UNPUBLISHED, API.STATE_PUBLISHED, API.STATE_DEPRECATED})
writableStates = {Constants.API_UNPUBLISHED, Constants.API_PUBLISHED, Constants.API_DEPRECATED})
protected Long retirementDate = null;

@JsonDeserialize(using = RemotehostDeserializer.class)
protected RemoteHost remoteHost = null;

@APIPropertyAnnotation(writableStates = {API.STATE_UNPUBLISHED})
@APIPropertyAnnotation(writableStates = {Constants.API_UNPUBLISHED})
protected List<APIMethod> apiMethods = null;

public APISpecification getApiDefinition() {
Expand Down Expand Up @@ -258,7 +253,7 @@ public void setState(String state) {
*/
public String getState() {
if (this.deprecated != null
&& this.deprecated.equals("true")) return STATE_DEPRECATED;
&& this.deprecated.equals("true")) return Constants.API_DEPRECATED;
return this.state;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.axway.apim.lib.utils;

public final class Constants {

private Constants() {
throw new IllegalStateException("Object creation is not allowed");
}
public static final String API_UNPUBLISHED = "unpublished";
public static final String API_PUBLISHED = "published";
public static final String API_DEPRECATED = "deprecated";
public static final String API_DELETED = "deleted";
public static final String API_UNDEPRECATED = "undeprecated";
public static final String API_PENDING = "pending";
}
Loading

0 comments on commit 4e214cc

Please sign in to comment.