Package org.geoserver.threadlocals

Source Code of org.geoserver.threadlocals.ThreadLocalsTransferTest$ThreadLocalTransferCallable

package org.geoserver.threadlocals;

import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.catalog.impl.WorkspaceInfoImpl;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.ows.Dispatcher;
import org.geoserver.ows.LocalLayer;
import org.geoserver.ows.LocalWorkspace;
import org.geoserver.ows.Request;
import org.geoserver.security.AdminRequest;
import org.geoserver.test.GeoServerSystemTestSupport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class ThreadLocalsTransferTest extends GeoServerSystemTestSupport {

    protected ExecutorService executor;

    @Override
    protected void setUpTestData(SystemTestData testData) throws Exception {
        // no test data needed for this test, only the spring context
    }

    @Before
    public void setupExecutor() {
        executor = Executors.newCachedThreadPool();
    }

    @After
    public void stopExecutor() {
        executor.shutdown();
    }
   
    @After
    public void cleanupThreadLocals() {
        Dispatcher.REQUEST.remove();
        AdminRequest.finish();
        LocalLayer.remove();
        LocalWorkspace.remove();
        SecurityContextHolder.getContext().setAuthentication(null);
    }
   

    @Test
    public void testThreadLocalTransfer() throws InterruptedException, ExecutionException {
        final Request request = new Request();
        Dispatcher.REQUEST.set(request);
        final LayerInfo layer = new LayerInfoImpl();
        LocalLayer.set(layer);
        final WorkspaceInfo ws = new WorkspaceInfoImpl();
        LocalWorkspace.set(ws);
        final Object myState = new Object();
        AdminRequest.start(myState);
        final Authentication auth = new UsernamePasswordAuthenticationToken("user", "password");
        SecurityContextHolder.getContext().setAuthentication(auth);
        final ThreadLocalsTransfer transfer = new ThreadLocalsTransfer();
        Future<Void> future = executor.submit(new Callable<Void>() {

            @Override
            public Void call() throws Exception {
                testApply();
                testCleanup();
                return null;
            }

            private void testApply() {
                transfer.apply();

                // check all thread locals have been applied to the current thread
                assertSame(request, Dispatcher.REQUEST.get());
                assertSame(myState, AdminRequest.get());
                assertSame(layer, LocalLayer.get());
                assertSame(ws, LocalWorkspace.get());
                assertSame(auth, SecurityContextHolder.getContext().getAuthentication());
            }

            private void testCleanup() {
                transfer.cleanup();

                // check all thread locals have been cleaned up from the current thread
                assertNull(Dispatcher.REQUEST.get());
                assertNull(AdminRequest.get());
                assertNull(LocalLayer.get());
                assertNull(LocalWorkspace.get());
                assertNull(SecurityContextHolder.getContext().getAuthentication());
            }

        });
        future.get();
    }

    protected abstract static class ThreadLocalTransferCallable implements Callable<Void> {

        Thread originalThread;

        ThreadLocalTransfer transfer;

        Map<String, Object> storage = new HashMap<String, Object>();

        public ThreadLocalTransferCallable(ThreadLocalTransfer transfer) {
            this.originalThread = Thread.currentThread();
            this.transfer = transfer;
            this.transfer.collect(storage);
        }

        @Override
        public Void call() throws Exception {
            // this is the the main thread, we are actually running inside the thread pool
            assertNotEquals(originalThread, Thread.currentThread());

            // apply the thread local, check it has been applied correctly
            transfer.apply(storage);
            assertThreadLocalApplied();

            // clean up, check the therad local is now empty
            transfer.cleanup();
            assertThreadLocalCleaned();

            return null;
        }

        abstract void assertThreadLocalCleaned();

        abstract void assertThreadLocalApplied();

    };
}
TOP

Related Classes of org.geoserver.threadlocals.ThreadLocalsTransferTest$ThreadLocalTransferCallable

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.