Package com.streamreduce

Source Code of com.streamreduce.AbstractInContainerTestCase

/*
* Copyright 2012 Nodeable Inc
*
*    Licensed 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 com.streamreduce;

import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import com.streamreduce.connections.AuthType;
import com.streamreduce.connections.CloudProvider;
import com.streamreduce.core.model.Account;
import com.streamreduce.core.model.Connection;
import com.streamreduce.core.model.ConnectionCredentials;
import com.streamreduce.core.model.Role;
import com.streamreduce.core.model.User;
import com.streamreduce.core.service.UserService;
import com.streamreduce.core.service.exception.UserNotFoundException;
import com.streamreduce.rest.dto.response.ConnectionResponseDTO;
import com.streamreduce.rest.resource.ErrorMessage;
import com.streamreduce.security.Roles;
import com.streamreduce.util.ConnectionUtils;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpProtocolParams;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.type.JavaType;
import org.jclouds.aws.ec2.reference.AWSEC2Constants;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.UUID;

import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
import static org.junit.Assert.assertEquals;


public abstract class AbstractInContainerTestCase extends AbstractServiceTestCase {

    public final ResourceBundle applicationProperties = ResourceBundle.getBundle("application");
    public final ResourceBundle cloudProperties = ResourceBundle.getBundle("cloud");
    public final ResourceBundle gitHubProperties = ResourceBundle.getBundle("github");
    public final ResourceBundle jiraProperties = ResourceBundle.getBundle("jira");
    public final ResourceBundle serverProperties = ResourceBundle.getBundle("server");
    public final String accountBaseUrl = getPublicApiUrlBase() + "/account";
    public final String adminBaseUrl = getPrivateUrlBase() + "/admin";
    public final String connectionsBaseUrl = getPublicApiUrlBase() + "/connections";
    public final String messagesBaseUrl = getPublicApiUrlBase() + "/messages";
    public final String imgBaseUrl = getPublicUrlBase() + "/gateway/custom";
    public final String inventoryItemBaseUrl = getPublicApiUrlBase() + "/inventory";
    public final String usersBaseUrl = getPublicApiUrlBase() + "/user";
    public final String testJcloudsInstanceGroup = "nodeable-test";
    public final String testUsername = "in_container_test_user@nodeable.com";

    public enum AuthTokenType {
        API,
        GATEWAY
    }

    protected Account testAccount;
    protected User testUser;
    @Autowired
    protected UserService userService;


    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();
        setUp(true);
    }

    protected void setUp(boolean startAMQ) throws Exception {

        // Create the test account and user
        // sometimes we fail to delete this... so don't just try it willy nilly.
        User user = null;
        try {
            user = userService.getUser(testUsername);
            testUser = user;
            testAccount = testUser.getAccount();

        } catch (UserNotFoundException unfe) {
        }

        if (user == null) {

            testAccount = new Account.Builder()
                    .name("In Container Test Account")
                    .description("This account is for testing in container.")
                    .url("http://nodeable.com")
                    .build();

            testAccount = userService.createAccount(testAccount);

            Set<Role> roles = userService.getAdminRoles();
            roles.add(applicationManager.getSecurityService().findRole(Roles.ADMIN_ROLE));

            testUser = new User.Builder()
                    .username(testUsername)
                    .password(testUsername)
                    .accountLocked(false)
                    .fullname("In Container Test User")
                    .userStatus(User.UserStatus.ACTIVATED)
                    .account(testAccount)
                    .roles(roles)
                    .accountOriginator(true)
                    .alias(UUID.randomUUID().toString())
                    .build();


            testUser = userService.createUser(testUser);
        }

        // TODO: Fix problem where local SecurityService doesn't see users logged in via RESTful API
    }



    @Override
    @After
    public void tearDown() throws Exception {
        // Delete the test account and user

        if (userService != null) {
            userService.deleteUser(testUser);
            userService.deleteAccount(testAccount.getId());

        }

        super.tearDown();
    }

    /**
     * Returns the user created for this test run.
     *
     * @return the user
     */
    public User getTestUser() {
        return testUser;
    }

    /**
     * Returns the base url for private endpoints.
     *
     * @return the private endpoint base url
     */
    public String getPrivateUrlBase() {
        String hostname = serverProperties.getString("server.host");
        String port = serverProperties.getString("server.port.private");
        return "http://" + hostname + ":" + port;
    }

    /**
     * Returns the base url for public endpoints.
     *
     * @return the public endpoint base url
     */
    public String getPublicUrlBase() {
        String hostname = serverProperties.getString("server.host");
        String port = serverProperties.getString("server.port.public");
        return "http://" + hostname + ":" + port;
    }

    /**
     * Returns the base url for public API endpoints.
     *
     * @return the public api endpoint base url
     */
    public String getPublicApiUrlBase() {
        return getPublicUrlBase() + "/api";
    }

    /**
     * Logs in the given user and returns the user's authentication token.
     *
     * @param username the username to login as
     * @param password the password for the username
     * @return the user's authentication token
     * @throws Exception if something goes wrong
     */
    public String login(String username, String password) throws Exception {
        HttpClient httpClient = new DefaultHttpClient();

        // Set the User-Agent to be safe
        httpClient.getParams().setParameter(HttpProtocolParams.USER_AGENT, Constants.NODEABLE_HTTP_USER_AGENT);

        HttpPost post = new HttpPost(getPublicUrlBase() + "/authentication/login");
//        HttpState state = httpClient.getState();
        String authnToken;

        try {
            // Login is done via Basic Authentication at this time

//            state.setCredentials(new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME),
//                    new UsernamePasswordCredentials(username, password));

            HttpResponse httpReponse = httpClient.execute(post);

            Header authHeader = httpReponse.getFirstHeader(Constants.NODEABLE_AUTH_TOKEN);

            if (authHeader != null) {
                authnToken = httpReponse.getFirstHeader(Constants.NODEABLE_AUTH_TOKEN).getValue();
            } else {
                String response = IOUtils.toString(httpReponse.getEntity().getContent());

                try {
                    ErrorMessage em = jsonToObject(response,
                            TypeFactory.defaultInstance().constructType(ErrorMessage.class));
                    throw new Exception(em.getErrorMessage());
                } catch (Exception e) {
                    throw new Exception("Unable to login: " + response);
                }
            }
        } finally {
            post.releaseConnection();
        }

        return authnToken;
    }

    /**
     * Logs a user out.
     *
     * @param authnToken the user's authentication url
     * @throws Exception if something goes wrong
     */
    public void logout(String authnToken) throws Exception {
        makeRequest(getPublicUrlBase() + "/api/user/logout", "GET", null, authnToken);
    }

    public String makeRequest(String url, String method, Object data, String authnToken)
            throws Exception {
        return makeRequest(url, method, data, authnToken, AuthTokenType.API);
    }

    /**
     * Makes a request to the given url using the given method and possibly submitting
     * the given data.  If you need the request to be an authenticated request, pass in
     * your authentication token as well.
     *
     * @param url        the url for the request
     * @param method     the method to use for the request
     * @param data       the data, if any, for the request
     * @param authnToken the token retrieved during authentication
     * @param type       API or GATEWAY, tells us the auth token key to use
     * @return the response as string (This is either the response payload or the status code if no payload is sent)
     * @throws Exception if something goes wrong
     */
    public String makeRequest(String url, String method, Object data, String authnToken, AuthTokenType type)
            throws Exception {
        HttpClient httpClient = new DefaultHttpClient();
        HttpRequestBase request;
        String actualPayload;

        // Set the User-Agent to be safe
        httpClient.getParams().setParameter(HttpProtocolParams.USER_AGENT, Constants.NODEABLE_HTTP_USER_AGENT);

        // Create the request object
        if (method.equals("DELETE")) {
            request = new HttpDelete(url);
        } else if (method.equals("GET")) {
            request = new HttpGet(url);
        } else if (method.equals("POST")) {
            request = new HttpPost(url);
        } else if (method.equals("PUT")) {
            request = new HttpPut(url);
        } else if (method.equals("HEAD")) {
            request = new HttpHead(url);
        } else {
            throw new IllegalArgumentException("The method you specified is not supported.");
        }

        // Put data into the request for POST and PUT requests
        if (method.equals("POST") || method.equals("PUT")) {
            HttpEntityEnclosingRequestBase eeMethod = (HttpEntityEnclosingRequestBase) request;
            String requestBody = data instanceof JSONObject ? ((JSONObject) data).toString() :
                    new ObjectMapper().writeValueAsString(data);

            eeMethod.setEntity(new StringEntity(requestBody, MediaType.APPLICATION_JSON, "UTF-8"));
        }

        // Add the authentication token to the request
        if (authnToken != null) {
            if (type.equals(AuthTokenType.API)) {
                request.addHeader(Constants.NODEABLE_AUTH_TOKEN, authnToken);
            } else if (type.equals(AuthTokenType.GATEWAY)) {
                request.addHeader(Constants.NODEABLE_API_KEY, authnToken);
            } else {
                throw new Exception("Unsupported Type of  " + type + " for authToken " + authnToken);
            }

        }

        // Execute the request
        try {
            HttpResponse response = httpClient.execute(request);
            String payload = IOUtils.toString(response.getEntity().getContent());

            // To work around HEAD, where we cannot receive a payload, and other scenarios where the payload could
            // be empty, let's stuff the response status code into the response.
            actualPayload = payload != null &&
                    payload.length() > 0 ?
                    payload :
                    Integer.toString(response.getStatusLine().getStatusCode());
        } finally {
            request.releaseConnection();
        }

        return actualPayload;
    }

    /**
     * Returns an object from the passed in JSON string based on the JavaType passed in.
     *
     * @param <T>  Variable type based on the JavaType passed in
     * @param json the JSON string to parse
     * @param type the type to return
     * @return the parsed object
     * @throws Exception if something goes wrong
     */

    @SuppressWarnings("unchecked")
    public <T> T jsonToObject(String json, JavaType type) throws Exception {
        ObjectMapper om = new ObjectMapper();

        try {
            return (T) om.readValue(json, type);
        } catch (Exception e) {
            try {
                ErrorMessage em = om.readValue(json, ErrorMessage.class);

                throw new Exception(em.getErrorMessage());
            } catch (IOException e2) {
                throw new IOException(e.getMessage() + ": " + json);
            }
        }
    }

    /**
     * Creates a dummy AWS EC2 node used for testing inventory.
     *
     * @param cloud         the cloud to create the node in/with
     * @param securityGroup the security group to create the node in/with
     * @return the created node
     * @throws Exception if something goes wrong
     */
    public NodeMetadata createDummyAWSEC2Node(ConnectionResponseDTO cloud, String securityGroup) throws Exception {
        ComputeService computeService = getComputeService(cloud);

        // Create a node
        Statement bootInstructions = AdminAccess.standard();
        NodeMetadata newNode = getOnlyElement(computeService.createNodesInGroup(securityGroup, 1,
                runScript(bootInstructions)));

        return newNode;
    }

    public ComputeService getComputeService(ConnectionResponseDTO cloud) {
        CloudProvider provider = (CloudProvider) ConnectionUtils.getProviderFromId(CloudProvider.TYPE,
                cloud.getProviderId());
        Properties overrides = new Properties();

        // Choose from only Amazon provided AMIs
        overrides.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY,
                "owner-id=137112412989;state=available;image-type=machine");
        overrides.setProperty(AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY, "");

        // Inject the SSH implementation
        Iterable<Module> modules = ImmutableSet.<Module>of(new SshjSshClientModule());

        return new ComputeServiceContextFactory().createContext(provider.getComputeId(),
                cloudProperties.getString("nodeable.aws.accessKeyId"), cloudProperties.getString("nodeable.aws.secretKey"), modules,
                overrides).getComputeService();
    }

    public void refreshCloudInventoryItemCache(Connection cloud, String authnToken) throws Exception {
        assertEquals("200",
                makeRequest(connectionsBaseUrl + "/" + cloud.getId() + "/inventory/refresh", "POST", null, authnToken));
    }

    public ConnectionResponseDTO createConnection(String authnToken, String alias, String description,
                                                  ConnectionCredentials credentials, String providerId,
                                                  String url, String type, AuthType authType
    )
            throws Exception {
        JSONObject json = new JSONObject();
        JSONObject credentialsJSON = new JSONObject();

        credentialsJSON.put("credential", credentials.getCredential());
        credentialsJSON.put("identity", credentials.getIdentity());

        json.put("alias", alias);
        json.put("description", description);
        json.put("credentials", credentialsJSON);
        json.put("providerId", providerId);
        json.put("url", url);
        json.put("type", type);
        json.put("authType", authType);

        return jsonToObject(makeRequest(connectionsBaseUrl, "POST", json, authnToken),
                TypeFactory.defaultInstance().constructType(ConnectionResponseDTO.class));
    }

}
TOP

Related Classes of com.streamreduce.AbstractInContainerTestCase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.