org.eclipse.orion.server.cf.commands.BindRouteCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.cf.commands.BindRouteCommand.java

Source

/*******************************************************************************
 * Copyright (c) 2013 IBM Corporation and others 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.orion.server.cf.commands;

import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.orion.server.cf.CFProtocolConstants;
import org.eclipse.orion.server.cf.manifest.v2.InvalidAccessException;
import org.eclipse.orion.server.cf.manifest.v2.ManifestParseTree;
import org.eclipse.orion.server.cf.objects.*;
import org.eclipse.orion.server.cf.utils.MultiServerStatus;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.osgi.util.NLS;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BindRouteCommand extends AbstractCFApplicationCommand {
    private final Logger logger = LoggerFactory.getLogger("org.eclipse.orion.server.cf"); //$NON-NLS-1$

    private String commandName;

    /* shared properties */
    private String appDomain;
    private Domain domain;
    private JSONObject route;
    private boolean noRoute;

    public JSONObject getRoute() {
        return route;
    }

    public String getAppDomain() {
        return appDomain;
    }

    public String getDomainName() {
        return domain.getDomainName();
    }

    public BindRouteCommand(Target target, App app) {
        super(target, app);

        String[] bindings = { app.getName(), app.getGuid() };
        this.commandName = NLS.bind("Bind a new route to application {1} (guid: {2})", bindings);
    }

    @Override
    protected ServerStatus _doIt() {
        /* multi server status */
        MultiServerStatus status = new MultiServerStatus();

        try {

            if (noRoute)
                /* nothing to do */
                return status;

            /* get available domains */
            GetDomainsCommand getDomainsCommand = new GetDomainsCommand(target);
            ServerStatus jobStatus = (ServerStatus) getDomainsCommand.doIt(); /* FIXME: unsafe type cast */
            status.add(jobStatus);

            if (!jobStatus.isOK())
                return status;

            List<Domain> domains = getDomainsCommand.getDomains();
            if (domains == null || domains.size() == 0) {
                status.add(new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST,
                        "Failed to find available domains in target", null));
                return status;
            }

            if (!appDomain.isEmpty()) {
                /* look if the domain is available */
                for (Iterator<Domain> iterator = domains.iterator(); iterator.hasNext();) {
                    Domain domain = iterator.next();
                    if (appDomain.equals(domain.getDomainName())) {
                        this.domain = domain;
                        break;
                    }
                }

                /* client requested an unavailable domain, fail */
                if (domain == null) {
                    String msg = NLS.bind("Failed to find domain {0} in target", appDomain);
                    status.add(new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
                    return status;
                }
            } else {
                /* client has not requested a specific domain, get the first available */
                this.domain = domains.get(0);
            }

            /* find out whether the declared host can be reused */
            String routeGUID = null;
            FindRouteCommand findRouteCommand = new FindRouteCommand(target, getApplication(), domain.getGuid());
            jobStatus = (ServerStatus) findRouteCommand.doIt(); /* FIXME: unsafe type cast */
            status.add(jobStatus);

            if (jobStatus.isOK()) {
                /* extract route guid */
                route = jobStatus.getJsonData();
                routeGUID = route.getJSONObject(CFProtocolConstants.V2_KEY_METADATA)
                        .getString(CFProtocolConstants.V2_KEY_GUID);

                /* attach route to application */
                AttachRouteCommand attachRoute = new AttachRouteCommand(target, getApplication(), routeGUID);
                jobStatus = (ServerStatus) attachRoute.doIt(); /* FIXME: unsafe type cast */
                status.add(jobStatus);

                if (jobStatus.isOK())
                    return status;

                /* the route is bound to another space */
                String msg = NLS.bind("The host {0} is already used in another space.",
                        findRouteCommand.getAppHost());
                status.add(new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_CONFLICT, msg, null));
                return status;
            }

            /* create a new route */
            CreateRouteCommand createRoute = new CreateRouteCommand(target, domain, getApplication());
            jobStatus = (ServerStatus) createRoute.doIt(); /* FIXME: unsafe type cast */
            status.add(jobStatus);

            if (!jobStatus.isOK())
                return status;

            /* extract route guid */
            route = jobStatus.getJsonData();
            routeGUID = route.getJSONObject(CFProtocolConstants.V2_KEY_METADATA)
                    .getString(CFProtocolConstants.V2_KEY_GUID);

            /* attach route to application */
            AttachRouteCommand attachRoute = new AttachRouteCommand(target, getApplication(), routeGUID);
            jobStatus = (ServerStatus) attachRoute.doIt(); /* FIXME: unsafe type cast */
            status.add(jobStatus);

            if (!jobStatus.isOK())
                return status;

            return status;

        } catch (Exception e) {
            String msg = NLS.bind("An error occured when performing operation {0}", commandName); //$NON-NLS-1$
            logger.error(msg, e);
            status.add(new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e));
            return status;
        }
    }

    @Override
    protected IStatus validateParams() {
        try {
            /* read deploy parameters */
            ManifestParseTree manifest = getApplication().getManifest();
            ManifestParseTree app = manifest.get("applications").get(0); //$NON-NLS-1$

            /* optional */
            ManifestParseTree domainNode = app.getOpt(CFProtocolConstants.V2_KEY_DOMAIN);
            appDomain = (domainNode != null) ? domainNode.getValue() : ""; //$NON-NLS-1$

            ManifestParseTree noRouteNode = app.getOpt(CFProtocolConstants.V2_KEY_NO_ROUTE);
            noRoute = (noRouteNode != null) ? Boolean.parseBoolean(noRouteNode.getValue()) : false;

            return Status.OK_STATUS;

        } catch (InvalidAccessException e) {
            return new MultiServerStatus(
                    new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, e.getMessage(), null));
        }
    }
}