All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.axway.apim.actions.tasks.ManageClientApps Maven / Gradle / Ivy
package com.axway.apim.actions.tasks;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import com.axway.apim.actions.rest.DELRequest;
import com.axway.apim.actions.rest.POSTRequest;
import com.axway.apim.actions.rest.RestAPICall;
import com.axway.apim.actions.rest.Transaction;
import com.axway.apim.lib.AppException;
import com.axway.apim.lib.CommandParameters;
import com.axway.apim.lib.ErrorCode;
import com.axway.apim.swagger.APIManagerAdapter;
import com.axway.apim.swagger.api.properties.apiAccess.APIAccess;
import com.axway.apim.swagger.api.properties.applications.ClientApplication;
import com.axway.apim.swagger.api.state.ActualAPI;
import com.axway.apim.swagger.api.state.IAPI;
import com.fasterxml.jackson.databind.JsonNode;
public class ManageClientApps extends AbstractAPIMTask implements IResponseParser {
private static String MODE = "MODE";
private static String MODE_CREATE_API_ACCESS = "MODE_CREATE_API_ACCESS";
private static String MODE_REMOVE_API_ACCESS = "MODE_REMOVE_API_ACCESS";
private static boolean hasAdminAccount;
/**
* In case, the API has been re-created, this is object contains the API how it was before
*/
IAPI oldAPI;
public ManageClientApps(IAPI desiredState, IAPI actualState, IAPI oldAPI) throws AppException {
super(desiredState, actualState);
hasAdminAccount = APIManagerAdapter.hasAdminAccount();
this.oldAPI = oldAPI;
}
public void execute(boolean reCreation) throws AppException {
if(desiredState.getApplications()==null && !reCreation) return;
if(CommandParameters.getInstance().isIgnoreClientApps()) {
LOG.info("Configured client applications are ignored, as flag ignoreClientApps has been set.");
return;
}
if(desiredState.getApplications()!=null) { // Happens, when config-file doesn't contains client apps
// Remove configured apps, for Non-Granted-Orgs!
removeNonGrantedClientApps(desiredState.getApplications());
}
List recreateActualApps = null;
// If an UNPUBLISHED API has been re-created, we have to create App-Subscriptions manually, as API-Manager Upgrade only works on PUBLISHED APIs
// But we only need to do this, if existing App-Subscriptions should be preserved (MODE_ADD).
if(reCreation && actualState.getState().equals(IAPI.STATE_UNPUBLISHED) && CommandParameters.getInstance().getClientAppsMode().equals(CommandParameters.MODE_ADD)) {
removeNonGrantedClientApps(oldAPI.getApplications());
recreateActualApps = getMissingApps(oldAPI.getApplications(), actualState.getApplications());
// Create previously existing App-Subscriptions
createAppSubscription(recreateActualApps, actualState.getId());
// Update the In-Memory actual state for further processing
actualState.setApplications(recreateActualApps);
}
List missingDesiredApps = getMissingApps(desiredState.getApplications(), actualState.getApplications());
List revomingActualApps = getMissingApps(actualState.getApplications(), desiredState.getApplications());
if(missingDesiredApps.size()==0 && desiredState.getApplications()!=null) {
LOG.info("All desired applications: "+desiredState.getApplications()+" have already a subscription. Nothing to do.");
} else {
createAppSubscription(missingDesiredApps, actualState.getId());
}
if(revomingActualApps.size()>0) {
if(CommandParameters.getInstance().getClientAppsMode().equals(CommandParameters.MODE_REPLACE)) {
LOG.info("Removing access for appplications: "+revomingActualApps+" from API: " + actualState.getName());
removeAppSubscription(revomingActualApps, actualState.getId());
} else {
LOG.info("NOT removing access for appplications: "+revomingActualApps+" from API: " + actualState.getName() + " as clientAppsMode NOT set to replace.");
}
}
}
private void removeNonGrantedClientApps(List apps) throws AppException {
if(apps == null) return;
ListIterator it = apps.listIterator();
ClientApplication app;
while(it.hasNext()) {
app = it.next();
if(!hasClientAppPermission(app)) {
LOG.error("Organization of configured application: '" + app.getName() + "' has NO permission to this API. Ignoring this application.");
it.remove();
continue;
}
}
}
private boolean hasClientAppPermission(ClientApplication app) throws AppException {
String appsOrgId = app.getOrganizationId();
String appsOrgName = APIManagerAdapter.getInstance().getOrg(appsOrgId).getName();
if(appsOrgName==null) return false;
// If the App belongs to the same Org as the API, it automatically has permission (esp. for Unpublished APIs)
if(app.getOrganizationId().equals(((ActualAPI)actualState).getOrganizationId())) return true;
if(actualState.getClientOrganizations()==null) {
LOG.debug("No Client-Orgs configured for this API, therefore other app has NO permission.");
return false;
}
return actualState.getClientOrganizations().contains(appsOrgName);
}
private void createAppSubscription(List missingDesiredApps, String apiId) throws AppException {
URI uri;
HttpEntity entity;
RestAPICall apiCall;
if(missingDesiredApps.size()==0) return;
Transaction.getInstance().put(MODE, MODE_CREATE_API_ACCESS);
LOG.info("Creating API-Access for the following apps: '"+missingDesiredApps.toString()+"'");
try {
for(ClientApplication app : missingDesiredApps) {
LOG.debug("Creating API-Access for application '"+app.getName()+"'");
Transaction.getInstance().put("appName", app);
uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(RestAPICall.API_VERSION+"/applications/"+app.getId()+"/apis").build();
entity = new StringEntity("{\"apiId\":\""+apiId+"\",\"enabled\":true}");
apiCall = new POSTRequest(entity, uri, this, hasAdminAccount);
apiCall.execute();
}
} catch (Exception e) {
throw new AppException("Can't create API access requests.", ErrorCode.API_MANAGER_COMMUNICATION, e);
}
}
private void removeAppSubscription(List revomingActualApps, String apiId) throws AppException {
URI uri;
RestAPICall apiCall;
Transaction.getInstance().put(MODE, MODE_REMOVE_API_ACCESS);
for(ClientApplication app : revomingActualApps) {
// A Client-App that doesn't belong to a granted organization, can't have a subscription.
if(!hasClientAppPermission(app)) continue;
LOG.debug("Removing API-Access for application '"+app.getName()+"'");
String apiAccessIdToDelete = null;
try {
Transaction.getInstance().put("appName", app);
for(APIAccess accessId : app.getApiAccess()) {
if(accessId.getApiId().equals(apiId)) apiAccessIdToDelete = accessId.getId();
}
if(apiAccessIdToDelete==null) {
LOG.warn("Application: '"+app.getName()+"' ("+app.getId()+") seems not have access to API: '"+actualState.getName()+"' ("+apiId+"). Continue");
continue;
}
uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(RestAPICall.API_VERSION+"/applications/"+app.getId()+"/apis/"+apiAccessIdToDelete).build();
apiCall = new DELRequest(uri, this, hasAdminAccount);
apiCall.execute();
} catch (Exception e) {
LOG.error("Can't delete API access requests for application.");
throw new AppException("Can't delete API access requests for application.", ErrorCode.API_MANAGER_COMMUNICATION, e);
}
}
}
@Override
public JsonNode parseResponse(HttpResponse httpResponse) throws AppException {
Transaction context = Transaction.getInstance();
int statusCode = httpResponse.getStatusLine().getStatusCode();
try {
if(context.get(MODE).equals(MODE_CREATE_API_ACCESS) && statusCode == HttpStatus.SC_CREATED) {
actualState.getApplications().add((ClientApplication)context.get("appName"));
LOG.debug("Successfully created API-Access for application: '"+context.get("appName")+"'");
} else if(context.get(MODE).equals(MODE_REMOVE_API_ACCESS) && statusCode == HttpStatus.SC_NO_CONTENT) {
actualState.getApplications().remove((ClientApplication)context.get("appName"));
LOG.debug("Successfully removed API-Access from application: '"+context.get("appName")+"'");
} else {
LOG.error("Received status code: " + httpResponse.getStatusLine().getStatusCode());
try {
LOG.error("Received response: " + EntityUtils.toString(httpResponse.getEntity()));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
throw new AppException("Failure creating/deleting API-Access to/from application: '"+context.get("appName")+"'. Mode: '"+context.get(MODE)+"'",
ErrorCode.API_MANAGER_COMMUNICATION);
}
} finally {
try {
((CloseableHttpResponse)httpResponse).close();
} catch (Exception ignore) { }
}
return null;
}
private List getMissingApps(List apps, List otherApps) throws AppException {
List missingApps = new ArrayList();
if(otherApps == null) otherApps = new ArrayList();
if(apps == null) apps = new ArrayList();
for(ClientApplication app : apps) {
if(otherApps.contains(app)) {
continue;
}
missingApps.add(app);
}
return missingApps;
}
}