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

org.apache.camel.component.jclouds.JcloudsComputeProducer Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.component.jclouds;

import java.util.Set;

import com.google.common.base.Predicate;
import org.apache.camel.CamelException;
import org.apache.camel.CamelExchangeException;
import org.apache.camel.Exchange;
import org.apache.camel.util.ObjectHelper;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.LoginCredentials;

public class JcloudsComputeProducer extends JcloudsProducer {

    private final ComputeService computeService;

    public JcloudsComputeProducer(JcloudsEndpoint endpoint, ComputeService computeService) {
        super(endpoint);
        this.computeService = computeService;
    }

    @Override
    public JcloudsComputeEndpoint getEndpoint() {
        return (JcloudsComputeEndpoint) super.getEndpoint();
    }

    @Override
    public void process(Exchange exchange) throws Exception {
        String operation = getOperation(exchange);

        if (operation == null) {
            throw new CamelExchangeException(
                    "Operation must be specified in the endpoint URI or as a property on the exchange.", exchange);
        }

        if (JcloudsConstants.LIST_NODES.equals(operation)) {
            listNodes(exchange);
        } else if (JcloudsConstants.LIST_IMAGES.equals(operation)) {
            listImages(exchange);
        } else if (JcloudsConstants.LIST_HARDWARE.equals(operation)) {
            listHardware(exchange);
        } else if (JcloudsConstants.RUN_SCRIPT.equals(operation)) {
            runScriptOnNode(exchange);
        } else if (JcloudsConstants.CREATE_NODE.equals(operation)) {
            createNode(exchange);
        } else if (JcloudsConstants.DESTROY_NODE.equals(operation)) {
            destroyNode(exchange);
        } else if (JcloudsConstants.REBOOT_NODE.equals(operation)) {
            rebootNode(exchange);
        } else if (JcloudsConstants.SUSPEND_NODE.equals(operation)) {
            suspendNode(exchange);
        } else if (JcloudsConstants.RESUME_NODE.equals(operation)) {
            resumeNode(exchange);
        }
    }

    /**
     * Create a node with the specified group.
     */
    protected void createNode(Exchange exchange) throws CamelException {
        String group = getGroup(exchange);
        String imageId = getImageId(exchange);
        String locationId = getLocationId(exchange);
        String hardwareId = getHardwareId(exchange);

        if (ObjectHelper.isEmpty(group)) {
            throw new CamelExchangeException(
                    "Group must be specific in the URI or as exchange property for the destroy node operation.", exchange);
        }
        TemplateBuilder builder = computeService.templateBuilder();
        builder.any();

        if (ObjectHelper.isNotEmpty(locationId)) {
            builder.locationId(locationId);
        }
        if (ObjectHelper.isNotEmpty(imageId)) {
            builder.imageId(imageId);
        }
        if (ObjectHelper.isNotEmpty(hardwareId)) {
            builder.hardwareId(hardwareId);
        }

        try {
            Set nodeMetadatas = computeService.createNodesInGroup(group, 1, builder.build());
            exchange.getMessage().setBody(nodeMetadatas);
            exchange.getMessage().setHeaders(exchange.getIn().getHeaders());
        } catch (RunNodesException e) {
            throw new CamelExchangeException("Error creating jclouds node.", exchange, e);
        }
    }

    /**
     * Runs a script on the target node.
     */
    protected void runScriptOnNode(Exchange exchange) throws CamelException {
        String script = exchange.getIn().getBody(String.class);
        String nodeId = getNodeId(exchange);
        String user = getUser(exchange);

        LoginCredentials credentials = null;

        if (ObjectHelper.isNotEmpty(user)) {
            credentials = LoginCredentials.builder().user(user).build();
        }
        ExecResponse execResponse = null;

        if (credentials == null) {
            execResponse = computeService.runScriptOnNode(nodeId, script);
        } else {
            execResponse = computeService.runScriptOnNode(nodeId, script,
                    RunScriptOptions.Builder.overrideLoginCredentials(credentials).runAsRoot(false));
        }

        if (execResponse == null) {
            throw new CamelExchangeException(
                    "Failed to receive response for run script operation on node: " + nodeId + " using script: " + script,
                    exchange);
        }

        exchange.setProperty(JcloudsConstants.RUN_SCRIPT_ERROR, execResponse.getError());
        exchange.setProperty(JcloudsConstants.RUN_SCRIPT_EXIT_CODE, execResponse.getExitStatus());
        exchange.getMessage().setBody(execResponse.getOutput());
    }

    /**
     * Destroys the node with the specified nodeId.
     */
    protected void destroyNode(Exchange exchange) {
        Predicate predicate = getNodePredicate(exchange);
        computeService.destroyNodesMatching(predicate);
    }

    /**
     * Sets the metadata of the available nodes to the out message.
     */
    protected void listNodes(Exchange exchange) {
        Predicate predicate = getComputePredicate(exchange);
        Set computeMetadatas = computeService.listNodesDetailsMatching(predicate);
        exchange.getMessage().setBody(computeMetadatas);
    }

    /**
     * Sets the available images to the out message.
     */
    protected void listImages(Exchange exchange) {
        Set images = computeService.listImages();
        exchange.getMessage().setBody(images);
    }

    /**
     * Sets the available hardware profiles to the out message.
     */
    protected void listHardware(Exchange exchange) {
        Set hardwareProfiles = computeService.listHardwareProfiles();
        exchange.getMessage().setBody(hardwareProfiles);
    }

    /**
     * Reboot the node with the specified nodeId.
     */
    protected void rebootNode(Exchange exchange) {
        Predicate predicate = getNodePredicate(exchange);
        computeService.rebootNodesMatching(predicate);
    }

    /**
     * Suspend the node with the specified nodeId.
     */
    protected void suspendNode(Exchange exchange) {
        Predicate predicate = getNodePredicate(exchange);
        computeService.suspendNodesMatching(predicate);
    }

    /**
     * Suspend the node with the specified nodeId.
     */
    protected void resumeNode(Exchange exchange) {
        Predicate predicate = getNodePredicate(exchange);
        computeService.resumeNodesMatching(predicate);
    }

    /**
     * Returns the required {@ComputeMetadata} {@link Predicate} for the Exhcnage. The predicate can be used for
     * filtering.
     */
    public Predicate getComputePredicate(final Exchange exchange) {
        final String nodeId = getNodeId(exchange);

        Predicate predicate = new Predicate() {
            public boolean apply(ComputeMetadata metadata) {
                if (nodeId != null && !nodeId.equals(metadata.getId())) {
                    return false;
                }

                //If NodeMetadata also delegate to Node predicate.
                if (metadata instanceof NodeMetadataImpl) {
                    Predicate nodeMetadataPredicate = getNodePredicate(exchange);
                    if (!nodeMetadataPredicate.apply((NodeMetadataImpl) metadata)) {
                        return false;
                    }
                }
                return true;
            }
        };

        return predicate;
    }

    /**
     * Returns the required {@ComputeMetadata} {@link Predicate} for the Exhcnage. The predicate can be used for
     * filtering.
     */
    public Predicate getNodePredicate(Exchange exchange) {
        final String nodeId = getNodeId(exchange);
        final String imageId = getImageId(exchange);
        final String group = getGroup(exchange);
        final NodeMetadata.Status queryState = getNodeState(exchange);

        Predicate predicate = new Predicate() {
            public boolean apply(NodeMetadata metadata) {
                if (nodeId != null && !nodeId.equals(metadata.getId())) {
                    return false;
                }
                if (imageId != null && !imageId.equals(metadata.getImageId())) {
                    return false;
                }
                if (queryState != null && !queryState.equals(metadata.getStatus())) {
                    return false;
                }
                if (group != null && !group.equals(metadata.getGroup())) {
                    return false;
                }
                return true;
            }
        };
        return predicate;
    }

    /**
     * Retrieves the operation from the URI or from the exchange headers. The header will take precedence over the URI.
     */
    public String getOperation(Exchange exchange) {
        String operation = getEndpoint().getOperation();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.OPERATION))) {
            operation = exchange.getIn().getHeader(JcloudsConstants.OPERATION, String.class);
        }
        return operation;
    }

    /**
     * Retrieves the node state from the URI or from the exchange headers. The header will take precedence over the URI.
     */
    public NodeMetadata.Status getNodeState(Exchange exchange) {
        NodeMetadata.Status nodeState = null;
        String state = getEndpoint().getNodeState();
        if (ObjectHelper.isNotEmpty(state)) {
            nodeState = NodeMetadata.Status.valueOf(state);
        }

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.NODE_STATE))) {
            Object stateHeader = exchange.getIn().getHeader(JcloudsConstants.NODE_STATE);
            if (stateHeader == null) {
                nodeState = null;
            } else if (stateHeader instanceof NodeMetadata.Status) {
                nodeState = (NodeMetadata.Status) stateHeader;
            } else {
                nodeState = NodeMetadata.Status.valueOf(String.valueOf(stateHeader));
            }
        }
        return nodeState;
    }

    /**
     * Retrieves the image id from the URI or from the exchange properties. The property will take precedence over the
     * URI.
     */
    protected String getImageId(Exchange exchange) {
        String imageId = getEndpoint().getImageId();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.IMAGE_ID))) {
            imageId = exchange.getIn().getHeader(JcloudsConstants.IMAGE_ID, String.class);
        }
        return imageId;
    }

    /**
     * Retrieves the hardware id from the URI or from the exchange headers. The header will take precedence over the
     * URI.
     */
    protected String getHardwareId(Exchange exchange) {
        String hardwareId = getEndpoint().getHardwareId();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.HARDWARE_ID))) {
            hardwareId = exchange.getIn().getHeader(JcloudsConstants.HARDWARE_ID, String.class);
        }
        return hardwareId;
    }

    /**
     * Retrieves the location id from the URI or from the exchange headers. The header will take precedence over the
     * URI.
     */
    protected String getLocationId(Exchange exchange) {
        String locationId = getEndpoint().getLocationId();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.LOCATION_ID))) {
            locationId = exchange.getIn().getHeader(JcloudsConstants.LOCATION_ID, String.class);
        }
        return locationId;
    }

    /**
     * Retrieves the node id from the URI or from the exchange headers. The header will take precedence over the URI.
     */
    protected String getNodeId(Exchange exchange) {
        String nodeId = getEndpoint().getNodeId();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.NODE_ID))) {
            nodeId = exchange.getIn().getHeader(JcloudsConstants.NODE_ID, String.class);
        }
        return nodeId;
    }

    /**
     * Retrieves the group from the URI or from the exchange headers. The header will take precedence over the URI.
     */
    protected String getGroup(Exchange exchange) {
        String group = getEndpoint().getGroup();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.GROUP))) {
            group = exchange.getIn().getHeader(JcloudsConstants.GROUP, String.class);
        }
        return group;
    }

    /**
     * Retrieves the user from the URI or from the exchange headers. The header will take precedence over the URI.
     */
    protected String getUser(Exchange exchange) {
        String user = getEndpoint().getUser();

        if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(JcloudsConstants.USER))) {
            user = exchange.getIn().getHeader(JcloudsConstants.USER, String.class);
        }
        return user;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy