All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.axway.apim.actions.tasks.UpgradeAccessToNewerAPI Maven / Gradle / Ivy

package com.axway.apim.actions.tasks;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Vector;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.axway.apim.actions.rest.POSTRequest;
import com.axway.apim.actions.rest.PUTRequest;
import com.axway.apim.actions.rest.RestAPICall;
import com.axway.apim.lib.AppException;
import com.axway.apim.lib.ErrorCode;
import com.axway.apim.lib.ErrorState;
import com.axway.apim.swagger.APIManagerAdapter;
import com.axway.apim.swagger.api.properties.applications.ClientApplication;
import com.axway.apim.swagger.api.properties.quota.QuotaRestriction;
import com.axway.apim.swagger.api.state.IAPI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class UpgradeAccessToNewerAPI extends AbstractAPIMTask implements IResponseParser {
	
	private IAPI inTransitState; 

	public UpgradeAccessToNewerAPI(IAPI inTransitState, IAPI actualState) {
		super(inTransitState, actualState);
		this.inTransitState = inTransitState;
	}
	public void execute() throws AppException {
		if(desiredState.getState().equals(IAPI.STATE_UNPUBLISHED)) {
			LOG.debug("No need to grant access to newly created API, as desired state of API is unpublished.");
			return;
		}
		LOG.info("Upgrade access & subscriptions to newly created API.");
		
		URI uri;
		HttpEntity entity;
		ObjectMapper objectMapper = new ObjectMapper();
		RestAPICall apiCall;
		
		try {
			uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(RestAPICall.API_VERSION+"/proxies/upgrade/"+actualState.getId()).build();
			
			List params = new Vector();
			params.add(new BasicNameValuePair("upgradeApiId", desiredState.getId()));
			
			entity = new UrlEncodedFormEntity(params, "UTF-8");
			
			apiCall = new POSTRequest(entity, uri, this, true);
			apiCall.setContentType("application/x-www-form-urlencoded");
			
			apiCall.execute();
			// API-Manager has now granted access to all existing orgs and give a subscription to existing app
			// therefore we have to update the new Actual-State to reflect this
			inTransitState.setClientOrganizations(actualState.getClientOrganizations());
			inTransitState.setApplications(actualState.getApplications());
		} catch (Exception e) {
			throw new AppException("Can't upgrade access to newer API!", ErrorCode.CANT_UPGRADE_API_ACCESS, e);
		}
		// Existing applications now got access to the new API, hence we have to update the internal state
		APIManagerAdapter.getInstance().addClientApplications(inTransitState, actualState);
		// Additionally we need to preserve existing (maybe manually created) application quotas
		boolean updateAppQuota = false;
		if(actualState.getApplications().size()!=0) {
			LOG.debug("Found: "+actualState.getApplications().size()+" subscribed applications for this API. Taking over potentially configured quota configuration.");
			for(ClientApplication app : actualState.getApplications()) {
				if(app.getAppQuota()==null) continue;
				// REST-API for App-Quota is also returning Default-Quotas, but we have to ignore them here!
				if(app.getAppQuota().getId().equals(APIManagerAdapter.APPLICATION_DEFAULT_QUOTA) || app.getAppQuota().getId().equals(APIManagerAdapter.SYSTEM_API_QUOTA)) continue;
				for(QuotaRestriction restriction : app.getAppQuota().getRestrictions()) {
					if(restriction.getApi().equals(actualState.getId())) { // This application has a restriction for this specific API
						updateAppQuota = true;
						restriction.setApi(desiredState.getId()); // Take over the quota config to new API
						if(!restriction.getMethod().equals("*")) { // The restriction is for a specific method
							String originalMethodName = APIManagerAdapter.getInstance().getMethodNameForId(actualState.getId(), restriction.getMethod());
							// Try to find the same operation for the newly created API based on the name
							String newMethodId = APIManagerAdapter.getInstance().getMethodIdPerName(desiredState.getId(), originalMethodName);
							restriction.setMethod(newMethodId);
						}
					}
				}
				if(updateAppQuota) {
					LOG.info("Taking over existing quota config for application: '"+app.getName()+"' to newly created API.");
					try {
						uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(RestAPICall.API_VERSION+"/applications/"+app.getId()+"/quota").build();
						entity = new StringEntity(objectMapper.writeValueAsString(app.getAppQuota()), StandardCharsets.UTF_8);
						
						apiCall = new PUTRequest(entity, uri, this, true);
						apiCall.execute();
						EntityUtils.consume(entity);
					} catch (Exception e) {
						ErrorState.getInstance().setError("Can't update application quota.", ErrorCode.CANT_UPDATE_QUOTA_CONFIG);
						throw new AppException("Can't update application quota.", ErrorCode.CANT_UPDATE_QUOTA_CONFIG);
					}
				}
			}
		}
	}
	@Override
	public JsonNode parseResponse(HttpResponse httpResponse) throws AppException {
		JsonNode jsonNode = null;
		try {
			if(httpResponse.getStatusLine().getStatusCode()!=204 && httpResponse.getStatusLine().getStatusCode()!=200) {
				throw new AppException("Unexpected response from API-Manager:" + httpResponse.getStatusLine() + httpResponse.getEntity(), ErrorCode.CANT_UPGRADE_API_ACCESS);
			}
		} finally {
			try {
				((CloseableHttpResponse)httpResponse).close();
			} catch (Exception ignore) { }
		}
		return jsonNode;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy