Java tutorial
/* * 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; } }