de.otto.mongodb.profiler.web.ConnectionController.java Source code

Java tutorial

Introduction

Here is the source code for de.otto.mongodb.profiler.web.ConnectionController.java

Source

/*
 *  Copyright 2013 Robert Gacki <robert.gacki@cgi.com>
 *
 *  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 de.otto.mongodb.profiler.web;

import de.otto.mongodb.profiler.*;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.util.UriComponentsBuilder;

import javax.validation.Valid;
import java.net.UnknownHostException;
import java.util.List;
import java.util.StringTokenizer;

@Controller
@RequestMapping(ConnectionController.CONTROLLER_RESOURCE)
public class ConnectionController extends AbstractController {

    public static final String CONTROLLER_RESOURCE = "/connections";

    public ConnectionController(final ProfilerService profilerService) {
        super(profilerService);
    }

    @Page(mainNavigation = MainNavigation.CONNECTIONS)
    @RequestMapping(method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView showConnections() {

        final ConnectionsPageViewModel viewModel = new ConnectionsPageViewModel(
                getProfilerService().getConnections());

        return new ModelAndView("page.connections").addObject("model", viewModel);
    }

    @Page(mainNavigation = MainNavigation.CONNECTIONS)
    @RequestMapping(value = "/{id:.+}", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView showConnection(@PathVariable("id") String connectionId) throws ResourceNotFoundException {

        final ProfiledConnection connection = requireConnection(connectionId);

        final List<? extends ProfiledDatabase> databases = getProfilerService().getDatabases(connection);

        final ConnectionPageViewModel viewModel = new ConnectionPageViewModel(connection, databases);

        return new ModelAndView("page.connection").addObject("model", viewModel).addObject("database",
                new AddDatabaseFormModel());
    }

    @Page(mainNavigation = MainNavigation.CONNECTIONS)
    @RequestMapping(value = "/new-connection", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView showCreateNewConnection() {

        return new ModelAndView("page.new-connection").addObject("connection", new CreateConnectionFormModel());
    }

    @Page(mainNavigation = MainNavigation.CONNECTIONS)
    @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ModelAndView createNewConnection(
            @Valid @ModelAttribute("connection") final CreateConnectionFormModel model,
            final BindingResult bindingResult, final UriComponentsBuilder uriComponentsBuilder) {

        if (bindingResult.hasErrors()) {
            return new ModelAndView("page.new-connection").addObject("connection", model);
        }

        final ProfiledConnectionConfiguration.Builder configBuilder = ProfiledConnectionConfiguration.build();

        try {
            parseHosts(model.getHosts(), configBuilder);
        } catch (ParseException e) {
            bindingResult.rejectValue("hosts", "invalidHostName", new Object[] { e.input },
                    "Host name \"{0}\" is invalid!");
        } catch (InvalidHostException e) {
            bindingResult.rejectValue("hosts", "unknownHostName", new Object[] { e.input },
                    "Host \"{0}\" is unknown!");
        }

        if (bindingResult.hasErrors()) {
            return new ModelAndView("page.new-connection").addObject("connection", model);
        }

        final ProfiledConnection connection;
        try {
            connection = getProfilerService().createConnection(model.getName(), configBuilder.toConfiguration());

            final String uri = uriComponentsBuilder.path("/connections/{id}").buildAndExpand(connection.getId())
                    .toUriString();

            return new ModelAndView(new RedirectView(uri));

        } catch (InvalidConnectionNameException e) {
            bindingResult.rejectValue("name", "invalid", new Object[] { e.getName() },
                    "The name \"{0}\" is invalid!");
            return new ModelAndView("page.new-connection").addObject("connection", model);
        }
    }

    @RequestMapping(value = "/{id:.+}/destroy", method = RequestMethod.POST)
    public View closeConnection(final @PathVariable("id") String connectionId,
            final UriComponentsBuilder uriComponentsBuilder) throws ResourceNotFoundException {

        final ProfiledConnection connection = requireConnection(connectionId);

        getProfilerService().destroyConnection(connection);

        final String uri = uriComponentsBuilder.path("/connections").build().toUriString();

        return new RedirectView(uri);
    }

    private static void parseHosts(final String input, final ProfiledConnectionConfiguration.Builder configBuilder)
            throws ParseException, InvalidHostException {

        final String raw = input.replace("\r", "").replace("\n", ",").replace(" ", "");

        final StringTokenizer tokenizer = new StringTokenizer(raw, ",");
        while (tokenizer.hasMoreTokens()) {
            parseHost(tokenizer.nextToken(), configBuilder);
        }
    }

    private static void parseHost(final String input, final ProfiledConnectionConfiguration.Builder configBuilder)
            throws ParseException, InvalidHostException {

        try {
            final String[] parts = input.split(":");
            if (parts.length == 2) {
                configBuilder.addHost(parts[0], Integer.parseInt(parts[1]));
            } else if (parts.length == 1) {
                configBuilder.addHost(parts[0]);
            }
        } catch (NumberFormatException e) {
            throw new ParseException(String.format("Invalid host [%s]!", input), e, input);
        } catch (UnknownHostException e) {
            throw new InvalidHostException(String.format("Unknown host [%s]!", input), e, input);
        }
    }

    private static class BadHostException extends Exception {

        public final String input;

        public BadHostException(String message, Throwable t, String input) {
            super(message, t);
            this.input = input;
        }
    }

    private static final class ParseException extends BadHostException {

        public ParseException(String message, Throwable t, String input) {
            super(message, t, input);
        }
    }

    private static final class InvalidHostException extends BadHostException {

        public InvalidHostException(String message, Throwable t, String input) {
            super(message, t, input);
        }
    }

}