package io.fathom.cloud.compute.api.aws.ec2; import io.fathom.cloud.CloudException; import io.fathom.cloud.compute.api.aws.ec2.actions.AwsAction; import io.fathom.cloud.compute.api.aws.ec2.actions.AwsActionHandler; import io.fathom.cloud.compute.api.aws.ec2.actions.DeleteKeyPair; import io.fathom.cloud.compute.api.aws.ec2.actions.DescribeInstances; import io.fathom.cloud.compute.api.aws.ec2.actions.DescribeKeyPairs; import io.fathom.cloud.compute.api.aws.ec2.actions.DescribeRegions; import io.fathom.cloud.compute.api.aws.ec2.actions.ImportKeyPair; import io.fathom.cloud.compute.api.aws.ec2.actions.RunInstancesHandler; import io.fathom.cloud.compute.api.aws.ec2.actions.TerminateInstances; import io.fathom.cloud.server.resources.FathomCloudResourceBase; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.inject.Inject; import javax.inject.Provider; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Maps; import com.google.inject.Injector; @Path("/") public class Ec2Endpoint extends FathomCloudResourceBase { private static final Logger log = LoggerFactory.getLogger(Ec2Endpoint.class); @Inject Injector injector; @Inject Provider<AwsRequestContext> requestContextProvider; @POST @Produces({ XML }) @Consumes("application/x-www-form-urlencoded") public Object doPost(final MultivaluedMap<String, String> formParameters) throws CloudException { for (Entry<String, List<String>> entry : formParameters.entrySet()) { log.info(entry.getKey() + "=" + entry.getValue()); } String action = formParameters.getFirst("Action"); if (action == null) { throw new WebApplicationException(Status.BAD_REQUEST); } Map<String, Class<?>> handlers = buildHandlers(); Class<?> handlerClass = handlers.get(action); if (handlerClass == null) { throw new WebApplicationException(Status.BAD_REQUEST); } AwsActionHandler handler = (AwsActionHandler) injector.getInstance(handlerClass); AwsRequestContext requestContext = requestContextProvider.get(); handler.init(requestContext, formParameters); return handler.go(); } private static Map<String, Class<?>> buildHandlers() { // TODO: We could do this using discovery Map<String, Class<?>> handlers = Maps.newHashMap(); addHandler(handlers, DescribeRegions.class); addHandler(handlers, ImportKeyPair.class); addHandler(handlers, DescribeKeyPairs.class); addHandler(handlers, DeleteKeyPair.class); addHandler(handlers, DescribeInstances.class); addHandler(handlers, RunInstancesHandler.class); addHandler(handlers, TerminateInstances.class); return handlers; } private static void addHandler(Map<String, Class<?>> handlers, Class<? extends AwsActionHandler> clazz) { AwsAction action = clazz.getAnnotation(AwsAction.class); if (action == null) { throw new IllegalStateException("No @Action annotation on: " + clazz); } handlers.put(action.value(), clazz); } }