com.wavemaker.spinup.web.SpinupController.java Source code

Java tutorial

Introduction

Here is the source code for com.wavemaker.spinup.web.SpinupController.java

Source

/*
 *  Copyright (C) 2012-2013 CloudJee, Inc. All rights reserved.
 *
 *  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.wavemaker.spinup.web;

import java.util.concurrent.TimeUnit;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.wavemaker.tools.cloudfoundry.spinup.InvalidLoginCredentialsException;
import com.wavemaker.tools.cloudfoundry.spinup.SpinupService;
import com.wavemaker.tools.cloudfoundry.spinup.authentication.SharedSecret;
import com.wavemaker.tools.cloudfoundry.spinup.authentication.TransportToken;

/**
 * Web {@link Controller} for spinning up wavemaker.
 * 
 * @author Phillip Webb
 */
@Controller
@SessionAttributes("loginCredentialsBean")
public class SpinupController {

    private final Log logger = LogFactory.getLog(getClass());

    private static final String SHARED_SECRET_ATTRIBUTE_NAME = SpinupController.class.getName() + ".SECRET";

    private static final String COOKIE_NAME = "wavemaker_authentication_token";

    private static final int COOKIE_MAX_AGE = (int) TimeUnit.DAYS.toSeconds(30);

    private SpinupService spinupService;

    @ModelAttribute("loginCredentialsBean")
    public LoginCredentialsBean createFormBean() {
        return new LoginCredentialsBean();
    }

    @ModelAttribute
    public void ajaxAttribute(HttpServletRequest request, Model model) {
        model.addAttribute("ajaxRequest", isAjaxRequest(request));
    }

    private boolean isAjaxRequest(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }

    /**
     * Login form used to collect cloud foundry credentials.
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public void loginForm() {
    }

    /**
     * Postback method from the login form. Will either re-direct back to the form (in the case of errors) or redirect
     * to start the spinup process.
     * 
     * @param credentials User credentials
     * @param bindingResult the binding result from the form
     * @param request the HTTP request
     * @param response the HTTP response
     * @return the response (either a redirect to the form or a redirect to the spinup process)
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView processLogin(@Valid LoginCredentialsBean credentials, BindingResult bindingResult,
            HttpServletRequest request, HttpServletResponse response) {

        Assert.state(isAjaxRequest(request), "Unable to handle non AJAX post");

        // If we have binding errors, re-render the page
        if (bindingResult.hasErrors()) {
            return new ModelAndView();
        }

        try {
            // Login, add the cookie and redirect to start the spinup process
            this.logger.debug("Starting WaveMaker spinup");
            SharedSecret secret = getSecret(request);
            TransportToken transportToken = this.spinupService.login(secret, credentials);
            this.logger.debug("Login complete");
            String url = performSpinup(credentials, secret, transportToken, response);
            this.logger.debug("Perform spinup complete");
            Cookie cookie = new Cookie(COOKIE_NAME, transportToken.encode());
            cookie.setMaxAge(COOKIE_MAX_AGE);
            cookie.setDomain(this.spinupService.getDomain());
            response.addCookie(cookie);
            response.setHeader("X-Ajax-Redirect", url);
            response.setStatus(HttpStatus.NO_CONTENT.value());
            this.logger.debug("Wavemake spinup complete");
            return null;
        } catch (InvalidLoginCredentialsException e) {
            // On invalid login redirect with a message in flash scope
            return new ModelAndView().addObject("message", "Unable to login, please check your credentials");
        }

    }

    private String performSpinup(LoginCredentialsBean credentials, SharedSecret secret,
            TransportToken transportToken, HttpServletResponse response) {
        String url = SpinupController.this.spinupService.start(secret, credentials.getUsername(), transportToken,
                false);
        // Give CloudFoundry some time to start
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
        }
        url = url + "?debug"; // FIXME make this an option ?
        return url;
    }

    private SharedSecret getSecret(HttpServletRequest request) {
        SharedSecret secret = (SharedSecret) request.getSession().getAttribute(SHARED_SECRET_ATTRIBUTE_NAME);
        if (secret == null) {
            secret = new SharedSecret();
            request.getSession().setAttribute(SHARED_SECRET_ATTRIBUTE_NAME, secret);
        }
        return secret;
    }

    @Autowired
    public void setSpinupService(SpinupService spinupService) {
        this.spinupService = spinupService;
    }
}