org.nimbustools.ctxbroker.service.ContextBrokerServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.nimbustools.ctxbroker.service.ContextBrokerServiceImpl.java

Source

/*
 * Copyright 1999-2008 University of Chicago
 *
 * 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 org.nimbustools.ctxbroker.service;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis.message.addressing.EndpointReferenceType;

import org.nimbustools.ctxbroker.generated.gt4_0.types.VoidType;
import org.nimbustools.ctxbroker.generated.gt4_0.types.RetrieveResponse_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.InjectData_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.ErrorExitingSend_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.OkExitingSend_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.InjectData_TypeData;
import org.nimbustools.ctxbroker.generated.gt4_0.types.IdentitiesResponse_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.IdentitiesSend_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.CreateContextResponse_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.types.CreateContext_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.description.IdentityProvides_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.description.Requires_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.description.BrokerContactType;
import org.nimbustools.ctxbroker.generated.gt4_0.description.AgentDescription_Type;
import org.nimbustools.ctxbroker.generated.gt4_0.broker.NimbusContextualizationFault;
import org.nimbustools.ctxbroker.BrokerConstants;
import org.nimbustools.ctxbroker.ContextBrokerException;

import org.globus.wsrf.Constants;
import org.globus.wsrf.ResourceContext;
import org.globus.wsrf.security.SecurityManager;
import org.nimbustools.ctxbroker.rest.RestHttp;

import javax.naming.InitialContext;
import java.io.File;

public class ContextBrokerServiceImpl implements ContextBrokerService {

    // -------------------------------------------------------------------------
    // STATIC VARIABLES
    // -------------------------------------------------------------------------

    private static final Log logger = LogFactory.getLog(ContextBrokerServiceImpl.class.getName());

    public static final String CONTEXTUALIZATION_HOME = Constants.JNDI_SERVICES_BASE_NAME
            + BrokerConstants.CTX_BROKER_PATH + "/home";

    public static final String REST_HTTP = Constants.JNDI_SERVICES_BASE_NAME + BrokerConstants.CTX_BROKER_PATH
            + "/rest";

    // -------------------------------------------------------------------------
    // INSTANCE VARIABLES
    // -------------------------------------------------------------------------

    private final ContextBrokerHome home;
    private final RestHttp restHttp;

    // -------------------------------------------------------------------------
    // CONSTRUCTOR
    // -------------------------------------------------------------------------

    public ContextBrokerServiceImpl() throws Exception {
        this.home = discoverHome();
        this.restHttp = discoverRestHttp();
    }

    protected static ContextBrokerHome discoverHome() throws Exception {

        InitialContext ctx = null;
        try {
            ctx = new InitialContext();

            final ContextBrokerHome home = (ContextBrokerHome) ctx.lookup(CONTEXTUALIZATION_HOME);

            if (home == null) {
                throw new Exception("null from JNDI for ContextBrokerHome (?)");
            }

            return home;

        } finally {
            if (ctx != null) {
                ctx.close();
            }
        }
    }

    protected static RestHttp discoverRestHttp() throws Exception {

        InitialContext ctx = null;
        try {
            ctx = new InitialContext();

            final RestHttp rest = (RestHttp) ctx.lookup(REST_HTTP);

            if (rest == null) {
                throw new Exception("null from JNDI for RestHttp (?)");
            }

            return rest;

        } finally {
            if (ctx != null) {
                ctx.close();
            }
        }
    }

    // -------------------------------------------------------------------------
    // implements ContextBrokerService
    // -------------------------------------------------------------------------

    public CreateContextResponse_Type create(CreateContext_Type create) throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();
        logger.info("WS-CTX-CREATE invoked by " + caller);

        if (caller == null || caller.trim().length() == 0) {
            throw ContextFault.makeCtxFault("WS-CTX-CREATE caller is empty (?)", null);
        }

        boolean expectInjections = false;
        if (create != null && create.isExpectInjections()) {
            expectInjections = true;
        }

        try {
            final EndpointReferenceType ref = this.home.createNewResource(caller, expectInjections);
            final String id = this.home.getResourceKey(ref).toString();

            final CreateContextResponse_Type resp = new CreateContextResponse_Type();
            resp.setContextEPR(ref);
            resp.setContact(new BrokerContactType(this.home.getBrokerURL(), id, this.home.getContextSecret(ref)));

            return resp;

        } catch (ContextBrokerException e) {
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }
    }

    public VoidType injectdata(InjectData_Type sent) throws NimbusContextualizationFault {

        if (sent == null) {
            throw ContextFault.makeCtxFault("sent empty input", null);
        }

        final InjectData_TypeData[] datas = sent.getData();
        if (datas == null || datas.length == 0) {
            throw ContextFault.makeCtxFault("sent empty input", null);
        }

        final String caller = SecurityManager.getManager().getCaller();
        logger.info("WS-CTX-INJECT-DATA invoked by " + caller);

        if (caller == null || caller.trim().length() == 0) {
            logger.trace("WS-CTX-INJECT-DATA caller is empty", null);
        }

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        // Dirty, but lets us have one resource with one policy (bootstrap
        // credential still gets access to retrieve).
        if (caller == null || !caller.equals(resource.getCreatorDN())) {
            logger.info("WS-CTX-INJECT-DATA unauthorized " + "-- invoked by " + caller);
            throw ContextFault.makeCtxFault("unauthorized", null);
        }

        for (InjectData_TypeData data : datas) {
            try {
                resource.injectData(data.getName(), data.get_value());
            } catch (ContextBrokerException e) {
                if (logger.isDebugEnabled()) {
                    logger.error(e.getMessage(), e);
                } else {
                    logger.error(e.getMessage());
                }
                throw ContextFault.makeCtxFault(e.getMessage(), null);
            }
        }
        return new VoidType();
    }

    public VoidType errorExiting(ErrorExitingSend_Type sent) throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();

        IdentityProvides_Type[] identities;
        Integer id = null;
        StringBuffer buf;

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        buf = new StringBuffer();
        buf.append("WS-CTX-ERROR-EXITING invoked by '").append(caller).append("' (");
        if (sent != null) {
            identities = sent.getIdentity();
            if (identities == null) {
                buf.append("identities is null");
            } else {
                id = this.getID(resource, identities, null);
                if (id != null) {
                    buf.append("identities map to #").append(id);
                } else {
                    buf.append("identities don't map to a known ID");
                }
            }
        } else {
            buf.append("sent envelope is null");
        }
        buf.append(")");
        logger.error(buf.toString());

        if (sent == null) {
            throw ContextFault.makeCtxFault("empty input", null);
        }

        if (id == null) {
            throw ContextFault.makeCtxFault("cannot resolve WS-CTX-ERROR-EXITING caller", null);
        }

        try {
            resource.errorExit(id, sent.getErrorcode(), sent.getMessage());
        } catch (ContextBrokerException e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }
        return new VoidType();
    }

    public VoidType okExiting(OkExitingSend_Type sent) throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();

        IdentityProvides_Type[] identities;
        Integer id = null;
        StringBuffer buf = null;

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        // this is debug level because it would be overwhelming in anything
        // but test situations
        if (logger.isDebugEnabled()) {
            buf = new StringBuffer();
            buf.append("WS-CTX-OK-EXITING invoked by '").append(caller).append("' (");
            if (sent != null) {
                identities = sent.getIdentity();
                if (identities == null) {
                    buf.append("identities is null");
                } else {
                    id = this.getID(resource, identities, null);
                    if (id != null) {
                        buf.append("identities map to #").append(id);
                    } else {
                        buf.append("identities don't map to a known ID");
                    }
                }
            } else {
                buf.append("sent envelope is null");
            }
            buf.append(")");
            logger.debug(buf.toString());
        }

        if (sent == null) {
            throw ContextFault.makeCtxFault("empty input", null);
        }

        if (buf == null) {
            identities = sent.getIdentity();
            id = this.getID(resource, identities, null);
        }

        if (id == null) {
            throw ContextFault.makeCtxFault("cannot resolve WS-CTX-OK-EXITING caller", null);
        }

        try {
            resource.okExit(id);
        } catch (ContextBrokerException e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }
        return new VoidType();
    }

    public VoidType noMoreInjections(VoidType none)

            throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();
        logger.info("WS-NO-MORE-INJECTIONS invoked by " + caller);

        if (caller == null || caller.trim().length() == 0) {
            logger.trace("WS-NO-MORE-INJECTIONS caller is empty", null);
        }

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        // Dirty, but lets us have one resource with one policy (bootstrap
        // credential still gets access to retrieve).
        //
        // Caller can be null so that an internal service thread can lock
        // if need be.
        if (caller != null && !caller.equals(resource.getCreatorDN())) {
            logger.info("WS-NO-MORE-INJECTIONS unauthorized " + "-- invoked by " + caller);
            throw ContextFault.makeCtxFault("unauthorized", null);
        }

        try {
            resource.noMoreInjections();
        } catch (ContextBrokerException e) {
            throw ContextFault.makeCtxFault(e.getMessage(), e);
        }

        return new VoidType();
    }

    public RetrieveResponse_Type retrieve(AgentDescription_Type sent)

            throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();

        IdentityProvides_Type[] identities = null;
        Integer id = null;
        StringBuffer buf = null;

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        // this is debug level because it would be overwhelming in anything
        // but test situations
        if (logger.isDebugEnabled()) {
            buf = new StringBuffer();
            buf.append("WS-CTX-RETRIEVE invoked by '").append(caller).append("' (");
            if (sent != null) {
                identities = sent.getIdentity();
                if (identities == null) {
                    buf.append("identities is null");
                } else {
                    id = this.getID(resource, identities, sent);
                    if (id != null) {
                        buf.append("identities map to #").append(id);
                    } else {
                        buf.append("identities don't map to a known ID");
                    }
                }
            } else {
                buf.append("sent envelope is null");
            }
            buf.append(")");
            logger.debug(buf.toString());
        }

        if (sent == null) {
            throw ContextFault.makeCtxFault("empty input", null);
        }

        if (buf == null) {
            identities = sent.getIdentity();
            id = this.getID(resource, identities, sent);
        }

        if (id == null) {
            throw ContextFault.makeCtxFault("broker cannot resolve this caller's identity", null);
        }

        final Requires_Type requires;
        try {
            requires = resource.retrieve(id);
        } catch (ContextBrokerException e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        final RetrieveResponse_Type response = new RetrieveResponse_Type();

        // For now we take requires being null to mean node is not complete.
        // If resource is not locked we are also currently not answering.
        // i.e., no partial answers.  Also for now.

        if (requires == null) {
            //requires = new Requires_Type();
            //requires.setIdentity(null);
            //requires.setRole(null);
            response.setComplete(false);
        } else {
            response.setComplete(true);
        }

        response.setNoMoreInjections(resource.isNoMoreInjections());
        response.setRequires(requires);

        return response;
    }

    public IdentitiesResponse_Type identities(IdentitiesSend_Type sent) throws NimbusContextualizationFault {

        final String caller = SecurityManager.getManager().getCaller();

        final ContextBrokerResource resource;
        try {
            resource = getResource();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        boolean all = false;
        String host = null;
        String ip = null;
        if (sent != null) {
            if (sent.getAll() != null) {
                all = sent.getAll();
            }
            host = sent.getHost();
            ip = sent.getIp();
        }

        StringBuffer buf;

        buf = new StringBuffer();
        buf.append("WS-CTX-IDENTITIES invoked by '").append(caller).append("' (");
        if (sent != null) {
            buf.append("all: ").append(all).append(", host: '").append(host).append("', ip: '").append(ip)
                    .append("'");
        } else {
            buf.append("sent envelope is null");
        }
        buf.append(")");
        logger.info(buf.toString());

        final IdentitiesResponse_Type response = new IdentitiesResponse_Type();
        try {
            if (all) {
                response.setNode(resource.identityQueryAll());
            } else if (host != null) {
                response.setNode(resource.identityQueryHost(host));
            } else if (ip != null) {
                response.setNode(resource.identityQueryIP(ip));
            } else {
                throw ContextFault.makeCtxFault("nothing queried?", null);
            }
        } catch (ContextBrokerException e) {
            if (logger.isDebugEnabled()) {
                logger.error(e.getMessage(), e);
            } else {
                logger.error(e.getMessage());
            }
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }

        return response;
    }

    // -------------------------------------------------------------------------
    // OTHER
    // -------------------------------------------------------------------------

    private Integer getID(ContextBrokerResource resource, IdentityProvides_Type[] identities,
            AgentDescription_Type sent) throws NimbusContextualizationFault {

        // every single query from an agent must contain identities
        if (identities == null || identities.length == 0) {
            logger.error("Caller did not send identities.");
            return null;
        }

        try {
            return this.home.getID(resource, identities, sent);
        } catch (ContextBrokerException e) {
            logger.error(e.getMessage(), e);
            throw ContextFault.makeCtxFault(e.getMessage(), null);
        }
    }

    private static ContextBrokerResource getResource() throws Exception {

        try {
            final ResourceContext context = ResourceContext.getResourceContext();
            return (ContextBrokerResource) context.getResource();
        } catch (Exception e) {
            final String err = "could not find that context";
            logger.error(err, e);
            throw new Exception(err, e);
        }
    }
}