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

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

package com.axway.apim.actions.tasks;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
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.PUTRequest;
import com.axway.apim.actions.rest.RestAPICall;
import com.axway.apim.actions.rest.Transaction;
import com.axway.apim.actions.tasks.props.PropertyHandler;
import com.axway.apim.lib.APIPropertyAnnotation;
import com.axway.apim.lib.AppException;
import com.axway.apim.lib.ErrorCode;
import com.axway.apim.swagger.api.state.IAPI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class UpdateAPIProxy extends AbstractAPIMTask implements IResponseParser {
	
	public UpdateAPIProxy(IAPI desiredState, IAPI actualState) {
		super(desiredState, actualState);
	}

	public void execute(List changedProps) throws AppException {
		LOG.debug("Updating API-Proxy");
		URI uri;
		HttpEntity entity;
		ObjectMapper objectMapper = new ObjectMapper();
		
		Transaction context = Transaction.getInstance();
		
		try {
			JsonNode lastJsonReponse = (JsonNode)context.get("lastResponse");
			if(lastJsonReponse==null) { // This class is called as the first, so, first load the API
				lastJsonReponse = initActualAPIContext(this.actualState);
			}
			handledChangedProps(lastJsonReponse, this.desiredState, this.actualState, changedProps);
		
			uri = new URIBuilder(cmd.getAPIManagerURL()).setPath(RestAPICall.API_VERSION+"/proxies/"+context.get("virtualAPIId")).build();
			entity = new StringEntity(objectMapper.writeValueAsString(lastJsonReponse), StandardCharsets.UTF_8);
			
			RestAPICall updateAPIProxy = new PUTRequest(entity, uri, this);
			updateAPIProxy.execute();
		} catch (Exception e) {
			throw new AppException("Cannot update API-Proxy.", ErrorCode.CANT_UPDATE_API_PROXY, e);
		}
	}
	
	@Override
	public JsonNode parseResponse(HttpResponse httpResponse) throws AppException {
		ObjectMapper objectMapper = new ObjectMapper();
		String response = null;
		try {
			response = EntityUtils.toString(httpResponse.getEntity());
			if(httpResponse.getStatusLine().getStatusCode()!=200) {
				throw new AppException("Error updating API-Proxy. "
						+ "[Return-Code: " + httpResponse.getStatusLine().getStatusCode() + ", Response: '"+response+"'", ErrorCode.CANT_UPDATE_API_PROXY);
			}
			JsonNode jsonNode = objectMapper.readTree(response);
			String backendAPIId = jsonNode.findPath("id").asText();
			Transaction.getInstance().put("backendAPIId", backendAPIId);
		} catch (Exception e) {
			try {
				Transaction context = Transaction.getInstance();
				Object lastRequest = context.get("lastRequest");
				LOG.error("Last request: " + EntityUtils.toString(((HttpEntityEnclosingRequestBase)lastRequest).getEntity()));
				LOG.error("Unable to parse received response from API-Manager: '" + response + "'");
				throw new AppException("Unable to parse received response from API-Manager", ErrorCode.UNXPECTED_ERROR, e);
			} catch (Exception e1) {
				throw new AppException("Unable to parse response", ErrorCode.UNXPECTED_ERROR, e1);
			}
		} finally {
			try {
				((CloseableHttpResponse)httpResponse).close();
			} catch (Exception ignore) { }
		}
		return null;
	}	
	
	private static JsonNode handledChangedProps(JsonNode lastJsonReponse, IAPI desired, IAPI actual, List changedProps) throws AppException {
		Field field = null;
		if(changedProps!=null && changedProps.size()!=0) {
			boolean propsChangedInProxy = false;
			String logMessage = "Updating Frontend-API (Proxy) for the following properties: ";
			for(String fieldName : changedProps) {
				try {
					field = desired.getClass().getSuperclass().getDeclaredField(fieldName);
					if (field.isAnnotationPresent(APIPropertyAnnotation.class)) {
						LOG.debug("Going to update property: " + field.getName());
						APIPropertyAnnotation property = field.getAnnotation(APIPropertyAnnotation.class);
						if(void.class != property.propHandler()) { // Properties going this way, must be migrated
							Class clazz = property.propHandler();
							LOG.trace("Calling property handler: " + clazz.getCanonicalName());
							PropertyHandler propHandler = (PropertyHandler) clazz.newInstance();
							lastJsonReponse = propHandler.handleProperty(desired, actual, lastJsonReponse);
							logMessage = logMessage + field.getName() + " ";
							propsChangedInProxy = true;
						} else {
							try {
								String getterMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
								Method method = desired.getClass().getSuperclass().getMethod(getterMethodName, null);
								Object handler = method.invoke(desired, null);
								if(handler instanceof PropertyHandler) { // This is NEW/Preferred way
									LOG.trace("Calling property handler: " + handler.getClass());
									((PropertyHandler)handler).handleProperty(desired, actual, lastJsonReponse);
									logMessage = logMessage + field.getName() + " ";
									propsChangedInProxy = true;
								} else {
									LOG.debug("Property: " + field.getName() + " has no handler configured and is not a propertyHandler");
								}
							} catch (Exception e) {
								LOG.debug("Property: " + field.getName() + " has no handler configured and is not a propertyHandler");
							}
						}
					}
				} catch (Exception e) {
					throw new AppException("Can't handle property: "+field+" to update API-Proxy.", ErrorCode.CANT_UPDATE_API_PROXY, e);
				}
			}
			if(propsChangedInProxy)
				LOG.info(logMessage);
		}
		return lastJsonReponse;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy