Package org.zanata.async

Source Code of org.zanata.async.AsyncTaskManager$RunnableOperation

/*
* Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.async;

import java.security.Principal;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.annotation.Nonnull;
import javax.security.auth.Subject;

import lombok.extern.slf4j.Slf4j;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.security.RunAsOperation;
import org.zanata.action.AuthenticationEvents;
import org.zanata.dao.AccountDAO;
import org.zanata.model.HAccount;
import org.zanata.security.ZanataIdentity;
import org.zanata.security.ZanataJpaIdentityStore;
import org.zanata.util.ServiceLocator;

import com.google.common.util.concurrent.ListenableFuture;

/**
* @author Carlos Munoz <a
*         href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
@Name("asyncTaskManager")
@Scope(ScopeType.APPLICATION)
@AutoCreate
@Slf4j
public class AsyncTaskManager {

    private ExecutorService scheduler;

    @Create
    public void init() {
        scheduler = Executors.newFixedThreadPool(3);
    }

    @Destroy
    public void cleanup() {
        scheduler.shutdown();
    }

    public <V> ListenableFuture<V> startTask(
            final @Nonnull AsyncTask<Future<V>> task) {
        HAccount taskOwner = ServiceLocator.instance()
                .getInstance(ZanataJpaIdentityStore.AUTHENTICATED_USER,
                        HAccount.class);
        ZanataIdentity ownerIdentity = ZanataIdentity.instance();

        // Extract security context from current thread
        final String taskOwnerUsername =
                taskOwner != null ? taskOwner.getUsername() : null;
        final Principal runAsPpal = ownerIdentity.getPrincipal();
        final Subject runAsSubject = ownerIdentity.getSubject();

        // final result
        final AsyncTaskResult<V> taskFuture = new AsyncTaskResult<V>();

        final RunnableOperation runnableOp = new RunnableOperation() {

            @Override
            public void execute() {
                try {
                    prepareSecurityContext(taskOwnerUsername);
                    V returnValue = getReturnValue(task.call());
                    taskFuture.set(returnValue);
                } catch (Throwable t) {
                    taskFuture.setException(t);
                    log.error(
                            "Exception when executing an asynchronous task.", t);
                }
            }

            @Override
            public Principal getPrincipal() {
                return runAsPpal;
            }

            @Override
            public Subject getSubject() {
                return runAsSubject;
            }
        };
        scheduler.execute(runnableOp);
        return taskFuture;
    }

    private static <V> V getReturnValue(Future<V> asyncTaskFuture)
            throws Exception {
        // If the async method returns void
        if (asyncTaskFuture == null) {
            return null;
        }
        return asyncTaskFuture.get();
    }

    /**
     * Prepares the Drools security context so that it contains all the
     * necessary facts for security checking.
     */
    private static void prepareSecurityContext(String username) {
        /*
         * TODO This should be changed to not need the username. There should be
         * a way to simulate a login for asyn tasks, or at least to inherit the
         * caller's context
         */
        if (username != null) {
            // Only if it's an authenticated task should it try and do this
            // injection
            AccountDAO accountDAO =
                    ServiceLocator.instance().getInstance(AccountDAO.class);
            ZanataJpaIdentityStore idStore =
                    ServiceLocator.instance().getInstance(
                            ZanataJpaIdentityStore.class);
            AuthenticationEvents authEvts =
                    ServiceLocator.instance().getInstance(
                            AuthenticationEvents.class);
            HAccount authenticatedAccount = accountDAO.getByUsername(username);
            idStore.setAuthenticateUser(authenticatedAccount);
        }
    }

    public abstract class RunnableOperation extends RunAsOperation implements
            Runnable {

        @Override
        public void run() {
            Lifecycle.beginCall(); // Start contexts
            super.run();
            Lifecycle.endCall(); // End contexts
        }
    }

}
TOP

Related Classes of org.zanata.async.AsyncTaskManager$RunnableOperation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.