diff --git a/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/impl/util/ClusteredSingletonLookupImplBase.java b/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/impl/util/ClusteredSingletonLookupImplBase.java index b992b28b64e..e4828842ff6 100644 --- a/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/impl/util/ClusteredSingletonLookupImplBase.java +++ b/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/impl/util/ClusteredSingletonLookupImplBase.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -57,14 +57,15 @@ * @author lprimak */ public abstract class ClusteredSingletonLookupImplBase implements ClusteredSingletonLookup { - private final HazelcastCore hzCore = Globals.getDefaultHabitat().getService(HazelcastCore.class); private final String componentId; private final SingletonType singletonType; private final String keyPrefix; private final String mapKey; private final AtomicReference sessionHzKey = new AtomicReference<>(); - private final AtomicReference lockKey = new AtomicReference<>(); + private final AtomicReference lock = new AtomicReference<>(); + private final AtomicReference count = new AtomicReference<>(); + public ClusteredSingletonLookupImplBase(String componentId, SingletonType singletonType) { this.componentId = componentId; @@ -81,26 +82,13 @@ protected final String getMapKey() { return mapKey; } - protected final String getLockKey() { - return lockKey.updateAndGet(v -> v != null ? v : makeLockKey()); - } - public final String getSessionHzKey() { return sessionHzKey.updateAndGet(v -> v != null ? v : makeSessionHzKey()); } - /** - * {@link #getSessionHzKey()} and {@link #getLockKey()} are dependent on {@link #getClusteredSessionKey()} so should - * its value change cache keys need to be invalidated using this method. - */ - protected final void invalidateKeys() { - sessionHzKey.set(null); - lockKey.set(null); - } - @Override public ILock getDistributedLock() { - return getHazelcastInstance().getLock(getLockKey()); + return lock.updateAndGet(v -> v != null ? v : getHazelcastInstance().getLock(makeLockKey())); } @Override @@ -109,8 +97,8 @@ public IMap getClusteredSingletonMap() { } @Override - public IAtomicLong getClusteredUsageCount() { - return getHazelcastInstance().getAtomicLong(getSessionHzKey()+ "/count"); + public IAtomicLong getClusteredUsageCount() { + return count.updateAndGet(v -> v != null ? v : getHazelcastInstance().getAtomicLong(makeCountKey())); } private HazelcastInstance getHazelcastInstance() { @@ -130,6 +118,19 @@ public boolean isDistributedLockEnabled() { return isClusteredEnabled(); } + @Override + public void destroy() { + getClusteredSingletonMap().delete(getClusteredSessionKey()); + + // CP locks and AtomicLong's can't be destroyed, as per https://github.com/hazelcast/hazelcast/issues/17498 + // so we just release the references to them and reset to zero where we can + lock.set(null); + IAtomicLong oldCountValue = count.getAndSet(null); + if (oldCountValue != null) { + oldCountValue.set(0); + } + } + @Override public HazelcastCore getHazelcastCore() { return hzCore; @@ -147,6 +148,10 @@ private String makeLockKey() { return getSessionHzKey() + "/lock"; } + private String makeCountKey() { + return getSessionHzKey() + "/count"; + } + private String makeSessionHzKey() { return getKeyPrefix() + componentId + "/" + getClusteredSessionKey(); } diff --git a/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/spi/ClusteredSingletonLookup.java b/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/spi/ClusteredSingletonLookup.java index b74653d9d92..caa8fc667d0 100644 --- a/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/spi/ClusteredSingletonLookup.java +++ b/appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/spi/ClusteredSingletonLookup.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2018] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -57,6 +57,10 @@ public interface ClusteredSingletonLookup { String getClusteredSessionKey(); boolean isClusteredEnabled(); IAtomicLong getClusteredUsageCount(); + /** + * destroys usage count and distributed lock objects + */ + void destroy(); HazelcastCore getHazelcastCore(); enum SingletonType { diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/AbstractSingletonContainer.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/AbstractSingletonContainer.java index 1daa6b011b5..12dfe41829e 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/AbstractSingletonContainer.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/AbstractSingletonContainer.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2020] [Payara Foundation and/or its affiliates] package com.sun.ejb.containers; @@ -121,7 +121,7 @@ public abstract class AbstractSingletonContainer extends BaseContainer { private final InvocationInfo postConstructInvInfo; private final InvocationInfo preDestroyInvInfo; - protected final ClusteredSingletonLookup clusteredLookup = // + protected final ClusteredSingletonLookup clusteredLookup = new ClusteredSingletonLookupImpl(ejbDescriptor, componentId); @@ -712,8 +712,7 @@ public void destroy(Object obj) { EjbSessionDescriptor sessDesc = (EjbSessionDescriptor) ejbDescriptor; IAtomicLong count = clusteredLookup.getClusteredUsageCount(); if (count.decrementAndGet() <= 0) { - clusteredLookup.getClusteredSingletonMap().delete(clusteredLookup.getClusteredSessionKey()); - count.destroy(); + clusteredLookup.destroy(); } else if (sessDesc.dontCallPreDestroyOnDetach()) { doPreDestroy = false; } diff --git a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopeContext.java b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopeContext.java index 873e5b672b3..e4c7322e09c 100644 --- a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopeContext.java +++ b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopeContext.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -121,12 +121,12 @@ private TT getFromApplicationScoped(Contextual contextual, Optional Clustered getAnnotation(BeanManager beanManager, Class clazz) { return CdiUtils.getAnnotation(beanManager, clazz, Clustered.class).get(); } - private static String firstNonNull(String... items) { + static String firstNonNull(String... items) { for (String i : items) { if (i != null && !i.trim().isEmpty()) { return i; diff --git a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopedInterceptor.java b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopedInterceptor.java index f52ed943514..0676e8c94d7 100644 --- a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopedInterceptor.java +++ b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusterScopedInterceptor.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -44,7 +44,6 @@ import fish.payara.cluster.DistributedLockType; import static fish.payara.micro.cdi.extension.cluster.ClusterScopeContext.getAnnotation; import static fish.payara.micro.cdi.extension.cluster.ClusterScopeContext.getBeanName; -import fish.payara.micro.cdi.extension.cluster.annotations.ClusterScoped; import fish.payara.micro.cdi.extension.cluster.annotations.ClusterScopedIntercepted; import java.io.IOException; import java.io.ObjectInputStream; @@ -53,7 +52,6 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Priority; -import javax.enterprise.context.spi.Context; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.CDI; @@ -88,7 +86,7 @@ public Object lockAndRefresh(InvocationContext invocationContext) throws Excepti return invocationContext.proceed(); } finally { - refresh(beanClass); + refresh(beanClass, invocationContext.getTarget()); unlock(beanClass, clusteredAnnotation); } } @@ -96,7 +94,8 @@ public Object lockAndRefresh(InvocationContext invocationContext) throws Excepti @PostConstruct Object postConstruct(InvocationContext invocationContext) throws Exception { Class beanClass = invocationContext.getTarget().getClass().getSuperclass(); - clusteredLookup.setClusteredSessionKey(beanClass); + Clustered clusteredAnnotation = getAnnotation(beanManager, beanClass); + clusteredLookup.setClusteredSessionKeyIfNotSet(beanClass, clusteredAnnotation); clusteredLookup.getClusteredUsageCount().incrementAndGet(); return invocationContext.proceed(); } @@ -105,11 +104,10 @@ Object postConstruct(InvocationContext invocationContext) throws Exception { Object preDestroy(InvocationContext invocationContext) throws Exception { Class beanClass = invocationContext.getTarget().getClass().getSuperclass(); Clustered clusteredAnnotation = getAnnotation(beanManager, beanClass); - clusteredLookup.setClusteredSessionKey(beanClass); + clusteredLookup.setClusteredSessionKeyIfNotSet(beanClass, clusteredAnnotation); IAtomicLong count = clusteredLookup.getClusteredUsageCount(); if (count.decrementAndGet() <= 0) { - clusteredLookup.getClusteredSingletonMap().delete(clusteredLookup.getClusteredSessionKey()); - count.destroy(); + clusteredLookup.destroy(); } else if (!clusteredAnnotation.callPreDestoyOnDetach()) { return null; } @@ -119,27 +117,26 @@ Object preDestroy(InvocationContext invocationContext) throws Exception { private void lock(Class beanClass, Clustered clusteredAnnotation) { if (clusteredAnnotation.lock() == DistributedLockType.LOCK) { - clusteredLookup.setClusteredSessionKey(beanClass); + clusteredLookup.setClusteredSessionKeyIfNotSet(beanClass, clusteredAnnotation); clusteredLookup.getDistributedLock().lock(); } } private void unlock(Class beanClass, Clustered clusteredAnnotation) { if (clusteredAnnotation.lock() == DistributedLockType.LOCK) { - clusteredLookup.setClusteredSessionKey(beanClass); + clusteredLookup.setClusteredSessionKeyIfNotSet(beanClass, clusteredAnnotation); clusteredLookup.getDistributedLock().unlock(); } } - private void refresh(Class beanClass) { + private void refresh(Class beanClass, Object instance) { Set> managedBeans = beanManager.getBeans(beanClass); if (managedBeans.size() > 1) { throw new IllegalArgumentException("Multiple beans found for " + beanClass); } Bean bean = managedBeans.iterator().next(); String beanName = getBeanName(bean, getAnnotation(beanManager, bean)); - Context ctx = beanManager.getContext(ClusterScoped.class); - clusteredLookup.getClusteredSingletonMap().put(beanName, ctx.get(bean)); + clusteredLookup.getClusteredSingletonMap().set(beanName, instance); } private void init() { diff --git a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusteredSingletonLookupImpl.java b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusteredSingletonLookupImpl.java index 6a34071061b..8e2d261e8b6 100644 --- a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusteredSingletonLookupImpl.java +++ b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/cluster/ClusteredSingletonLookupImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2018] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -41,9 +41,11 @@ import com.sun.enterprise.container.common.impl.util.ClusteredSingletonLookupImplBase; import static com.sun.enterprise.container.common.spi.ClusteredSingletonLookup.SingletonType.CDI; +import fish.payara.cluster.Clustered; import static fish.payara.micro.cdi.extension.cluster.ClusterScopeContext.getAnnotation; import static fish.payara.micro.cdi.extension.cluster.ClusterScopeContext.getBeanName; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; @@ -53,9 +55,8 @@ * @author lprimak */ public class ClusteredSingletonLookupImpl extends ClusteredSingletonLookupImplBase { - private final BeanManager beanManager; - private final ThreadLocal sessionKey = new ThreadLocal<>(); + private final AtomicReference sessionKey = new AtomicReference<>(); public ClusteredSingletonLookupImpl(BeanManager beanManager, String componentId) { super(componentId, CDI); @@ -67,15 +68,19 @@ public String getClusteredSessionKey() { return sessionKey.get(); } - void setClusteredSessionKey(Class beanClass) { + void setClusteredSessionKeyIfNotSet(Class beanClass, Clustered clusteredAnnotation) { + sessionKey.updateAndGet(v -> v != null ? v : makeSessionKey(beanClass, clusteredAnnotation)); + } + + private String makeSessionKey(Class beanClass, Clustered clusteredAnnotation) { Set> managedBeans = beanManager.getBeans(beanClass); if (managedBeans.size() > 1) { throw new IllegalArgumentException("Multiple beans found for " + beanClass); } if (managedBeans.size() == 1) { Bean bean = managedBeans.iterator().next(); - sessionKey.set(getBeanName(bean, getAnnotation(beanManager, bean))); - invalidateKeys(); + return getBeanName(bean, getAnnotation(beanManager, bean)); } + return ClusterScopeContext.firstNonNull(clusteredAnnotation.keyName(), beanClass.getName()); } } diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/pom.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/pom.xml new file mode 100644 index 00000000000..39fd3340004 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/pom.xml @@ -0,0 +1,87 @@ + + + + 4.0.0 + clustered-singleton + war + + Payara Tests - Clustered Singleton Sample and Test + + + fish.payara.samples + clustered-singleton-parent + 5.2020.8-SNAPSHOT + + + + UTF-8 + false + + + + + jakarta.platform + jakarta.jakartaee-web-api + provided + + + fish.payara.api + payara-api + provided + + + + junit + junit + test + + + org.hamcrest + hamcrest-library + test + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI1.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI1.java new file mode 100644 index 00000000000..66d42104df3 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI1.java @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.AnnotatedSingletonAPI; +import fish.payara.cluster.Clustered; +import java.util.UUID; +import java.util.logging.Logger; +import javax.ejb.Singleton; +import javax.enterprise.inject.Vetoed; + +/** + * @author lprimak + */ +@Clustered(keyName = "ClusteredAnnotated1") +@Singleton(name = "ClusteredSingletonAnnotatedEJB1") +@Vetoed +public class ClusteredAnnotatedAPI1 implements AnnotatedSingletonAPI { + private static final Logger log = Logger.getLogger(ClusteredAnnotatedAPI1.class.getName()); + private static final long serialVersionUID = 1L; + protected final SingletonCommon sc = new SingletonCommon(this); + + @Override + public String getHello() { + return String.format("Clustered Annotated API EJB Hello (1): %s", sc); + } + + + @Override + public void randomizeState() { + this.sc.randomizeState(); + } + + @Override + public UUID getState() { + return this.sc.getState(); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI2.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI2.java new file mode 100644 index 00000000000..cf1f7c3ba0a --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredAnnotatedAPI2.java @@ -0,0 +1,62 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.AnnotatedSingletonAPI; +import fish.payara.cluster.Clustered; +import java.util.logging.Logger; +import javax.ejb.Singleton; +import javax.enterprise.inject.Vetoed; + +/** + * @author lprimak + */ +@Clustered(keyName = "ClusteredAnnotated1") +@Singleton(name = "ClusteredSingletonAnnotatedEJB2") +@Vetoed +public class ClusteredAnnotatedAPI2 extends ClusteredAnnotatedAPI1 implements AnnotatedSingletonAPI { + private static final Logger log = Logger.getLogger(ClusteredAnnotatedAPI2.class.getName()); + private static final long serialVersionUID = 1L; + + @Override + public String getHello() { + return String.format("Clustered Annotated API EJB Hello (2): %s", sc); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredEventBusStartup.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredEventBusStartup.java new file mode 100644 index 00000000000..b0f5be3a807 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredEventBusStartup.java @@ -0,0 +1,74 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.cluster.Clustered; +import fish.payara.micro.cdi.Outbound; +import java.io.Serializable; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.ejb.Schedule; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +/** + * @author lprimak + */ +@Clustered +@Singleton @Startup +public class ClusteredEventBusStartup implements Serializable { + private static final Logger log = Logger.getLogger(ClusteredEventBusStartup.class.getName()); + private static final long serialVersionUID = 1L; + private Stock stock; + private int numInvocations; + @Inject + @Outbound(loopBack = true) + private Event stockEvents; + + @Schedule(hour = "*", minute = "*", second = "*/1", persistent = false) + private void generatePrice() { + ++numInvocations; + stock = new Stock("PYA", "Some very long description of Payara", Math.random() * 100.0); + log.log(Level.INFO, "Sock: {0}, numInvocations: {1}", new Object[] { stock, numInvocations }); + stockEvents.fire(stock); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI1.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI1.java new file mode 100644 index 00000000000..0e879d521cc --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI1.java @@ -0,0 +1,88 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.SingletonAPI; +import fish.payara.cluster.Clustered; +import fish.payara.cluster.DistributedLockType; +import java.io.Serializable; +import java.util.UUID; +import java.util.logging.Logger; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Default; + +/** + * @author lprimak + */ +@ApplicationScoped +@Clustered(keyName = "ClusteredSingletonCDI1", lock = DistributedLockType.LOCK) +@Default +public class ClusteredSingletonCDI1 implements SingletonAPI, Serializable { + private static final Logger log = Logger.getLogger(ClusteredSingletonCDI1.class.getName()); + private static final long serialVersionUID = 1L; + protected final SingletonCommon sc = new SingletonCommon(this); + + @Override + public String getHello() { + return String.format("CDI Bean Hello (1): %s", sc); + } + + @PostConstruct + void postConstruct() { + log.info("CDI1 PostConstruct"); + } + + @PreDestroy + void preDestroy() { + log.info("CDI1 PreDestroy"); + } + + @Override + public void randomizeState() { + this.sc.randomizeState(); + } + + @Override + public UUID getState() { + return this.sc.getState(); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI2.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI2.java new file mode 100644 index 00000000000..d79555ca048 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonCDI2.java @@ -0,0 +1,76 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.Secondary; +import fish.payara.cluster.Clustered; +import fish.payara.cluster.DistributedLockType; +import java.util.logging.Logger; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; + +/** + * @author lprimak + */ +@ApplicationScoped +@Clustered(keyName = "ClusteredSingletonCDI1", lock = DistributedLockType.LOCK) +@Secondary +public class ClusteredSingletonCDI2 extends ClusteredSingletonCDI1 { + private static final Logger log = Logger.getLogger(ClusteredSingletonCDI2.class.getName()); + private static final long serialVersionUID = 1L; + + @Override + public String getHello() { + return String.format("CDI Bean Hello (2): %s", sc); + } + + @PostConstruct + @Override + void postConstruct() { + log.info("CDI2 PostConstruct"); + } + + @PreDestroy + @Override + void preDestroy() { + log.info("CDI2 PreDestroy"); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml.java new file mode 100644 index 00000000000..b79d8eae7cc --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml.java @@ -0,0 +1,69 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.SingletonAPI; +import java.io.Serializable; +import java.util.UUID; +import javax.enterprise.inject.Vetoed; + +/** + * @author lprimak + */ +@Vetoed +public class ClusteredSingletonEjbXml implements SingletonAPI, Serializable { + private static final long serialVersionUID = 1L; + private final SingletonCommon sc = new SingletonCommon(this); + + @Override + public String getHello() { + return String.format("Descriptor EJB Hello: %s", sc); + } + + @Override + public void randomizeState() { + this.sc.randomizeState(); + } + + @Override + public UUID getState() { + return this.sc.getState(); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml2.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml2.java new file mode 100644 index 00000000000..1e92734dfac --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonEjbXml2.java @@ -0,0 +1,54 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.SingletonAPI; +import java.io.Serializable; +import javax.enterprise.inject.Vetoed; + +/** + * + * @author lprimak + */ +@Vetoed +public class ClusteredSingletonEjbXml2 extends ClusteredSingletonEjbXml implements SingletonAPI, Serializable { + + private static final long serialVersionUID = 1L; +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonInterceptedEJB.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonInterceptedEJB.java new file mode 100644 index 00000000000..8d8bf3e2828 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/ClusteredSingletonInterceptedEJB.java @@ -0,0 +1,155 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.InterceptedSingletonAPI; +import fish.payara.samples.clustered.singleton.interceptor.ClusteredInterceptor; +import fish.payara.samples.clustered.singleton.interceptor.TimerRanFlag; +import fish.payara.cluster.Clustered; +import java.io.Serializable; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import javax.ejb.Asynchronous; +import javax.ejb.ConcurrencyManagement; +import javax.ejb.ConcurrencyManagementType; +import javax.ejb.EJB; +import javax.ejb.SessionContext; +import javax.ejb.Singleton; +import javax.ejb.Timeout; +import javax.ejb.TimerConfig; +import javax.ejb.TimerService; +import javax.enterprise.inject.Vetoed; +import javax.interceptor.Interceptors; + +/** + * @author lprimak + */ +@Clustered +@Singleton(name = "ClusteredSingletonInterceptedEJB") +@Vetoed +@ConcurrencyManagement(ConcurrencyManagementType.BEAN) +@Interceptors(ClusteredInterceptor.class) +public class ClusteredSingletonInterceptedEJB implements InterceptedSingletonAPI, Serializable { + private static final Logger log = Logger.getLogger(ClusteredSingletonInterceptedEJB.class.getName()); + private static final long serialVersionUID = 1L; + private final SingletonCommon sc = new SingletonCommon(this); + @Resource + private transient TimerService ts; + @Resource + private transient SessionContext ctx; + private boolean constructorIntercepted; + private boolean timerIntercepted; + private boolean invocationIntercepted; + @EJB + private transient TimerRanFlag timerRan; + + public ClusteredSingletonInterceptedEJB() { + log.log(Level.INFO, "{0} - Constructor", getClass().getSimpleName()); + } + + @PostConstruct + void init() { + log.log(Level.INFO, "{0} - PostConstruct", getClass().getSimpleName()); + ts.createSingleActionTimer(0, new TimerConfig(null, false)); + } + + @PreDestroy + void destroy() { + log.log(Level.INFO, "{0} - PreDestroy", getClass().getSimpleName()); + } + + @Override + public String getHello() { + invocationIntercepted = (ctx.getContextData().get(ClusteredInterceptor.AroundInvokeKey) != null) ? + ctx.getContextData().get(ClusteredInterceptor.AroundInvokeKey).equals(ClusteredInterceptor.AroundInvokeValue) + : "".equals(ClusteredInterceptor.AroundInvokeValue); + return String.format("Intercepted Annotated EJB Hello: %s, consistent: %s", sc, isConsistent()? "yes" : "NO!!!"); + } + + @Override + public void waitForTimer() { + try { + for (int ii = 0; ii < 1000 && !timerRan.isTimerRan(); ++ii) { + Thread.sleep(5); + } + } catch (final InterruptedException ex) { + throw new RuntimeException(ex); + } + } + + @Override + public boolean isConsistent() { + return constructorIntercepted && timerIntercepted && invocationIntercepted; + } + + public void setConstructorInterceptorCalled() { + constructorIntercepted = true; + } + + + @Override + public void randomizeState() { + this.sc.randomizeState(); + } + + @Override + public UUID getState() { + return this.sc.getState(); + } + + @Override + @Asynchronous + public void async() { + log.info(String.format("Async called: %s", getState())); + } + + @Timeout + private void timeout() { + log.info("Timer Action"); + timerRan.setTimerRan(true); + timerIntercepted = (ctx.getContextData().get(ClusteredInterceptor.AroundTimeoutKey) != null) ? + ctx.getContextData().get(ClusteredInterceptor.AroundTimeoutKey).equals(ClusteredInterceptor.AroundTimeoutValue) + : "".equals(ClusteredInterceptor.AroundTimeoutValue); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/SingletonCommon.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/SingletonCommon.java new file mode 100644 index 00000000000..3cef57d460c --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/SingletonCommon.java @@ -0,0 +1,79 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import java.io.Serializable; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Objects; +import java.util.UUID; +import java.util.logging.Logger; + +/** + * @author lprimak + */ +public class SingletonCommon implements Serializable { + private static final Logger log = Logger.getLogger(SingletonCommon.class.getName()); + private static final long serialVersionUID = 1L; + private final Object parent; + private UUID state = UUID.randomUUID(); + + @Override + public String toString() { + try { + return String.format("instance = 0x%x, host = %s, State(UUID) = %s", + Objects.hashCode(parent), InetAddress.getLocalHost().getHostName(), getState()); + } catch (final UnknownHostException ex) { + throw new RuntimeException(ex); + } + } + + public void randomizeState() { + state = UUID.randomUUID(); + } + + public SingletonCommon(final Object parent) { + this.parent = parent; + } + + public UUID getState() { + return this.state; + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/Stock.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/Stock.java new file mode 100644 index 00000000000..771249eefad --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/Stock.java @@ -0,0 +1,122 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import java.io.Serializable; + +/** + * @author lprimak + */ +public class Stock implements Serializable { + private static final long serialVersionUID = 1L; + private String cusip; + private String description; + private Double price; + + public Stock(final String cusip, final String description, final Double price) { + this.cusip = cusip; + this.description = description; + this.price = price; + } + + public String getCusip() { + return this.cusip; + } + + public String getDescription() { + return this.description; + } + + public Double getPrice() { + return this.price; + } + + public void setCusip(final String cusip) { + this.cusip = cusip; + } + + public void setDescription(final String description) { + this.description = description; + } + + public void setPrice(final Double price) { + this.price = price; + } + + @Override + public boolean equals(final java.lang.Object o) { + if (o == this) return true; + if (!(o instanceof Stock)) return false; + final Stock other = (Stock) o; + if (!other.canEqual((java.lang.Object) this)) return false; + final java.lang.Object this$price = this.getPrice(); + final java.lang.Object other$price = other.getPrice(); + if (this$price == null ? other$price != null : !this$price.equals(other$price)) return false; + final java.lang.Object this$cusip = this.getCusip(); + final java.lang.Object other$cusip = other.getCusip(); + if (this$cusip == null ? other$cusip != null : !this$cusip.equals(other$cusip)) return false; + final java.lang.Object this$description = this.getDescription(); + final java.lang.Object other$description = other.getDescription(); + if (this$description == null ? other$description != null : !this$description.equals(other$description)) return false; + return true; + } + + protected boolean canEqual(final java.lang.Object other) { + return other instanceof Stock; + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + final java.lang.Object $price = this.getPrice(); + result = result * PRIME + ($price == null ? 43 : $price.hashCode()); + final java.lang.Object $cusip = this.getCusip(); + result = result * PRIME + ($cusip == null ? 43 : $cusip.hashCode()); + final java.lang.Object $description = this.getDescription(); + result = result * PRIME + ($description == null ? 43 : $description.hashCode()); + return result; + } + + @Override + public String toString() { + return "Stock(cusip=" + this.getCusip() + ", description=" + this.getDescription() + ", price=" + this.getPrice() + ")"; + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/AnnotatedSingletonAPI.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/AnnotatedSingletonAPI.java new file mode 100644 index 00000000000..0ba1c4f2ad7 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/AnnotatedSingletonAPI.java @@ -0,0 +1,52 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.api; + +import java.io.Serializable; +import javax.ejb.Local; + +/** + * + * @author lprimak + */ +@Local +public interface AnnotatedSingletonAPI extends SingletonAPI, Serializable { + // intentionally left blank +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/InterceptedSingletonAPI.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/InterceptedSingletonAPI.java new file mode 100644 index 00000000000..2c308813294 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/InterceptedSingletonAPI.java @@ -0,0 +1,53 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.api; + +import javax.ejb.Local; + +/** + * + * @author lprimak + */ +@Local +public interface InterceptedSingletonAPI extends SingletonAPI { + void waitForTimer(); + boolean isConsistent(); + void async(); +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/Secondary.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/Secondary.java new file mode 100644 index 00000000000..f1245463f84 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/Secondary.java @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.api; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** + * + * @author lprimak + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER, ElementType.METHOD}) +@Inherited +@Documented +public @interface Secondary { + +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/SingletonAPI.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/SingletonAPI.java new file mode 100644 index 00000000000..71bd644785f --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/api/SingletonAPI.java @@ -0,0 +1,52 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.api; + +import java.util.UUID; + +/** + * + * @author lprimak + */ +public interface SingletonAPI { + String getHello(); + UUID getState(); + void randomizeState(); +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/ClusteredInterceptor.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/ClusteredInterceptor.java new file mode 100644 index 00000000000..6a935907fc1 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/ClusteredInterceptor.java @@ -0,0 +1,93 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.interceptor; + +import fish.payara.samples.clustered.singleton.ClusteredSingletonInterceptedEJB; +import java.io.Serializable; +import java.util.logging.Logger; +import javax.interceptor.AroundConstruct; +import javax.interceptor.AroundInvoke; +import javax.interceptor.AroundTimeout; +import javax.interceptor.InvocationContext; + +/** + * @author lprimak + */ +public class ClusteredInterceptor implements Serializable { + private static final Logger log = Logger.getLogger(ClusteredInterceptor.class.getName()); + private static final long serialVersionUID = 1L; + public static final String AroundTimeoutKey = "AroundTimeout"; + public static final String AroundTimeoutValue = "timeout"; + public static final String AroundInvokeKey = "AroundInvoke"; + public static final String AroundInvokeValue = "invoke"; + private final InterceptorCommon ic = new InterceptorCommon(); + + @AroundConstruct + public void aroundConstruct(InvocationContext ctx) { + try { + log.info("AroundConstruct"); + ctx.proceed(); + ClusteredSingletonInterceptedEJB target = (ClusteredSingletonInterceptedEJB) ctx.getTarget(); + target.setConstructorInterceptorCalled(); + } catch (final Exception ex) { + throw new RuntimeException(ex); + } + } + + @AroundTimeout + public Object aroundTimeout(InvocationContext ctx) { + log.info("AroundTimeout"); + try (InterceptorCommon.InterceptorData cd = ic.setData(ctx, AroundTimeoutKey, AroundTimeoutValue)) { + return ctx.proceed(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + @AroundInvoke + public Object aroundInvoke(InvocationContext ctx) { + log.info("AroundInvoke"); + try (InterceptorCommon.InterceptorData cd = ic.setData(ctx, AroundInvokeKey, AroundInvokeValue)) { + return ctx.proceed(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/InterceptorCommon.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/InterceptorCommon.java new file mode 100644 index 00000000000..84994530a92 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/InterceptorCommon.java @@ -0,0 +1,74 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.interceptor; + +import java.io.Serializable; +import javax.interceptor.InvocationContext; + +/** + * @author lprimak + */ +public class InterceptorCommon implements Serializable { + private static final long serialVersionUID = 1L; + + public InterceptorData setData(InvocationContext ctx, String key, Object value) { + return new InterceptorData(ctx, key).setData(value); + } + + public static class InterceptorData implements AutoCloseable { + private final InvocationContext ctx; + private final String key; + + public InterceptorData(final InvocationContext ctx, final String key) { + this.ctx = ctx; + this.key = key; + } + + public InterceptorData setData(Object value) { + ctx.getContextData().put(key, value); + return this; + } + + @Override + public void close() { + ctx.getContextData().remove(key); + } + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/TimerRanFlag.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/TimerRanFlag.java new file mode 100644 index 00000000000..a4743ec00f7 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/interceptor/TimerRanFlag.java @@ -0,0 +1,58 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.interceptor; + +import javax.ejb.Singleton; + +/** + * @author lprimak + */ +@Singleton +public class TimerRanFlag { + private boolean timerRan; + + public boolean isTimerRan() { + return this.timerRan; + } + + public void setTimerRan(final boolean timerRan) { + this.timerRan = timerRan; + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/startup/AppStartup.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/startup/AppStartup.java new file mode 100644 index 00000000000..10961034088 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/java/fish/payara/samples/clustered/singleton/startup/AppStartup.java @@ -0,0 +1,90 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.startup; + +import fish.payara.samples.clustered.singleton.api.InterceptedSingletonAPI; +import fish.payara.samples.clustered.singleton.api.SingletonAPI; +import java.util.logging.Logger; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.ejb.EJB; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.ejb.Timeout; +import javax.ejb.TimerConfig; +import javax.ejb.TimerService; +import javax.inject.Inject; + +/** + * + * @author lprimak + */ +@Singleton +@Startup +public class AppStartup { + private static final Logger log = Logger.getLogger(AppStartup.class.getName()); + private @EJB(lookup = "java:module/ClusteredSingletonEjbXml1") SingletonAPI descAPI; + private @EJB InterceptedSingletonAPI annotatedAPI; + private @Inject SingletonAPI cdiAPI; + private @Resource TimerService ts; + + @PostConstruct + void postConstruct() { + ts.createSingleActionTimer(0, new TimerConfig(null, false)); + } + + @Timeout + void init() { + annotatedAPI.waitForTimer(); + log.info("First Time ..."); + doInit(); + log.info("Second Time ..."); + doInit(); + } + + + void doInit() { + log.info(descAPI.getHello()); + log.info(annotatedAPI.getHello()); + log.info(cdiAPI.getHello()); + cdiAPI.getHello(); + annotatedAPI.async(); + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/ejb-jar.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/ejb-jar.xml new file mode 100644 index 00000000000..645ad661a64 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/ejb-jar.xml @@ -0,0 +1,22 @@ + + + + + ClusteredSingletonEjbXml1 + fish.payara.samples.clustered.singleton.api.SingletonAPI + fish.payara.samples.clustered.singleton.ClusteredSingletonEjbXml + Singleton + Container + + + ClusteredSingletonEjbXml2 + fish.payara.samples.clustered.singleton.api.SingletonAPI + fish.payara.samples.clustered.singleton.ClusteredSingletonEjbXml2 + Singleton + Container + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-ejb-jar.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-ejb-jar.xml new file mode 100644 index 00000000000..7fd7efe07ce --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-ejb-jar.xml @@ -0,0 +1,16 @@ + + + + + ClusteredSingletonEjbXml1 + true + ClusteredSingletonEjbXml + + + ClusteredSingletonEjbXml2 + true + ClusteredSingletonEjbXml + + + true + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-web.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-web.xml new file mode 100644 index 00000000000..13e0059fffb --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/glassfish-web.xml @@ -0,0 +1,10 @@ + + + + + + + Keep a copy of the generated servlet class' java code. + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/web.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..d8feb7e697e --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,4 @@ + + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/index.html b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/index.html new file mode 100644 index 00000000000..3368e9c377e --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/main/webapp/index.html @@ -0,0 +1,10 @@ + + + + Start Page + + + +

Hello World!

+ + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/ClusteredSingletonTest.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/ClusteredSingletonTest.java new file mode 100644 index 00000000000..6ec12f2b505 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/ClusteredSingletonTest.java @@ -0,0 +1,122 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton; + +import fish.payara.samples.clustered.singleton.api.AnnotatedSingletonAPI; +import fish.payara.samples.clustered.singleton.api.InterceptedSingletonAPI; +import fish.payara.samples.clustered.singleton.api.Secondary; +import fish.payara.samples.clustered.singleton.api.SingletonAPI; +import java.io.File; +import java.util.logging.Logger; +import javax.ejb.EJB; +import javax.ejb.EJBException; +import javax.inject.Inject; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * @author lprimak + */ +@RunWith(Arquillian.class) +public class ClusteredSingletonTest { + private static final Logger log = Logger.getLogger(ClusteredSingletonTest.class.getName()); + + @Deployment + public static WebArchive createDeployment() { + return ShrinkWrap.create(WebArchive.class, "cst.war") + .addPackages(false, "fish.payara.samples.clustered.singleton", + "fish.payara.samples.clustered.singleton.api", + "fish.payara.samples.clustered.singleton.interceptor") + .addAsWebInfResource(new File(WEBAPP_SRC, "WEB-INF/ejb-jar.xml")) + .addAsWebInfResource(new File(WEBAPP_SRC, "WEB-INF/glassfish-ejb-jar.xml")); + } + + @Test + public void descriptorApi() { + assertThat(descAPI1.getHello(), startsWith("Descriptor EJB Hello")); + assertThat(descAPI1.getState(), equalTo(descAPI2.getState())); + } + + @Test + public void annotatedApi() { + assertThat(annotatedApi1.getHello(), startsWith("Clustered Annotated API EJB Hello")); + assertThat(annotatedApi1.getState(), equalTo(annotatedApi2.getState())); + } + + @Test + public void cdiApi() { + assertThat(cdiApi1.getHello(), startsWith("CDI Bean Hello")); + assertThat(cdiApi1.getState(), equalTo(cdiApi2.getState())); + } + + @Test(expected = EJBException.class) + public void twoMethodsNotEqual() { + assertThat(annotatedApi1.getHello(), not(equalTo(annotatedApi2.getHello()))); + } + + @Test + public void interceptor() { + assertThat(interceptedAPI.getHello(), startsWith("Intercepted Annotated EJB Hello")); + interceptedAPI.waitForTimer(); + assertThat(interceptedAPI.isConsistent(), is(true)); + } + + + private @EJB(lookup = "java:module/ClusteredSingletonEjbXml1") SingletonAPI descAPI1; + private @EJB(lookup = "java:module/ClusteredSingletonEjbXml2") SingletonAPI descAPI2; + + private @EJB(lookup = "java:module/ClusteredSingletonAnnotatedEJB1") AnnotatedSingletonAPI annotatedApi1; + private @EJB(lookup = "java:module/ClusteredSingletonAnnotatedEJB2") AnnotatedSingletonAPI annotatedApi2; + + private @EJB InterceptedSingletonAPI interceptedAPI; + private @Inject SingletonAPI cdiApi1; + private @Inject @Secondary SingletonAPI cdiApi2; + + public static final String WEBAPP_SRC = "src/main/webapp"; +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/expectedfail/NonSerializableDeploymentFailTest.java b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/expectedfail/NonSerializableDeploymentFailTest.java new file mode 100644 index 00000000000..7feeba1cd92 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/java/fish/payara/samples/clustered/singleton/expectedfail/NonSerializableDeploymentFailTest.java @@ -0,0 +1,76 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2016-2020] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/master/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package fish.payara.samples.clustered.singleton.expectedfail; + +import fish.payara.cluster.Clustered; +import java.util.logging.Logger; +import javax.ejb.Singleton; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.ShouldThrowException; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * @author lprimak + */ +@RunWith(Arquillian.class) +public class NonSerializableDeploymentFailTest { + private static final Logger log = Logger.getLogger(NonSerializableDeploymentFailTest.class.getName()); + + @Deployment @ShouldThrowException(RuntimeException.class) + public static WebArchive createDeployment() { + log.info("Please Ignore the following SEVERE: exit_code, it\'s expected"); + return ShrinkWrap.create(WebArchive.class) + .addPackage(NonSerializableDeploymentFailTest.class.getPackage()); + } + + @Clustered + @Singleton + static public class NonSerializableClusteredSingleton { + + } + + @Test + public void dummy() { + } +} diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/ejb-jar.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/ejb-jar.xml new file mode 100644 index 00000000000..e7f78d5f19c --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/ejb-jar.xml @@ -0,0 +1,15 @@ + + + + + NonSerializableSingleton + fish.payara.samples.clustered.singleton.api.SingletonAPI + fish.payara.samples.clustered.singleton.expectedfail.NonSerializableSingleton + Singleton + Container + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/glassfish-ejb-jar.xml b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/glassfish-ejb-jar.xml new file mode 100644 index 00000000000..435f9edbb38 --- /dev/null +++ b/appserver/tests/payara-samples/samples/clustered-singleton/clustered-singleton-test/src/test/resources/ForFailures/META-INF/glassfish-ejb-jar.xml @@ -0,0 +1,10 @@ + + + + + ClusteredSingletonEjbXml + true + true + + + diff --git a/appserver/tests/payara-samples/samples/clustered-singleton/pom.xml b/appserver/tests/payara-samples/samples/clustered-singleton/pom.xml index 247cfbf93c2..1598b6e3aea 100644 --- a/appserver/tests/payara-samples/samples/clustered-singleton/pom.xml +++ b/appserver/tests/payara-samples/samples/clustered-singleton/pom.xml @@ -3,7 +3,7 @@ ~ /* ~ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. ~ * - ~ * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + ~ * Copyright (c) [2019-2020] Payara Foundation and/or its affiliates. All rights reserved. ~ * ~ * The contents of this file are subject to the terms of either the GNU ~ * General Public License Version 2 only ("GPL") or the Common Development @@ -62,6 +62,7 @@ clustered-singleton-ejb + clustered-singleton-test