All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ee.jakarta.tck.concurrent.spec.Platform.anno.AnnotationTestBean Maven / Gradle / Ivy

/*
 * Copyright (c) 2024 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */
package ee.jakarta.tck.concurrent.spec.Platform.anno;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import ee.jakarta.tck.concurrent.common.context.IntContext;
import ee.jakarta.tck.concurrent.common.context.StringContext;
import jakarta.ejb.EJBException;
import jakarta.ejb.Local;
import jakarta.ejb.Stateless;
import jakarta.enterprise.concurrent.ManagedScheduledExecutorService;
import jakarta.enterprise.concurrent.ManagedThreadFactory;

@Local(AnnotationTestBeanInterface.class)
@Stateless
public class AnnotationTestBean implements AnnotationTestBeanInterface {
    private static final long MAX_WAIT_SECONDS = TimeUnit.MINUTES.toSeconds(2);

    @Override
    public void testAnnotationDefinesManagedScheduledExecutor() {
        try {
            LinkedBlockingQueue started = new LinkedBlockingQueue();
            CountDownLatch taskCanEnd = new CountDownLatch(1);

            Callable task = () -> {
                started.add(IntContext.get());
                assertTrue(taskCanEnd.await(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
                return StringContext.get();
            };

            ManagedScheduledExecutorService executor = InitialContext
                    .doLookup("java:app/concurrent/ScheduledExecutorE");

            IntContext.set(3000);

            StringContext.set("testAnnotationDefinesManagedScheduledExecutor-1");
            Future future1 = executor.submit(task);

            StringContext.set("testAnnotationDefinesManagedScheduledExecutor-2");
            Future future2 = executor.submit(task);

            StringContext.set("testAnnotationDefinesManagedScheduledExecutor-3");
            Future future3 = executor.submit(task);

            StringContext.set("testAnnotationDefinesManagedScheduledExecutor-4");

            // 2 can start per max-async
            assertEquals(Integer.valueOf(0), started.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
            assertEquals(Integer.valueOf(0), started.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
            assertEquals(null, started.poll(1, TimeUnit.SECONDS));

            taskCanEnd.countDown();

            assertEquals("testAnnotationDefinesManagedScheduledExecutor-1",
                    future1.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
            assertEquals("testAnnotationDefinesManagedScheduledExecutor-2",
                    future2.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
            assertEquals("testAnnotationDefinesManagedScheduledExecutor-3",
                    future3.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS));

            assertEquals(Integer.valueOf(0), started.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
        } catch (ExecutionException | InterruptedException | NamingException | TimeoutException x) {
            throw new EJBException(x);
        } finally {
            IntContext.set(0);
            StringContext.set(null);
        }
    }

    @Override
    public void testAnnotationDefinesManagedThreadFactory() {
        try {
            IntContext.set(4000);
            StringContext.set("testAnnotationDefinesManagedThreadFactory-1");

            ManagedThreadFactory threadFactory = (ManagedThreadFactory) InitialContext
                    .doLookup("java:app/concurrent/ThreadFactoryE");

            StringContext.set("testAnnotationDefinesManagedThreadFactory-2");

            LinkedBlockingQueue results = new LinkedBlockingQueue<>();

            Thread thread = threadFactory.newThread(() -> {
                results.add(Thread.currentThread().getPriority());
                results.add(IntContext.get());
                results.add(StringContext.get());
                try {
                    results.add(InitialContext.doLookup("java:app/concurrent/ThreadFactoryE"));
                } catch (Exception x) {
                    results.add(x);
                }
            });

            assertEquals(6, thread.getPriority()); // configured value on managed-thread-factory

            thread.start();

            // priority from managed-thread-factory
            assertEquals(Integer.valueOf(6), results.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS));
            assertEquals(Integer.valueOf(0), results.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS)); // IntContext cleared
            assertEquals("testAnnotationDefinesManagedThreadFactory-1",
                    results.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS)); // propagated
            Object lookupResult = results.poll(MAX_WAIT_SECONDS, TimeUnit.SECONDS);
            if (lookupResult instanceof Exception)
                throw new EJBException((Exception) lookupResult);
            assertNotNull(lookupResult);

        } catch (InterruptedException | NamingException x) {
            throw new EJBException(x);
        } finally {
            IntContext.set(0);
            StringContext.set(null);
        }
    }
}