diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/AppClientContainerBuilder.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/AppClientContainerBuilder.java index cb6a36c6d93..98ae893b582 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/AppClientContainerBuilder.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/AppClientContainerBuilder.java @@ -40,7 +40,7 @@ import org.glassfish.appclient.client.acc.config.TargetServer; import org.glassfish.appclient.client.acc.config.util.XML; import org.glassfish.embeddable.client.UserError; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.xml.sax.SAXException; import static java.util.logging.Level.CONFIG; @@ -87,7 +87,7 @@ public class AppClientContainerBuilder implements AppClientContainer.Builder { private boolean sendPassword = true; - private GlassFishORBHelper orbHelper; + private GlassFishORBLocator orbLocator; /** caller-provided message security configurations */ private final List messageSecurityConfigs = new ArrayList<>(); @@ -183,7 +183,7 @@ private CallbackHandler getCallbackHandlerFromDescriptor(final String callbackHa private void prepareHabitat() throws URISyntaxException { ACCModulesManager.initialize(Thread.currentThread().getContextClassLoader()); - orbHelper = ACCModulesManager.getService(GlassFishORBHelper.class); + orbLocator = ACCModulesManager.getService(GlassFishORBLocator.class); } /** @@ -220,11 +220,10 @@ private void prepareIIOP(final TargetServer[] targetServers, Properties containe } if (isSSLRequired(targetServers, containerProperties)) { - orbHelper.setCSIv2Prop(ORB_SSL_CLIENT_REQUIRED, "true"); + orbLocator.setCSIv2Prop(ORB_SSL_CLIENT_REQUIRED, "true"); } logger.log(CONFIG, "Using endpoint address(es): {0}", sb.toString()); - } /** diff --git a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/TargetServerHelper.java b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/TargetServerHelper.java index 0eb9b55cb00..350e0fbabd6 100644 --- a/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/TargetServerHelper.java +++ b/appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/TargetServerHelper.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -24,7 +25,8 @@ import org.glassfish.appclient.client.acc.config.Security; import org.glassfish.appclient.client.acc.config.TargetServer; import org.glassfish.embeddable.client.UserError; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; + +import static org.glassfish.internal.api.ORBLocator.DEFAULT_ORB_INIT_PORT; /** * Encapsulates the logic for deciding what TargetServer objects to use for @@ -34,7 +36,7 @@ */ public class TargetServerHelper { - private static int DEFAULT_ENDPOINT_PORT = Integer.parseInt(GlassFishORBHelper.DEFAULT_ORB_INIT_PORT); + private static int DEFAULT_ENDPOINT_PORT = Integer.parseInt(DEFAULT_ORB_INIT_PORT); private static final String SSL_PROPERTY_NAME = "ssl"; diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbNamingReferenceManagerImpl.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbNamingReferenceManagerImpl.java index f448ed81eba..0ed0f2b7f45 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbNamingReferenceManagerImpl.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbNamingReferenceManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -33,7 +33,7 @@ import org.glassfish.api.invocation.ComponentInvocation; import org.glassfish.api.invocation.InvocationManager; import org.glassfish.api.naming.SimpleJndiName; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.internal.api.ORBLocator; import org.jvnet.hk2.annotations.Service; import org.omg.CORBA.ORB; @@ -48,10 +48,10 @@ public class EjbNamingReferenceManagerImpl implements EjbNamingReferenceManager { @Inject - InvocationManager invMgr; + private InvocationManager invMgr; @Inject - Provider glassFishORBHelperProvider; + private Provider orbLocatorProvider; @Override public Object resolveEjbReference(EjbReferenceDescriptor ejbRefDesc, Context context) @@ -119,22 +119,17 @@ public Object resolveEjbReference(EjbReferenceDescriptor ejbRefDesc, Context con ClassLoader origClassLoader = Utility.getClassLoader(); boolean setCL = false; - try { - try { - - String refInterface = ejbRefDesc.isEJB30ClientView() ? - ejbRefDesc.getEjbInterface() : ejbRefDesc.getHomeClassName(); + String refInterface = ejbRefDesc.isEJB30ClientView() + ? ejbRefDesc.getEjbInterface() + : ejbRefDesc.getHomeClassName(); origClassLoader.loadClass(refInterface); - } catch(ClassNotFoundException e) { - - ClassLoader referringBundleClassLoader = - ejbRefDesc.getReferringBundleDescriptor().getClassLoader(); - Utility.setContextClassLoader(referringBundleClassLoader); - setCL = true; - + } catch (ClassNotFoundException e) { + ClassLoader referringBundleClassLoader = ejbRefDesc.getReferringBundleDescriptor().getClassLoader(); + Utility.setContextClassLoader(referringBundleClassLoader); + setCL = true; } /* For remote ejb refs, first lookup the target remote object @@ -147,8 +142,7 @@ public Object resolveEjbReference(EjbReferenceDescriptor ejbRefDesc, Context con * MEJB resolution for cluster support post V3 FCS. */ if (remoteJndiName.hasCorbaPrefix()) { - GlassFishORBHelper orbHelper = glassFishORBHelperProvider.get(); - ORB orb = orbHelper.getORB(); + ORB orb = orbLocatorProvider.get().getORB(); jndiObj = orb.string_to_object(remoteJndiName.toString()); } else { jndiObj = context.lookup(remoteJndiName.toString()); @@ -190,17 +184,13 @@ public Object getEJBContextObject(String contextType) { if(currentInv == null) { throw new IllegalStateException("no current invocation"); - } else if (currentInv.getInvocationType() != - ComponentInvocation.ComponentInvocationType.EJB_INVOCATION) { - throw new IllegalStateException - ("Illegal invocation type for EJB Context : " - + currentInv.getInvocationType()); + } else if (currentInv.getInvocationType() != ComponentInvocation.ComponentInvocationType.EJB_INVOCATION) { + throw new IllegalStateException( + "Illegal invocation type for EJB Context : " + currentInv.getInvocationType()); } EjbInvocation ejbInv = (EjbInvocation) currentInv; - Object returnObject = ejbInv.context; - if (contextType.equals("jakarta.ejb.TimerService")) { if (EJBTimerService.getEJBTimerService() == null) { throw new IllegalStateException("EJB Timer Service not available"); diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectInputStreamHandler.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectInputStreamHandler.java index 1e776bbb836..e2723aeafe9 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectInputStreamHandler.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectInputStreamHandler.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -25,7 +26,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.ProtocolManager; import org.glassfish.internal.api.Globals; @@ -69,14 +70,8 @@ public Object resolveObject(Object obj) } } - /** - * Do all ProtocolManager access lazily and only request orb if it has already been - * initialized so that code doesn't make the assumption that an orb is available in - * this runtime. - */ private ProtocolManager getProtocolManager() { - GlassFishORBHelper orbHelper = Globals.getDefaultHabitat().getService(GlassFishORBHelper.class); - return orbHelper.isORBInitialized() ? orbHelper.getProtocolManager() : null; + GlassFishORBLocator orbLocator = Globals.getDefaultHabitat().getService(GlassFishORBLocator.class); + return orbLocator.getProtocolManager(); } - } diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectOutputStreamHandler.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectOutputStreamHandler.java index 142af008c94..a627befa9af 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectOutputStreamHandler.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/base/io/EJBObjectOutputStreamHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -40,7 +40,7 @@ import org.glassfish.api.naming.GlassfishNamingManager; import org.glassfish.api.naming.SimpleJndiName; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.ProtocolManager; import org.glassfish.internal.api.Globals; @@ -92,14 +92,9 @@ public Object replaceObject(Object obj) throws IOException { } - /** - * Do all ProtocolManager access lazily and only request orb if it has already been - * initialized so that code doesn't make the assumption that an orb is available in - * this runtime. - */ private ProtocolManager getProtocolManager() { - GlassFishORBHelper orbHelper = Globals.getDefaultHabitat().getService(GlassFishORBHelper.class); - return orbHelper.isORBInitialized() ? orbHelper.getProtocolManager() : null; + GlassFishORBLocator orbLocator = Globals.getDefaultHabitat().getService(GlassFishORBLocator.class); + return orbLocator.getProtocolManager(); } @@ -199,7 +194,7 @@ protected static java.rmi.Remote doRemoteRefClassLoaderConversion(final java.rmi byte[] serializedRef = EJBObjectOutputStreamHandler._javaEEIOUtils.serializeObject(reference, false); Remote returnReference = (java.rmi.Remote) EJBObjectOutputStreamHandler._javaEEIOUtils .deserializeObject(serializedRef, false, contextClassLoader); - GlassFishORBHelper orbHelper = EjbContainerUtilImpl.getInstance().getORBHelper(); + GlassFishORBLocator orbHelper = EjbContainerUtilImpl.getInstance().getOrbLocator(); ProtocolManager protocolMgr = orbHelper.getProtocolManager(); protocolMgr.connectObject(returnReference); return returnReference; diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/BaseContainer.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/BaseContainer.java index 1b37a773ad5..040444dda7c 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/BaseContainer.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/BaseContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -142,7 +142,6 @@ import org.glassfish.ejb.deployment.descriptor.EjbSessionDescriptor; import org.glassfish.ejb.spi.EjbContainerInterceptor; import org.glassfish.ejb.spi.WSEjbEndpointRegistry; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; import org.glassfish.enterprise.iiop.api.ProtocolManager; import org.glassfish.enterprise.iiop.api.RemoteReferenceFactory; import org.glassfish.enterprise.iiop.spi.EjbContainerFacade; @@ -765,9 +764,7 @@ private void addToGeneratedMonitoredMethodInfo(Class generatedClass) { protected void initializeProtocolManager() { try { - GlassFishORBHelper orbHelper = ejbContainerUtilImpl.getORBHelper(); - protocolMgr = orbHelper.getProtocolManager(); - + protocolMgr = ejbContainerUtilImpl.getOrbLocator().getProtocolManager(); } catch (Throwable t) { throw new RuntimeException( "IIOP Protocol Manager initialization failed. " + "Possible cause is that ORB is not available in this " diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtil.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtil.java index 7b57f374c3e..0738c867d36 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtil.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -38,7 +38,7 @@ import org.glassfish.api.naming.GlassfishNamingManager; import org.glassfish.ejb.config.EjbContainer; import org.glassfish.ejb.config.EjbTimerService; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.flashlight.provider.ProbeProviderFactory; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.internal.api.ServerContext; @@ -64,7 +64,7 @@ public interface EjbContainerUtil { // Used by the TimerService upgrade String TIMER_SERVICE_UPGRADED = "ejb-timer-service-upgraded"; - GlassFishORBHelper getORBHelper(); + GlassFishORBLocator getOrbLocator(); ServiceLocator getServices(); diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtilImpl.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtilImpl.java index 6ef4c950835..05e5ae3c079 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtilImpl.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/EjbContainerUtilImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -63,7 +63,7 @@ import org.glassfish.ejb.config.EjbContainer; import org.glassfish.ejb.config.EjbTimerService; import org.glassfish.ejb.spi.CMPDeployer; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.flashlight.provider.ProbeProviderFactory; import org.glassfish.hk2.api.PostConstruct; import org.glassfish.hk2.api.PreDestroy; @@ -93,7 +93,7 @@ public class EjbContainerUtilImpl implements PostConstruct, PreDestroy, EjbConta private ServerContext serverContext; @Inject - JavaEEIOUtils javaEEIOUtils; + private JavaEEIOUtils javaEEIOUtils; private final Map id2Container = new ConcurrentHashMap<>(); @@ -123,7 +123,7 @@ public class EjbContainerUtilImpl implements PostConstruct, PreDestroy, EjbConta private EjbContainer ejbContainer; @Inject - private GlassFishORBHelper orbHelper; + private GlassFishORBLocator orbLocator; @Inject private ServerEnvironmentImpl env; @@ -138,13 +138,13 @@ public class EjbContainerUtilImpl implements PostConstruct, PreDestroy, EjbConta private EjbAsyncInvocationManager ejbAsyncInvocationManager; @Inject - ProbeProviderFactory probeProviderFactory; + private ProbeProviderFactory probeProviderFactory; @Inject - Domain domain; + private Domain domain; @Inject - Provider deploymentProvider; + private Provider deploymentProvider; @Inject private Provider cmpDeployerProvider; @@ -199,8 +199,8 @@ public void preDestroy() { } @Override - public GlassFishORBHelper getORBHelper() { - return orbHelper; + public GlassFishORBLocator getOrbLocator() { + return orbLocator; } @Override diff --git a/appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/FormAuthHttpClient.java b/appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/FormAuthHttpClient.java index 63ed412634d..3c4cc959a1d 100644 --- a/appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/FormAuthHttpClient.java +++ b/appserver/itest-tools/src/main/java/org/glassfish/main/itest/tools/FormAuthHttpClient.java @@ -107,16 +107,18 @@ public HttpURLConnection get(String relativePath) throws IOException { private HttpCookie createSession(String relativePath) throws IOException { final HttpURLConnection connection = openConnection(baseUrl.getPort(), baseUrl.getPath() + "/" + relativePath); - connection.setRequestMethod("GET"); - assertThat(connection.getResponseCode(), equalTo(200)); - try (InputStream is = connection.getInputStream()) { - final String text = new String(is.readAllBytes(), UTF_8); - assertThat(text, - stringContainsInOrder("Login Page", "Please login", "j_username", "j_password")); - final HttpCookie sessionId = cookieManager.getCookieStore().getCookies().stream() - .filter(c -> c.getName().equals("JSESSIONID")).findFirst().get(); - is.readAllBytes(); - return sessionId; + try { + connection.setRequestMethod("GET"); + assertThat(connection.getResponseCode(), equalTo(200)); + try (InputStream is = connection.getInputStream()) { + final String text = new String(is.readAllBytes(), UTF_8); + assertThat(text, + stringContainsInOrder("Login Page", "Please login", "j_username", "j_password")); + final HttpCookie sessionId = cookieManager.getCookieStore().getCookies().stream() + .filter(c -> c.getName().equals("JSESSIONID")).findFirst().get(); + is.readAllBytes(); + return sessionId; + } } finally { connection.disconnect(); } diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBFactory.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBFactory.java index b8c2a5333e0..794a772c3cc 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBFactory.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBFactory.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -16,10 +17,13 @@ package org.glassfish.enterprise.iiop.api; +import com.sun.enterprise.deployment.EjbDescriptor; + import java.util.Properties; import org.jvnet.hk2.annotations.Contract; import org.omg.CORBA.ORB; +import org.omg.PortableInterceptor.IORInfo; import org.omg.PortableInterceptor.ServerRequestInfo; /** @@ -33,6 +37,7 @@ public interface GlassFishORBFactory { String ENV_IS_SERVER_PROPERTY = "com.sun.corba.ee.ORBEnvironmentIsGlassFishServer"; ORB createORB(Properties props); + int getOTSPolicyType(); int getCSIv2PolicyType(); @@ -50,4 +55,6 @@ public interface GlassFishORBFactory { boolean isEjbCall(ServerRequestInfo sri); String getIIOPEndpoints(); + + EjbDescriptor getEjbDescriptor(IORInfo iorInfo); } diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLifeCycleListener.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLifeCycleListener.java deleted file mode 100644 index 766d6719f1f..00000000000 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLifeCycleListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0, which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the - * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, - * version 2 with the GNU Classpath Exception, which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - */ - -package org.glassfish.enterprise.iiop.api; - -import java.util.List; -import java.util.Properties; - -import org.jvnet.hk2.annotations.Contract; - -/** - * @author Mahesh Kannan - * Date: Jan 16, 2009 - */ -@Contract -public interface GlassFishORBLifeCycleListener { - - public void initializeORBInitProperties(List args, Properties props); - - public void orbCreated(org.omg.CORBA.ORB orb); - -} diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBHelper.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLocator.java similarity index 55% rename from appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBHelper.java rename to appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLocator.java index de499b33d67..f060d00d537 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBHelper.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/GlassFishORBLocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation. + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -17,6 +17,9 @@ package org.glassfish.enterprise.iiop.api; +import com.sun.corba.ee.impl.folb.InitialGroupInfoService; +import com.sun.enterprise.deployment.EjbDescriptor; + import jakarta.annotation.PostConstruct; import jakarta.ejb.Singleton; import jakarta.inject.Inject; @@ -26,18 +29,21 @@ import java.nio.channels.SelectableChannel; import java.rmi.Remote; import java.util.Properties; +import java.util.concurrent.Semaphore; import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.event.EventListener; import org.glassfish.api.event.Events; import org.glassfish.api.naming.GlassfishNamingManager; -import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.internal.api.ORBLocator; import org.jvnet.hk2.annotations.Service; import org.omg.CORBA.ORB; +import org.omg.PortableInterceptor.IORInfo; import org.omg.PortableInterceptor.ServerRequestInfo; +import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.INFO; +import static java.lang.System.Logger.Level.TRACE; import static org.glassfish.api.event.EventTypes.SERVER_SHUTDOWN; /** @@ -48,16 +54,14 @@ */ @Service @Singleton -public class GlassFishORBHelper implements ORBLocator { +public class GlassFishORBLocator implements ORBLocator { - private static final Logger LOG = System.getLogger(GlassFishORBHelper.class.getName()); + private static final Logger LOG = System.getLogger(GlassFishORBLocator.class.getName()); + private static final ThreadLocal TMP_ORB = new ThreadLocal<>(); @Inject private Provider eventsProvider; - @Inject - private ServiceLocator services; - @Inject private ProcessEnvironment processEnv; @@ -67,16 +71,21 @@ public class GlassFishORBHelper implements ORBLocator { @Inject private Provider glassfishNamingManagerProvider; + @Inject + private GlassFishORBFactory orbFactory; + private ProtocolManager protocolManager; private SelectableChannelDelegate selectableChannelDelegate; - private GlassFishORBFactory orbFactory; // volatile is enough for sync, just one thread can write private volatile ORB orb; private volatile boolean destroyed; + private volatile Exception failure; + private Semaphore semaphore = new Semaphore(1); + private Thread initializerThread; @PostConstruct - public void postConstruct() { + private void postConstruct() { // WARN: Neither PreDestroy annotation nor interface worked! EventListener glassfishEventListener = event -> { if (event.is(SERVER_SHUTDOWN)) { @@ -84,15 +93,16 @@ public void postConstruct() { } }; eventsProvider.get().register(glassfishEventListener); - orbFactory = services.getService(GlassFishORBFactory.class); LOG.log(INFO, "GlassFishORBLocator created."); } private void onShutdown() { - // FIXME: getORB is able to create another, it should be refactored and simplified. destroyed = true; - LOG.log(INFO, "ORB shutdown started"); + LOG.log(INFO, "GlassFishORBLocator shutdown started"); if (this.orb != null) { + LOG.log(INFO, "GlassFishORBLocator shutdown waits for lock"); + semaphore.acquireUninterruptibly(); + LOG.log(INFO, "GlassFishORBLocator shutdown has the lock"); // First remove, then destroy. // Still, threads already working with the instance will have it unstable. final ORB destroyedOrb = orb; @@ -109,68 +119,86 @@ private void onShutdown() { } } - // Called by PEORBConfigurator executed from glassfish-corba-orb.jar - public synchronized void setORB(ORB orb) { - this.orb = orb; - } - - /** - * Get or create the default orb. This can be called for any process type. However, protocol manager and CosNaming - * initialization only take place for the Server. - */ @Override public ORB getORB() { - // Use a volatile double-checked locking idiom here so that we can publish - // a partly-initialized ORB early, so that lazy init can come into getORB() - // and allow an invocation to the transport to complete. - { - final ORB orbInstance = this.orb; - if (orbInstance != null || destroyed) { - return orbInstance; + LOG.log(TRACE, "getORB() entry"); + if (destroyed) { + return null; + } + if (orb != null) { + LOG.log(TRACE, "getORB() the shortest path out"); + return orb; + } + + if (semaphore.tryAcquire()) { + // First thread will create the ORB. + initializerThread = Thread.currentThread(); + } else if (Thread.currentThread() == initializerThread) { + // Awful design of corba-orb library needs this. + LOG.log(DEBUG, "Detected recursion!", new Exception()); + return TMP_ORB.get(); + } else { + try { + // Other threads must wait. + semaphore.acquire(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } - synchronized (this) { - if (this.orb != null) { - return this.orb; + + try { + if (this.orb != null || destroyed) { + LOG.log(TRACE, "getORB() second shortest path out"); + return orb; + } + if (this.failure != null) { + throw new RuntimeException("ORB initialization already failed in another thread!", failure); } try { - final boolean isServer = processEnv.getProcessType().isServer(); - - final Properties props = new Properties(); - props.setProperty(GlassFishORBFactory.ENV_IS_SERVER_PROPERTY, Boolean.toString(isServer)); - - // Create orb and make it visible. - // - // This will allow loopback calls to getORB() from portable interceptors activated - // as a side-effect of the remaining initialization. - // - // If it's a server, there's a small time window during which the ProtocolManager - // won't be available. - // Any callbacks that result from the protocol manager initialization itself cannot - // depend on having access to the protocol manager. - orb = orbFactory.createORB(props); - if (isServer && protocolManager == null) { - protocolManager = initProtocolManager(orb); - } + initialize(processEnv.getProcessType().isServer()); + LOG.log(DEBUG, "ORB initialization finished successfuly."); return orb; } catch (Exception e) { - orb = null; - protocolManager = null; - throw new RuntimeException("Orb initialization erorr", e); + failure = e; + // Close all ports, etc. + if (orb != null) { + orb.destroy(); + } } + // Current stacktrace + original cause. + throw new RuntimeException("ORB initialization failed!", failure); + } finally { + TMP_ORB.remove(); + semaphore.release(); + initializerThread = null; } } + private void initialize(boolean isServer) throws Exception { + LOG.log(DEBUG, "getORB(): Initialization started by " + Thread.currentThread(), new Exception()); + final Properties props = new Properties(); + props.setProperty(GlassFishORBFactory.ENV_IS_SERVER_PROPERTY, Boolean.toString(isServer)); + this.orb = orbFactory.createORB(props); + if (isServer) { + // Does the JNDI binding + new InitialGroupInfoService(orb); + } + LOG.log(INFO, "ORB initialization succeeded: {0}", orb); + } - private ProtocolManager initProtocolManager(final ORB orbInstance) throws Exception { + private ProtocolManager initProtocolManager() throws Exception { + if (failure != null) { + throw new IllegalStateException( + "Cannot initialize the protocol manager, because ORB initialization failed.", failure); + } final ProtocolManager manager = protocolManagerProvider.get(); - manager.initialize(orbInstance); + manager.initialize(orb); // Move startup of naming to PEORBConfigurator so it runs before interceptors. manager.initializePOAs(); final GlassfishNamingManager namingManager = glassfishNamingManagerProvider.get(); - final Remote remoteSerialProvider = namingManager.initializeRemoteNamingSupport(orbInstance); + final Remote remoteSerialProvider = namingManager.initializeRemoteNamingSupport(orb); manager.initializeRemoteNaming(remoteSerialProvider); return manager; } @@ -188,23 +216,34 @@ public SelectableChannelDelegate getSelectableChannelDelegate() { * Get a protocol manager for creating remote references. * ProtocolManager is only available in the server. * Otherwise, this method returns null. - * If it's the server and the orb hasn't been already created, calling this method has the side - * effect of creating the orb. */ public ProtocolManager getProtocolManager() { if (!processEnv.getProcessType().isServer() || destroyed) { return null; } - synchronized (this) { - if (protocolManager == null) { - getORB(); + if (!isORBInitialized()) { + getORB(); + } + if (protocolManager != null) { + return protocolManager; + } + + semaphore.acquireUninterruptibly(); + try { + if (processEnv.getProcessType().isServer()) { + protocolManager = initProtocolManager(); + LOG.log(INFO, "ProtocolManager initialization finished successfuly."); } return protocolManager; + } catch (Exception e) { + throw new IllegalStateException("ProtocolManager initialization failed!", e); + } finally { + semaphore.release(); } } public boolean isORBInitialized() { - return orb != null; + return orb != null && initializerThread == null; } public int getOTSPolicyType() { @@ -227,13 +266,15 @@ public int getORBInitialPort() { return orbFactory.getORBInitialPort(); } - @Override - public String getORBHost(ORB orb) { - return orbFactory.getORBHost(orb); + public EjbDescriptor getEjbDescriptor(IORInfo iorInfo) { + return orbFactory.getEjbDescriptor(iorInfo); } @Override - public int getORBPort(ORB orb) { + public int getORBPort() { + while (!isORBInitialized()) { + Thread.onSpinWait(); + } return orbFactory.getORBPort(orb); } @@ -241,6 +282,16 @@ public boolean isEjbCall(ServerRequestInfo sri) { return orbFactory.isEjbCall(sri); } + /** + * Due to bad corba-orb design, we need to have a partially initialized {@link ORB} instance + * ready for recursive requests. + * + * @param orb + */ + public static void setThreadLocal(ORB orb) { + TMP_ORB.set(orb); + } + public interface SelectableChannelDelegate { void handleRequest(SelectableChannel channel); } diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/IIOPSSLUtil.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/IIOPSSLUtil.java index 7af507a0252..b45ff7e7687 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/IIOPSSLUtil.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/IIOPSSLUtil.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -16,7 +17,10 @@ package org.glassfish.enterprise.iiop.api; +import com.sun.corba.ee.spi.transport.SocketInfo; + import java.security.SecureRandom; +import java.util.List; import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager; @@ -24,6 +28,7 @@ import org.jvnet.hk2.annotations.Contract; import org.omg.IOP.TaggedComponent; import org.omg.PortableInterceptor.IORInfo; + /** * This class tries to avoid the need for orb-iiop to * depend on some security modules for getting SSL related info @@ -31,12 +36,11 @@ */ @Contract public interface IIOPSSLUtil { - public Object getAppClientSSL(); - public void setAppClientSSL(Object ssl); - public KeyManager[] getKeyManagers(String certNickname); - public TrustManager[] getTrustManagers(); - public SecureRandom getInitializedSecureRandom(); - public Object getSSLPortsAsSocketInfo(Object ior); - public TaggedComponent createSSLTaggedComponent(IORInfo iorInfo, Object socketInfos); - + Object getAppClientSSL(); + void setAppClientSSL(Object ssl); + KeyManager[] getKeyManagers(String certNickname); + TrustManager[] getTrustManagers(); + SecureRandom getInitializedSecureRandom(); + List getSSLPortsAsSocketInfo(Object ior); + TaggedComponent createSSLTaggedComponent(IORInfo iorInfo, Object socketInfos); } diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBLazyServiceInitializer.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBLazyServiceInitializer.java index d5087d91ce6..c165f737c46 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBLazyServiceInitializer.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBLazyServiceInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -26,7 +26,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.glassfish.hk2.api.PostConstruct; import org.glassfish.internal.grizzly.LazyServiceInitializer; import org.jvnet.hk2.annotations.Service; @@ -37,30 +36,23 @@ */ @Service @Named("iiop-service") -public class ORBLazyServiceInitializer implements LazyServiceInitializer, PostConstruct { - +public class ORBLazyServiceInitializer implements LazyServiceInitializer { private static final Logger LOG = LogDomains.getLogger(ORBLazyServiceInitializer.class, SERVER_LOGGER, false); - @Inject - private GlassFishORBHelper orbHelper; + private GlassFishORBLocator orbLocator; boolean initializedSuccessfully; - @Override - public void postConstruct() { - } - public String getServiceName() { return "iiop-service"; } - @Override public boolean initializeService() { try { - orbHelper.getORB(); - initializedSuccessfully = true; + orbLocator.getORB(); + initializedSuccessfully = orbLocator.isORBInitialized(); // TODO add check to ensure that lazy init is enabled for the orb // and throw exception if not @@ -68,15 +60,13 @@ public boolean initializeService() { } catch(Exception e) { LOG.log(Level.WARNING, "ORB initialization failed in lazy init", e); } - return initializedSuccessfully; } - @Override public void handleRequest(SelectableChannel channel) { if (initializedSuccessfully) { - orbHelper.getSelectableChannelDelegate().handleRequest(channel); + orbLocator.getSelectableChannelDelegate().handleRequest(channel); } else { LOG.log(Level.WARNING, "Cannot handle SelectableChannel request in ORBLazyServiceInitializer. " + "ORB did not initialize successfully"); diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBNamingProxy.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBNamingProxy.java index 0f29c600d63..32e76079219 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBNamingProxy.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/api/ORBNamingProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -23,8 +23,8 @@ import org.glassfish.api.naming.NamedNamingObjectProxy; import org.glassfish.api.naming.NamespacePrefixes; +import org.glassfish.internal.api.ORBLocator; import org.jvnet.hk2.annotations.Service; -import org.omg.CORBA.ORB; import static org.glassfish.api.naming.SimpleJndiName.JNDI_CTX_JAVA_COMPONENT; @@ -36,29 +36,23 @@ @Service @NamespacePrefixes(ORBNamingProxy.ORB_CONTEXT) public class ORBNamingProxy implements NamedNamingObjectProxy { - + // Must not be private so it can be used in the annotation static final String ORB_CONTEXT = JNDI_CTX_JAVA_COMPONENT + "ORB"; @Inject - private GlassFishORBHelper orbHelper; + private ORBLocator orbLocator; @Override public Object handle(String name) throws NamingException { - - ORB orb = null; - - if (ORB_CONTEXT.equals(name)) { - try { - orb = orbHelper.getORB(); - } catch(Throwable t) { - NamingException ne = new NamingException("Error retrieving orb for java:comp/ORB lookup"); - ne.initCause(t); - throw ne; - } + if (!ORB_CONTEXT.equals(name)) { + return null; + } + try { + return orbLocator.getORB(); + } catch(Throwable t) { + NamingException ne = new NamingException("Error retrieving orb for java:comp/ORB lookup"); + ne.initCause(t); + throw ne; } - - return orb; } - - } diff --git a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/util/IIOPUtils.java b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/util/IIOPUtils.java index ed817510485..dc9ba648111 100644 --- a/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/util/IIOPUtils.java +++ b/appserver/orb/orb-connector/src/main/java/org/glassfish/enterprise/iiop/util/IIOPUtils.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -30,7 +31,6 @@ import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.enterprise.iiop.api.GlassFishORBLifeCycleListener; import org.glassfish.enterprise.iiop.api.IIOPInterceptorFactory; import org.glassfish.grizzly.config.dom.NetworkListener; import org.glassfish.grizzly.config.dom.ThreadPool; @@ -40,11 +40,9 @@ import org.glassfish.orb.admin.config.IiopListener; import org.glassfish.orb.admin.config.IiopService; import org.jvnet.hk2.annotations.Service; -import org.omg.CORBA.ORB; /** - * @author Mahesh Kannan - * Date: Jan 15, 2009 + * @author Mahesh Kannan 2009 */ @Service public class IIOPUtils implements PostConstruct { @@ -52,7 +50,7 @@ public class IIOPUtils implements PostConstruct { private static IIOPUtils _me; @Inject - ServiceLocator services; + private ServiceLocator serviceLocator; @Inject private ClassLoaderHierarchy clHierarchy; @@ -67,68 +65,41 @@ public class IIOPUtils implements PostConstruct { private IiopService iiopService; private Collection serverRefs; - // Set during init - private ORB defaultORB; - - //private GlassFishORBManager gfORBMgr; - + @Override public void postConstruct() { + this.processType = processEnv.getProcessType(); + if (this.processType.isServer()) { + final Config config = serviceLocator.getService(Config.class, ServerEnvironment.DEFAULT_INSTANCE_NAME); + this.iiopService = config.getExtensionByType(IiopService.class); - processType = processEnv.getProcessType(); - - if( processEnv.getProcessType().isServer()) { - - Config c = services.getService(Config.class, ServerEnvironment.DEFAULT_INSTANCE_NAME); - iiopService =c.getExtensionByType(IiopService.class); - - final Collection threadPool = c.getThreadPools().getThreadPool(); + final Collection threadPool = config.getThreadPools().getThreadPool(); final Collection listeners = allByContract(NetworkListener.class); - final Set names = new TreeSet(); - threadPools = new ArrayList(); + final Set names = new TreeSet<>(); + this.threadPools = new ArrayList<>(); + for (NetworkListener listener : listeners) { names.add(listener.getThreadPool()); } for (ThreadPool pool : threadPool) { if(!names.contains(pool.getName())) { - threadPools.add(pool); + this.threadPools.add(pool); } } - serverRefs = allByContract(ServerRef.class); + this.serverRefs = allByContract(ServerRef.class); } - - IIOPUtils.initMe(this); - - } - - private static void initMe(IIOPUtils utils) { - _me = utils; + _me = this; } public static IIOPUtils getInstance() { return _me; } - - public static void setInstance(IIOPUtils utils) { - _me = utils; - } - - /* - void setGlassFishORBManager(GlassFishORBManager orbMgr) { - gfORBMgr = orbMgr; - } - - GlassFishORBManager getGlassFishORBManager() { - return gfORBMgr; - } - */ - public ClassLoader getCommonClassLoader() { return clHierarchy.getCommonClassLoader(); } private void assertServer() { - if ( !processType.isServer() ) { + if (!processType.isServer()) { throw new IllegalStateException("Only available in Server mode"); } } @@ -153,34 +124,19 @@ public List getIiopListeners() { return iiopService.getIiopListener(); } - public Collection getAllIIOPInterceptrFactories() { + public List getAllIIOPInterceptrFactories() { return allByContract(IIOPInterceptorFactory.class); } - public Collection getGlassFishORBLifeCycleListeners() { - return allByContract(GlassFishORBLifeCycleListener.class); - } - public ProcessType getProcessType() { return processType; } - public ServiceLocator getHabitat() { - return services; - } - - public void setORB(ORB orb) { - defaultORB = orb; + public ServiceLocator getServiceLocator() { + return serviceLocator; } - // For internal use only. All other modules should use orb-connector - // GlassFishORBHelper to acquire default ORB. - public ORB getORB() { - return defaultORB; + private List allByContract(Class contractClass) { + return serviceLocator.getAllServices(contractClass); } - - private Collection allByContract(Class contractClass) { - return services.getAllServices(contractClass); - } - } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/CSIv2SSLTaggedComponentHandlerImpl.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/CSIv2SSLTaggedComponentHandlerImpl.java index 2a655209b6f..82180c3728f 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/CSIv2SSLTaggedComponentHandlerImpl.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/CSIv2SSLTaggedComponentHandlerImpl.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -48,19 +49,10 @@ public class CSIv2SSLTaggedComponentHandlerImpl extends org.omg.CORBA.LocalObjec private final String baseMsg = CSIv2SSLTaggedComponentHandlerImpl.class.getName(); - private ORB orb; - - //////////////////////////////////////////////////// - // - // CSIv2SSLTaggedComponentHandler - // - @Override public TaggedComponent insert(IORInfo iorInfo, List clusterInstanceInfo) { try { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "{0}.insert->:", baseMsg); - } + _logger.log(Level.FINE, "{0}.insert->:", baseMsg); List socketInfos = new ArrayList<>(); for (ClusterInstanceInfo clInstInfo : clusterInstanceInfo) { @@ -71,13 +63,11 @@ public TaggedComponent insert(IORInfo iorInfo, List cluster } } IIOPSSLUtil sslUtil = null; - if (Globals.getDefaultHabitat() != null) { - sslUtil = Globals.getDefaultHabitat().getService(IIOPSSLUtil.class); - return sslUtil.createSSLTaggedComponent(iorInfo, socketInfos); - } else { + if (Globals.getDefaultHabitat() == null) { return null; } - + sslUtil = Globals.getDefaultHabitat().getService(IIOPSSLUtil.class); + return sslUtil.createSSLTaggedComponent(iorInfo, socketInfos); } finally { if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "{0}.insert<-: {1}", new Object[] {baseMsg, null}); @@ -90,63 +80,38 @@ public TaggedComponent insert(IORInfo iorInfo, List cluster public List extract(IOR ior) { List socketInfo = null; try { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "{0}.extract->:", baseMsg); - } - - // IIOPProfileTemplate iiopProfileTemplate = - // (IIOPProfileTemplate)ior.getProfile().getTaggedProfileTemplate(); - // IIOPAddress primary = iiopProfileTemplate.getPrimaryAddress() ; - // String host = primary.getHost().toLowerCase(Locale.ENGLISH); + _logger.log(Level.FINE, "{0}.extract->:", baseMsg); IIOPSSLUtil sslUtil = null; if (Globals.getDefaultHabitat() != null) { sslUtil = Globals.getDefaultHabitat().getService(IIOPSSLUtil.class); - socketInfo = (List) sslUtil.getSSLPortsAsSocketInfo(ior); + socketInfo = sslUtil.getSSLPortsAsSocketInfo(ior); } if (socketInfo == null) { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "{0}.extract: did not find SSL SocketInfo", baseMsg); - } + _logger.log(Level.FINE, "{0}.extract: did not find SSL SocketInfo", baseMsg); } else { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "{0}.extract: found SSL socketInfo", baseMsg); - } - } - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "{0}.extract: Connection Context", baseMsg); + _logger.log(Level.FINE, "{0}.extract: found SSL socketInfo", baseMsg); } - } catch (Exception ex) { - _logger.log(Level.WARNING, "Exception getting SocketInfo", ex); + _logger.log(Level.FINE, "{0}.extract: Connection Context", baseMsg); + return socketInfo; + } catch (Exception e) { + throw new IllegalStateException("Exception getting SocketInfo", e); } finally { if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "{0}.extract<-: {1}", new Object[] {baseMsg, socketInfo}); } } - return socketInfo; } - //////////////////////////////////////////////////// - // - // ORBConfigurator - // - @Override public void configure(DataCollector collector, ORB orb) { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, ".configure->:"); - } - - this.orb = orb; + _logger.log(Level.FINE, ".configure->:"); try { orb.register_initial_reference(ORBConstants.CSI_V2_SSL_TAGGED_COMPONENT_HANDLER, this); - } catch (InvalidName e) { - _logger.log(Level.WARNING, ".configure: ", e); - } - - if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, ".configure<-:"); + } catch (InvalidName e) { + throw new IllegalStateException(e.getMessage(), e); } } } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBFactoryImpl.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBFactoryImpl.java index 6fd1da2c992..577655cd7e5 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBFactoryImpl.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBFactoryImpl.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -13,43 +14,42 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.enterprise.iiop.impl; +import com.sun.enterprise.deployment.EjbDescriptor; + import jakarta.inject.Inject; +import java.lang.System.Logger; import java.util.Properties; import org.glassfish.enterprise.iiop.api.GlassFishORBFactory; -import org.glassfish.enterprise.iiop.util.IIOPUtils; import org.glassfish.hk2.api.PostConstruct; import org.glassfish.hk2.api.ServiceLocator; import org.jvnet.hk2.annotations.Service; +import org.omg.CORBA.INV_POLICY; import org.omg.CORBA.ORB; +import org.omg.PortableInterceptor.IORInfo; import org.omg.PortableInterceptor.ServerRequestInfo; +import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.TRACE; + /** - * @author Mahesh Kannan - * Date: Jan 15, 2009 + * @author Mahesh Kannan 2009 */ @Service -public class GlassFishORBFactoryImpl - implements GlassFishORBFactory, PostConstruct { - - @Inject - private ServiceLocator habitat; +public class GlassFishORBFactoryImpl implements GlassFishORBFactory, PostConstruct { + private static final Logger LOG = System.getLogger(GlassFishORBFactoryImpl.class.getName()); @Inject - private IIOPUtils iiopUtils; + private ServiceLocator serviceLocator; - private GlassFishORBManager gfORBManager = null; + private GlassFishORBManager gfORBManager; @Override public void postConstruct() { - gfORBManager = new GlassFishORBManager(habitat); - - IIOPUtils.setInstance(iiopUtils); - //iiopUtils.setGlassFishORBManager(gfORBManager); + this.gfORBManager = new GlassFishORBManager(serviceLocator); } @Override @@ -64,8 +64,7 @@ public int getCSIv2PolicyType() { @Override public ORB createORB(Properties props) { - // TODO change this to a create call - return gfORBManager.getORB(props); + return gfORBManager.createOrb(props); } @Override @@ -103,13 +102,29 @@ public int getORBPort(ORB orb) { * method calls as new request starts. */ @Override - public boolean isEjbCall (ServerRequestInfo sri) { - return (gfORBManager.isEjbAdapterName(sri.adapter_name()) && - (!gfORBManager.isIsACall(sri.operation()))); + public boolean isEjbCall(ServerRequestInfo sri) { + return gfORBManager.isEjbAdapterName(sri.adapter_name()) && !"_is_a".equals(sri.operation()); } @Override public String getIIOPEndpoints() { - return gfORBManager.getIIOPEndpoints() ; + return gfORBManager.getIIOPEndpoints(); + } + + public EjbDescriptor getEjbDescriptor(IORInfo iorInfo) { + CSIv2Policy csiv2Policy = null; + try { + csiv2Policy = (CSIv2Policy) iorInfo.get_effective_policy(getCSIv2PolicyType()); + } catch (INV_POLICY e) { + LOG.log(TRACE, "CSIv2Policy cound not be loaded", e); + } + LOG.log(DEBUG, "CSIv2Policy: {0}", csiv2Policy); + + // Add CSIv2 tagged component for this EJB type. + + if (csiv2Policy != null) { + return csiv2Policy.getEjbDescriptor(); + } + return null; } } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBInitializer.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBInitializer.java index ea0554f9fb4..ce8d953aec6 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBInitializer.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBInitializer.java @@ -19,7 +19,7 @@ import com.sun.logging.LogDomains; -import java.util.Collection; +import java.util.List; import java.util.logging.Logger; import org.glassfish.enterprise.iiop.api.IIOPInterceptorFactory; @@ -46,6 +46,7 @@ */ public class GlassFishORBInitializer extends org.omg.CORBA.LocalObject implements ORBInitializer { + private static final long serialVersionUID = 1L; private static final Logger LOG = LogDomains.getLogger(GlassFishORBInitializer.class, LogDomains.CORBA_LOGGER); /** @@ -79,7 +80,7 @@ public void post_init(ORBInitInfo info) { try { Codec codec = cf.create_codec(encoding); IIOPUtils iiopUtils = IIOPUtils.getInstance(); - Collection interceptorFactories = iiopUtils.getAllIIOPInterceptrFactories(); + List interceptorFactories = iiopUtils.getAllIIOPInterceptrFactories(); for (IIOPInterceptorFactory factory : interceptorFactories) { LOG.log(FINE, "Processing interceptor factory: {0}", factory); diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBManager.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBManager.java index cab58a6799b..1bd56a138c0 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBManager.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishORBManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -17,45 +17,30 @@ package org.glassfish.enterprise.iiop.impl; -import com.sun.corba.ee.impl.folb.InitialGroupInfoService ; -import com.sun.corba.ee.impl.javax.rmi.CORBA.StubDelegateImpl; -import com.sun.corba.ee.impl.javax.rmi.CORBA.Util; -import com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject; -import com.sun.corba.ee.impl.orb.ORBImpl; -import com.sun.corba.ee.impl.orb.ORBSingleton; -import com.sun.corba.ee.spi.misc.ORBConstants; +import com.sun.corba.ee.spi.folb.GroupInfoService; import com.sun.corba.ee.spi.oa.rfm.ReferenceFactoryManager; -import com.sun.corba.ee.spi.orb.ORB ; -import com.sun.corba.ee.spi.osgi.ORBFactory; -import com.sun.enterprise.config.serverbeans.SslClientConfig; import com.sun.enterprise.module.HK2Module; import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.module.ResolveError; import com.sun.enterprise.util.Utility; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; -import org.glassfish.enterprise.iiop.api.GlassFishORBLifeCycleListener; import org.glassfish.enterprise.iiop.util.IIOPUtils; -import org.glassfish.grizzly.config.dom.Ssl; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.internal.api.ORBLocator; import org.glassfish.orb.admin.config.IiopListener; import org.glassfish.orb.admin.config.IiopService; import org.glassfish.orb.admin.config.Orb; -import org.jvnet.hk2.config.types.Property; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ORBPackage.InvalidName; -import static org.glassfish.main.jdke.props.SystemProperties.setProperty; +import static com.sun.corba.ee.spi.misc.ORBConstants.REFERENCE_FACTORY_MANAGER; /** * This class initializes the ORB with a list of (standard) properties @@ -65,153 +50,44 @@ public final class GlassFishORBManager { private static final Logger LOG = IIOPImplLogFacade.getLogger(GlassFishORBManager.class); - private static final Properties EMPTY_PROPERTIES = new Properties(); - - // Various pluggable classes defined in the app server that are used - // by the ORB. - private static final String ORB_CLASS = ORBImpl.class.getName(); - private static final String ORB_SINGLETON_CLASS = ORBSingleton.class.getName(); - - private static final String PEORB_CONFIG_CLASS = PEORBConfigurator.class.getName(); - private static final String IIOP_SSL_SOCKET_FACTORY_CLASS = IIOPSSLSocketFactory.class.getName(); - private static final String RMI_UTIL_CLASS = Util.class.getName(); - private static final String RMI_STUB_CLASS = StubDelegateImpl.class.getName(); - private static final String RMI_PRO_CLASS = PortableRemoteObject.class.getName(); - - // JNDI constants - public static final String JNDI_PROVIDER_URL_PROPERTY = "java.naming.provider.url"; - public static final String JNDI_CORBA_ORB_PROPERTY = "java.naming.corba.orb"; - - // RMI-IIOP delegate constants - public static final String ORB_UTIL_CLASS_PROPERTY = "javax.rmi.CORBA.UtilClass"; - public static final String RMIIIOP_STUB_DELEGATE_CLASS_PROPERTY = "javax.rmi.CORBA.StubClass"; - public static final String RMIIIOP_PRO_DELEGATE_CLASS_PROPERTY = "javax.rmi.CORBA.PortableRemoteObjectClass"; - - // ORB constants: OMG standard - public static final String OMG_ORB_CLASS_PROPERTY = "org.omg.CORBA.ORBClass"; - public static final String OMG_ORB_SINGLETON_CLASS_PROPERTY = "org.omg.CORBA.ORBSingletonClass"; - - // ORB constants: Sun specific - public static final String SUN_ORB_SOCKET_FACTORY_CLASS_PROPERTY = ORBConstants.SOCKET_FACTORY_CLASS_PROPERTY; - - // ORB configuration constants - private static final String DEFAULT_SERVER_ID = "100"; - private static final String ACC_DEFAULT_SERVER_ID = "101"; - private static final String USER_DEFINED_ORB_SERVER_ID_PROPERTY = "org.glassfish.orb.iiop.orbserverid"; - - private static final String DEFAULT_MAX_CONNECTIONS = "1024"; - private static final String GLASSFISH_INITIALIZER = GlassFishORBInitializer.class.getName(); - - private static final String SUN_GIOP_DEFAULT_FRAGMENT_SIZE = "1024"; - private static final String SUN_GIOP_DEFAULT_BUFFER_SIZE = "1024"; - - public static final String DEFAULT_ORB_INIT_HOST = "localhost"; - - // This will only apply for stand-alone java clients, since - // in the server the orb port comes from domain.xml, and in an appclient - // the port is set from the sun-acc.xml. It's set to the same - // value as the default orb port in domain.xml as a convenience. - // That way the code only needs to do a "new InitialContext()" - // without setting any jvm properties and the naming service will be - // found. Of course, if the port was changed in domain.xml for some - // reason the code will still have to set org.omg.CORBA.ORBInitialPort. - public static final String DEFAULT_ORB_INIT_PORT = "3700"; - private static final String ORB_SSL_STANDALONE_CLIENT_REQUIRED = "com.sun.CSIV2.ssl.standalone.client.required"; - // We need this to get the ORB monitoring set up correctly - private static final String S1AS_ORB_ID = "S1AS-ORB"; - private static final String IIOP_ENDPOINTS_PROPERTY = "com.sun.appserv.iiop.endpoints"; - private static final String IIOP_URL = "iiop:1.2@"; - // Set in constructor private final ServiceLocator services; private final IIOPUtils iiopUtils; - // the ORB instance - private ORB orb; - - // The ReferenceFactoryManager from the orb. - private ReferenceFactoryManager rfm; - - private int orbInitialPort = -1; + private final int orbInitialPort; - private List iiopListeners; - private Orb orbBean; - private IiopService iiopService; + private final List iiopListeners; + private final IiopService iiopService; private final Properties csiv2Props = new Properties(); private final ProcessType processType; - private IiopFolbGmsClient gmsClient; + private final IiopFolbGmsClient gmsClient; - /** - * Keep this class private to the package. Eventually we need to - * move all public statics or change them to package private. - * All external orb/iiop access should go through orb-connector module - */ - GlassFishORBManager(ServiceLocator h ) { - LOG.log(Level.CONFIG, "GlassFishORBManager({0})", h); - services = h; - iiopUtils = services.getService(IIOPUtils.class); - ProcessEnvironment processEnv = services.getService(ProcessEnvironment.class); - processType = processEnv.getProcessType(); - initProperties(); - } + private final Orb orbConfig; - /** - * Returns whether an adapterName (from ServerRequestInfo.adapter_name) - * represents an EJB or not. - * @param adapterName The adapter name - * @return whether this adapter is an EJB or not - */ - public boolean isEjbAdapterName(String[] adapterName) { - boolean result = false; - if (rfm != null) { - result = rfm.isRfmName(adapterName); - } - return result; - } + // The ReferenceFactoryManager from the orb. + private ReferenceFactoryManager rfm; - /** - * Returns whether the operationName corresponds to an "is_a" call - * or not (used to implement PortableRemoteObject.narrow. - */ - boolean isIsACall(String operationName) { - return operationName.equals("_is_a"); - } /** - * Return the shared ORB instance for the app server. - * If the ORB is not already initialized, it is created - * with the standard server properties, which can be - * overridden by Properties passed in the props argument. + * Keep this class private to the package. + * Eventually we need to move all public statics or change them to package private. + * All external orb/iiop access should go through orb-connector module. */ - synchronized ORB getORB(Properties props) { - LOG.log(Level.FINEST, "getORB({0})", props); - if (orb == null) { - initORB(props); - LOG.log(Level.INFO, "ORB initialization succeeded: {0}", orb); - } - return orb; - } - - Properties getCSIv2Props() { - // Return a copy of the CSIv2Props - return new Properties(csiv2Props); - } - - void setCSIv2Prop(String name, String value) { - csiv2Props.setProperty(name, value); - } + GlassFishORBManager(ServiceLocator serviceLocator) { + LOG.log(Level.CONFIG, "GlassFishORBManager({0})", serviceLocator); + services = serviceLocator; + iiopUtils = services.getService(IIOPUtils.class); + ProcessEnvironment processEnv = services.getService(ProcessEnvironment.class); + processType = processEnv.getProcessType(); - int getORBInitialPort() { - return orbInitialPort; - } + LOG.log(Level.FINEST, "processType: {0}", processType); + gmsClient = processType.isServer() ? new IiopFolbGmsClient(serviceLocator) : null; - private void initProperties() { - LOG.log(Level.FINEST, "initProperties(); processType: {0}", processType); if (processType != ProcessType.ACC) { String sslClientRequired = System.getProperty(ORB_SSL_STANDALONE_CLIENT_REQUIRED); if ("true".equals(sslClientRequired)) { @@ -220,20 +96,20 @@ private void initProperties() { } if (!processType.isServer()) { - // No access to domain.xml. Just init properties. + // No access to domain.xml. Just init properties. // In this case iiopListener beans will be null. - checkORBInitialPort(EMPTY_PROPERTIES); + orbInitialPort = OrbCreator.evaluateInitialPort(null, List.of()); + orbConfig = null; + iiopService = null; + iiopListeners = List.of(); return; } iiopService = iiopUtils.getIiopService(); - iiopListeners = iiopService.getIiopListener() ; - assert iiopListeners != null; + iiopListeners = iiopService.getIiopListener(); // checkORBInitialPort looks at iiopListenerBeans, if present - checkORBInitialPort(EMPTY_PROPERTIES); - - orbBean = iiopService.getOrb(); - assert orbBean != null; + orbInitialPort = OrbCreator.evaluateInitialPort(null, iiopListeners); + orbConfig = iiopService.getOrb(); // Initialize IOR security config for non-EJB CORBA objects //iiopServiceBean.isClientAuthenticationRequired())); @@ -254,470 +130,69 @@ private void initProperties() { } /** - * Set ORB-related system properties that are required in case - * user code in the app server or app client container creates a - * new ORB instance. The default result of calling - * ORB.init( String[], Properties ) must be a fully usuable, consistent - * ORB. This avoids difficulties with having the ORB class set - * to a different ORB than the RMI-IIOP delegates. - */ - private void setORBSystemProperties() { - setProperty(OMG_ORB_CLASS_PROPERTY, ORB_CLASS, false); - setProperty(OMG_ORB_SINGLETON_CLASS_PROPERTY, ORB_SINGLETON_CLASS, false); - setProperty(ORB_UTIL_CLASS_PROPERTY, RMI_UTIL_CLASS, true); - setProperty(RMIIIOP_STUB_DELEGATE_CLASS_PROPERTY, RMI_STUB_CLASS, true); - setProperty(RMIIIOP_PRO_DELEGATE_CLASS_PROPERTY, RMI_PRO_CLASS, true); - } - - /** - * Set the ORB properties for IIOP failover and load balancing. + * Returns whether an adapterName (from ServerRequestInfo.adapter_name) + * represents an EJB or not. + * @param adapterName The adapter name + * @return whether this adapter is an EJB or not */ - private void setFOLBProperties(Properties orbInitProperties) { - - orbInitProperties.put(ORBConstants.RFM_PROPERTY, "dummy"); - orbInitProperties.put(ORBConstants.SOCKET_FACTORY_CLASS_PROPERTY, IIOP_SSL_SOCKET_FACTORY_CLASS); - - // ClientGroupManager. - // Registers itself as - // ORBInitializer (that registers ClientRequestInterceptor) - // IIOPPrimaryToContactInfo - // IORToSocketInfo - orbInitProperties.setProperty( - ORBConstants.USER_CONFIGURATOR_PREFIX + "com.sun.corba.ee.impl.folb.ClientGroupManager", "dummy"); - - // This configurator registers the CSIv2SSLTaggedComponentHandler - orbInitProperties.setProperty( - ORBConstants.USER_CONFIGURATOR_PREFIX + CSIv2SSLTaggedComponentHandlerImpl.class.getName(), "dummy"); - - if (processType.isServer()) { - gmsClient = new IiopFolbGmsClient(services); - - if (gmsClient.isGMSAvailable()) { - LOG.fine("GMS available and enabled - doing EE initialization"); - - // Register ServerGroupManager. - // Causes it to register itself as an ORBInitializer - // that then registers it as - // IOR and ServerRequest Interceptors. - orbInitProperties.setProperty( - ORBConstants.USER_CONFIGURATOR_PREFIX + "com.sun.corba.ee.impl.folb.ServerGroupManager", "dummy"); - LOG.finest("Did EE property initialization"); - } - } - } - - private void initORB(Properties props) { - try { - LOG.log(Level.CONFIG, "initORB({0})", props); - setORBSystemProperties(); - - Properties orbInitProperties = new Properties(); - orbInitProperties.putAll(props); - - orbInitProperties.put(ORBConstants.APPSERVER_MODE, "true"); - - // The main configurator. - orbInitProperties.put(ORBConstants.USER_CONFIGURATOR_PREFIX + PEORB_CONFIG_CLASS, "dummy"); - - setFOLBProperties(orbInitProperties); - - // Standard OMG Properties. - String orbDefaultServerId = DEFAULT_SERVER_ID; - if (!processType.isServer()) { - orbDefaultServerId = ACC_DEFAULT_SERVER_ID; - } - - orbDefaultServerId = System.getProperty(USER_DEFINED_ORB_SERVER_ID_PROPERTY, orbDefaultServerId); - orbInitProperties.put(ORBConstants.ORB_SERVER_ID_PROPERTY, orbDefaultServerId); - orbInitProperties.put(OMG_ORB_CLASS_PROPERTY, ORB_CLASS); - orbInitProperties.put(ORBConstants.PI_ORB_INITIALIZER_CLASS_PREFIX + GLASSFISH_INITIALIZER, ""); - orbInitProperties.put(ORBConstants.ALLOW_LOCAL_OPTIMIZATION, "true"); - orbInitProperties.put(ORBConstants.GET_SERVICE_CONTEXT_RETURNS_NULL, "true"); - orbInitProperties.put(ORBConstants.ORB_ID_PROPERTY, S1AS_ORB_ID); - orbInitProperties.put(ORBConstants.SHOW_INFO_MESSAGES, "true"); - - // Do this even if propertiesInitialized, since props may override - // ORBInitialHost and port. - String initialPort = checkORBInitialPort(orbInitProperties); - - String orbInitialHost = checkORBInitialHost(orbInitProperties); - String endpointsProperty = System.getProperty(IIOP_ENDPOINTS_PROPERTY); - String[] orbInitRefArgs; - if (endpointsProperty != null && !endpointsProperty.isEmpty()) { - orbInitRefArgs = getORBInitRef(endpointsProperty); - } else { - // Add -ORBInitRef for INS to work - orbInitRefArgs = getORBInitRef(orbInitialHost, initialPort); - } - - // In a server, don't configure any default acceptors so that lazy init - // can be used. Actual lazy init setup takes place in PEORBConfigurator - if (processType.isServer()) { - validateIiopListeners(); - orbInitProperties.put(ORBConstants.NO_DEFAULT_ACCEPTORS, "true"); - // 14734893 - IIOP ports don't bind to the network address set for the cluster instance - // GLASSFISH-17469 IIOP Listener Network Address Setting Ignored - checkORBServerHost(orbInitProperties); - } - - checkConnectionSettings(orbInitProperties); - checkMessageFragmentSize(orbInitProperties); - checkServerSSLOutboundSettings(orbInitProperties); - checkForOrbPropertyValues(orbInitProperties); - - Collection lcListeners = iiopUtils.getGlassFishORBLifeCycleListeners(); - - List argsList = new ArrayList<>(); - argsList.addAll(Arrays.asList(orbInitRefArgs)); - - for (GlassFishORBLifeCycleListener listener : lcListeners) { - listener.initializeORBInitProperties(argsList, orbInitProperties); - } - - String[] args = argsList.toArray(new String[argsList.size()]); - - // The following is done only on the Server Side to set the - // ThreadPoolManager in the ORB. ThreadPoolManager on the server - // is initialized based on configuration parameters found in - // domain.xml. On the client side this is not done - - if (processType.isServer()) { - PEORBConfigurator.setThreadPoolManager(); - } - - // orb MUST be set before calling getFVDCodeBaseIOR, or we can - // recurse back into initORB due to interceptors that run - // when the TOA supporting the FVD is created! - // DO NOT MODIFY initORB to return ORB!!! - - /** - * we can't create object adapters inside the ORB init path, - * or else we'll get this same problem in slightly different ways. - * (address in use exception) Having an IORInterceptor - * (TxSecIORInterceptor) get called during ORB init always - * results in a nested ORB.init call because of the call to getORB - * in the IORInterceptor.i - */ - - // TODO Right now we need to explicitly set useOSGI flag. If it's set to - // OSGI mode and we're not in OSGI mode, orb initialization fails. - boolean useOSGI = false; - - final ClassLoader prevCL = Utility.getClassLoader(); - try { - Utility.setContextClassLoader(GlassFishORBManager.class.getClassLoader()); - - if (processType.isServer()) { - // start glassfish-corba-orb bundle - ModulesRegistry modulesRegistry = services.getService(ModulesRegistry.class); - HK2Module corbaOrbModule = null; - for (HK2Module m : modulesRegistry.getModules()) { - if (m.getName().equals("glassfish-corba-orb")) { - corbaOrbModule = m; - break; - } - } - - if (corbaOrbModule != null) { - useOSGI = true; - corbaOrbModule.start(); - } - } - } finally { - Utility.setContextClassLoader(prevCL); - } - - // Can't run with GlassFishORBManager.class.getClassLoader() as the context ClassLoader - - // For ORB compatibility with JDK11+ JDKs see https://github.com/eclipse-ee4j/orb-gmbal/issues/22 - setProperty("org.glassfish.gmbal.no.multipleUpperBoundsException", "true", true); - orb = ORBFactory.create(); - ORBFactory.initialize(orb, args, orbInitProperties, useOSGI); - - // Done to indicate this is a server and needs to create listen ports. - try { - orb.resolve_initial_references("RootPOA"); - } catch (org.omg.CORBA.ORBPackage.InvalidName e) { - LOG.log(Level.SEVERE, IIOPImplLogFacade.INVALID_ROOT_POA_NAME, e); - } - - if (processType.isServer()) { - // This MUST happen before new InitialGroupInfoService, - // or the ServerGroupManager will get initialized before the - // GIS is available. - gmsClient.setORB(orb) ; - - // J2EEServer's persistent server port is same as ORBInitialPort. - orbInitialPort = getORBInitialPort(); - - for (GlassFishORBLifeCycleListener listener : lcListeners) { - listener.orbCreated(orb); - } - - // TODO: The following statement can be moved to - // some GlassFishORBLifeCycleListeners - - rfm = (ReferenceFactoryManager) orb.resolve_initial_references(ORBConstants.REFERENCE_FACTORY_MANAGER); - new InitialGroupInfoService(orb); - iiopUtils.setORB(orb); - } - - // SeeBeyond fix for 6325988: needs testing. - // Still do not know why this might make any difference. - // Invoke this for its side-effects: ignore returned IOR. - orb.getFVDCodeBaseIOR(); - } catch (Exception ex) { - LOG.log(Level.SEVERE, IIOPImplLogFacade.ORB_INITIALIZATION_FAILED, ex); - throw new IllegalStateException("ORB initialization failed.", ex); - } - } - - private String checkForAddrAny(Properties props, String orbInitialHost) { - if (orbInitialHost.equals("0.0.0.0") || orbInitialHost.equals("::") - || orbInitialHost.equals("::ffff:0.0.0.0")) { - try { - return InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException uhe) { - LOG.log(Level.WARNING, "Unknown host exception - Setting host to localhost"); - return DEFAULT_ORB_INIT_HOST; - } - } - return orbInitialHost; - } - - // Returns the first IiopListenerBean which represents a clear text endpoint - // Note: it is questionable whether the system actually support multiple - // endpoints of the same type, or no clear text endpoint at all in the - // configuration. - private IiopListener getClearTextIiopListener() { - if (iiopListeners != null) { - for (IiopListener il : iiopListeners) { - if (il.getSsl() == null) { - return il ; - } - } + public boolean isEjbAdapterName(String[] adapterName) { + if (rfm == null) { + return false; } - - return null ; + return rfm.isRfmName(adapterName); } - private String checkORBInitialHost(Properties props) { - // Host setting in system properties always takes precedence. - String initialHost = System.getProperty(ORBConstants.INITIAL_HOST_PROPERTY); - if (initialHost == null) { - initialHost = props.getProperty(ORBConstants.INITIAL_HOST_PROPERTY); - } - - if (initialHost == null) { - IiopListener il = getClearTextIiopListener(); - if (il != null) { - initialHost = il.getAddress(); - } - } - - if (initialHost == null) { - initialHost = DEFAULT_ORB_INIT_HOST; - } - - initialHost = checkForAddrAny(props, initialHost); - props.setProperty(ORBConstants.INITIAL_HOST_PROPERTY, initialHost); - LOG.log(Level.CONFIG, "ORB initial host set to {0}", initialHost); - return initialHost; + Properties getCSIv2Props() { + // Return a copy of the CSIv2Props + return new Properties(csiv2Props); } - - private String checkORBInitialPort(Properties props) { - // Port setting in system properties always takes precedence. - String initialPort = System.getProperty( - ORBConstants.INITIAL_PORT_PROPERTY ); - - if (initialPort == null) { - initialPort = props.getProperty(ORBConstants.INITIAL_PORT_PROPERTY); - } - - if (initialPort == null) { - IiopListener listener = getClearTextIiopListener(); - if (listener != null) { - initialPort = listener.getPort(); - } - } - - if (initialPort == null) { - initialPort = DEFAULT_ORB_INIT_PORT; - } - - // Make sure we set initial port in System properties so that - // any instantiations of org.glassfish.jndi.cosnaming.CNCtxFactory - // use same port. - props.setProperty(ORBConstants.INITIAL_PORT_PROPERTY, initialPort); - - - // Done to initialize the Persistent Server Port, before any - // POAs are created. This was earlier done in POAEJBORB - // Do it only in the appserver, not on appclient. - if (processType.isServer()) { - props.setProperty(ORBConstants.PERSISTENT_SERVER_PORT_PROPERTY, initialPort); - } - - LOG.log(Level.CONFIG, "ORB initial port set to {0}", initialPort); - orbInitialPort = Integer.parseInt(initialPort); - return initialPort; + void setCSIv2Prop(String name, String value) { + csiv2Props.setProperty(name, value); } - // Server host property is used only for ORB running in server mode - // Return host name (or ip address string) if the SERVER_HOST PROPERTY is set or - // network-address attribute is specified in iiop-listener element - // Return null otherwise. - private String checkORBServerHost(Properties props) { - // Host setting in system properties always takes precedence. - String serverHost = System.getProperty(ORBConstants.SERVER_HOST_PROPERTY); - - if (serverHost == null) { - serverHost = props.getProperty(ORBConstants.SERVER_HOST_PROPERTY ); - } - - if (serverHost == null) { - IiopListener listener = getClearTextIiopListener() ; - if (listener != null) { - // For this case, use same value as ORBInitialHost, - serverHost = listener.getAddress(); - } - } - - if (serverHost != null) { - // set the property, to be used during ORB initialization - // Bug 14734893 - IIOP ports don't bind to the network address set for the cluster instance - props.setProperty(ORBConstants.SERVER_HOST_PROPERTY, serverHost); - LOG.log(Level.CONFIG, "ORB server host set to {0}", serverHost); - } - - return serverHost; + int getORBInitialPort() { + return orbInitialPort; } - private void validateIiopListeners() { - if (iiopListeners == null) { - return; - } - var lazyListeners = iiopListeners.stream() - .filter(ilb -> Boolean.valueOf(ilb.getLazyInit())).collect(Collectors.toList()); - - if (lazyListeners.size() > 1) { - throw new IllegalStateException( - "Only one iiop-listener can be configured with lazy-init=true. " - + lazyListeners.stream().map(ilb -> ilb.getId()).collect(Collectors.toList())); - } - - var lazySslListeners = lazyListeners.stream() - .filter(ilb -> Boolean.valueOf(ilb.getSecurityEnabled()) && ilb.getSsl() != null).collect(Collectors.toList()); - - if (lazySslListeners.size() > 0) { - throw new IllegalStateException( - "Lazy-init not supported for SSL iiop-listeners. " - + lazySslListeners.stream().map(ilb -> ilb.getId()).collect(Collectors.toList())); - } + String getIIOPEndpoints() { + return gmsClient.getIIOPEndpoints() ; } - private void checkConnectionSettings(Properties props) { - if (orbBean != null) { - String maxConnections = orbBean.getMaxConnections(); - try { - Integer.parseInt(maxConnections); - } catch (NumberFormatException nfe) { - LOG.log(Level.WARNING, IIOPImplLogFacade.INVALID_MAX_CONNECTIONS, - new Object[] {maxConnections, DEFAULT_MAX_CONNECTIONS}); - maxConnections = DEFAULT_MAX_CONNECTIONS; - } - props.setProperty(ORBConstants.HIGH_WATER_MARK_PROPERTY, maxConnections); + ORB createOrb(Properties props) { + final HK2Module orbOsgiModule = resolveCorbaOrbOsgiModule(); + final GroupInfoService clusterGroupInfo; + if (processType.isServer() && gmsClient.isGMSAvailable()) { + clusterGroupInfo = gmsClient.getGroupInfoService(); + } else { + clusterGroupInfo = null; } - } - - private void checkMessageFragmentSize(Properties props) { - if (orbBean != null) { - String fragmentSize = null; - String bufferSize = null; - try { - int fsize = ((Integer.parseInt(orbBean.getMessageFragmentSize().trim())) / 8) * 8; - if (fsize < 32) { - fragmentSize = "32"; - LOG.log(Level.INFO, "Setting ORB Message Fragment size to {0}", fragmentSize); - } else { - fragmentSize = String.valueOf(fsize); - } - bufferSize = fragmentSize; - } catch (NumberFormatException nfe) { - LOG.log(Level.WARNING, IIOPImplLogFacade.INVALID_MESSAGE_FRAGMENT_SIZE, - new Object[] {fragmentSize, SUN_GIOP_DEFAULT_FRAGMENT_SIZE}); - fragmentSize = SUN_GIOP_DEFAULT_FRAGMENT_SIZE; - bufferSize = SUN_GIOP_DEFAULT_BUFFER_SIZE; - } - props.setProperty(ORBConstants.GIOP_FRAGMENT_SIZE, fragmentSize); - props.setProperty(ORBConstants.GIOP_BUFFER_SIZE, bufferSize); + final OrbCreator creator = new OrbCreator(orbConfig, processType, clusterGroupInfo, iiopListeners, orbOsgiModule); + com.sun.corba.ee.spi.orb.ORB orb = creator.createOrb(props); + try { + this.rfm = (ReferenceFactoryManager) orb.resolve_initial_references(REFERENCE_FACTORY_MANAGER); + } catch (InvalidName e) { + throw new IllegalStateException("ReferenceFactoryManager not found in ORB", e); } + return orb; } - - private void checkServerSSLOutboundSettings(Properties props) { - if (iiopService != null) { - SslClientConfig sslClientConfigBean = iiopService.getSslClientConfig(); - if (sslClientConfigBean != null) { - Ssl ssl = sslClientConfigBean.getSsl(); - assert (ssl != null); - } + private HK2Module resolveCorbaOrbOsgiModule() throws ResolveError { + if (!processType.isServer()) { + return null; } - } - - private void checkForOrbPropertyValues(Properties props) { - if (orbBean != null) { - List orbBeanProps = orbBean.getProperty(); - if (orbBeanProps != null) { - for (Property orbBeanProp : orbBeanProps) { - props.setProperty(orbBeanProp.getName(), - orbBeanProp.getValue()); + final ClassLoader originalClassLoader = Utility.getClassLoader(); + try { + Utility.setContextClassLoader(OrbCreator.class.getClassLoader()); + ModulesRegistry modulesRegistry = services.getService(ModulesRegistry.class); + for (HK2Module module : modulesRegistry.getModules()) { + if ("glassfish-corba-orb".equals(module.getName())) { + return module; } } + return null; + } finally { + Utility.setContextClassLoader(originalClassLoader); } } - - private String[] getORBInitRef(String orbInitialHost, - String initialPort) { - // Add -ORBInitRef NameService=.... - // This ensures that INS will be used to talk with the NameService. - String[] newArgs = new String[] {"-ORBInitRef", - "NameService=corbaloc:" + IIOP_URL + orbInitialHost + ":" + initialPort + "/NameService"}; - - return newArgs; - } - - private String[] getORBInitRef(String endpoints) { - - String[] list = endpoints.split(","); - String corbalocURL = getCorbalocURL(list); - LOG.log(Level.FINE, "GlassFishORBManager.getORBInitRef = {0}", corbalocURL); - - // Add -ORBInitRef NameService=.... - // This ensures that INS will be used to talk with the NameService. - String[] newArgs = new String[] {"-ORBInitRef", "NameService=corbaloc:" + corbalocURL + "/NameService"}; - - return newArgs; - } - - private String getCorbalocURL(Object[] list) { - - String corbalocURL = ""; - //convert list into corbaloc url - for (Object element : list) { - LOG.log(Level.FINE, "list[i] ==> {0}", element); - if (corbalocURL.isEmpty()) { - corbalocURL = IIOP_URL + ((String) element).trim(); - } else { - corbalocURL = corbalocURL + "," + IIOP_URL + ((String) element).trim(); - } - } - LOG.log(Level.INFO, "corbaloc url ==> {0}", corbalocURL); - return corbalocURL; - } - - String getIIOPEndpoints() { - return gmsClient.getIIOPEndpoints() ; - } } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishOrbImpl.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishOrbImpl.java new file mode 100644 index 00000000000..1b97c0e788d --- /dev/null +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/GlassFishOrbImpl.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.enterprise.iiop.impl; + +import com.sun.corba.ee.impl.naming.cosnaming.TransientNameService; +import com.sun.corba.ee.impl.orb.ORBImpl; +import com.sun.corba.ee.impl.osgi.loader.OSGIListener; +import com.sun.corba.ee.spi.folb.ClusterInstanceInfo; +import com.sun.corba.ee.spi.folb.GroupInfoService; +import com.sun.corba.ee.spi.misc.ORBConstants; +import com.sun.corba.ee.spi.orb.ORB; +import com.sun.enterprise.module.HK2Module; + +import java.lang.System.Logger; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.glassfish.external.amx.AMXGlassfish; +import org.omg.CORBA.ORBPackage.InvalidName; + +import static com.sun.corba.ee.spi.misc.ORBConstants.FOLB_SERVER_GROUP_INFO_SERVICE; +import static java.lang.System.Logger.Level.DEBUG; + +class GlassFishOrbImpl extends ORBImpl { + + private static final Logger LOG = System.getLogger(GlassFishOrbImpl.class.getName()); + + private final String description; + + public GlassFishOrbImpl( + HK2Module corbaOrbOsgiModule, + GroupInfoService clusterGroupInfo, + Properties orbInitProperties, + String[] args) { + + this.description = super.toString() + "[corbaOrbModule=" + corbaOrbOsgiModule + ", clusterGroupInfo=" + + clusterGroupInfo + ", orbInitProperties=" + orbInitProperties + ", args=" + Arrays.toString(args) + "]"; + if (corbaOrbOsgiModule != null) { + corbaOrbOsgiModule.start(); + } + orbInitProperties.setProperty(ORBConstants.DISABLE_ORBD_INIT_PROPERTY, "true"); + if (corbaOrbOsgiModule != null) { + classNameResolver( + makeCompositeClassNameResolver(OSGIListener.classNameResolver(), ORB.defaultClassNameResolver())); + classCodeBaseHandler(OSGIListener.classCodeBaseHandler()); + } + setRootParentObjectName(AMXGlassfish.DEFAULT.serverMonForDAS()); + + setParameters(args, orbInitProperties); + + new TransientNameService(this); + + // Done to indicate this is a server and needs to create listen ports. + try { + resolve_initial_references("RootPOA"); + } catch (InvalidName e) { + throw new IllegalStateException("RootPOA not found", e); + } + + if (clusterGroupInfo == null) { + return; + } + + try { + register_initial_reference(FOLB_SERVER_GROUP_INFO_SERVICE, (org.omg.CORBA.Object) clusterGroupInfo); + LOG.log(DEBUG, "Naming registration complete: {0}", clusterGroupInfo); + + // Just for logging + GroupInfoService gisRef = (GroupInfoService) resolve_initial_references(FOLB_SERVER_GROUP_INFO_SERVICE); + List clusterInstances = gisRef.getClusterInstanceInfo(null); + LOG.log(DEBUG, "Results from getClusterInstanceInfo:"); + if (clusterInstances != null) { + for (ClusterInstanceInfo instance : clusterInstances) { + LOG.log(DEBUG, instance); + } + } + } catch (InvalidName e) { + throw new IllegalStateException("Registering GroupInfoService failed: {0}", e); + } + } + + @Override + public String toString() { + return description; + } +} diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPEndpointsInfo.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPEndpointsInfo.java deleted file mode 100644 index 39fbc1a01b8..00000000000 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPEndpointsInfo.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0, which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the - * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, - * version 2 with the GNU Classpath Exception, which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - */ - -package org.glassfish.enterprise.iiop.impl; - -import com.sun.corba.ee.spi.folb.ClusterInstanceInfo; -import com.sun.logging.LogDomains; - -import java.util.List; -import java.util.logging.Logger; - -import org.glassfish.enterprise.iiop.util.IIOPUtils; - -/** - * This class is responsible for reading the domain.xml via Config API - * and producing a list of instances in the form of ClusterInstanceInfo - * objects. - * This class is designed for use by both FailoverIORInterceptor - * and Java Web Start. - * @author Sheetal Vartak - * @date 1/12/05 - */ -public class IIOPEndpointsInfo { - - private static final IIOPUtils iiopUtils = IIOPUtils.getInstance(); - - private static Logger _logger = LogDomains.getLogger(IIOPEndpointsInfo.class, LogDomains.CORBA_LOGGER); - - private static final String baseMsg = IIOPEndpointsInfo.class.getName(); - - - /** - * TODO implement post V3 FCS - public static Collection getServersInCluster() { - - return iiopUtils.getServerRefs(); - } - - public static List getListenersInCluster() { - - - return iiopUtils.getIiopListeners(); - } - - **/ - - /** - * This method returns a list of SocketInfo objects for a particular - * server. This method is the common code called by - * getIIOPEndpoints() and getClusterInstanceInfo() - */ - /* - public static List getSocketInfoForServer(ServerRef serverRef, - IiopListener[] listen) { - - List listOfSocketInfo = - new LinkedList(); - String serverName = serverRef.getRef(); - String hostName = - getHostNameForServerInstance(serverName); - if (hostName == null) { - hostName = listen[0].getAddress(); - } - for (int j = 0; j < listen.length; j++) { - String id = listen[j].getId(); - String port = - getResolvedPort(listen[j], serverName); - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, - baseMsg + ".getSocketInfoForServer:" + - " adding address for "+ - serverName + "/" + id + - "/" + hostName + "/" + port); - } - listOfSocketInfo.add(new SocketInfo(id, hostName, Integer.valueOf(port))); - } - return listOfSocketInfo; - } - */ - - /** - * This method returns the endpoints in host:port,host1:port1,host2:port2,... - * format. This is called by Java Web Start - */ - public static String getIIOPEndpoints() { - // TODO FIXME - String endpoints = null; - return endpoints; - } - - /** - * This method returns a ClusterInstanceInfo list. - */ - public static List getClusterInstanceInfo() { - // TODO FIXME - return null; - } - - /** - * The following returns the IIOP listener(s) for all the - * servers belonging to the current cluster. - * - * @author satish.viswanatham@sun.com - * - */ - /* - public static IiopListener[][] getIIOPEndPointsForCurrentCluster() { - // For each server instance in a cluster, there are 3 iiop listeners: - // one for non ssl, one for ssl and third for ssl mutual auth - - IiopListener[][] listeners = new IiopListener[serverRefs.length][3]; //SHEETAL can there be multiple SSL or - //SSL_MUTH_AUTH ports? bug 6321813 - for (int i = 0; i < serverRefs.length; i++) { - Server server = - ServerHelper.getServerByName(configCtx, serverRefs[i].getRef()); - String configRef = server.getConfigRef(); - Config config = - ConfigAPIHelper.getConfigByName(configCtx, configRef); - IiopService iiopService = config.getIiopService(); - listeners[i] = iiopService.getIiopListener(); - } - return listeners; - } - */ - /** - * Returns ip address from node agent refered from instance - * or null if Exception - * - * @author sridatta.viswanath@sun.com - */ - /* - public static String getHostNameForServerInstance(String serverName) - { - try { - JMXConnectorConfig info = - ServerHelper.getJMXConnectorInfo(configCtx, serverName); - _logger.log(Level.FINE, - baseMsg + ".getHostNameForServerInstance: " + - "found info: " + info.toString()); - String host = info.getHost(); - _logger.log(Level.FINE, - baseMsg + ".getHostNameForServerInstance: " + - "found host: " + host); - return host; - } catch (Throwable e){ - _logger.log(Level.FINE, - baseMsg + ".getHostNameForServerInstance: " + - "gotException: " + e + " " + e.getMessage() + - "; returning null"); - return null; - } - } - */ - /** - * Gets the correct resolved value for the specific instance - * Without this routine, config context resolves the value - * to the current running instance - * - * @author sridatta.viswanath@sun.com - */ - /* - public static String getResolvedPort(IiopListener l, - String server) { - String rawPort = l.getRawAttributeValue("port"); - PropertyResolver pr = new PropertyResolver(configCtx, server); - return pr.resolve(rawPort); - } - */ -} diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPImplLogFacade.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPImplLogFacade.java index 89bf8670fb9..f5b5d14b647 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPImplLogFacade.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPImplLogFacade.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Eclipse Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -43,24 +43,6 @@ public static Logger getLogger(final Class clazz) { return Logger.getLogger(clazz.getName(), BUNDLE_NAME); } - - @LogMessageInfo( - message = "Exception converting the message fragment size {0} to integer, using default value: {1}.", - level = "WARNING") - public static final String INVALID_MESSAGE_FRAGMENT_SIZE = "AS-ORB-0001"; - - @LogMessageInfo( - message = "Exception converting the max connections value {0} to integer, using default value {1}.", - level = "WARNING") - public static final String INVALID_MAX_CONNECTIONS = "AS-ORB-0002"; - - @LogMessageInfo( - message = "Unexpected Exception in ORB initialization", - cause = "Check server.log for details", - action = "Check network configuration", - level = "SEVERE") - public static final String ORB_INITIALIZATION_FAILED = "AS-ORB-0010"; - @LogMessageInfo( message = "Invalid or unavailable RootPOA service name", cause = "Check server.log for details", diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPSSLSocketFactory.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPSSLSocketFactory.java index 023e95b5283..5ee5c69b685 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPSSLSocketFactory.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IIOPSSLSocketFactory.java @@ -239,6 +239,7 @@ private SSLInfo init(String alias, @Override public void setORB(ORB orb) { + LOG.log(Level.INFO, () -> "Setting ORB " + orb + " by thread " + Thread.currentThread()); this.orb = orb; } @@ -253,15 +254,14 @@ public void setORB(ORB orb) { */ @Override public ServerSocket createServerSocket(String type, InetSocketAddress inetSocketAddress) throws IOException { - LOG.log(Level.INFO, "Creating server socket for type =" + type + " inetSocketAddress =" + inetSocketAddress); + LOG.log(Level.INFO, () -> "Creating server socket for type =" + type + " inetSocketAddress =" + inetSocketAddress); if (type.equals(SSL_MUTUALAUTH) || type.equals(SSL) || type.equals(PERSISTENT_SSL)) { return createSSLServerSocket(type, inetSocketAddress); } final ServerSocket serverSocket; if (orb.getORBData().acceptorSocketType().equals(SOCKETCHANNEL)) { - ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); - serverSocket = serverSocketChannel.socket(); + serverSocket = ServerSocketChannel.open().socket(); } else { serverSocket = new ServerSocket(); } @@ -280,12 +280,8 @@ public ServerSocket createServerSocket(String type, InetSocketAddress inetSocket * @return the socket. */ @Override - public Socket createSocket(String type, InetSocketAddress inetSocketAddress) - throws IOException { - - if (LOG.isLoggable(Level.FINE)) { - LOG.log(Level.FINE, "createSocket(" + type + ", " + inetSocketAddress + ")"); - } + public Socket createSocket(String type, InetSocketAddress inetSocketAddress) throws IOException { + LOG.log(Level.FINE, () -> "createSocket(" + type + ", " + inetSocketAddress + ")"); try { int port = inetSocketAddress.getPort(); @@ -308,17 +304,14 @@ public Socket createSocket(String type, InetSocketAddress inetSocketAddress) socket.setTcpNoDelay(true); return socket; } catch (Exception ex) { - LOG.log(Level.FINE,"Exception creating socket",ex); - throw new RuntimeException(ex); + throw new RuntimeException("Exception creating socket", ex); } } @Override public void setAcceptedSocketOptions(Acceptor acceptor, ServerSocket serverSocket, Socket socket) { - if (LOG.isLoggable(Level.FINE)) { - LOG.log(Level.FINE, "setAcceptedSocketOptions: " + acceptor + " " + serverSocket + " " + socket); - } + LOG.log(Level.FINE, () -> "setAcceptedSocketOptions: " + acceptor + " " + serverSocket + " " + socket); // Disable Nagle's algorithm (i.e., always send immediately). try { socket.setTcpNoDelay(true); @@ -362,11 +355,11 @@ private ServerSocket createSSLServerSocket(String type, InetSocketAddress inetSo LOG.log(Level.FINE, "Setting Mutual auth"); ((SSLServerSocket) ss).setNeedClientAuth(true); } + LOG.log(Level.FINE, () -> "Created server socket: " + ss); + return ss; } catch (Exception e) { throw new IOException(e.getMessage(), e); } - LOG.log(Level.FINE, () -> "Created server socket: " + ss); - return ss; } /** @@ -376,16 +369,11 @@ private ServerSocket createSSLServerSocket(String type, InetSocketAddress inetSo * @return the socket. */ private Socket createSSLSocket(String host, int port) throws IOException { - SSLSocket socket = null; - SSLSocketFactory factory = null; try { // get socketfactory+sanity check // clientSslInfo is never null - factory = clientSslInfo.getContext().getSocketFactory(); - - if(LOG.isLoggable(Level.FINE)) { - LOG.log(Level.FINE,"Creating SSL Socket for host:" + host +" port:" + port); - } + SSLSocketFactory factory = clientSslInfo.getContext().getSocketFactory(); + LOG.log(Level.FINE,"Creating SSL Socket for host: " + host + " port: " + port); String[] ssl3TlsCiphers = clientSslInfo.getSsl3TlsCiphers(); String[] ssl2Ciphers = clientSslInfo.getSsl2Ciphers(); String[] clientCiphers = null; @@ -394,18 +382,14 @@ private Socket createSSLSocket(String host, int port) throws IOException { clientCiphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers); } - socket = (SSLSocket)factory.createSocket(host, port); + SSLSocket socket = (SSLSocket) factory.createSocket(host, port); if (clientCiphers != null) { socket.setEnabledCipherSuites(clientCiphers); } + return socket; } catch (Exception e) { - if(LOG.isLoggable(Level.FINE)) { - LOG.log(Level.FINE, "createSSLSocket failed.", new Object[] {host, port}); - LOG.log(Level.FINE, "", e); - } throw new IOException("Error opening SSL socket to host=" + host + " port=" + port, e); } - return socket; } /** @@ -424,7 +408,7 @@ private String[] getEnabledCipherSuites(String cipherSuiteStr, boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled) { String[] cipherArr = null; if (cipherSuiteStr != null && cipherSuiteStr.length() > 0) { - ArrayList cipherList = new ArrayList(); + ArrayList cipherList = new ArrayList<>(); StringTokenizer tokens = new StringTokenizer(cipherSuiteStr, ","); while (tokens.hasMoreTokens()) { String cipherAction = tokens.nextToken(); @@ -448,7 +432,7 @@ private String[] getEnabledCipherSuites(String cipherSuiteStr, } } - cipherArr = (String[]) cipherList.toArray(new String[cipherList.size()]); + cipherArr = cipherList.toArray(String[]::new); } return cipherArr; } @@ -466,24 +450,15 @@ private String[] mergeCiphers(String[] enableCiphers, return null; } - int eSize = (enableCiphers != null)? enableCiphers.length : 0; + LOG.log(Level.FINE, "Default socket ciphers: " + Arrays.toString(enableCiphers)); - if (LOG.isLoggable(Level.FINE)) { - StringBuilder buf = new StringBuilder("Default socket ciphers: "); - for (int i = 0; i < eSize; i++) { - buf.append(enableCiphers[i] + ", "); - } - LOG.log(Level.FINE, buf.toString()); - } - - ArrayList cList = new ArrayList(); + ArrayList cList = new ArrayList<>(); if (ssl3TlsCiphers != null) { for (String ssl3TlsCipher : ssl3TlsCiphers) { cList.add(ssl3TlsCipher); } } else { - for (int i = 0; i < eSize; i++) { - String cipher = enableCiphers[i]; + for (String cipher : enableCiphers) { CipherInfo cInfo = CipherInfo.getCipherInfo(cipher); if (cInfo != null && (cInfo.isTLS() || cInfo.isSSL3())) { cList.add(cipher); @@ -496,20 +471,15 @@ private String[] mergeCiphers(String[] enableCiphers, cList.add(ssl2Cipher); } } else { - for (int i = 0; i < eSize; i++) { - String cipher = enableCiphers[i]; + for (String cipher : enableCiphers) { CipherInfo cInfo = CipherInfo.getCipherInfo(cipher); if (cInfo != null && cInfo.isSSL2()) { cList.add(cipher); } } } - - if (LOG.isLoggable(Level.FINE)) { - LOG.log(Level.FINE, "Merged socket ciphers: " + cList); - } - - return (String[]) cList.toArray(new String[cList.size()]); + LOG.log(Level.FINE, "Merged socket ciphers: " + cList); + return cList.toArray(String[]::new); } /** @@ -521,12 +491,11 @@ private String[] mergeCiphers(String[] enableCiphers, */ private boolean isValidProtocolCipher(CipherInfo cipherInfo, boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled) { - return (tlsEnabled && cipherInfo.isTLS() || - ssl3Enabled && cipherInfo.isSSL3() || - ssl2Enabled && cipherInfo.isSSL2()); + return tlsEnabled && cipherInfo.isTLS() + || ssl3Enabled && cipherInfo.isSSL3() + || ssl2Enabled && cipherInfo.isSSL2(); } - private static T repeat(Action action, Duration timeout) throws IOException { final Instant deadline = Instant.now().plus(timeout); while (true) { @@ -543,8 +512,8 @@ private static T repeat(Action action, Duration timeout) throws IOExcepti class SSLInfo { private final SSLContext ctx; - private String[] ssl3TlsCiphers = null; - private String[] ssl2Ciphers = null; + private String[] ssl3TlsCiphers; + private String[] ssl2Ciphers; SSLInfo(SSLContext ctx, String[] ssl3TlsCiphers, String[] ssl2Ciphers) { this.ctx = ctx; diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java index 6b77d0227d8..cc2b093d331 100644 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/IiopFolbGmsClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -22,8 +22,6 @@ import com.sun.corba.ee.spi.folb.GroupInfoService; import com.sun.corba.ee.spi.folb.GroupInfoServiceObserver; import com.sun.corba.ee.spi.folb.SocketInfo; -import com.sun.corba.ee.spi.misc.ORBConstants; -import com.sun.corba.ee.spi.orb.ORB ; import com.sun.enterprise.config.serverbeans.Cluster; import com.sun.enterprise.config.serverbeans.Config; import com.sun.enterprise.config.serverbeans.Configs; @@ -37,18 +35,15 @@ import com.sun.enterprise.ee.cms.core.JoinedAndReadyNotificationSignal; import com.sun.enterprise.ee.cms.core.PlannedShutdownSignal; import com.sun.enterprise.ee.cms.core.Signal; -import com.sun.enterprise.ee.cms.core.SignalAcquireException; import com.sun.enterprise.ee.cms.core.SignalReleaseException; -import com.sun.logging.LogDomains; +import java.lang.System.Logger; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; import org.glassfish.config.support.GlassFishConfigBean; import org.glassfish.config.support.PropertyResolver; @@ -57,41 +52,30 @@ import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.orb.admin.config.IiopListener; import org.glassfish.orb.admin.config.IiopService; -import org.omg.CORBA.ORBPackage.InvalidName; + +import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.ERROR; +import static java.lang.System.Logger.Level.INFO; /** * @author Harold Carr */ -public class IiopFolbGmsClient implements CallBack { +class IiopFolbGmsClient implements CallBack { - private static final Logger _logger = LogDomains.getLogger(IiopFolbGmsClient.class, LogDomains.CORBA_LOGGER, false); + private static final Logger LOG = System.getLogger(IiopFolbGmsClient.class.getName()); private ServiceLocator services; - - private Domain domain ; - - private Server myServer ; - - private Nodes nodes ; - - private GMSAdapterService gmsAdapterService ; - - private GMSAdapter gmsAdapter ; - + private Domain domain; + private Server myServer; + private Nodes nodes; + private GMSAdapterService gmsAdapterService; + private GMSAdapter gmsAdapter; private Map currentMembers; - private GroupInfoService gis; - private void fineLog( String fmt, Object... args ) { - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, fmt, args); - } - } - - - public IiopFolbGmsClient(ServiceLocator services) { - fineLog("IiopFolbGmsClient: constructor: services {0}", services); + IiopFolbGmsClient(ServiceLocator services) { + LOG.log(DEBUG, "IiopFolbGmsClient: constructor: services {0}", services); this.services = services; gmsAdapterService = services.getService(GMSAdapterService.class); @@ -102,75 +86,54 @@ public IiopFolbGmsClient(ServiceLocator services) { } gmsAdapter = gmsAdapterService.getGMSAdapter(); - fineLog("IiopFolbGmsClient: gmsAdapter {0}", gmsAdapter); + LOG.log(DEBUG, "IiopFolbGmsClient: gmsAdapter {0}", gmsAdapter); - if (gmsAdapter != null) { + if (gmsAdapter == null) { + LOG.log(DEBUG, "IiopFolbGmsClient: gmsAdapterService is null"); + gis = new GroupInfoServiceNoGMSImpl(); + } else { domain = services.getService(Domain.class); - fineLog("IiopFolbGmsClient: domain {0}", domain); + LOG.log(DEBUG, "IiopFolbGmsClient: domain {0}", domain); Servers servers = services.getService(Servers.class); - fineLog("IiopFolbGmsClient: servers {0}", servers); + LOG.log(DEBUG, "IiopFolbGmsClient: servers {0}", servers); nodes = services.getService(Nodes.class); - fineLog("IiopFolbGmsClient: nodes {0}", nodes); + LOG.log(DEBUG, "IiopFolbGmsClient: nodes {0}", nodes); String instanceName = gmsAdapter.getModule().getInstanceName(); - fineLog("IiopFolbGmsClient: instanceName {0}", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient: instanceName {0}", instanceName); myServer = servers.getServer(instanceName); - fineLog("IiopFolbGmsClient: myServer {0}", myServer); + LOG.log(DEBUG, "IiopFolbGmsClient: myServer {0}", myServer); gis = new GroupInfoServiceGMSImpl(); - fineLog("IiopFolbGmsClient: IIOP GIS created"); + LOG.log(DEBUG, "IiopFolbGmsClient: IIOP GIS created"); currentMembers = getAllClusterInstanceInfo(); - fineLog("IiopFolbGmsClient: currentMembers = ", currentMembers); + LOG.log(DEBUG, "IiopFolbGmsClient: currentMembers = ", currentMembers); - fineLog("iiop instance info = " + getIIOPEndpoints()); + LOG.log(DEBUG, "iiop instance info = " + getIIOPEndpoints()); gmsAdapter.registerFailureNotificationListener(this); gmsAdapter.registerJoinedAndReadyNotificationListener(this); gmsAdapter.registerPlannedShutdownListener(this); - fineLog("IiopFolbGmsClient: GMS action factories added"); - } else { - fineLog("IiopFolbGmsClient: gmsAdapterService is null"); - gis = new GroupInfoServiceNoGMSImpl(); + LOG.log(DEBUG, "IiopFolbGmsClient: GMS action factories added"); } - } catch (Throwable t) { - _logger.log(Level.SEVERE, t.getLocalizedMessage(), t); + } catch (Exception e) { + LOG.log(ERROR, "Initialization failed.", e); } finally { - fineLog("IiopFolbGmsClient: gmsAdapter {0}", gmsAdapter); + LOG.log(DEBUG, "IiopFolbGmsClient: gmsAdapter {0}", gmsAdapter); } } - - public void setORB(ORB orb) { - try { - orb.register_initial_reference(ORBConstants.FOLB_SERVER_GROUP_INFO_SERVICE, (org.omg.CORBA.Object) gis); - fineLog(".initGIS: naming registration complete: {0}", gis); - - // Just for logging - GroupInfoService gisRef = (GroupInfoService) orb - .resolve_initial_references(ORBConstants.FOLB_SERVER_GROUP_INFO_SERVICE); - List lcii = gisRef.getClusterInstanceInfo(null); - fineLog("Results from getClusterInstanceInfo:"); - if (lcii != null) { - for (ClusterInstanceInfo cii : lcii) { - fineLog(cii.toString()); - } - } - } catch (InvalidName e) { - fineLog(".initGIS: registering GIS failed: {0}", e); - } - } - - public GroupInfoService getGroupInfoService() { + GroupInfoService getGroupInfoService() { return gis ; } - public boolean isGMSAvailable() { + boolean isGMSAvailable() { return gmsAdapter != null ; } @@ -182,62 +145,50 @@ public boolean isGMSAvailable() { @Override public void processNotification(final Signal signal) { try { - fineLog("processNotification: signal {0}", signal); + LOG.log(INFO, "processNotification: signal {0}", signal); signal.acquire(); - handleSignal(signal); - } catch (SignalAcquireException e) { - _logger.log(Level.SEVERE, e.getLocalizedMessage()); - } catch (Throwable t) { - _logger.log(Level.SEVERE, t.getLocalizedMessage(), t); + LOG.log(DEBUG, "Signal from: {0}, member details: {1}", + signal.getMemberToken(), + signal.getMemberDetails().entrySet()); + + if (signal instanceof PlannedShutdownSignal || signal instanceof FailureNotificationSignal) { + removeMember(signal); + } else if (signal instanceof JoinedAndReadyNotificationSignal) { + addMember(signal); + } else { + LOG.log(ERROR, "IiopFolbGmsClient.handleSignal: unknown signal: {0}", signal); + } + } catch (Exception e) { + LOG.log(ERROR, "Could not handle signal " + signal, e); } finally { try { signal.release(); } catch (SignalReleaseException e) { - _logger.log(Level.SEVERE, e.getLocalizedMessage()); + LOG.log(ERROR, "signal.release failed.", e); } } } - //////////////////////////////////////////////////// - // - // Implementation - // - - - private void handleSignal(final Signal signal) { - fineLog("IiopFolbGmsClient.handleSignal: signal from: {0}", signal.getMemberToken()); - fineLog("IiopFolbGmsClient.handleSignal: map entryset: {0}", signal.getMemberDetails().entrySet()); - - if (signal instanceof PlannedShutdownSignal || signal instanceof FailureNotificationSignal) { - removeMember(signal); - } else if (signal instanceof JoinedAndReadyNotificationSignal) { - addMember(signal); - } else { - _logger.log(Level.SEVERE, "IiopFolbGmsClient.handleSignal: unknown signal: {0}", signal.toString()); - } - } - - private void removeMember(final Signal signal) { String instanceName = signal.getMemberToken(); try { - fineLog("IiopFolbGmsClient.removeMember->: {0}", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.removeMember->: {0}", instanceName); synchronized (this) { if (currentMembers.get(instanceName) != null) { currentMembers.remove(instanceName); - fineLog("IiopFolbGmsClient.removeMember: {0} removed - notifying listeners", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.removeMember: {0} removed - notifying listeners", instanceName); gis.notifyObservers(); - fineLog("IiopFolbGmsClient.removeMember: {0} - notification complete", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.removeMember: {0} - notification complete", instanceName); } else { - fineLog("IiopFolbGmsClient.removeMember: {0} not present: no action", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.removeMember: {0} not present: no action", instanceName); } } } finally { - fineLog("IiopFolbGmsClient.removeMember<-: {0}", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.removeMember<-: {0}", instanceName); } } @@ -245,40 +196,40 @@ private void removeMember(final Signal signal) { private void addMember(final Signal signal) { final String instanceName = signal.getMemberToken(); try { - fineLog("IiopFolbGmsClient.addMember->: {0}", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.addMember->: {0}", instanceName); synchronized (this) { if (currentMembers.get(instanceName) != null) { - fineLog("IiopFolbGmsClient.addMember: {0} already present: no action", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.addMember: {0} already present: no action", instanceName); } else { ClusterInstanceInfo clusterInstanceInfo = getClusterInstanceInfo(instanceName); currentMembers.put(clusterInstanceInfo.name(), clusterInstanceInfo); - fineLog("IiopFolbGmsClient.addMember: {0} added - notifying listeners", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.addMember: {0} added - notifying listeners", instanceName); gis.notifyObservers(); - fineLog("IiopFolbGmsClient.addMember: {0} - notification complete", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.addMember: {0} - notification complete", instanceName); } } } finally { - fineLog("IiopFolbGmsClient.addMember<-: {0}", instanceName); + LOG.log(DEBUG, "IiopFolbGmsClient.addMember<-: {0}", instanceName); } } private int resolvePort(Server server, IiopListener listener) { - fineLog("resolvePort: server {0} listener {1}", server, listener); + LOG.log(DEBUG, "resolvePort: server {0} listener {1}", server, listener); IiopListener ilRaw = GlassFishConfigBean.getRawView(listener); - fineLog("resolvePort: ilRaw {0}", ilRaw); + LOG.log(DEBUG, "resolvePort: ilRaw {0}", ilRaw); PropertyResolver pr = new PropertyResolver(domain, server.getName()); - fineLog("resolvePort: pr {0}", pr); + LOG.log(DEBUG, "resolvePort: pr {0}", pr); String port = pr.getPropertyValue(ilRaw.getPort()); - fineLog("resolvePort: port {0}", port); + LOG.log(DEBUG, "resolvePort: port {0}", port); return Integer.parseInt(port); } @@ -295,13 +246,13 @@ private ClusterInstanceInfo getClusterInstanceInfo(Server server, Config config, } } - fineLog("getClusterInstanceInfo: server {0}, config {1}", server, config); + LOG.log(DEBUG, "getClusterInstanceInfo: server {0}, config {1}", server, config); final String name = server.getName(); - fineLog("getClusterInstanceInfo: name {0}", name); + LOG.log(DEBUG, "getClusterInstanceInfo: name {0}", name); final int weight = Integer.parseInt(server.getLbWeight()); - fineLog("getClusterInstanceInfo: weight {0}", weight); + LOG.log(DEBUG, "getClusterInstanceInfo: weight {0}", weight); final String nodeName = server.getNodeRef(); String hostName = nodeName; @@ -312,7 +263,7 @@ private ClusterInstanceInfo getClusterInstanceInfo(Server server, Config config, try { hostName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException exc) { - fineLog("getClusterInstanceInfo: caught exception for localhost lookup {0}", exc); + LOG.log(DEBUG, "getClusterInstanceInfo: caught exception for localhost lookup {0}", exc); } } else { hostName = node.getNodeHost(); @@ -320,39 +271,39 @@ private ClusterInstanceInfo getClusterInstanceInfo(Server server, Config config, } } - fineLog("getClusterInstanceInfo: host {0}", hostName); + LOG.log(DEBUG, "getClusterInstanceInfo: host {0}", hostName); final IiopService iservice = config.getExtensionByType(IiopService.class); - fineLog("getClusterInstanceInfo: iservice {0}", iservice); + LOG.log(DEBUG, "getClusterInstanceInfo: iservice {0}", iservice); final List listeners = iservice.getIiopListener(); - fineLog("getClusterInstanceInfo: listeners {0}", listeners); + LOG.log(DEBUG, "getClusterInstanceInfo: listeners {0}", listeners); final List sinfos = new ArrayList<>(); for (IiopListener il : listeners) { SocketInfo sinfo = new SocketInfo(il.getId(), hostName, resolvePort(server, il)); sinfos.add(sinfo); } - fineLog("getClusterInstanceInfo: sinfos {0}", sinfos); + LOG.log(DEBUG, "getClusterInstanceInfo: sinfos {0}", sinfos); final ClusterInstanceInfo result = new ClusterInstanceInfo(name, weight, sinfos); - fineLog("getClusterInstanceInfo: result {0}", result); + LOG.log(DEBUG, "getClusterInstanceInfo: result {0}", result); return result; } private Config getConfigForServer(Server server) { - fineLog("getConfigForServer: server {0}", server); + LOG.log(DEBUG, "getConfigForServer: server {0}", server); String configRef = server.getConfigRef(); - fineLog("getConfigForServer: configRef {0}", configRef); + LOG.log(DEBUG, "getConfigForServer: configRef {0}", configRef); Configs configs = services.getService(Configs.class); - fineLog("getConfigForServer: configs {0}", configs); + LOG.log(DEBUG, "getConfigForServer: configs {0}", configs); Config config = configs.getConfigByName(configRef); - fineLog("getConfigForServer: config {0}", config); + LOG.log(DEBUG, "getConfigForServer: config {0}", config); return config; } @@ -360,21 +311,21 @@ private Config getConfigForServer(Server server) { // For addMember. private ClusterInstanceInfo getClusterInstanceInfo(String instanceName) { - fineLog("getClusterInstanceInfo: instanceName {0}", instanceName); + LOG.log(DEBUG, "getClusterInstanceInfo: instanceName {0}", instanceName); final Servers servers = services.getService(Servers.class); - fineLog("getClusterInstanceInfo: servers {0}", servers); + LOG.log(DEBUG, "getClusterInstanceInfo: servers {0}", servers); final Server server = servers.getServer(instanceName); - fineLog("getClusterInstanceInfo: server {0}", server); + LOG.log(DEBUG, "getClusterInstanceInfo: server {0}", server); final Config config = getConfigForServer(server); - fineLog("getClusterInstanceInfo: servers {0}", servers); + LOG.log(DEBUG, "getClusterInstanceInfo: servers {0}", servers); // assumeInstanceIsRunning is set to true since this is // coming from addMember, because shoal just told us that the instance is up. ClusterInstanceInfo result = getClusterInstanceInfo(server, config, true); - fineLog("getClusterInstanceInfo: result {0}", result); + LOG.log(DEBUG, "getClusterInstanceInfo: result {0}", result); return result; } @@ -382,10 +333,10 @@ private ClusterInstanceInfo getClusterInstanceInfo(String instanceName) { private Map getAllClusterInstanceInfo() { final Cluster myCluster = myServer.getCluster(); - fineLog("getAllClusterInstanceInfo: myCluster {0}", myCluster); + LOG.log(DEBUG, "getAllClusterInstanceInfo: myCluster {0}", myCluster); final Config myConfig = getConfigForServer(myServer); - fineLog("getAllClusterInstanceInfo: myConfig {0}", myConfig); + LOG.log(DEBUG, "getAllClusterInstanceInfo: myConfig {0}", myConfig); final Map result = new HashMap<>(); @@ -400,7 +351,7 @@ private Map getAllClusterInstanceInfo() { } } - fineLog("getAllClusterInstanceInfo: result {0}", result); + LOG.log(DEBUG, "getAllClusterInstanceInfo: result {0}", result); return result; } @@ -432,13 +383,11 @@ class GroupInfoServiceGMSImpl extends GroupInfoServiceBase { @Override public List internalClusterInstanceInfo(List endpoints) { - fineLog("internalClusterInstanceInfo: currentMembers {0}", currentMembers); - + LOG.log(DEBUG, "internalClusterInstanceInfo: currentMembers {0}", currentMembers); if (currentMembers == null) { return new ArrayList<>(); - } else { - return new ArrayList<>(currentMembers.values()); } + return new ArrayList<>(currentMembers.values()); } } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/OrbCreator.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/OrbCreator.java new file mode 100644 index 00000000000..5d0925e4145 --- /dev/null +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/OrbCreator.java @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.enterprise.iiop.impl; + +import com.sun.corba.ee.impl.folb.ClientGroupManager; +import com.sun.corba.ee.impl.folb.ServerGroupManager; +import com.sun.corba.ee.impl.orb.ORBImpl; +import com.sun.corba.ee.impl.orb.ORBSingleton; +import com.sun.corba.ee.spi.folb.GroupInfoService; +import com.sun.corba.ee.spi.misc.ORBConstants; +import com.sun.corba.ee.spi.orb.ORB; +import com.sun.enterprise.module.HK2Module; + +import java.lang.System.Logger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.stream.Collectors; + +import org.glassfish.api.admin.ProcessEnvironment.ProcessType; +import org.glassfish.orb.admin.config.IiopListener; +import org.glassfish.orb.admin.config.Orb; +import org.jvnet.hk2.config.types.Property; + +import static com.sun.corba.ee.spi.misc.ORBConstants.USER_CONFIGURATOR_PREFIX; +import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.INFO; +import static java.lang.System.Logger.Level.TRACE; +import static java.lang.System.Logger.Level.WARNING; +import static org.glassfish.main.jdke.props.SystemProperties.setProperty; + +/** + * Creates the {@link ORB} singleton object. + */ +final class OrbCreator { + private static final Logger LOG = System.getLogger(OrbCreator.class.getName()); + + // Various pluggable classes defined in the app server that are used + // by the ORB. + private static final String ORB_CLASS = ORBImpl.class.getName(); + private static final String ORB_SINGLETON_CLASS = ORBSingleton.class.getName(); + + private static final String PEORB_CONFIG_CLASS = PEORBConfigurator.class.getName(); + private static final String IIOP_SSL_SOCKET_FACTORY_CLASS = IIOPSSLSocketFactory.class.getName(); + private static final String RMI_STUB_CLASS = com.sun.corba.ee.impl.javax.rmi.CORBA.StubDelegateImpl.class.getName(); + private static final String RMI_PRO_CLASS = com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject.class.getName(); + + // RMI-IIOP delegate constants + private static final String ORB_UTIL_CLASS_PROPERTY = "javax.rmi.CORBA.UtilClass"; + private static final String RMIIIOP_STUB_DELEGATE_CLASS_PROPERTY = "javax.rmi.CORBA.StubClass"; + private static final String RMIIIOP_PRO_DELEGATE_CLASS_PROPERTY = "javax.rmi.CORBA.PortableRemoteObjectClass"; + + // ORB constants: OMG standard + private static final String OMG_ORB_CLASS_PROPERTY = "org.omg.CORBA.ORBClass"; + private static final String OMG_ORB_SINGLETON_CLASS_PROPERTY = "org.omg.CORBA.ORBSingletonClass"; + private static final String ORB_UTIL_CLASS = com.sun.corba.ee.impl.javax.rmi.CORBA.Util.class.getName(); + + // ORB configuration constants + private static final String DEFAULT_SERVER_ID = "100"; + private static final String ACC_DEFAULT_SERVER_ID = "101"; + private static final String USER_DEFINED_ORB_SERVER_ID_PROPERTY = "org.glassfish.orb.iiop.orbserverid"; + + private static final String DEFAULT_MAX_CONNECTIONS = "1024"; + private static final String GLASSFISH_INITIALIZER = GlassFishORBInitializer.class.getName(); + + private static final String SUN_GIOP_DEFAULT_FRAGMENT_SIZE = "1024"; + private static final String SUN_GIOP_DEFAULT_BUFFER_SIZE = "1024"; + + private static final String DEFAULT_ORB_INIT_HOST = "localhost"; + + // This will only apply for stand-alone java clients, since + // in the server the orb port comes from domain.xml, and in an appclient + // the port is set from the sun-acc.xml. It's set to the same + // value as the default orb port in domain.xml as a convenience. + // That way the code only needs to do a "new InitialContext()" + // without setting any jvm properties and the naming service will be + // found. Of course, if the port was changed in domain.xml for some + // reason the code will still have to set org.omg.CORBA.ORBInitialPort. + private static final int DEFAULT_ORB_INIT_PORT = 3700; + + // We need this to get the ORB monitoring set up correctly + private static final String S1AS_ORB_ID = "S1AS-ORB"; + private static final String IIOP_ENDPOINTS_PROPERTY = "com.sun.appserv.iiop.endpoints"; + private static final String IIOP_URL = "iiop:1.2@"; + + private final Orb orbConfig; + private final ProcessType processType; + private final List iiopListeners; + private final GroupInfoService clusterGroupInfo; + private final HK2Module corbaOrbOsgiModule; + + /** + * Set ORB-related system properties that are required in case + * user code in the app server or app client container creates a + * new ORB instance. The default result of calling + * ORB.init( String[], Properties ) must be a fully usuable, consistent + * ORB. This avoids difficulties with having the ORB class set + * to a different ORB than the RMI-IIOP delegates. + * @param orbConfig + * + * @param processType + * @param clusterGroupInfo + * @param iiopListeners + * @param corbaOrbOsgiModule + */ + OrbCreator(Orb orbConfig, ProcessType processType, GroupInfoService clusterGroupInfo, + List iiopListeners, HK2Module corbaOrbOsgiModule) { + this.orbConfig = orbConfig; + this.processType = processType; + this.iiopListeners = iiopListeners; + this.clusterGroupInfo = clusterGroupInfo; + this.corbaOrbOsgiModule = corbaOrbOsgiModule; + setProperty(OMG_ORB_CLASS_PROPERTY, ORB_CLASS, false); + setProperty(OMG_ORB_SINGLETON_CLASS_PROPERTY, ORB_SINGLETON_CLASS, false); + setProperty(ORB_UTIL_CLASS_PROPERTY, ORB_UTIL_CLASS, true); + setProperty(RMIIIOP_STUB_DELEGATE_CLASS_PROPERTY, RMI_STUB_CLASS, true); + setProperty(RMIIIOP_PRO_DELEGATE_CLASS_PROPERTY, RMI_PRO_CLASS, true); + // For ORB compatibility with JDK11+ JDKs + // See https://github.com/eclipse-ee4j/orb-gmbal/issues/22 + // See TypeEvaluator class in the gmbal.jar + setProperty("org.glassfish.gmbal.no.multipleUpperBoundsException", "true", true); + } + + + /** + * Create the shared ORB instance for the server. + * The ORB is created with the standard server properties, which can be overridden by Properties + * passed in the props argument. + * + * @param processType + */ + ORB createOrb(Properties props) { + LOG.log(INFO, "createOrb({0})", props); + try { + Properties orbInitProperties = setFOLBProperties(props); + + // Standard OMG Properties. + String orbDefaultServerId = System.getProperty(USER_DEFINED_ORB_SERVER_ID_PROPERTY, + processType.isServer() ? DEFAULT_SERVER_ID : ACC_DEFAULT_SERVER_ID); + orbInitProperties.put(ORBConstants.ORB_SERVER_ID_PROPERTY, orbDefaultServerId); + orbInitProperties.put(OMG_ORB_CLASS_PROPERTY, ORB_CLASS); + orbInitProperties.put(ORBConstants.PI_ORB_INITIALIZER_CLASS_PREFIX + GLASSFISH_INITIALIZER, ""); + orbInitProperties.put(ORBConstants.ALLOW_LOCAL_OPTIMIZATION, "true"); + orbInitProperties.put(ORBConstants.GET_SERVICE_CONTEXT_RETURNS_NULL, "true"); + orbInitProperties.put(ORBConstants.ORB_ID_PROPERTY, S1AS_ORB_ID); + orbInitProperties.put(ORBConstants.SHOW_INFO_MESSAGES, "true"); + + // Do this even if propertiesInitialized, since props may override + // ORBInitialHost and port. + final String initialPort = Integer.toString(evaluateInitialPort(orbInitProperties, iiopListeners)); + // Make sure we set initial port in System properties so that + // any instantiations of org.glassfish.jndi.cosnaming.CNCtxFactory + // use same port. + orbInitProperties.setProperty(ORBConstants.INITIAL_PORT_PROPERTY, initialPort); + + // Done to initialize the Persistent Server Port, before any + // POAs are created. This was earlier done in POAEJBORB + // Do it only in the appserver, not on appclient. + if (processType.isServer()) { + orbInitProperties.setProperty(ORBConstants.PERSISTENT_SERVER_PORT_PROPERTY, initialPort); + } + + final String initialHost = evaluateInitialHost(orbInitProperties, iiopListeners); + orbInitProperties.setProperty(ORBConstants.INITIAL_HOST_PROPERTY, initialHost); + LOG.log(DEBUG, "ORB initial host set to {0}", initialHost); + + // In a server, don't configure any default acceptors so that lazy init + // can be used. Actual lazy init setup takes place in PEORBConfigurator + if (processType.isServer()) { + validateIiopListeners(); + orbInitProperties.put(ORBConstants.NO_DEFAULT_ACCEPTORS, "true"); + // 14734893 - IIOP ports don't bind to the network address set for the cluster instance + // GLASSFISH-17469 IIOP Listener Network Address Setting Ignored + String serverHost = evaluateHostname(orbInitProperties, iiopListeners); + if (serverHost != null) { + // set the property, to be used during ORB initialization + // Bug 14734893 - IIOP ports don't bind to the network address set for the cluster instance + orbInitProperties.setProperty(ORBConstants.SERVER_HOST_PROPERTY, serverHost); + LOG.log(DEBUG, "ORB server host set to {0}", serverHost); + } + } + + checkConnectionSettings(orbInitProperties); + checkMessageFragmentSize(orbInitProperties); + checkForOrbPropertyValues(orbInitProperties); + + String[] args = toOrbArgs(initialPort, initialHost); + + // The following is done only on the Server Side to set the + // ThreadPoolManager in the ORB. ThreadPoolManager on the server + // is initialized based on configuration parameters found in + // domain.xml. On the client side this is not done + + if (processType.isServer()) { + PEORBConfigurator.setThreadPoolManager(); + } + return new GlassFishOrbImpl(corbaOrbOsgiModule, clusterGroupInfo, orbInitProperties, args); + } catch (Exception ex) { + throw new IllegalStateException("ORB initialization failed.", ex); + } + } + + private String[] toOrbArgs(final String initialPort, final String initialHost) { + String endpointsProperty = System.getProperty(IIOP_ENDPOINTS_PROPERTY); + final String[] orbInitRefArgs; + if (endpointsProperty == null || endpointsProperty.isEmpty()) { + // Add -ORBInitRef for INS to work + orbInitRefArgs = getORBInitRef(initialHost, initialPort); + } else { + orbInitRefArgs = getORBInitRef(endpointsProperty); + } + List argsList = new ArrayList<>(); + argsList.addAll(Arrays.asList(orbInitRefArgs)); + String[] args = argsList.toArray(String[]::new); + return args; + } + + /** + * Set the ORB properties for IIOP failover and load balancing. + * @param props + */ + private Properties setFOLBProperties(Properties props) { + + Properties orbInitProperties = new Properties(); + orbInitProperties.putAll(props); + orbInitProperties.put(ORBConstants.APPSERVER_MODE, "true"); + + // The main configurator. + orbInitProperties.put(USER_CONFIGURATOR_PREFIX + PEORB_CONFIG_CLASS, "dummy"); + + + orbInitProperties.put(ORBConstants.RFM_PROPERTY, "dummy"); + orbInitProperties.put(ORBConstants.SOCKET_FACTORY_CLASS_PROPERTY, IIOP_SSL_SOCKET_FACTORY_CLASS); + + // ClientGroupManager. + // Registers itself as + // ORBInitializer (that registers ClientRequestInterceptor) + // IIOPPrimaryToContactInfo + // IORToSocketInfo + orbInitProperties.setProperty(USER_CONFIGURATOR_PREFIX + ClientGroupManager.class.getName(), "dummy"); + + // This configurator registers the CSIv2SSLTaggedComponentHandler + orbInitProperties.setProperty(USER_CONFIGURATOR_PREFIX + CSIv2SSLTaggedComponentHandlerImpl.class.getName(), "dummy"); + + if (this.clusterGroupInfo != null) { + LOG.log(DEBUG, "GMS available and enabled - doing EE initialization"); + + // Register ServerGroupManager. + // Causes it to register itself as an ORBInitializer + // that then registers it as + // IOR and ServerRequest Interceptors. + orbInitProperties.setProperty(USER_CONFIGURATOR_PREFIX + ServerGroupManager.class.getName(), "dummy"); + LOG.log(TRACE, "Did EE property initialization"); + } + return orbInitProperties; + } + + private void checkConnectionSettings(Properties props) { + if (orbConfig != null) { + String maxConnections = orbConfig.getMaxConnections(); + try { + Integer.parseInt(maxConnections); + } catch (NumberFormatException nfe) { + LOG.log(WARNING, "The max connections value {0} must be an integer, using default value {1} instead.", + maxConnections, DEFAULT_MAX_CONNECTIONS); + maxConnections = DEFAULT_MAX_CONNECTIONS; + } + props.setProperty(ORBConstants.HIGH_WATER_MARK_PROPERTY, maxConnections); + } + } + + private void checkMessageFragmentSize(Properties props) { + if (orbConfig == null) { + return; + } + String fragmentSize = null; + String bufferSize = null; + try { + int fsize = ((Integer.parseInt(orbConfig.getMessageFragmentSize().trim())) / 8) * 8; + if (fsize < 32) { + fragmentSize = "32"; + LOG.log(INFO, "Setting ORB Message Fragment size to {0}", fragmentSize); + } else { + fragmentSize = String.valueOf(fsize); + } + bufferSize = fragmentSize; + } catch (NumberFormatException nfe) { + LOG.log(WARNING, "The message fragment size {0} must be an integer, using default value {1} instead.", + fragmentSize, SUN_GIOP_DEFAULT_FRAGMENT_SIZE); + fragmentSize = SUN_GIOP_DEFAULT_FRAGMENT_SIZE; + bufferSize = SUN_GIOP_DEFAULT_BUFFER_SIZE; + } + props.setProperty(ORBConstants.GIOP_FRAGMENT_SIZE, fragmentSize); + props.setProperty(ORBConstants.GIOP_BUFFER_SIZE, bufferSize); + } + + private void checkForOrbPropertyValues(Properties props) { + if (orbConfig != null) { + List orbConfigProps = orbConfig.getProperty(); + if (orbConfigProps != null) { + for (Property orbConfigProp : orbConfigProps) { + props.setProperty(orbConfigProp.getName(), + orbConfigProp.getValue()); + } + } + } + } + + private void validateIiopListeners() { + if (iiopListeners == null) { + return; + } + var lazyListeners = iiopListeners.stream().filter(ilb -> Boolean.valueOf(ilb.getLazyInit())) + .collect(Collectors.toList()); + + if (lazyListeners.size() > 1) { + throw new IllegalStateException("Only one iiop-listener can be configured with lazy-init=true. " + + lazyListeners.stream().map(ilb -> ilb.getId()).collect(Collectors.toList())); + } + if (lazyListeners.isEmpty()) { + return; + } + final IiopListener listener = lazyListeners.get(0); + if ("true".equalsIgnoreCase(listener.getSecurityEnabled()) && listener.getSsl() != null) { + throw new IllegalStateException( + "Lazy-init not supported for SSL iiop-listeners. Listener id: " + listener.getId()); + } + } + + + static String evaluateInitialHost(Properties props, List listeners) { + // Host setting in system properties always takes precedence. + String initialHost = System.getProperty(ORBConstants.INITIAL_HOST_PROPERTY); + if (initialHost == null) { + initialHost = props.getProperty(ORBConstants.INITIAL_HOST_PROPERTY); + } + if (initialHost == null) { + IiopListener listener = getClearTextIiopListener(listeners); + if (listener != null) { + initialHost = listener.getAddress(); + } + } + return initialHost == null ? DEFAULT_ORB_INIT_HOST : replaceAnyWithLocalHost(initialHost); + } + + private static String replaceAnyWithLocalHost(String orbInitialHost) { + if (orbInitialHost.equals("0.0.0.0") || orbInitialHost.equals("::") + || orbInitialHost.equals("::ffff:0.0.0.0")) { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException uhe) { + LOG.log(WARNING, "Unknown host exception - Setting host to localhost", uhe); + return DEFAULT_ORB_INIT_HOST; + } + } + return orbInitialHost; + } + + + // Server host property is used only for ORB running in server mode + // Return host name (or ip address string) if the SERVER_HOST PROPERTY is set or + // network-address attribute is specified in iiop-listener element + // Return null otherwise. + private static String evaluateHostname(Properties props, List listeners) { + // Host setting in system properties always takes precedence. + String serverHost = System.getProperty(ORBConstants.SERVER_HOST_PROPERTY); + if (serverHost == null) { + serverHost = props.getProperty(ORBConstants.SERVER_HOST_PROPERTY ); + } + if (serverHost == null) { + IiopListener listener = getClearTextIiopListener(listeners); + if (listener != null) { + // For this case, use same value as ORBInitialHost, + serverHost = listener.getAddress(); + } + } + return serverHost; + } + + + static int evaluateInitialPort(Properties props, List listeners) { + String initialPort = System.getProperty(ORBConstants.INITIAL_PORT_PROPERTY); + if (initialPort == null && props != null) { + initialPort = props.getProperty(ORBConstants.INITIAL_PORT_PROPERTY); + } + if (initialPort == null) { + IiopListener listener = getClearTextIiopListener(listeners); + if (listener != null) { + initialPort = listener.getPort(); + } + } + return initialPort == null ? DEFAULT_ORB_INIT_PORT : Integer.valueOf(initialPort); + } + + // Returns the first IiopListenerBean which represents a clear text endpoint + // Note: it is questionable whether the system actually support multiple + // endpoints of the same type, or no clear text endpoint at all in the + // configuration. + private static IiopListener getClearTextIiopListener(List listeners) { + for (IiopListener il : listeners) { + if (il.getSsl() == null) { + return il ; + } + } + return null ; + } + + /** + * Add -ORBInitRef NameService=.... + * This ensures that INS will be used to talk with the NameService. + */ + private static String[] getORBInitRef(String orbInitialHost, String initialPort) { + return new String[] {"-ORBInitRef", + "NameService=corbaloc:" + IIOP_URL + orbInitialHost + ":" + initialPort + "/NameService"}; + } + + /** + * Add -ORBInitRef NameService=.... + * This ensures that INS will be used to talk with the NameService. + */ + private static String[] getORBInitRef(String endpoints) { + String corbalocURL = getCorbaUrlList(endpoints.split(",")); + return new String[] {"-ORBInitRef", "NameService=corbaloc:" + corbalocURL + "/NameService"}; + } + + private static String getCorbaUrlList(Object[] list) { + String corbalocURL = ""; + for (Object element : list) { + LOG.log(DEBUG, "list[i] ==> {0}", element); + if (corbalocURL.isEmpty()) { + corbalocURL = IIOP_URL + ((String) element).trim(); + } else { + corbalocURL = corbalocURL + "," + IIOP_URL + ((String) element).trim(); + } + } + LOG.log(INFO, "corbaloc url ==> {0}", corbalocURL); + return corbalocURL; + } + +} diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/PEORBConfigurator.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/PEORBConfigurator.java index cadf972de0c..21ac3ddfc67 100755 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/PEORBConfigurator.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/PEORBConfigurator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -17,9 +17,7 @@ package org.glassfish.enterprise.iiop.impl; -import com.sun.corba.ee.impl.naming.cosnaming.TransientNameService; import com.sun.corba.ee.spi.copyobject.CopierManager; -import com.sun.corba.ee.spi.copyobject.CopyobjectDefaults ; import com.sun.corba.ee.spi.orb.DataCollector; import com.sun.corba.ee.spi.orb.ORB; import com.sun.corba.ee.spi.orb.ORBConfigurator; @@ -30,21 +28,20 @@ import com.sun.corba.ee.spi.transport.Acceptor; import com.sun.corba.ee.spi.transport.TransportDefault; import com.sun.corba.ee.spi.transport.TransportManager; -import com.sun.logging.LogDomains; +import java.lang.System.Logger; import java.net.Socket; +import java.net.UnknownHostException; import java.nio.channels.SelectableChannel; import java.nio.channels.SocketChannel; import java.util.Arrays; import java.util.HashSet; -import java.util.List; import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator.SelectableChannelDelegate; import org.glassfish.enterprise.iiop.api.IIOPConstants; import org.glassfish.enterprise.iiop.util.IIOPUtils; import org.glassfish.enterprise.iiop.util.S1ASThreadPoolManager; @@ -56,107 +53,76 @@ import org.glassfish.orb.admin.config.IiopListener; import org.glassfish.pfl.dynamic.copyobject.spi.ObjectCopierFactory ; +import static com.sun.corba.ee.spi.copyobject.CopyobjectDefaults.getReferenceObjectCopierFactory; +import static com.sun.corba.ee.spi.copyobject.CopyobjectDefaults.makeFallbackObjectCopierFactory; +import static com.sun.corba.ee.spi.copyobject.CopyobjectDefaults.makeORBStreamObjectCopierFactory; +import static com.sun.corba.ee.spi.copyobject.CopyobjectDefaults.makeReflectObjectCopierFactory; +import static java.lang.System.Logger.Level.ERROR; +import static java.lang.System.Logger.Level.WARNING; + public class PEORBConfigurator implements ORBConfigurator { - private static final java.util.logging.Logger logger = - java.util.logging.Logger.getLogger(LogDomains.CORBA_LOGGER); + private static final Logger LOG = System.getLogger(PEORBConfigurator.class.getName()); private static final String SSL = "SSL"; private static final String SSL_MUTUALAUTH = "SSL_MUTUALAUTH"; - private static final String IIOP_CLEAR_TEXT_CONNECTION = - "IIOP_CLEAR_TEXT"; + private static final String IIOP_CLEAR_TEXT_CONNECTION = "IIOP_CLEAR_TEXT"; private static final String DEFAULT_ORB_INIT_HOST = "localhost"; + private static final Set ANY_ADDRS = new HashSet<>(Arrays.asList("0.0.0.0", "::", "::ffff:0.0.0.0")); - // TODO private static TSIdentification tsIdent; - private static ThreadPoolManager threadpoolMgr = null; - - static { - // TODO tsIdent = new TSIdentificationImpl(); - } + private static ThreadPoolManager threadpoolMgr; - private GlassFishORBHelper getHelper() { - IIOPUtils iiopUtils = IIOPUtils.getInstance(); - return iiopUtils.getHabitat().getService(GlassFishORBHelper.class); - } @Override - public void configure(DataCollector dc, ORB orb) { - try { - //begin temp fix for bug 6320008 - // this is needed only because we are using transient Name Service - //this should be removed once we have the persistent Name Service in place - /*TODO - orb.setBadServerIdHandler( - new BadServerIdHandler() { - public void handle(ObjectKey objectkey) { - // NO-OP - } - } - ); - */ - //end temp fix for bug 6320008 - if (threadpoolMgr != null) { - // This will be the case for the Server Side ORB created - // For client side threadpoolMgr will be null, so we will - // never come here - orb.setThreadPoolManager(threadpoolMgr); - } + public synchronized void configure(DataCollector dc, ORB orb) { + if (threadpoolMgr != null) { + // This will be the case for the Server Side ORB created + // For client side threadpoolMgr will be null, so we will + // never come here + orb.setThreadPoolManager(threadpoolMgr); + } - // Do the stats for the threadpool - - ThreadPoolManager tpool = orb.getThreadPoolManager(); - // ORB creates its own threadpool if threadpoolMgr was null above - ThreadPool thpool=tpool.getDefaultThreadPool(); - String ThreadPoolName = thpool.getName(); - ThreadPoolStats tpStats = new ThreadPoolStatsImpl( - thpool.getWorkQueue(0).getThreadPool()); - StatsProviderManager.register("orb", PluginPoint.SERVER, - "thread-pool/orb/threadpool/"+ThreadPoolName, tpStats); - - configureCopiers(orb); - configureCallflowInvocationInterceptor(orb); - - // In the server-case, iiop acceptors need to be set up after the - // initial part of the orb creation but before any - // portable interceptor initialization - IIOPUtils iiopUtils = IIOPUtils.getInstance(); - if (iiopUtils.getProcessType().isServer()) { - List iiop_listener_list = IIOPUtils.getInstance() - .getIiopService().getIiopListener() ; - IiopListener[] iiopListenerBeans = iiop_listener_list - .toArray(new IiopListener [iiop_listener_list.size()]) ; - this.createORBListeners(iiopUtils, iiopListenerBeans, orb); - } - if (orb.getORBData().environmentIsGFServer()) { - // Start the transient name service, which publishes NameService - // in the ORB's local resolver. - new TransientNameService(orb); - } - // Publish the ORB reference back to GlassFishORBHelper, so that - // subsequent calls from interceptor ORBInitializers can call - // GlassFishORBHelper.getORB() without problems. This is - // especially important for code running in the service initializer - // thread. - getHelper().setORB(orb); + try { + configureStats(orb); } catch (NoSuchWorkQueueException ex) { - Logger.getLogger(PEORBConfigurator.class.getName()).log(Level.SEVERE, null, ex); + LOG.log(ERROR, "Failed to configure ORB: " + orb, ex); } + + configureCopiers(orb); + configureCallflowInvocationInterceptor(orb); + + // In the server-case, iiop acceptors need to be set up after the + // initial part of the orb creation but before any + // portable interceptor initialization + IIOPUtils iiopUtils = IIOPUtils.getInstance(); + if (iiopUtils.getProcessType().isServer()) { + IiopListener[] iiopListeners = iiopUtils.getIiopService().getIiopListener().toArray(IiopListener[]::new); + createORBListeners(iiopUtils, iiopListeners, orb); + } + + if (orb.getORBData().environmentIsGFServer()) { + GlassFishORBLocator.setThreadLocal(orb); + } + } + + private void configureStats(ORB orb) throws NoSuchWorkQueueException { + // Do the stats for the threadpool + ThreadPoolManager tpool = orb.getThreadPoolManager(); + // ORB creates its own threadpool if threadpoolMgr was null above + ThreadPool thpool = tpool.getDefaultThreadPool(); + ThreadPoolStats tpStats = new ThreadPoolStatsImpl(thpool.getWorkQueue(0).getThreadPool()); + StatsProviderManager.register("orb", PluginPoint.SERVER, "thread-pool/orb/threadpool/" + thpool.getName(), + tpStats); } private static void configureCopiers(ORB orb) { CopierManager cpm = orb.getCopierManager(); - - ObjectCopierFactory stream = - CopyobjectDefaults.makeORBStreamObjectCopierFactory(orb) ; - ObjectCopierFactory reflect = - CopyobjectDefaults.makeReflectObjectCopierFactory(orb) ; - ObjectCopierFactory fallback = - CopyobjectDefaults.makeFallbackObjectCopierFactory( reflect, stream ) ; - ObjectCopierFactory reference = - CopyobjectDefaults.getReferenceObjectCopierFactory() ; - - cpm.registerObjectCopierFactory( fallback, IIOPConstants.PASS_BY_VALUE_ID ) ; - cpm.registerObjectCopierFactory( reference, IIOPConstants.PASS_BY_REFERENCE_ID ) ; - cpm.setDefaultId( IIOPConstants.PASS_BY_VALUE_ID ) ; + ObjectCopierFactory stream = makeORBStreamObjectCopierFactory(orb); + ObjectCopierFactory reflect = makeReflectObjectCopierFactory(orb); + ObjectCopierFactory fallback = makeFallbackObjectCopierFactory(reflect, stream); + ObjectCopierFactory reference = getReferenceObjectCopierFactory(); + cpm.registerObjectCopierFactory(fallback, IIOPConstants.PASS_BY_VALUE_ID); + cpm.registerObjectCopierFactory(reference, IIOPConstants.PASS_BY_REFERENCE_ID); + cpm.setDefaultId(IIOPConstants.PASS_BY_VALUE_ID); } // Called from GlassFishORBManager only when the ORB is running on server side @@ -164,91 +130,68 @@ public static void setThreadPoolManager() { threadpoolMgr = S1ASThreadPoolManager.getThreadPoolManager(); } + private static void configureCallflowInvocationInterceptor(ORB orb) { - orb.setInvocationInterceptor( - new InvocationInterceptor() { + orb.setInvocationInterceptor(new InvocationInterceptor() { + @Override - public void preInvoke() { - /* TODO - Agent agent = Switch.getSwitch().getCallFlowAgent(); - if (agent != null) { - agent.startTime( - ContainerTypeOrApplicationType.ORB_CONTAINER); - } - */ - } + public void preInvoke() { + } + @Override - public void postInvoke() { - /* TODO - Agent agent = Switch.getSwitch().getCallFlowAgent(); - if (agent != null) { - agent.endTime(); - } - */ - } - } - ); + public void postInvoke() { + } + }); } - private Acceptor addAcceptor( org.omg.CORBA.ORB orb, boolean isLazy, - String host, String type, int port ) { - com.sun.corba.ee.spi.orb.ORB theOrb = (com.sun.corba.ee.spi.orb.ORB) orb; - TransportManager ctm = theOrb.getTransportManager() ; - Acceptor acceptor ; + private Acceptor addAcceptor(org.omg.CORBA.ORB orb, boolean isLazy, String host, String type, int port) { + ORB theOrb = (ORB) orb; + TransportManager ctm = theOrb.getTransportManager(); + Acceptor acceptor; if (isLazy) { - acceptor = TransportDefault.makeLazyCorbaAcceptor( - theOrb, port, host, type ); + acceptor = TransportDefault.makeLazyCorbaAcceptor(theOrb, port, host, type); } else { - acceptor = TransportDefault.makeStandardCorbaAcceptor( - theOrb, port, host, type ) ; + acceptor = TransportDefault.makeStandardCorbaAcceptor(theOrb, port, host, type); } - ctm.registerAcceptor( acceptor ) ; + ctm.registerAcceptor(acceptor); return acceptor; } - private static final Set ANY_ADDRS = new HashSet<>( - Arrays.asList( "0.0.0.0", "::", "::ffff:0.0.0.0" ) ) ; - private String handleAddrAny( String hostAddr ) { - if (ANY_ADDRS.contains( hostAddr )) { - try { - return java.net.InetAddress.getLocalHost().getHostAddress() ; - } catch (java.net.UnknownHostException exc) { - logger.log( Level.WARNING, - "Unknown host exception : Setting host to localhost" ) ; - return DEFAULT_ORB_INIT_HOST ; - } - } else { - return hostAddr ; + if (!ANY_ADDRS.contains(hostAddr)) { + return hostAddr; + } + try { + return java.net.InetAddress.getLocalHost().getHostAddress() ; + } catch (UnknownHostException exc) { + LOG.log(WARNING, "Unknown host exception : Setting host to localhost"); + return DEFAULT_ORB_INIT_HOST; } } - private void createORBListeners(IIOPUtils iiopUtils, - IiopListener[] iiopListenerBeans, org.omg.CORBA.ORB orb) { + private void createORBListeners(IIOPUtils iiopUtils, IiopListener[] iiopListenerBeans, org.omg.CORBA.ORB orb) { if (iiopListenerBeans == null) { return; } var lazyListeners = Stream.of(iiopListenerBeans) - .filter(ilb -> Boolean.parseBoolean(ilb.getLazyInit())).collect(Collectors.toList()); + .filter(ilb -> Boolean.parseBoolean(ilb.getLazyInit())).collect(Collectors.toList()); if (lazyListeners.size() > 1) { - throw new IllegalStateException( - "Only one iiop-listener can be configured with lazy-init=true. " - + lazyListeners.stream().map(IiopListener::getId).collect(Collectors.toList())); + throw new IllegalStateException("Only one iiop-listener can be configured with lazy-init=true. " + + lazyListeners.stream().map(IiopListener::getId).collect(Collectors.toList())); } var lazySslListeners = lazyListeners.stream() - .filter(ilb -> Boolean.valueOf(ilb.getSecurityEnabled()) && ilb.getSsl() != null) - .collect(Collectors.toList()); + .filter(ilb -> Boolean.valueOf(ilb.getSecurityEnabled()) && ilb.getSsl() != null) + .collect(Collectors.toList()); - if (lazySslListeners.size() > 0) { - throw new IllegalStateException( - "Lazy-init not supported for SSL iiop-listeners. " - + lazySslListeners.stream().map(IiopListener::getId).collect(Collectors.toList())); + if (!lazySslListeners.isEmpty()) { + throw new IllegalStateException("Lazy-init not supported for SSL iiop-listeners. " + + lazySslListeners.stream().map(IiopListener::getId).collect(Collectors.toList())); } for (IiopListener ilb : iiopListenerBeans) { @@ -263,23 +206,23 @@ private void createORBListeners(IIOPUtils iiopUtils, boolean isSslListener = Boolean.valueOf(ilb.getSecurityEnabled()) && ilb.getSsl() != null; if (isSslListener) { Ssl sslBean = ilb.getSsl(); - boolean clientAuth = Boolean.parseBoolean( - sslBean.getClientAuthEnabled()); + boolean clientAuth = Boolean.parseBoolean(sslBean.getClientAuthEnabled()); String type = clientAuth ? SSL_MUTUALAUTH : SSL; addAcceptor(orb, isLazy, host, type, port); } else { - Acceptor acceptor = addAcceptor(orb, isLazy, host, - IIOP_CLEAR_TEXT_CONNECTION, port); + Acceptor acceptor = addAcceptor(orb, isLazy, host, IIOP_CLEAR_TEXT_CONNECTION, port); if (isLazy) { - getHelper().setSelectableChannelDelegate(new AcceptorDelegateImpl( - acceptor)); + getOrbLocator().setSelectableChannelDelegate(new AcceptorDelegateImpl(acceptor)); } } } } - private static class AcceptorDelegateImpl - implements GlassFishORBHelper.SelectableChannelDelegate { + private GlassFishORBLocator getOrbLocator() { + return IIOPUtils.getInstance().getServiceLocator().getService(GlassFishORBLocator.class); + } + + private static class AcceptorDelegateImpl implements SelectableChannelDelegate { private final Acceptor acceptor; @@ -289,9 +232,9 @@ private static class AcceptorDelegateImpl @Override public void handleRequest(SelectableChannel channel) { - SocketChannel sch = (SocketChannel)channel ; - Socket socket = sch.socket() ; - acceptor.processSocket( socket ) ; + SocketChannel sch = (SocketChannel) channel; + Socket socket = sch.socket(); + acceptor.processSocket(socket); } } } diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java index eb377b56b88..620fe06f5d4 100755 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java @@ -350,9 +350,7 @@ private Remote createRef(byte[] instanceKey, ReferenceFactory rf, PresentationMa // NOTE: The repoid is only needed for logging. private org.omg.CORBA.Object _createRef(ReferenceFactory rf, byte[] instanceKey, String repoid) throws Exception { - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, "\t\tIn POARemoteReferenceFactory._createRef, repositoryId = {0}", repoid); - } + logger.log(Level.FINE, "\t\tIn POARemoteReferenceFactory._createRef, repositoryId = {0}", repoid); // Create the ejbKey using EJB's unique id + instanceKey byte[] ejbKey = createEJBKey(ejbDescriptor.getUniqueId(), instanceKey); diff --git a/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/AppclientIIOPInterceptorFactory.java b/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/AppclientIIOPInterceptorFactory.java index 040aae403a7..1949684b204 100644 --- a/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/AppclientIIOPInterceptorFactory.java +++ b/appserver/security/appclient.security/src/main/java/com/sun/enterprise/security/appclient/AppclientIIOPInterceptorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -27,6 +27,7 @@ import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.enterprise.iiop.api.IIOPInterceptorFactory; +import org.glassfish.internal.api.ORBLocator; import org.jvnet.hk2.annotations.Service; import org.omg.IOP.Codec; import org.omg.PortableInterceptor.ClientRequestInterceptor; @@ -51,6 +52,8 @@ public class AppclientIIOPInterceptorFactory implements IIOPInterceptorFactory { @Inject private ProcessEnvironment processEnvironment; + @Inject ORBLocator orbLocator; + private AlternateSecurityInterceptorFactory altSecFactory; // Are we supposed to add the interceptor and then return or just return an instance? @@ -90,10 +93,8 @@ private synchronized boolean createAlternateSecurityInterceptorFactory() { private synchronized ClientRequestInterceptor getClientInterceptorInstance(Codec codec) { if (clientRequestInterceptor == null) { - clientRequestInterceptor = new SecClientRequestInterceptor("SecClientRequestInterceptor", codec); + clientRequestInterceptor = new SecClientRequestInterceptor("SecClientRequestInterceptor", codec, orbLocator); } - return clientRequestInterceptor; } - } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/CSIV2TaggedComponentInfo.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/CSIV2TaggedComponentInfo.java index 680cfd4d556..b7958cc7fe4 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/CSIV2TaggedComponentInfo.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/CSIV2TaggedComponentInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -51,18 +51,14 @@ import java.util.List; import java.util.Properties; import java.util.Set; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; -import org.glassfish.enterprise.iiop.impl.CSIv2Policy; import org.glassfish.internal.api.ORBLocator; -import org.glassfish.pfl.basic.func.UnaryFunction; import org.glassfish.security.common.Role; import org.ietf.jgss.GSSException; -import org.omg.CORBA.INV_POLICY; import org.omg.CORBA.ORB; -import org.omg.PortableInterceptor.IORInfo; import static com.sun.logging.LogDomains.SECURITY_LOGGER; @@ -74,8 +70,7 @@ * @author Harpreet Singh * @author Ken Cavanaugh */ - -public final class CSIV2TaggedComponentInfo { +final class CSIV2TaggedComponentInfo { public static final int SUPPORTED_IDENTITY_TOKEN_TYPES = 15; private static final String DEFAULT_REALM = "default"; @@ -89,64 +84,43 @@ public final class CSIV2TaggedComponentInfo { // The fallback is "default" // private String _realm_name = null; // private byte[] _realm_name_bytes = null; - private final ORB orb; - private int sslMutualAuthPort; - private final GlassFishORBHelper orbHelper; + private final int sslMutualAuthPort; + + private ORB orb; - public CSIV2TaggedComponentInfo(ORB orb) { + CSIV2TaggedComponentInfo(ORB orb) { + this.sslMutualAuthPort = 0; this.orb = orb; - orbHelper = Lookups.getGlassFishORBHelper(); } - public CSIV2TaggedComponentInfo(ORB orb, int sslMutualAuthPort) { - this(orb); + CSIV2TaggedComponentInfo(int sslMutualAuthPort, ORB orb) { this.sslMutualAuthPort = sslMutualAuthPort; + this.orb = orb; } - public EjbDescriptor getEjbDescriptor(IORInfo iorInfo) { - CSIv2Policy csiv2Policy = null; - try { - csiv2Policy = (CSIv2Policy) iorInfo.get_effective_policy(orbHelper.getCSIv2PolicyType()); - } catch (INV_POLICY ex) { - LOG.log(Level.FINE, "CSIV2TaggedComponentInfo.getEjbDescriptor: CSIv2Policy not present"); - } - - // Add CSIv2 tagged component for this EJB type. - LOG.log(Level.FINE, "TxSecIORInterceptor.establish_components: CSIv2Policy: {0}", csiv2Policy); - - EjbDescriptor ejbDesc = null; - if (csiv2Policy != null) { - ejbDesc = csiv2Policy.getEjbDescriptor(); - } - - return ejbDesc; - } /** * Create the security mechanism list tagged component based on the deployer specified configuration information. This * method is on the server side for all ejbs in the non-cluster app server case. */ - public org.omg.IOP.TaggedComponent createSecurityTaggedComponent(int sslPort, EjbDescriptor desc) { - - org.omg.IOP.TaggedComponent tc = null; + org.omg.IOP.TaggedComponent createSecurityTaggedComponent(int sslPort, EjbDescriptor desc) { try { LOG.log(Level.FINE, "IIOP: Creating a Security Tagged Component"); // get the realm from the application object. // _realm_name = desc.getApplication().getRealm(); CompoundSecMech[] mechList = createCompoundSecMechs(sslPort, desc); - tc = createCompoundSecMechListComponent(mechList); + return createCompoundSecMechListComponent(mechList); } catch (Exception e) { LOG.log(Level.SEVERE, "Creation of a Security Tagged Component failed.", e); + return null; } - - return tc; } /** * Create the CSIv2 tagged component for a clustered app server. */ - public org.omg.IOP.TaggedComponent createSecurityTaggedComponent(List socketInfos, EjbDescriptor desc) { + org.omg.IOP.TaggedComponent createSecurityTaggedComponent(List socketInfos, EjbDescriptor desc) { org.omg.IOP.TaggedComponent tc = null; if (desc != null) { try { @@ -173,35 +147,27 @@ private boolean getBooleanValue(Properties props, String name) { /** * This method is called on the server side for all non-EJB POAs. */ - public org.omg.IOP.TaggedComponent createSecurityTaggedComponent(int sslPort) { - - org.omg.IOP.TaggedComponent tc = null; - + org.omg.IOP.TaggedComponent createSecurityTaggedComponent(int sslPort, Properties props) { try { - Properties props = orbHelper.getCSIv2Props(); boolean sslRequired = getBooleanValue(props, ORBLocator.ORB_SSL_SERVER_REQUIRED); boolean clientAuthRequired = getBooleanValue(props, ORBLocator.ORB_CLIENT_AUTH_REQUIRED); - CompoundSecMech[] mechList = new CompoundSecMech[1]; org.omg.IOP.TaggedComponent transportMech = createSSLInfo(sslPort, null, sslRequired); - - // Create AS_Context AS_ContextSec asContext = createASContextSec(null, DEFAULT_REALM); - - // Create SAS_Context SAS_ContextSec sasContext = createSASContextSec(null); - short targetRequires = (clientAuthRequired ? EstablishTrustInClient.value : 0); + short targetRequires = clientAuthRequired ? EstablishTrustInClient.value : 0; // Convert Profile.TaggedComponent to org.omg.IOP.TaggedComponent + CompoundSecMech[] mechList = new CompoundSecMech[1]; mechList[0] = new CompoundSecMech(targetRequires, transportMech, asContext, sasContext); - tc = createCompoundSecMechListComponent(mechList); + return createCompoundSecMechListComponent(mechList); } catch (Exception e) { LOG.log(Level.SEVERE, "Failed to create a Security Tagged Component", e); + return null; } - return tc; } private org.omg.IOP.TaggedComponent createCompoundSecMechListComponent(CompoundSecMech[] mechList) { @@ -209,12 +175,8 @@ private org.omg.IOP.TaggedComponent createCompoundSecMechListComponent(CompoundS CDROutputObject out = (CDROutputObject) orb.create_output_stream(); out.putEndian(); - boolean stateful = false; - CompoundSecMechList list = new CompoundSecMechList(stateful, mechList); - CompoundSecMechListHelper.write(out, list); - byte[] buf = out.toByteArray(); - org.omg.IOP.TaggedComponent tc = new org.omg.IOP.TaggedComponent(TAG_CSI_SEC_MECH_LIST.value, buf); - return tc; + CompoundSecMechListHelper.write(out, new CompoundSecMechList(false, mechList)); + return new org.omg.IOP.TaggedComponent(TAG_CSI_SEC_MECH_LIST.value, out.toByteArray()); } private Set getIORConfigurationDescriptors(EjbDescriptor desc) { @@ -260,10 +222,6 @@ private Set getIORConfigurationDescriptors(EjbDes return iorDescSet; } - // Type of simple closure used for createCompoundSecMechs - private interface DescriptorMaker extends UnaryFunction { - } - /** * Create the security mechanisms. Only 1 such mechanism is created although the spec allows multiple mechanisms (in * decreasing order of preference). Note that creating more than one CompoundSecMech here will cause @@ -277,7 +235,7 @@ private CompoundSecMech[] createCompoundSecMechs(DescriptorMaker maker, EjbDescr return null; } - Set iorDescSet = getIORConfigurationDescriptors(desc); + Set iorDescSet = getIORConfigurationDescriptors(desc); CompoundSecMech[] mechList = new CompoundSecMech[iorDescSet.size()]; Iterator itr = iorDescSet.iterator(); @@ -287,7 +245,7 @@ private CompoundSecMech[] createCompoundSecMechs(DescriptorMaker maker, EjbDescr for (int i = 0; i < iorDescSet.size(); i++) { EjbIORConfigurationDescriptor iorDesc = itr.next(); int target_requires = getTargetRequires(iorDesc); - org.omg.IOP.TaggedComponent comp = maker.evaluate(iorDesc); + org.omg.IOP.TaggedComponent comp = maker.apply(iorDesc); if (desc.getApplication() != null) { realmName = desc.getApplication().getRealm(); @@ -316,33 +274,19 @@ private CompoundSecMech[] createCompoundSecMechs(DescriptorMaker maker, EjbDescr } private CompoundSecMech[] createCompoundSecMechs(final List socketInfos, final EjbDescriptor desc) throws GSSException { - - DescriptorMaker maker = new DescriptorMaker() { - @Override - public org.omg.IOP.TaggedComponent evaluate(EjbIORConfigurationDescriptor desc) { - return createSSLInfo(socketInfos, desc, false); - } - }; - + DescriptorMaker maker = d -> createSSLInfo(socketInfos, d, false); return createCompoundSecMechs(maker, desc); } private CompoundSecMech[] createCompoundSecMechs(final int sslPort, final EjbDescriptor desc) throws GSSException { - - DescriptorMaker maker = new DescriptorMaker() { - @Override - public org.omg.IOP.TaggedComponent evaluate(EjbIORConfigurationDescriptor desc) { - return createSSLInfo(sslPort, desc, false); - } - }; - + DescriptorMaker maker = d -> createSSLInfo(sslPort, d, false); return createCompoundSecMechs(maker, desc); } /** * Create the AS layer context within a compound mechanism definition. */ - public AS_ContextSec createASContextSec(EjbIORConfigurationDescriptor iorDesc, String realmName) throws GSSException { + AS_ContextSec createASContextSec(EjbIORConfigurationDescriptor iorDesc, String realmName) throws GSSException { AS_ContextSec asContext = null; int target_supports = 0; int target_requires = 0; @@ -371,7 +315,7 @@ public AS_ContextSec createASContextSec(EjbIORConfigurationDescriptor iorDesc, S LOG.log(Level.FINE, "IIOP:AS_Context: Realm Name for login = {0}", realmName); - if (realmName == null) { + if (realmName == null && iorDesc != null) { realmName = iorDesc.getRealmName(); } if (realmName == null) { @@ -397,7 +341,7 @@ public AS_ContextSec createASContextSec(EjbIORConfigurationDescriptor iorDesc, S /** * Create the SAS layer context within a compound mechanism definition. */ - public SAS_ContextSec createSASContextSec(EjbIORConfigurationDescriptor iorDesc) throws GSSException { + SAS_ContextSec createSASContextSec(EjbIORConfigurationDescriptor iorDesc) { SAS_ContextSec sasContext = null; // target_supports = 0 means that target supports ITTAbsent int target_supports = 0; @@ -443,7 +387,7 @@ public SAS_ContextSec createSASContextSec(EjbIORConfigurationDescriptor iorDesc) /** * Get the value of target_supports for the transport layer. */ - public int getTargetSupports(EjbIORConfigurationDescriptor iorDesc) { + int getTargetSupports(EjbIORConfigurationDescriptor iorDesc) { if (iorDesc == null) { return 0; } @@ -475,7 +419,7 @@ public int getTargetSupports(EjbIORConfigurationDescriptor iorDesc) { /** * Get the value of target_requires for the transport layer. */ - public int getTargetRequires(EjbIORConfigurationDescriptor iorDesc) { + int getTargetRequires(EjbIORConfigurationDescriptor iorDesc) { if (iorDesc == null) { return 0; } @@ -671,7 +615,7 @@ public CompoundSecMech[] getSecurityMechanisms(IOR ior) { /** * Retrieve the SSL tagged component from the compound security mechanism. */ - public TLS_SEC_TRANS getSSLInformation(CompoundSecMech mech) { + TLS_SEC_TRANS getSSLInformation(CompoundSecMech mech) { org.omg.IOP.TaggedComponent pcomp = mech.transport_mech; TLS_SEC_TRANS ssl = getSSLComponent(pcomp); return ssl; @@ -689,4 +633,9 @@ private TLS_SEC_TRANS getSSLComponent(org.omg.IOP.TaggedComponent comp) { in.consumeEndian(); return TLS_SEC_TRANSHelper.read(in); } + + + // Type of simple closure used for createCompoundSecMechs + private interface DescriptorMaker extends Function { + } } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/IIOPSSLUtilImpl.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/IIOPSSLUtilImpl.java index 90bc0ac90ce..27523487997 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/IIOPSSLUtilImpl.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/IIOPSSLUtilImpl.java @@ -17,6 +17,7 @@ package com.sun.enterprise.iiop.security; +import com.sun.corba.ee.spi.transport.SocketInfo; import com.sun.enterprise.deployment.EjbDescriptor; import com.sun.enterprise.security.ssl.J2EEKeyManager; import com.sun.enterprise.security.ssl.SSLUtils; @@ -33,7 +34,7 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509KeyManager; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.IIOPSSLUtil; import org.jvnet.hk2.annotations.Service; import org.omg.IOP.TaggedComponent; @@ -54,7 +55,8 @@ public class IIOPSSLUtilImpl implements IIOPSSLUtil { @Inject private SSLUtils sslUtils; - private GlassFishORBHelper orbHelper; + @Inject + private GlassFishORBLocator orbLocator; private Object appClientSSL; @@ -111,17 +113,14 @@ public SecureRandom getInitializedSecureRandom() { } @Override - public Object getSSLPortsAsSocketInfo(Object ior) { + public List getSSLPortsAsSocketInfo(Object ior) { SecurityMechanismSelector selector = Lookups.getSecurityMechanismSelector(); - return selector.getSSLSocketInfo(ior); + return (List) selector.getSSLSocketInfo(ior); } @Override public TaggedComponent createSSLTaggedComponent(IORInfo iorInfo, Object sInfos) { List socketInfos = (List) sInfos; - orbHelper = Lookups.getGlassFishORBHelper(); - TaggedComponent result = null; - org.omg.CORBA.ORB orb = orbHelper.getORB(); int sslMutualAuthPort = -1; try { if (iorInfo instanceof com.sun.corba.ee.spi.legacy.interceptor.IORInfoExt) { @@ -134,12 +133,11 @@ public TaggedComponent createSSLTaggedComponent(IORInfo iorInfo, Object sInfos) LOG.log(FINE, "sslMutualAuthPort: {0}", sslMutualAuthPort); - CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(orb, sslMutualAuthPort); - EjbDescriptor desc = ctc.getEjbDescriptor(iorInfo); - if (desc != null) { - result = ctc.createSecurityTaggedComponent(socketInfos, desc); + EjbDescriptor desc = orbLocator.getEjbDescriptor(iorInfo); + if (desc == null) { + return null; } - return result; + CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(sslMutualAuthPort, orbLocator.getORB()); + return ctc.createSecurityTaggedComponent(socketInfos, desc); } - } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/Lookups.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/Lookups.java index afa88114e2b..d8260047db4 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/Lookups.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/Lookups.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -22,7 +22,7 @@ import java.lang.ref.WeakReference; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.gms.bootstrap.GMSAdapterService; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.internal.api.Globals; @@ -37,9 +37,6 @@ public class Lookups { @Inject private Provider securityMechanismSelectorProvider; - @Inject - private Provider glassFishORBHelperProvider; - @Inject private Provider securityContextUtilProvider; @@ -49,7 +46,7 @@ public class Lookups { /** * Static singleton {@link Habitat} instance. */ - private static final ServiceLocator habitat = Globals.getDefaultHabitat(); + private static final ServiceLocator SERVICE_LOCATOR = Globals.getDefaultHabitat(); /** * Static singleton {@link Lookups} instance. Note that this is assigned lazily and may remain null if the @@ -58,7 +55,7 @@ public class Lookups { private static Lookups singleton; private static WeakReference sms = new WeakReference<>(null); - private static WeakReference orb = new WeakReference<>(null); + private static WeakReference orbLocator = new WeakReference<>(null); private static WeakReference sc = new WeakReference<>(null); private Lookups() { @@ -71,11 +68,11 @@ private Lookups() { * @return true if the singleton instance has been successfully assigned; false otherwise */ private static synchronized boolean checkSingleton() { - if (singleton == null && habitat != null) { + if (singleton == null && SERVICE_LOCATOR != null) { // Obtaining the singleton through the habitat will cause the injections to occur. - singleton = habitat.create(Lookups.class); - habitat.inject(singleton); - habitat.postConstruct(singleton); + singleton = SERVICE_LOCATOR.create(Lookups.class); + SERVICE_LOCATOR.inject(singleton); + SERVICE_LOCATOR.postConstruct(singleton); } return singleton != null; } @@ -89,35 +86,16 @@ static SecurityMechanismSelector getSecurityMechanismSelector() { if (sms.get() != null) { return sms.get(); } - return _getSecurityMechanismSelector(); + return provideSecurityMechanismSelector(); } - private static synchronized SecurityMechanismSelector _getSecurityMechanismSelector() { + private static synchronized SecurityMechanismSelector provideSecurityMechanismSelector() { if (sms.get() == null && checkSingleton()) { sms = new WeakReference<>(singleton.securityMechanismSelectorProvider.get()); } return sms.get(); } - /** - * Get the {@link GlassFishORBHelper}. - * - * @return the {@link GlassFishORBHelper}; null if not available - */ - static GlassFishORBHelper getGlassFishORBHelper() { - if (orb.get() != null) { - return orb.get(); - } - return _getGlassFishORBHelper(); - } - - private static synchronized GlassFishORBHelper _getGlassFishORBHelper() { - if (orb.get() == null && checkSingleton()) { - orb = new WeakReference<>(singleton.glassFishORBHelperProvider.get()); - } - return orb.get(); - } - /** * Get the {@link SecurityContextUtil}. * @@ -127,10 +105,10 @@ static SecurityContextUtil getSecurityContextUtil() { if (sc.get() != null) { return sc.get(); } - return _getSecurityContextUtil(); + return provideSecurityContextUtil(); } - private static synchronized SecurityContextUtil _getSecurityContextUtil() { + private static synchronized SecurityContextUtil provideSecurityContextUtil() { if (sc.get() == null && checkSingleton()) { sc = new WeakReference<>(singleton.securityContextUtilProvider.get()); } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecClientRequestInterceptor.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecClientRequestInterceptor.java index 4df0bd901fc..a1f2df5ae3d 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecClientRequestInterceptor.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecClientRequestInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -46,7 +46,7 @@ import javax.security.auth.x500.X500Principal; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.internal.api.ORBLocator; import org.omg.CORBA.Any; import org.omg.CORBA.ORB; import org.omg.IOP.Codec; @@ -69,8 +69,16 @@ */ public class SecClientRequestInterceptor extends org.omg.CORBA.LocalObject implements ClientRequestInterceptor { + private static final long serialVersionUID = -1324916857150102312L; + private static final Logger LOG = LogDomains.getLogger(SecClientRequestInterceptor.class, SECURITY_LOGGER, false); + /** + * Hard code the value of 15 for SecurityAttributeService until it is defined in IOP.idl. sc.context_id = + * SecurityAttributeService.value; + */ + protected static final int SECURITY_ATTRIBUTE_SERVICE_ID = 15; + /** name of interceptor */ private final String name; @@ -81,21 +89,15 @@ public class SecClientRequestInterceptor extends org.omg.CORBA.LocalObject imple private final String prname; /** used for marshalling */ private final Codec codec; - private final GlassFishORBHelper orbHelper; private final SecurityContextUtil secContextUtil; + private final ORBLocator orbLocator; - /** - * Hard code the value of 15 for SecurityAttributeService until it is defined in IOP.idl. sc.context_id = - * SecurityAttributeService.value; - */ - protected static final int SECURITY_ATTRIBUTE_SERVICE_ID = 15; - - public SecClientRequestInterceptor(String name, Codec codec) { + public SecClientRequestInterceptor(String name, Codec codec, ORBLocator orbLocator) { this.name = name; this.codec = codec; this.prname = name + "::"; - orbHelper = Lookups.getGlassFishORBHelper(); - secContextUtil = Lookups.getSecurityContextUtil(); + this.orbLocator = orbLocator; + this.secContextUtil = Lookups.getSecurityContextUtil(); } @Override @@ -236,7 +238,6 @@ public void send_request(ClientRequestInfo ri) throws ForwardRequest { LOG.log(Level.FINE, "++++ Entered {0} send_request()", prname); SecurityContext secctxt = null; // SecurityContext to be sent - ORB orb = orbHelper.getORB(); org.omg.CORBA.Object effective_target = ri.effective_target(); try { secctxt = secContextUtil.getSecurityContext(effective_target); @@ -254,6 +255,7 @@ public void send_request(ClientRequestInfo ri) throws ForwardRequest { return; } + final ORB orb = orbLocator.getORB(); final SecurityContext sCtx = secctxt; /* Construct an authentication token */ if (secctxt.authcls != null) { @@ -437,8 +439,4 @@ public void receive_other(ClientRequestInfo ri) throws ForwardRequest { @Override public void destroy() { } - - protected GlassFishORBHelper getORBHelper() { - return this.orbHelper; - } } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecIORInterceptor.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecIORInterceptor.java index f9a7ab9bde6..cb6ce0a181f 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecIORInterceptor.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecIORInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -24,29 +24,25 @@ import java.util.logging.Level; import java.util.logging.Logger; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.util.IIOPUtils; import org.glassfish.gms.bootstrap.GMSAdapter; import org.glassfish.gms.bootstrap.GMSAdapterService; import org.glassfish.orb.admin.config.IiopListener; -import org.omg.CORBA.ORB; import org.omg.IOP.Codec; import org.omg.IOP.TaggedComponent; import org.omg.PortableInterceptor.IORInfo; -public class SecIORInterceptor extends org.omg.CORBA.LocalObject implements org.omg.PortableInterceptor.IORInterceptor { +class SecIORInterceptor extends org.omg.CORBA.LocalObject implements org.omg.PortableInterceptor.IORInterceptor { private static final Logger LOG = LogDomains.getLogger(SecIORInterceptor.class, LogDomains.SECURITY_LOGGER, false); - private final Codec codec; + private final GMSAdapter gmsAdapter; private final GMSAdapterService gmsAdapterService; - private GMSAdapter gmsAdapter; + private final GlassFishORBLocator orbLocator; - // private GlassFishORBHelper helper = null; - private final ORB orb; - - public SecIORInterceptor(Codec c, ORB orb) { - codec = c; - this.orb = orb; + SecIORInterceptor(Codec c, GlassFishORBLocator orbLocator) { + this.orbLocator = orbLocator; this.gmsAdapterService = Lookups.getGMSAdapterService(); if (this.gmsAdapterService == null) { this.gmsAdapter = null; @@ -70,7 +66,6 @@ public String name() { public void establish_components(IORInfo iorInfo) { try { LOG.log(Level.FINE, "SecIORInterceptor.establish_components->:"); - // EjbDescriptor desc = CSIV2TaggedComponentInfo.getEjbDescriptor( iorInfo ) ; addCSIv2Components(iorInfo); } catch (Exception e) { LOG.log(Level.WARNING, "Exception in establish_components", e); @@ -98,38 +93,24 @@ private void addCSIv2Components(IORInfo iorInfo) { // ORB orb = helper.getORB(); int sslMutualAuthPort = getServerPort("SSL_MUTUALAUTH"); -// try { -// sslMutualAuthPort = ((com.sun.corba.ee.spi.legacy.interceptor.IORInfoExt)iorInfo). -// getServerPort("SSL_MUTUALAUTH"); -// } catch (com.sun.corba.ee.spi.legacy.interceptor.UnknownType ute) { -// _logger.log(Level.FINE,"UnknownType exception", ute); -// } LOG.log(Level.FINE, ".addCSIv2Components: sslMutualAuthPort: {0}", sslMutualAuthPort); - CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(orb, sslMutualAuthPort); - desc = ctc.getEjbDescriptor(iorInfo); + desc = orbLocator.getEjbDescriptor(iorInfo); // Create CSIv2 tagged component int sslport = getServerPort("SSL"); -// try { -// sslport = ((com.sun.corba.ee.spi.legacy.interceptor.IORInfoExt)iorInfo). -// getServerPort("SSL"); -// } catch (com.sun.corba.ee.spi.legacy.interceptor.UnknownType ute) { -// _logger.log(Level.FINE,"UnknownType exception", ute); -// } LOG.log(Level.FINE, ".addCSIv2Components: sslport: {0}", sslport); - TaggedComponent csiv2Comp = null; - if (desc != null) { - csiv2Comp = ctc.createSecurityTaggedComponent(sslport, desc); - } else { + CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(sslMutualAuthPort, orbLocator.getORB()); + final TaggedComponent csiv2Comp; + if (desc == null) { // this is not an EJB object, must be a non-EJB CORBA object - csiv2Comp = ctc.createSecurityTaggedComponent(sslport); + csiv2Comp = ctc.createSecurityTaggedComponent(sslport, orbLocator.getCSIv2Props()); + } else { + csiv2Comp = ctc.createSecurityTaggedComponent(sslport, desc); } - iorInfo.add_ior_component(csiv2Comp); - } finally { LOG.log(Level.FINE, ".addCSIv2Components<-: {0} {1}", new Object[] {iorInfo, desc}); } @@ -158,5 +139,3 @@ private int getServerPort(String mech) { return -1; } } - -// End of file. diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecServerRequestInterceptor.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecServerRequestInterceptor.java index 5f5d59ff0fb..fafece59cf0 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecServerRequestInterceptor.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecServerRequestInterceptor.java @@ -56,7 +56,7 @@ import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.internal.api.ORBLocator; import org.omg.CORBA.Any; import org.omg.CORBA.NO_PERMISSION; import org.omg.CORBA.ORB; @@ -103,18 +103,16 @@ public class SecServerRequestInterceptor extends org.omg.CORBA.LocalObject imple private final String name; private final Codec codec; private final SecurityContextUtil secContextUtil; - private final GlassFishORBHelper orbHelper; - private final SecurityMechanismSelector smSelector; + private final ORBLocator orbLocator; // Not required // SecurityService secsvc = null; // Security Service - public SecServerRequestInterceptor(String name, Codec codec) { + public SecServerRequestInterceptor(String name, Codec codec, ORBLocator orbLocator) { this.name = name; this.codec = codec; this.prname = name + "::"; - secContextUtil = Lookups.getSecurityContextUtil(); - orbHelper = Lookups.getGlassFishORBHelper(); - smSelector = Lookups.getSecurityMechanismSelector(); + this.secContextUtil = Lookups.getSecurityContextUtil(); + this.orbLocator = orbLocator; } @Override @@ -174,11 +172,11 @@ private SASContextBody createCompleteEstablishContext(int status) { /** * CDR encode a SAS Context body and then construct a service context element. */ - private ServiceContext createSvcContext(SASContextBody sasctxtbody, ORB orb) { + private ServiceContext createSvcContext(SASContextBody sasctxtbody) { ServiceContext sc = null; - Any a = orb.create_any(); + Any a = orbLocator.getORB().create_any(); SASContextBodyHelper.insert(a, sasctxtbody); byte[] cdr_encoded_saselm = {}; @@ -335,14 +333,14 @@ private void createAuthCred(SecurityContext sc, byte[] authtok, ORB orb) throws sc.authcls = PasswordCredential.class; } - private void handle_null_service_context(ServerRequestInfo ri, ORB orb) { + private void handle_null_service_context(ServerRequestInfo ri) { LOG.log(Level.FINE, "No SAS context element found in service context list for operation: {0}", ri.operation()); ServiceContext sc = null; int secStatus = secContextUtil.setSecurityContext(null, ri.object_id(), ri.operation(), getServerSocket()); if (secStatus == SecurityContextUtil.STATUS_FAILED) { SASContextBody sasctxbody = createContextError(INVALID_MECHANISM_MAJOR, INVALID_MECHANISM_MINOR); - sc = createSvcContext(sasctxbody, orb); + sc = createSvcContext(sasctxbody); ri.add_reply_service_context(sc, NO_REPLACE); LOG.log(Level.FINE, "SecServerRequestInterceptor.receive_request: NO_PERMISSION"); throw new NO_PERMISSION(); @@ -351,24 +349,17 @@ private void handle_null_service_context(ServerRequestInfo ri, ORB orb) { @Override public void receive_request(ServerRequestInfo ri) throws ForwardRequest { - SecurityContext seccontext = null; // SecurityContext to be sent - ServiceContext sc = null; // service context - int status = 0; - boolean raise_no_perm = false; - LOG.log(Level.FINE, "Entered {0} receive_request", prname); - // secsvc = Csiv2Manager.getSecurityService(); - ORB orb = orbHelper.getORB(); - + ServiceContext serviceContext; try { - sc = ri.get_request_service_context(SECURITY_ATTRIBUTE_SERVICE_ID); - if (sc == null) { - handle_null_service_context(ri, orb); + serviceContext = ri.get_request_service_context(SECURITY_ATTRIBUTE_SERVICE_ID); + if (serviceContext == null) { + handle_null_service_context(ri); return; } } catch (org.omg.CORBA.BAD_PARAM e) { - handle_null_service_context(ri, orb); + handle_null_service_context(ri); return; } @@ -376,7 +367,7 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { /* Decode the service context field */ Any SasAny; try { - SasAny = codec.decode_value(sc.context_data, SASContextBodyHelper.type()); + SasAny = codec.decode_value(serviceContext.context_data, SASContextBodyHelper.type()); } catch (Exception e) { throw new SecurityException("CDR Decoding error for SAS context element.", e); } @@ -401,15 +392,12 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { if (sasdiscr == MTMessageInContext.value) { sasctxbody = createContextError(SvcContextUtils.MessageInContextMinor); - sc = createSvcContext(sasctxbody, orb); + serviceContext = createSvcContext(sasctxbody); if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Adding ContextError message to service context list"); LOG.log(Level.FINE, "SecurityContext set to null"); } - ri.add_reply_service_context(sc, NO_REPLACE); - // no need to set the security context -// secsvc.setSecurityContext(null, ri.object_id(), ri.operation()); - + ri.add_reply_service_context(serviceContext, NO_REPLACE); throw new NO_PERMISSION(); } @@ -429,13 +417,13 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { EstablishContext ec = sasctxbody.establish_msg(); - seccontext = new SecurityContext(); + final SecurityContext seccontext = new SecurityContext(); seccontext.subject = new Subject(); try { if (ec.client_authentication_token.length != 0) { LOG.log(Level.FINE, "Message contains Client Authentication Token"); - createAuthCred(seccontext, ec.client_authentication_token, orb); + createAuthCred(seccontext, ec.client_authentication_token, orbLocator.getORB()); } } catch (Exception e) { throw new SecurityException("Error while creating a JAAS subject credential.", e); @@ -449,8 +437,8 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { } catch (SecurityException secex) { LOG.log(Level.SEVERE, "Could not create an identity for an identity token.", secex); sasctxbody = createContextError(INVALID_MECHANISM_MAJOR, INVALID_MECHANISM_MINOR); - sc = createSvcContext(sasctxbody, orb); - ri.add_reply_service_context(sc, NO_REPLACE); + serviceContext = createSvcContext(sasctxbody); + ri.add_reply_service_context(serviceContext, NO_REPLACE); throw new NO_PERMISSION(); } catch (Exception e) { throw new SecurityException("Error while creating a JAAS subject credential.", e); @@ -458,7 +446,7 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { } LOG.log(Level.FINE, "Invoking setSecurityContext() to set security context"); - status = secContextUtil.setSecurityContext(seccontext, ri.object_id(), ri.operation(), getServerSocket()); + final int status = secContextUtil.setSecurityContext(seccontext, ri.object_id(), ri.operation(), getServerSocket()); LOG.log(Level.FINE, "setSecurityContext() returned status code {0}", status); /** @@ -471,17 +459,17 @@ public void receive_request(ServerRequestInfo ri) throws ForwardRequest { if (status == SecurityContextUtil.STATUS_FAILED) { LOG.log(Level.FINE, "setSecurityContext() returned STATUS_FAILED"); sasctxbody = createContextError(status); - sc = createSvcContext(sasctxbody, orb); + serviceContext = createSvcContext(sasctxbody); LOG.log(Level.FINE, "Adding ContextError message to service context list"); - ri.add_reply_service_context(sc, NO_REPLACE); + ri.add_reply_service_context(serviceContext, NO_REPLACE); throw new NO_PERMISSION(); } LOG.log(Level.FINE, "setSecurityContext() returned SUCCESS"); sasctxbody = createCompleteEstablishContext(status); - sc = createSvcContext(sasctxbody, orb); + serviceContext = createSvcContext(sasctxbody); LOG.log(Level.FINE, "Adding CompleteEstablisContext message to service context list"); - ri.add_reply_service_context(sc, NO_REPLACE); + ri.add_reply_service_context(serviceContext, NO_REPLACE); } /* diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityContextUtil.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityContextUtil.java index b0d08d41299..ad69b7f1809 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityContextUtil.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityContextUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -40,7 +40,7 @@ import javax.security.auth.Subject; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.ProtocolManager; import org.glassfish.hk2.api.PostConstruct; import org.jvnet.hk2.annotations.Service; @@ -67,7 +67,7 @@ public class SecurityContextUtil implements PostConstruct { private Policy policy; @Inject - private GlassFishORBHelper orbHelper; + private GlassFishORBLocator orbLocator; @Inject private SecurityMechanismSelector sms; @@ -97,8 +97,7 @@ public Object run() { */ public SecurityContext getSecurityContext(org.omg.CORBA.Object effective_target) throws InvalidMechanismException, InvalidIdentityTokenException { - assert (orbHelper != null); - IOR ior = ((com.sun.corba.ee.spi.orb.ORB) orbHelper.getORB()).getIOR(effective_target, false); + IOR ior = ((com.sun.corba.ee.spi.orb.ORB) orbLocator.getORB()).getIOR(effective_target, false); if (StubAdapter.isStub(effective_target)) { if (StubAdapter.isLocal(effective_target)) { // XXX: Workaround for non-null connection object ri for local invocation. @@ -194,7 +193,7 @@ public int setSecurityContext(SecurityContext context, byte[] object_id, String private boolean authorizeCORBA(byte[] object_id, String method) throws Exception { // Check if target is an EJB - ProtocolManager protocolMgr = orbHelper.getProtocolManager(); + ProtocolManager protocolMgr = orbLocator.getProtocolManager(); // Check to make sure protocolMgr is not null. // This could happen during server initialization or if this call // is on a callback object in the client VM. diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityIIOPInterceptorFactory.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityIIOPInterceptorFactory.java index 409e916e69b..d0ac4d73a09 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityIIOPInterceptorFactory.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityIIOPInterceptorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -26,9 +26,9 @@ import java.util.logging.Logger; import org.glassfish.api.admin.ProcessEnvironment; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.IIOPInterceptorFactory; import org.jvnet.hk2.annotations.Service; -import org.omg.CORBA.ORB; import org.omg.IOP.Codec; import org.omg.PortableInterceptor.ClientRequestInterceptor; import org.omg.PortableInterceptor.IORInterceptor; @@ -47,13 +47,17 @@ public class SecurityIIOPInterceptorFactory implements IIOPInterceptorFactory { private static final Logger LOG = LogDomains.getLogger(SecurityIIOPInterceptorFactory.class, SECURITY_LOGGER, false); final String interceptorFactory = System.getProperty(AlternateSecurityInterceptorFactory.SEC_INTEROP_INTFACTORY_PROP); - private ClientRequestInterceptor creq; - private ServerRequestInterceptor sreq; - private SecIORInterceptor sior; @Inject private ProcessEnvironment penv; + @Inject + private GlassFishORBLocator orbLocator; + + private ClientRequestInterceptor creq; + private ServerRequestInterceptor sreq; + private SecIORInterceptor sior; + private AlternateSecurityInterceptorFactory altSecFactory; // are we supposed to add the interceptor and then return or just return an instance ?. @@ -83,9 +87,7 @@ public ServerRequestInterceptor createServerRequestInterceptor(ORBInitInfo info, } // also register the IOR Interceptor here if (info instanceof com.sun.corba.ee.spi.legacy.interceptor.ORBInitInfoExt) { - com.sun.corba.ee.spi.legacy.interceptor.ORBInitInfoExt infoExt = (com.sun.corba.ee.spi.legacy.interceptor.ORBInitInfoExt) info; - IORInterceptor secIOR = getSecIORInterceptorInstance(codec, infoExt.getORB()); - info.add_ior_interceptor(secIOR); + info.add_ior_interceptor(getSecIORInterceptorInstance(codec)); } } catch (DuplicateName ex) { @@ -96,40 +98,36 @@ public ServerRequestInterceptor createServerRequestInterceptor(ORBInitInfo info, private synchronized boolean createAlternateSecurityInterceptorFactory() { try { - Class clazz = Thread.currentThread().getContextClassLoader().loadClass(interceptorFactory); + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(interceptorFactory); if (AlternateSecurityInterceptorFactory.class.isAssignableFrom(clazz) && !clazz.isInterface()) { - altSecFactory = (AlternateSecurityInterceptorFactory) clazz.newInstance(); + altSecFactory = (AlternateSecurityInterceptorFactory) clazz.getConstructor().newInstance(); return true; } LOG.log(Level.INFO, "Not a valid factory class: {0}. Must implement {1}", new Object[] {interceptorFactory, AlternateSecurityInterceptorFactory.class}); - } catch (ClassNotFoundException ex) { - LOG.log(Level.INFO, "Interceptor Factory class " + interceptorFactory + " not loaded: ", ex); - } catch (InstantiationException ex) { - LOG.log(Level.INFO, "Interceptor Factory class " + interceptorFactory + " not loaded: ", ex); - } catch (IllegalAccessException ex) { - LOG.log(Level.INFO, "Interceptor Factory class " + interceptorFactory + " not loaded: ", ex); + } catch (Exception ex) { + LOG.log(Level.WARNING, "Interceptor Factory class " + interceptorFactory + " not loaded: ", ex); } return false; } private synchronized ClientRequestInterceptor getClientInterceptorInstance(Codec codec) { if (creq == null) { - creq = new SecClientRequestInterceptor("SecClientRequestInterceptor", codec); + creq = new SecClientRequestInterceptor("SecClientRequestInterceptor", codec, orbLocator); } return creq; } private synchronized ServerRequestInterceptor getServerInterceptorInstance(Codec codec) { if (sreq == null) { - sreq = new SecServerRequestInterceptor("SecServerRequestInterceptor", codec); + sreq = new SecServerRequestInterceptor("SecServerRequestInterceptor", codec, orbLocator); } return sreq; } - private synchronized IORInterceptor getSecIORInterceptorInstance(Codec codec, ORB orb) { + private synchronized IORInterceptor getSecIORInterceptorInstance(Codec codec) { if (sior == null) { - sior = new SecIORInterceptor(codec, orb); + sior = new SecIORInterceptor(codec, orbLocator); } return sior; } diff --git a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityMechanismSelector.java b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityMechanismSelector.java index 7f45fcdb2cc..1596c34435e 100644 --- a/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityMechanismSelector.java +++ b/appserver/security/ejb.security/src/main/java/com/sun/enterprise/iiop/security/SecurityMechanismSelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -79,15 +79,15 @@ import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; import org.glassfish.api.invocation.ComponentInvocation; -import org.glassfish.api.invocation.InvocationManager; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBFactory; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.enterprise.iiop.api.ProtocolManager; import org.glassfish.hk2.api.PostConstruct; import org.glassfish.internal.api.ORBLocator; import org.ietf.jgss.Oid; import org.jvnet.hk2.annotations.Service; -import org.omg.CORBA.ORB; +import static com.sun.enterprise.iiop.security.IORToSocketInfoImpl.createSocketInfo; import static com.sun.logging.LogDomains.SECURITY_LOGGER; /** @@ -99,7 +99,6 @@ * @author Nithya Subramanian * */ - @Service @Singleton public final class SecurityMechanismSelector implements PostConstruct { @@ -126,15 +125,13 @@ public final class SecurityMechanismSelector implements PostConstruct { @Inject private SSLUtils sslUtils; - private GlassFishORBHelper orbHelper; + @Inject + private GlassFishORBLocator orbLocator; + @Inject + private GlassFishORBFactory orbFactory; - // private CompoundSecMech mechanism = null; - private ORB orb; private CSIV2TaggedComponentInfo ctc; - @Inject - private InvocationManager invMgr; - @Inject private ProcessEnvironment processEnv; @@ -147,10 +144,8 @@ public SecurityMechanismSelector() { @Override public void postConstruct() { try { - orbHelper = Lookups.getGlassFishORBHelper(); // Initialize client security config - String s = (orbHelper.getCSIv2Props()).getProperty(ORBLocator.ORB_SSL_CLIENT_REQUIRED); - if (s != null && s.equals("true")) { + if ("true".equals(orbFactory.getCSIv2Props().getProperty(ORBLocator.ORB_SSL_CLIENT_REQUIRED))) { sslRequired = true; } @@ -158,14 +153,14 @@ public void postConstruct() { corbaIORDescSet = new HashSet<>(); EjbIORConfigurationDescriptor iorDesc = new EjbIORConfigurationDescriptor(); EjbIORConfigurationDescriptor iorDesc2 = new EjbIORConfigurationDescriptor(); - String serverSslReqd = (orbHelper.getCSIv2Props()).getProperty(ORBLocator.ORB_SSL_SERVER_REQUIRED); + String serverSslReqd = orbFactory.getCSIv2Props().getProperty(ORBLocator.ORB_SSL_SERVER_REQUIRED); if (serverSslReqd != null && serverSslReqd.equals("true")) { iorDesc.setIntegrity(EjbIORConfigurationDescriptor.REQUIRED); iorDesc.setConfidentiality(EjbIORConfigurationDescriptor.REQUIRED); iorDesc2.setIntegrity(EjbIORConfigurationDescriptor.REQUIRED); iorDesc2.setConfidentiality(EjbIORConfigurationDescriptor.REQUIRED); } - String clientAuthReq = (orbHelper.getCSIv2Props()).getProperty(ORBLocator.ORB_CLIENT_AUTH_REQUIRED); + String clientAuthReq = orbFactory.getCSIv2Props().getProperty(ORBLocator.ORB_CLIENT_AUTH_REQUIRED); if (clientAuthReq != null && clientAuthReq.equals("true")) { // Need auth either by SSL or username-password. // This sets SSL clientauth to required. @@ -197,7 +192,6 @@ public void setClientConnectionContext(ConnectionContext scc) { * return null if SSL should not be used or an SocketInfo containing the SSL port if SSL should be used. */ public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx) { - SocketInfo info = null; CompoundSecMech mechanism = null; try { mechanism = selectSecurityMechanism(ior); @@ -213,15 +207,13 @@ public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx) { } if (ssl == null) { - if (isSslRequired()) { - // Attempt to create SSL connection to host, ORBInitialPort - IIOPProfileTemplate templ = (IIOPProfileTemplate) ior.getProfile().getTaggedProfileTemplate(); - IIOPAddress addr = templ.getPrimaryAddress(); - info = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector1", "SSL", addr.getHost(), orbHelper.getORBPort(orbHelper.getORB())); - return info; - } else { + if (!isSslRequired()) { return null; } + // Attempt to create SSL connection to host, ORBInitialPort + IIOPProfileTemplate templ = (IIOPProfileTemplate) ior.getProfile().getTaggedProfileTemplate(); + IIOPAddress addr = templ.getPrimaryAddress(); + return createSocketInfo("SecurityMechanismSelector1", "SSL", addr.getHost(), orbLocator.getORBPort()); } int targetRequires = ssl.target_requires; @@ -242,9 +234,7 @@ public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx) { int ssl_port = Utility.shortToInt(sslport); String host_name = ssl.addresses[0].host_name; - info = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector2", type, host_name, ssl_port); - - return info; + return createSocketInfo("SecurityMechanismSelector2", type, host_name, ssl_port); } else if (isSet(targetSupports, Integrity.value) || isSet(targetSupports, Confidentiality.value) || isSet(targetSupports, EstablishTrustInClient.value)) { LOG.log(Level.FINE, "Target supports SSL"); @@ -256,8 +246,7 @@ public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx) { short sslport = ssl.addresses[0].port; String host_name = ssl.addresses[0].host_name; int ssl_port = Utility.shortToInt(sslport); - info = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector3", "SSL", host_name, ssl_port); - return info; + return createSocketInfo("SecurityMechanismSelector3", "SSL", host_name, ssl_port); } else if (isSslRequired()) { throw new RuntimeException("SSL required by client but not supported by server."); } else { @@ -265,23 +254,9 @@ public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx) { } } - /* - * public String[] getServerTrustedHosts() { return serverTrustedHosts; } - * - * public void setServerTrustedHosts(String[] val) { this.serverTrustedHosts = val; } - */ - - public ORB getOrb() { - return orb; - } - - public void setOrb(ORB val) { - this.orb = val; - } - public synchronized CSIV2TaggedComponentInfo getCtc() { if (ctc == null) { - this.ctc = new CSIV2TaggedComponentInfo(orbHelper.getORB()); + this.ctc = new CSIV2TaggedComponentInfo(orbLocator.getORB()); } return ctc; } @@ -302,19 +277,17 @@ public java.util.List getSSLPorts(IOR ior, ConnectionContext ctx) { } if (ssl == null) { - if (isSslRequired()) { - // Attempt to create SSL connection to host, ORBInitialPort - IIOPProfileTemplate templ = (IIOPProfileTemplate) ior.getProfile().getTaggedProfileTemplate(); - IIOPAddress addr = templ.getPrimaryAddress(); - SocketInfo info = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector1", "SSL", addr.getHost(), - orbHelper.getORBPort(orbHelper.getORB())); - // SocketInfo[] sInfos = new SocketInfo[]{info}; - List sInfos = new ArrayList<>(); - sInfos.add(info); - return sInfos; - } else { + if (!isSslRequired()) { return null; } + // Attempt to create SSL connection to host, ORBInitialPort + IIOPProfileTemplate templ = (IIOPProfileTemplate) ior.getProfile().getTaggedProfileTemplate(); + IIOPAddress addr = templ.getPrimaryAddress(); + SocketInfo info = createSocketInfo("SecurityMechanismSelector1", "SSL", + addr.getHost(), orbLocator.getORBPort()); + List sInfos = new ArrayList<>(); + sInfos.add(info); + return sInfos; } int targetRequires = ssl.target_requires; @@ -338,7 +311,7 @@ public java.util.List getSSLPorts(IOR ior, ConnectionContext ctx) { int ssl_port = Utility.shortToInt(sslport); String host_name = element.host_name; - SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector2", type, host_name, ssl_port); + SocketInfo sInfo = createSocketInfo("SecurityMechanismSelector2", type, host_name, ssl_port); socketInfos.add(sInfo); } return socketInfos; @@ -357,7 +330,7 @@ public java.util.List getSSLPorts(IOR ior, ConnectionContext ctx) { int ssl_port = Utility.shortToInt(sslport); String host_name = element.host_name; - SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo("SecurityMechanismSelector3", "SSL", host_name, ssl_port); + SocketInfo sInfo = createSocketInfo("SecurityMechanismSelector3", "SSL", host_name, ssl_port); socketInfos.add(sInfo); } return socketInfos; @@ -417,9 +390,9 @@ public SecurityContext selectSecurityContext(IOR ior) throws InvalidIdentityToke * * @return the security context. */ - public SecurityContext getSecurityContextForAppClient(ComponentInvocation ci, boolean sslUsed, boolean clientAuthOccurred, CompoundSecMech mechanism) - throws InvalidMechanismException, InvalidIdentityTokenException, SecurityMechanismException { - + public SecurityContext getSecurityContextForAppClient(ComponentInvocation ci, boolean sslUsed, + boolean clientAuthOccurred, CompoundSecMech mechanism) + throws InvalidMechanismException, InvalidIdentityTokenException, SecurityMechanismException { return sendUsernameAndPassword(ci, sslUsed, clientAuthOccurred, mechanism); } @@ -429,9 +402,9 @@ public SecurityContext getSecurityContextForAppClient(ComponentInvocation ci, bo * * @return the security context. */ - public SecurityContext getSecurityContextForWebOrEJB(ComponentInvocation ci, boolean sslUsed, boolean clientAuthOccurred, CompoundSecMech mechanism) - throws InvalidMechanismException, InvalidIdentityTokenException, SecurityMechanismException { - + public SecurityContext getSecurityContextForWebOrEJB(ComponentInvocation ci, boolean sslUsed, + boolean clientAuthOccurred, CompoundSecMech mechanism) + throws InvalidMechanismException, InvalidIdentityTokenException, SecurityMechanismException { SecurityContext ctx = null; if (!sslUsed) { ctx = propagateIdentity(false, ci, mechanism); @@ -1099,7 +1072,7 @@ private boolean evaluate_client_conformance(SecurityContext ctx, byte[] object_i } if (protocolMgr == null) { - protocolMgr = orbHelper.getProtocolManager(); + protocolMgr = orbLocator.getProtocolManager(); } // Check to make sure protocolMgr is not null. @@ -1244,7 +1217,7 @@ public SecurityContext evaluateTrust(SecurityContext ctx, byte[] object_id, Sock return null; } - if (evaluate_client_conformance(ctx, object_id, ssl_used, certChain) == false) { + if (!evaluate_client_conformance(ctx, object_id, ssl_used, certChain)) { throw new SecurityMechanismException( "Trust evaluation failed because client does not conform to configured security policies"); } @@ -1352,7 +1325,7 @@ public String getSecurityMechanismString(CSIV2TaggedComponentInfo tCI, IOR ior) } public static String getSecurityMechanismString(CSIV2TaggedComponentInfo tCI, CompoundSecMech[] list, String name) { - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); b.append("\ntypeId: " + name); try { for (int i = 0; list != null && i < list.length; i++) { diff --git a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/AsadminLoggingITest.java b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/AsadminLoggingITest.java index e6046a29aa1..4a0b668a3aa 100644 --- a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/AsadminLoggingITest.java +++ b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/AsadminLoggingITest.java @@ -16,8 +16,6 @@ package org.glassfish.main.admin.test; -import com.sun.enterprise.util.OS; - import java.io.File; import java.io.FileReader; import java.io.LineNumberReader; @@ -74,13 +72,7 @@ public class AsadminLoggingITest { /** Fill up the server log. */ @BeforeAll public static void fillUpServerLog() throws Exception { - if (OS.isWindowsForSure()) { - // For some reason windows can collide on debug port. - assertThat(ASADMIN.exec("stop-domain"), asadminOK()); - assertThat(ASADMIN.exec("start-domain"), asadminOK()); - } else { - assertThat(ASADMIN.exec("restart-domain"), asadminOK()); - } + assertThat(ASADMIN.exec("restart-domain"), asadminOK()); } @Test diff --git a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/ConnectionUtils.java b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/ConnectionUtils.java index 7b99ffd8a63..7532ee2a072 100644 --- a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/ConnectionUtils.java +++ b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/ConnectionUtils.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter; +import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; @@ -34,8 +35,12 @@ public class ConnectionUtils { * @return The string returned from that URL, or empty string if there was a problem contacting the URL */ public static String getURL(String urlstr) { - URLConnection urlc = openConnection(urlstr); - return getContent(urlc); + HttpURLConnection urlc = openConnection(urlstr); + try { + return getContent(urlc); + } finally { + urlc.disconnect(); + } } /** @@ -45,8 +50,8 @@ public static String getURL(String urlstr) { * @return The string returned from that connection, or empty string if there was a problem contacting the URL */ public static String getContent(URLConnection connection) { - try ( - BufferedReader ir = new BufferedReader(new InputStreamReader(connection.getInputStream(), ISO_8859_1)); StringWriter ow = new StringWriter()) { + try (BufferedReader ir = new BufferedReader(new InputStreamReader(connection.getInputStream(), ISO_8859_1)); + StringWriter ow = new StringWriter()) { String line; while ((line = ir.readLine()) != null) { ow.write(line); @@ -58,13 +63,11 @@ public static String getContent(URLConnection connection) { } } - public static URLConnection openConnection(String url) { + public static HttpURLConnection openConnection(String url) { try { - return new URL(url).openConnection(); + return (HttpURLConnection) new URL(url).openConnection(); } catch (IOException e) { throw new IllegalArgumentException(e); } } - - } diff --git a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/webapp/HttpServerNameITest.java b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/webapp/HttpServerNameITest.java index fbb5d159afd..b745a025156 100644 --- a/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/webapp/HttpServerNameITest.java +++ b/appserver/tests/admin/tests/src/test/java/org/glassfish/main/admin/test/webapp/HttpServerNameITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2024, 2025 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -55,12 +55,14 @@ public class HttpServerNameITest { @ParameterizedTest(name = "[{index}] testServerName: {0}") public void testHostName(String description, String serverName, String expectedUrlPrefix) throws Exception { assertThat(ASADMIN.exec("set", SERVER_NAME_PROPERTY + "=" + serverName), asadminOK()); - final HttpURLConnection conn = GlassFishTestEnvironment.openConnection(HTTP_PORT, "/" + TEST_APP_NAME); - conn.setInstanceFollowRedirects(false); - - assertThat(conn.getHeaderField("Location"), stringContainsInOrder(expectedUrlPrefix)); - assertThat(getContent(conn), stringContainsInOrder("This document has moved assertEquals(200, connection.getResponseCode()), () -> assertEquals(message, HttpParser.readResponseInputStream(connection).trim()) - ); + ); + } finally { + connection.disconnect(); + } } @Test void testAccessLocalEJBByJNDI() throws Exception { String message = RandomGenerator.generateRandomString(); - HttpURLConnection connection = GlassFishTestEnvironment - .openConnection(8080, "/local_ejb_jndi?message=" + message); - connection.setRequestMethod("GET"); - assertAll( + HttpURLConnection connection = openConnection(8080, "/local_ejb_jndi?message=" + message); + try { + connection.setRequestMethod("GET"); + assertAll( () -> assertEquals(200, connection.getResponseCode()), () -> assertEquals(message, HttpParser.readResponseInputStream(connection).trim()) - ); + ); + } finally { + connection.disconnect(); + } } @Test void testAccessRemoteEJBByCDI() throws Exception { String message = RandomGenerator.generateRandomString(); - HttpURLConnection connection = GlassFishTestEnvironment - .openConnection(8080, "/remote_ejb_cdi?message=" + message); - connection.setRequestMethod("GET"); - assertAll( + HttpURLConnection connection = openConnection(8080, "/remote_ejb_cdi?message=" + message); + try { + connection.setRequestMethod("GET"); + assertAll( () -> assertEquals(200, connection.getResponseCode()), () -> assertEquals(message, HttpParser.readResponseInputStream(connection).trim()) - ); + ); + } finally { + connection.disconnect(); + } } @Test void testAccessRemoteEJBByJNDI() throws Exception { String message = RandomGenerator.generateRandomString(); - HttpURLConnection connection = GlassFishTestEnvironment - .openConnection(8080, "/remote_ejb_jndi?message=" + message); - connection.setRequestMethod("GET"); - assertAll( + HttpURLConnection connection = openConnection(8080, "/remote_ejb_jndi?message=" + message); + try { + connection.setRequestMethod("GET"); + assertAll( () -> assertEquals(200, connection.getResponseCode()), () -> assertEquals(message, HttpParser.readResponseInputStream(connection).trim()) - ); + ); + } finally { + connection.disconnect(); + } } private static File createDeployment() { diff --git a/appserver/tests/application/src/test/java/org/glassfish/main/test/app/ejblinksyntax/EjbDependsOnByFileNameTest.java b/appserver/tests/application/src/test/java/org/glassfish/main/test/app/ejblinksyntax/EjbDependsOnByFileNameTest.java index 621f16469d9..fa2dc39fe87 100644 --- a/appserver/tests/application/src/test/java/org/glassfish/main/test/app/ejblinksyntax/EjbDependsOnByFileNameTest.java +++ b/appserver/tests/application/src/test/java/org/glassfish/main/test/app/ejblinksyntax/EjbDependsOnByFileNameTest.java @@ -82,14 +82,18 @@ public static void undeploy() { @Test public void testEjbLinkSyntax() throws Exception{ HttpURLConnection connection = openConnection(8080, "/ejblinksyntax/inspector"); - connection.setRequestMethod("GET"); - assertAll( - () -> assertEquals(200, connection.getResponseCode()), - () -> assertEquals( - "Cat of color: brown (file-name#) and creature with name: Z", - readResponseInputStream(connection) - ) - ); + try { + connection.setRequestMethod("GET"); + assertAll( + () -> assertEquals(200, connection.getResponseCode()), + () -> assertEquals( + "Cat of color: brown (file-name#) and creature with name: Z", + readResponseInputStream(connection) + ) + ); + } finally { + connection.disconnect(); + } } private static File createDeployment() { diff --git a/appserver/tests/application/src/test/java/org/glassfish/main/test/app/web/jsp/JspReloadGeneratedServletIfUpdatedTest.java b/appserver/tests/application/src/test/java/org/glassfish/main/test/app/web/jsp/JspReloadGeneratedServletIfUpdatedTest.java index 2bd1f1b21b1..620e38ed3ea 100644 --- a/appserver/tests/application/src/test/java/org/glassfish/main/test/app/web/jsp/JspReloadGeneratedServletIfUpdatedTest.java +++ b/appserver/tests/application/src/test/java/org/glassfish/main/test/app/web/jsp/JspReloadGeneratedServletIfUpdatedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -93,12 +93,16 @@ public void doTest() throws Exception { private void doHttpGet(String expectedText) throws Exception { HttpURLConnection connection = GlassFishTestEnvironment.openConnection(8080, "/reload/" + JSP_FILE_NAME + ".jsp"); - connection.setRequestMethod("GET"); - String line = HttpParser.readResponseInputStream(connection).trim(); - assertAll( - () -> assertEquals(200, connection.getResponseCode(), "Wrong response code."), - () -> assertEquals(expectedText, line, "Wrong response body.") - ); + try { + connection.setRequestMethod("GET"); + String line = HttpParser.readResponseInputStream(connection).trim(); + assertAll( + () -> assertEquals(200, connection.getResponseCode(), "Wrong response code."), + () -> assertEquals(expectedText, line, "Wrong response body.") + ); + } finally { + connection.disconnect(); + } } diff --git a/appserver/tests/embedded/maven-plugin/applicationDispatcher/src/test/java/org/glassfish/tests/applicationDispatcher/WebTest.java b/appserver/tests/embedded/maven-plugin/applicationDispatcher/src/test/java/org/glassfish/tests/applicationDispatcher/WebTest.java index 763754193da..5b8bea1334f 100644 --- a/appserver/tests/embedded/maven-plugin/applicationDispatcher/src/test/java/org/glassfish/tests/applicationDispatcher/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/applicationDispatcher/src/test/java/org/glassfish/tests/applicationDispatcher/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,56 +18,47 @@ package org.glassfish.tests.applicationDispatcher; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class WebTest { - private static int count = 0; - private static int EXPECTED_COUNT = 1; + private static final int EXPECTED_COUNT = 1; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "ApplicationDispatcher", contextPath+"/ServletTest"); } - private static void goGet(String host, int port, - String result, String contextPath) throws Exception { - try { - URL servlet = new URL("http://localhost:8080/test"); - URLConnection yc = servlet.openConnection(); - BufferedReader in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); + + private static void goGet(String host, int port, String result, String contextPath) throws Exception { + URL servlet = new URL("http://localhost:8080/test"); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; - int index, lineNum=0; + int index, lineNum = 0; + int count = 0; while ((line = in.readLine()) != null) { index = line.indexOf("::"); - System.out.println(lineNum+": "+line); + System.out.println(lineNum + ": " + line); if (index != -1) { - String status = line.substring(index+2); - if (status.equalsIgnoreCase("PASS")){ + String status = line.substring(index + 2); + if (status.equalsIgnoreCase("PASS")) { count++; } } lineNum++; } - Assertions.assertTrue(count==EXPECTED_COUNT); - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertEquals(EXPECTED_COUNT, count); + } finally { + connection.disconnect(); } - } - + } } diff --git a/appserver/tests/embedded/maven-plugin/dirListing/src/test/java/org/glassfish/tests/dirListing/WebTest.java b/appserver/tests/embedded/maven-plugin/dirListing/src/test/java/org/glassfish/tests/dirListing/WebTest.java index ee2d3bc4e3f..263689a2eb4 100644 --- a/appserver/tests/embedded/maven-plugin/dirListing/src/test/java/org/glassfish/tests/dirListing/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/dirListing/src/test/java/org/glassfish/tests/dirListing/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,54 +18,45 @@ package org.glassfish.tests.dirListing; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class WebTest { private static int count = 0; - private static int EXPECTED_COUNT = 1; + private static final int EXPECTED_COUNT = 1; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "", contextPath+"/"); } - private static void goGet(String host, int port, - String result, String contextPath) throws Exception { - try { - URL servlet = new URL("http://localhost:8080/test"); - URLConnection yc = servlet.openConnection(); - BufferedReader in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); + + private static void goGet(String host, int port, String result, String contextPath) throws Exception { + URL servlet = new URL("http://localhost:8080/test"); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; - int lineNum=0; + int lineNum = 0; while ((line = in.readLine()) != null) { System.out.println(lineNum + ": " + line); - if (line.indexOf("Directory Listing") != -1){ + if (line.indexOf("Directory Listing") != -1) { System.out.println("Getting a \"Directory Listing\""); count++; break; } lineNum++; } - Assertions.assertTrue(count==EXPECTED_COUNT); - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertEquals(EXPECTED_COUNT, count); + } finally { + connection.disconnect(); } - } - + } } diff --git a/appserver/tests/embedded/maven-plugin/filterURIMapping/src/test/java/org/glassfish/tests/filterURIMapping/WebTest.java b/appserver/tests/embedded/maven-plugin/filterURIMapping/src/test/java/org/glassfish/tests/filterURIMapping/WebTest.java index 04a8bfc801e..944ce17cc39 100644 --- a/appserver/tests/embedded/maven-plugin/filterURIMapping/src/test/java/org/glassfish/tests/filterURIMapping/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/filterURIMapping/src/test/java/org/glassfish/tests/filterURIMapping/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,26 +18,20 @@ package org.glassfish.tests.filterURIMapping; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class WebTest { - private static int count = 0; - private static int EXPECTED_COUNT = 1; + private static final int EXPECTED_COUNT = 1; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "DESTROYED", contextPath+"/ServletTest;test=aaa"); @@ -45,15 +39,11 @@ public void testWeb() throws Exception { private static void goGet(String host, int port, String result, String contextPath) throws Exception { - BufferedReader in = null; boolean pass = false; - try { - URL servlet = new URL("http://localhost:8080/"+contextPath); - URLConnection yc = servlet.openConnection(); - in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); + URL servlet = new URL("http://localhost:8080/" + contextPath); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; - int index; while ((line = in.readLine()) != null) { System.out.println(line); if (line.startsWith("Filter invoked")) { @@ -61,19 +51,9 @@ private static void goGet(String host, int port, break; } } - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertTrue(pass); } finally { - try { - if (in != null) { - in.close(); - } - } catch (IOException ioe) { - // ignore - } + connection.disconnect(); } - Assertions.assertTrue(pass); - } - + } } diff --git a/appserver/tests/embedded/maven-plugin/jmxUndeployEvent/src/test/java/org/glassfish/tests/jmxUndeployEvent/WebTest.java b/appserver/tests/embedded/maven-plugin/jmxUndeployEvent/src/test/java/org/glassfish/tests/jmxUndeployEvent/WebTest.java index 00f92b8f94d..5bb29efe590 100644 --- a/appserver/tests/embedded/maven-plugin/jmxUndeployEvent/src/test/java/org/glassfish/tests/jmxUndeployEvent/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/jmxUndeployEvent/src/test/java/org/glassfish/tests/jmxUndeployEvent/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -21,13 +21,13 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; import org.hamcrest.CoreMatchers; -import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; + public class WebTest { private String contextPath = "test"; @@ -38,18 +38,15 @@ public static void setup() throws IOException { @Test public void testWeb() throws Exception { - URL url = new URL("http://localhost:8080/"+contextPath+"/ServletTest"); - URLConnection conn = url.openConnection(); - if (conn instanceof HttpURLConnection) { - HttpURLConnection urlConnection = (HttpURLConnection)conn; + URL url = new URL("http://localhost:8080/" + contextPath + "/ServletTest"); + HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + try { urlConnection.setDoOutput(true); - DataOutputStream out = - new DataOutputStream(urlConnection.getOutputStream()); + DataOutputStream out = new DataOutputStream(urlConnection.getOutputStream()); out.writeByte(1); - int responseCode= urlConnection.getResponseCode(); - System.out.println("responseCode: " + responseCode); - MatcherAssert.assertThat(urlConnection.getResponseCode(), CoreMatchers.is(404)); + assertThat(urlConnection.getResponseCode(), CoreMatchers.is(404)); + } finally { + urlConnection.disconnect(); } } - } diff --git a/appserver/tests/embedded/maven-plugin/jsptest/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java b/appserver/tests/embedded/maven-plugin/jsptest/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java index 780fad95bf9..7eedc686884 100644 --- a/appserver/tests/embedded/maven-plugin/jsptest/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java +++ b/appserver/tests/embedded/maven-plugin/jsptest/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,7 +18,6 @@ package org.glassfish.tests.embedded.jsptest; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; @@ -30,21 +29,16 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class JspTest { -// private static int count = 0; - private static int EXPECTED_COUNT = 3; + private static final int EXPECTED_COUNT = 3; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { // test non secure access. @@ -57,46 +51,47 @@ public void testWeb() throws Exception { } private static void goGet(String url, String result) throws Exception { - try { disableCertValidation(); URL servlet = new URL(url); HttpURLConnection uc = (HttpURLConnection)servlet.openConnection(); - System.out.println("\nURLConnection = " + uc + " : "); - if (uc.getResponseCode() != 200) { - throw new Exception("Servlet did not return 200 OK response code"); - } - BufferedReader in = new BufferedReader(new InputStreamReader( - uc.getInputStream())); - String line = null; - boolean found = false; - int index; - while ((line = in.readLine()) != null) { - System.out.println(line); - index = line.indexOf(result); - if (index != -1) { - found = true; + try { + System.out.println("\nURLConnection = " + uc + " : "); + if (uc.getResponseCode() != 200) { + throw new Exception("Servlet did not return 200 OK response code"); + } + try (BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()))) { + String line = null; + boolean found = false; + int index; + while ((line = in.readLine()) != null) { + System.out.println(line); + index = line.indexOf(result); + if (index != -1) { + found = true; + } + } + assertTrue(found); + System.out.println("\n***** SUCCESS **** Found [" + result + "] in the response.*****\n"); } + } finally { + uc.disconnect(); } - Assertions.assertTrue(found); - System.out.println("\n***** SUCCESS **** Found [" + result + "] in the response.*****\n"); - in.close(); - } catch (Exception e) { - e.printStackTrace(); - throw e; } - } public static void disableCertValidation() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + @Override public X509Certificate[] getAcceptedIssuers() { return null; } + @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { return; } + @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { return; } diff --git a/appserver/tests/embedded/maven-plugin/localejbs/src/test/java/org/glassfish/tests/embedded/localejbs/EjbTest.java b/appserver/tests/embedded/maven-plugin/localejbs/src/test/java/org/glassfish/tests/embedded/localejbs/EjbTest.java index 2c99ec1b642..3558c96db57 100644 --- a/appserver/tests/embedded/maven-plugin/localejbs/src/test/java/org/glassfish/tests/embedded/localejbs/EjbTest.java +++ b/appserver/tests/embedded/maven-plugin/localejbs/src/test/java/org/glassfish/tests/embedded/localejbs/EjbTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -31,11 +31,14 @@ public class EjbTest { @Test public void test() throws Exception { URL url = new URL("http://localhost:8080/test/TesterServlet"); - HttpURLConnection uc = (HttpURLConnection)url.openConnection(); - System.out.println("Test status : " + uc.getResponseMessage()); - if(uc.getResponseCode() != 200) { - throw new Exception(uc.getResponseCode() + ": " + uc.getResponseMessage()); + HttpURLConnection uc = (HttpURLConnection) url.openConnection(); + try { + System.out.println("Test status : " + uc.getResponseMessage()); + if (uc.getResponseCode() != 200) { + throw new Exception(uc.getResponseCode() + ": " + uc.getResponseMessage()); + } + } finally { + uc.disconnect(); } - uc.disconnect(); } } diff --git a/appserver/tests/embedded/maven-plugin/multipleApps/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java b/appserver/tests/embedded/maven-plugin/multipleApps/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java index a53c886d6a9..ad5d0c804a7 100644 --- a/appserver/tests/embedded/maven-plugin/multipleApps/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java +++ b/appserver/tests/embedded/maven-plugin/multipleApps/src/test/java/org/glassfish/tests/embedded/jsptest/JspTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,7 +18,6 @@ package org.glassfish.tests.embedded.jsptest; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; @@ -30,21 +29,16 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class JspTest { -// private static int count = 0; - private static int EXPECTED_COUNT = 3; + private static final int EXPECTED_COUNT = 3; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { // test non secure access. @@ -61,46 +55,47 @@ public void testWeb() throws Exception { } private static void goGet(String url, String result) throws Exception { + disableCertValidation(); + URL servlet = new URL(url); + HttpURLConnection uc = (HttpURLConnection) servlet.openConnection(); try { - disableCertValidation(); - URL servlet = new URL(url); - HttpURLConnection uc = (HttpURLConnection)servlet.openConnection(); System.out.println("\nURLConnection = " + uc + " : "); if (uc.getResponseCode() != 200) { throw new Exception("Servlet did not return 200 OK response code"); } - BufferedReader in = new BufferedReader(new InputStreamReader( - uc.getInputStream())); - String line = null; - boolean found = false; - int index; - while ((line = in.readLine()) != null) { - System.out.println(line); - index = line.indexOf(result); - if (index != -1) { - found = true; + try (BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()))) { + String line = null; + boolean found = false; + int index; + while ((line = in.readLine()) != null) { + System.out.println(line); + index = line.indexOf(result); + if (index != -1) { + found = true; + } } + assertTrue(found); + System.out.println("\n***** SUCCESS **** Found [" + result + "] in the response.*****\n"); } - Assertions.assertTrue(found); - System.out.println("\n***** SUCCESS **** Found [" + result + "] in the response.*****\n"); - in.close(); - } catch (Exception e) { - e.printStackTrace(); - throw e; + } finally { + uc.disconnect(); } } public static void disableCertValidation() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + @Override public X509Certificate[] getAcceptedIssuers() { return null; } + @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { return; } + @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { return; } diff --git a/appserver/tests/embedded/maven-plugin/queryString/src/test/java/org/glassfish/tests/queryString/WebTest.java b/appserver/tests/embedded/maven-plugin/queryString/src/test/java/org/glassfish/tests/queryString/WebTest.java index 11382e2b599..364930a5bee 100644 --- a/appserver/tests/embedded/maven-plugin/queryString/src/test/java/org/glassfish/tests/queryString/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/queryString/src/test/java/org/glassfish/tests/queryString/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,78 +18,69 @@ package org.glassfish.tests.queryString; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class WebTest { - private static int count = 0; - private static int EXPECTED_COUNT = 1; + private static final int EXPECTED_COUNT = 1; private String contextPath = "/test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "TEST", contextPath+"/ServletTest"); } - private static void goGet(String host, int port, - String result, String contextPath) throws Exception { - try { - contextPath += "?url=" + contextPath; - System.out.println("Connecting "+contextPath); - URL servlet = new URL("http://localhost:8080/"+contextPath); - //URL servlet = new URL("http://localhost:8080/test/ServletTest?TEST=PASS"); - URLConnection yc = servlet.openConnection(); - BufferedReader in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); - + private static void goGet(String host, int port, String result, String contextPath) throws Exception { + contextPath += "?url=" + contextPath; + System.out.println("Connecting " + contextPath); + URL servlet = new URL("http://localhost:8080/" + contextPath); + // URL servlet = new URL("http://localhost:8080/test/ServletTest?TEST=PASS"); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; - int index; while ((line = in.readLine()) != null) { - index = line.indexOf(result); + int index = line.indexOf(result); System.out.println("[Server response]" + line); int pos = line.indexOf("Location"); - if (pos != -1){ - contextPath = line.substring(pos + "Location:".length()).trim(); - in.close(); - break; + if (pos != -1) { + contextPath = line.substring(pos + "Location:".length()).trim(); + in.close(); + break; } } + } finally { + connection.disconnect(); + } - servlet = new URL("http://localhost:8080/"+contextPath); - yc = servlet.openConnection(); - in = new BufferedReader(new InputStreamReader(yc.getInputStream())); + servlet = new URL("http://localhost:8080/" + contextPath); + HttpURLConnection connection2 = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection2.getInputStream()))) { + String line; + int count = 0; while ((line = in.readLine()) != null) { - index = line.indexOf(result); + int index = line.indexOf(result); System.out.println("[Redirect response]" + line); if (index != -1) { index = line.indexOf(":"); - String status = line.substring(index+1); + String status = line.substring(index + 1); - if (status.equalsIgnoreCase("PASS")){ + if (status.equalsIgnoreCase("PASS")) { count++; } else { break; } } } - - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertEquals(EXPECTED_COUNT, count); } - } - + } } diff --git a/appserver/tests/embedded/maven-plugin/secureWebApp/src/test/java/org/glassfish/tests/embedded/securewebapp/SecureWebAppTest.java b/appserver/tests/embedded/maven-plugin/secureWebApp/src/test/java/org/glassfish/tests/embedded/securewebapp/SecureWebAppTest.java index 57be14284a7..9b0a33bc0c5 100644 --- a/appserver/tests/embedded/maven-plugin/secureWebApp/src/test/java/org/glassfish/tests/embedded/securewebapp/SecureWebAppTest.java +++ b/appserver/tests/embedded/maven-plugin/secureWebApp/src/test/java/org/glassfish/tests/embedded/securewebapp/SecureWebAppTest.java @@ -87,28 +87,32 @@ private static void goGet(boolean secured, String contextPath, String expectedBo final int port = secured ? 8181 : 8080; URL servlet = new URI(protocol + "://localhost:" + port + "/test/SecureWebAppTestServlet").toURL(); HttpURLConnection uc = openConnection(secured, servlet); - System.out.println("URLConnection = " + uc); - if (uc.getResponseCode() != 200) { - throw new Exception("Servlet did not return 200 OK response code"); - } - int count = 0; - try (BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()))) { - String line; - while ((line = in.readLine()) != null) { - System.out.println(line); - int index = line.indexOf(expectedBody); - if (index == -1) { - continue; - } - index = line.indexOf(":"); - String status = line.substring(index + 1); - if (!status.equalsIgnoreCase("PASS")) { - return; + try { + System.out.println("URLConnection = " + uc); + if (uc.getResponseCode() != 200) { + throw new Exception("Servlet did not return 200 OK response code"); + } + int count = 0; + try (BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()))) { + String line; + while ((line = in.readLine()) != null) { + System.out.println(line); + int index = line.indexOf(expectedBody); + if (index == -1) { + continue; + } + index = line.indexOf(":"); + String status = line.substring(index + 1); + if (!status.equalsIgnoreCase("PASS")) { + return; + } + count++; } - count++; } + assertEquals(3, count, "Expected count of successful tests"); + } finally { + uc.disconnect(); } - assertEquals(3, count, "Expected count of successful tests"); } private static HttpURLConnection openConnection(boolean secured, URL endpoint) diff --git a/appserver/tests/embedded/maven-plugin/sessionDestroyed/src/test/java/org/glassfish/tests/sessionDestroyed/WebTest.java b/appserver/tests/embedded/maven-plugin/sessionDestroyed/src/test/java/org/glassfish/tests/sessionDestroyed/WebTest.java index 6a6a0ee8a30..e1dd1a7c9b5 100644 --- a/appserver/tests/embedded/maven-plugin/sessionDestroyed/src/test/java/org/glassfish/tests/sessionDestroyed/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/sessionDestroyed/src/test/java/org/glassfish/tests/sessionDestroyed/WebTest.java @@ -18,59 +18,48 @@ package org.glassfish.tests.sessionDestroyed; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class WebTest { - private static int count = 0; - private static int EXPECTED_COUNT = 1; + private static final int EXPECTED_COUNT = 1; private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "DESTROYED", contextPath+"/ServletTest"); } - private static void goGet(String host, int port, - String result, String contextPath) throws Exception { - try { - URL servlet = new URL("http://localhost:8080/"+contextPath); - URLConnection yc = servlet.openConnection(); - BufferedReader in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); + private static void goGet(String host, int port, String result, String contextPath) throws Exception { + URL servlet = new URL("http://localhost:8080/" + contextPath); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; - int index; + int count = 0; while ((line = in.readLine()) != null) { - index = line.indexOf(result); + int index = line.indexOf(result); System.out.println(line); if (index != -1) { index = line.indexOf(":"); - String status = line.substring(index+1); + String status = line.substring(index + 1); - if (status.equalsIgnoreCase("PASS")){ + if (status.equalsIgnoreCase("PASS")) { count++; } else { return; } } } - Assertions.assertTrue(count==EXPECTED_COUNT); - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertEquals(EXPECTED_COUNT, count); + } finally { + connection.disconnect(); } - } - + } } diff --git a/appserver/tests/embedded/maven-plugin/standalonewar/src/test/java/org/glassfish/tests/standalonewar/WebTest.java b/appserver/tests/embedded/maven-plugin/standalonewar/src/test/java/org/glassfish/tests/standalonewar/WebTest.java index b8305dc63c9..3b7be47d130 100644 --- a/appserver/tests/embedded/maven-plugin/standalonewar/src/test/java/org/glassfish/tests/standalonewar/WebTest.java +++ b/appserver/tests/embedded/maven-plugin/standalonewar/src/test/java/org/glassfish/tests/standalonewar/WebTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -18,59 +18,47 @@ package org.glassfish.tests.standalonewar; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -public class WebTest { +import static org.junit.jupiter.api.Assertions.assertEquals; - private static int count = 0; - private static int EXPECTED_COUNT = 3; +public class WebTest { private String contextPath = "test"; - @BeforeAll - public static void setup() throws IOException { - } - @Test public void testWeb() throws Exception { goGet("localhost", 8080, "FILTER", contextPath); } - private static void goGet(String host, int port, - String result, String contextPath) throws Exception { - try { - URL servlet = new URL("http://localhost:8080/test/ServletTest"); - URLConnection yc = servlet.openConnection(); - BufferedReader in = new BufferedReader(new InputStreamReader( - yc.getInputStream())); + private static void goGet(String host, int port, String result, String contextPath) throws Exception { + URL servlet = new URL("http://localhost:8080/test/ServletTest"); + HttpURLConnection connection = (HttpURLConnection) servlet.openConnection(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line = null; int index; + int count = 0; while ((line = in.readLine()) != null) { index = line.indexOf(result); System.out.println(line); if (index != -1) { index = line.indexOf(":"); - String status = line.substring(index+1); - - if (status.equalsIgnoreCase("PASS")){ + String status = line.substring(index + 1); + if (status.equalsIgnoreCase("PASS")) { count++; } else { return; } } } - Assertions.assertTrue(count==3); - } catch(Exception e) { - e.printStackTrace(); - throw e; + assertEquals(3, count); + } finally { + connection.disconnect(); } - } + } } diff --git a/appserver/tests/embedded/scatteredarchive/src/test/java/org/glassfish/tests/embedded/scatteredarchive/ScatteredArchiveTest.java b/appserver/tests/embedded/scatteredarchive/src/test/java/org/glassfish/tests/embedded/scatteredarchive/ScatteredArchiveTest.java index 693d2072051..9a7ec6d4ecb 100644 --- a/appserver/tests/embedded/scatteredarchive/src/test/java/org/glassfish/tests/embedded/scatteredarchive/ScatteredArchiveTest.java +++ b/appserver/tests/embedded/scatteredarchive/src/test/java/org/glassfish/tests/embedded/scatteredarchive/ScatteredArchiveTest.java @@ -22,9 +22,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; -import java.net.URLConnection; import java.util.Date; import java.util.Enumeration; import java.util.List; @@ -197,10 +197,12 @@ private void get(String urlStr, String key, String value) throws Exception { } private List getLinesFromUrl(URL url) throws Exception { - URLConnection yc = url.openConnection(); - logger.log(DEBUG, "\nURLConnection [" + yc + "] : "); - try (BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()))) { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + logger.log(DEBUG, "\nURLConnection [" + connection + "] : "); + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { return in.lines().collect(toList()); + } finally { + connection.disconnect(); } } diff --git a/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TransactionServerInterceptor.java b/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TransactionServerInterceptor.java index eaeee9c44a8..15079387312 100644 --- a/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TransactionServerInterceptor.java +++ b/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TransactionServerInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -19,7 +19,7 @@ import com.sun.enterprise.transaction.api.JavaEETransactionManager; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.hk2.api.ServiceLocator; import org.omg.CORBA.LocalObject; import org.omg.PortableInterceptor.ServerRequestInfo; @@ -29,10 +29,10 @@ public class TransactionServerInterceptor extends LocalObject implements ServerR private static final long serialVersionUID = 1L; private static final String name = "TransactionServerInterceptor"; - private int order; - private JavaEETransactionManager javaEETransactionManager; - private GlassFishORBHelper gfORBHelper; + private final int order; + private final JavaEETransactionManager javaEETransactionManager; + private final GlassFishORBLocator orbLocator; /** * Construct the interceptor. @@ -41,8 +41,8 @@ public class TransactionServerInterceptor extends LocalObject implements ServerR */ public TransactionServerInterceptor(int order, ServiceLocator serviceLocator) { this.order = order; - gfORBHelper = serviceLocator.getService(GlassFishORBHelper.class); - javaEETransactionManager = serviceLocator.getService(JavaEETransactionManager.class); + this.orbLocator = serviceLocator.getService(GlassFishORBLocator.class); + this.javaEETransactionManager = serviceLocator.getService(JavaEETransactionManager.class); } @Override @@ -97,7 +97,7 @@ private void checkTransaction(ServerRequestInfo sri) { javaEETransactionManager.checkTransactionImport(); } } finally { - if (gfORBHelper.isEjbCall(sri)) { + if (orbLocator.isEjbCall(sri)) { javaEETransactionManager.cleanTxnTimeout(); } } diff --git a/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TxIORInterceptor.java b/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TxIORInterceptor.java index 8d101e6e0d5..50417c00c3f 100755 --- a/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TxIORInterceptor.java +++ b/appserver/transaction/jts/src/main/java/com/sun/enterprise/transaction/jts/iiop/TxIORInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -22,7 +22,7 @@ import java.util.logging.Logger; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.hk2.api.ServiceLocator; import org.omg.CORBA.Any; import org.omg.CORBA.INTERNAL; @@ -46,10 +46,10 @@ public class TxIORInterceptor extends LocalObject implements IORInterceptor { private static final long serialVersionUID = 1L; - private static Logger _logger = LogDomains.getLogger(InterceptorImpl.class, LogDomains.TRANSACTION_LOGGER); + private static final Logger LOG = LogDomains.getLogger(InterceptorImpl.class, LogDomains.TRANSACTION_LOGGER); - private Codec codec; - private ServiceLocator serviceLocator; + private final Codec codec; + private final ServiceLocator serviceLocator; public TxIORInterceptor(Codec codec, ServiceLocator serviceLocator) { this.codec = codec; @@ -66,21 +66,21 @@ public String name() { @Override public void establish_components(IORInfo iorInfo) { try { - _logger.log(FINE, "TxIORInterceptor.establish_components->:"); + LOG.log(FINE, "TxIORInterceptor.establish_components->:"); // Add OTS tagged components. These are always the same for all EJBs OTSPolicy otsPolicy = null; try { - otsPolicy = (OTSPolicy) iorInfo.get_effective_policy(serviceLocator.getService(GlassFishORBHelper.class).getOTSPolicyType()); + otsPolicy = (OTSPolicy) iorInfo.get_effective_policy(serviceLocator.getService(GlassFishORBLocator.class).getOTSPolicyType()); } catch (INV_POLICY ex) { - _logger.log(FINE, "TxIORInterceptor.establish_components: OTSPolicy not present"); + LOG.log(FINE, "TxIORInterceptor.establish_components: OTSPolicy not present"); } addOTSComponents(iorInfo, otsPolicy); } catch (Exception e) { - _logger.log(WARNING, "Exception in establish_components", e); + LOG.log(WARNING, "Exception in establish_components", e); } finally { - _logger.log(FINE, "TxIORInterceptor.establish_components<-:"); + LOG.log(FINE, "TxIORInterceptor.establish_components<-:"); } } diff --git a/appserver/transaction/jts/src/main/java/com/sun/jts/jta/TransactionServiceProperties.java b/appserver/transaction/jts/src/main/java/com/sun/jts/jta/TransactionServiceProperties.java index 8cecb922930..6946df2ddc5 100644 --- a/appserver/transaction/jts/src/main/java/com/sun/jts/jta/TransactionServiceProperties.java +++ b/appserver/transaction/jts/src/main/java/com/sun/jts/jta/TransactionServiceProperties.java @@ -36,7 +36,7 @@ import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ServerEnvironment; -import org.glassfish.enterprise.iiop.api.GlassFishORBHelper; +import org.glassfish.enterprise.iiop.api.GlassFishORBLocator; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.BuilderHelper; import org.glassfish.internal.api.ServerContext; @@ -154,7 +154,7 @@ public static synchronized Properties getJTSProperties (ServiceLocator serviceLo int jtsServerId = DEFAULT_SERVER_ID; // default value if (isORBAvailable) { - jtsServerId = serviceLocator.getService(GlassFishORBHelper.class).getORBInitialPort(); + jtsServerId = serviceLocator.getService(GlassFishORBLocator.class).getORBInitialPort(); if (jtsServerId == 0) { // XXX Can this ever happen? jtsServerId = DEFAULT_SERVER_ID; // default value diff --git a/appserver/web/war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties b/appserver/web/war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties index 3bb6ee506cc..592b0fb5f10 100644 --- a/appserver/web/war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties +++ b/appserver/web/war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties @@ -252,7 +252,6 @@ webModuleContextConfig.unbindNamespaceError=WEB0610: [{0}] failed to unbind name # # com.sun.enterprise.web # -webApplication.unknownError=WEB0670: Unknown error, loadWebModule returned null, file a bug webApplication.loadingApplication=WEB0671: Loading application [{0}] at [{1}] webApplication.exceptionShutdownCoherenceWeb=WEB0672: Exception during Coherence*Web shutdown for application [{0}] diff --git a/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebApplication.java b/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebApplication.java index 2e538a51535..e47687f7c87 100644 --- a/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebApplication.java +++ b/appserver/web/web-glue/src/main/java/com/sun/enterprise/web/WebApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -52,7 +52,7 @@ public class WebApplication implements ApplicationContainer { private static final Logger LOG = System.getLogger(DetachListener.class.getName()); - private static final LocalStringsImpl I18N = new LocalStringsImpl(DetachListener.class); - private final RemoteRestAdminCommand rac; + private final RemoteRestAdminCommand command; private final boolean terse; public DetachListener(RemoteRestAdminCommand rac, boolean terse) { - this.rac = rac; + this.command = rac; this.terse = terse; } @@ -55,16 +53,16 @@ public DetachListener(RemoteRestAdminCommand rac, boolean terse) { public void onAdminCommandEvent(String name, GfSseInboundEvent event) { LOG.log(TRACE, "onAdminCommandEvent(name={0}, event={1})", name, event); try { - AdminCommandState acs = event.getData(AdminCommandState.class, "application/json"); - String id = acs.getId(); + final AdminCommandState acs = event.getData(AdminCommandState.class, "application/json"); + final String id = acs.getId(); if (StringUtils.ok(id)) { if (terse) { - rac.closeSse(id, ExitCode.SUCCESS); + command.closeSse(id, ExitCode.SUCCESS); } else { - rac.closeSse(I18N.get("detach.jobid", id), ExitCode.SUCCESS); + command.closeSse("Job ID: " + id, ExitCode.SUCCESS); } } else { - LOG.log(ERROR, I18N.getString("detach.noid", "Command was started but id was not retrieved. Cannot detach.")); + LOG.log(ERROR, "Command was started but id was not retrieved. Cannot detach."); } } catch (IOException ex) { LOG.log(ERROR, "Failed to retrieve event data.", ex); diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/LocalStrings.properties b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/LocalStrings.properties index a650767fa85..3d8344798d1 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/LocalStrings.properties +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/LocalStrings.properties @@ -19,7 +19,6 @@ AdminUserPasswordPrompt=Enter admin password for user "{0}">\u0020 AdminPasswordPrompt=Enter admin password>\u0020 badHttpCode=Bad HTTP code received from server: {0} internal=Internal Error: {0} -emptyResponse=Empty response from server. unknownResponse=Unknown Response: {0} unknownFormat=Unknown plain text format. Response from the server: {0} badport=Bad port number: {0}. It must be an integer in the range 1-65535. @@ -42,5 +41,3 @@ CantUploadDirectory=CLI031: Can't upload a directory, specify --upload=false. progressstatus.event.parseerror=Can not parse progress status event progressstatus.event.applyerror=Inapplicable progress status event progressstatus.message.starting=Starting -detach.jobid=Job ID: {0} -detach.noid=Command was started but id was not retrieved. Can not detach. diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java index bb8a35c382c..c78e1dd3e9f 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCLICommand.java @@ -40,7 +40,6 @@ import java.io.Console; import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; @@ -90,7 +89,6 @@ public class RemoteCLICommand extends CLICommand { private ActionReport ar; private String usage; private String responseFormatType; - private OutputStream userOut; private File outputDir; //Options from first round if reexecuted because of CommandModel update protected ParameterMap reExecutedOptions; @@ -139,11 +137,6 @@ private CLIRemoteAdminCommand(String name, String host, int port, boolean secure } } - @Override - public void fetchCommandModel() throws CommandException { - super.fetchCommandModel(); - } - /** * If we're interactive, prompt for a new username and password. Return true if we're successful in collecting new * information (and thus the caller should try the request again). @@ -501,17 +494,6 @@ public RemoteCLICommand(String name, ProgramOptions po, Environment env) throws super(name, po, env); } - /** - * Construct a new remote command object. The command and arguments are supplied later using the execute method in the - * superclass. This variant is used by the RemoteDeploymentFacility class to control and capture the output. - */ - public RemoteCLICommand(String name, ProgramOptions po, Environment env, String responseFormatType, OutputStream userOut) - throws CommandException { - this(name, po, env); - this.responseFormatType = responseFormatType; - this.userOut = userOut; - } - /** * Helper for situation, where {@code CommandModel} is from cache and something shows, that server side signature of * command was changed @@ -580,9 +562,6 @@ protected void prepare() throws CommandException, CommandValidationException { if (responseFormatType != null) { rac.setResponseFormatType(responseFormatType); } - if (userOut != null) { - rac.setUserOut(userOut); - } /* * Initialize a CookieManager so that we can retreive @@ -695,17 +674,6 @@ protected void inject() throws CommandException { } } - // /** - // * We do all our help processing in executeCommand. - // */ - // @Override - // protected boolean checkHelp() - // throws CommandException, CommandValidationException { - // return false; - // } - /** - * Runs the command using the specified arguments. - */ @Override protected int executeCommand() throws CommandException, CommandValidationException { try { @@ -716,10 +684,6 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti rac.registerListener(EVENT_STATE_CHANGED, new DetachListener(rac, programOpts.isTerse())); } - /*if (programOpts.isNotifyCommand()) { - rac.registerListener(AdminCommandState.EVENT_STATE_CHANGED, - new NotifyListener(logger, rac, programOpts.isTerse())); - }*/ try { output = rac.executeCommand(options); } finally { @@ -727,7 +691,7 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti } ar = rac.getActionReport(); if (!returnActionReport && !returnOutput) { - if (!output.isEmpty()) { + if (output != null && !output.isEmpty()) { logger.info(output); } } diff --git a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java index 7b1397cbc4b..0d73a97e5c1 100644 --- a/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java +++ b/nucleus/admin/cli/src/main/java/com/sun/enterprise/admin/cli/remote/RemoteCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -109,11 +109,6 @@ private CLIRemoteAdminCommand(String name, String host, int port, boolean secure sessionCache = AsadminSecurityUtil.getGfClientSessionFile(host, port); } - @Override - public void fetchCommandModel() throws CommandException { - super.fetchCommandModel(); - } - /** * If we're interactive, prompt for a new username and password. Return true if we're successful in collecting new * information (and thus the caller should try the request again). diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/CommandModelHttpCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/CommandModelHttpCommand.java new file mode 100644 index 00000000000..85d5fe214de --- /dev/null +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/CommandModelHttpCommand.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package com.sun.enterprise.admin.remote; + +import com.sun.enterprise.admin.remote.reader.ProprietaryReaderFactory; +import com.sun.enterprise.admin.util.AdminLoggerInfo; +import com.sun.enterprise.admin.util.CachedCommandModel; +import com.sun.enterprise.admin.util.CommandModelData.ParamModelData; +import com.sun.enterprise.admin.util.cache.AdminCacheUtils; + +import java.io.File; +import java.io.IOException; +import java.lang.System.Logger; +import java.net.HttpURLConnection; +import java.util.List; +import java.util.Properties; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.glassfish.api.admin.CommandException; +import org.glassfish.api.admin.CommandModel; +import org.glassfish.api.admin.InvalidCommandException; + +import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.TRACE; +import static java.lang.System.Logger.Level.WARNING; + + +/** + * + */ +public class CommandModelHttpCommand implements HttpCommand { + + private static final String MEDIATYPE_JSON = "application/json"; + private static final Logger LOG = System.getLogger(CommandModelHttpCommand.class.getName()); + + private final String commandName; + private final String commandCacheKey; + private final boolean detached; + private final boolean notify; + + /** + * @param commandName + * @param commandCacheKey + */ + public CommandModelHttpCommand(String commandName, String commandCacheKey, boolean detached, boolean notify) { + this.commandName = commandName; + this.commandCacheKey = commandCacheKey; + this.detached = detached; + this.notify = notify; + } + + + @Override + public void prepareConnection(HttpURLConnection urlConnection) throws IOException { + urlConnection.setRequestProperty("Accept", MEDIATYPE_JSON); + } + + + @Override + public CachedCommandModel useConnection(HttpURLConnection urlConnection) throws CommandException, IOException { + long startNanos = System.nanoTime(); + String eTag = urlConnection.getHeaderField("ETag"); + if (eTag != null) { + eTag = eTag.trim(); + if (eTag.startsWith("W/")) { + eTag = eTag.substring(2).trim(); + } + if (eTag.startsWith("\"")) { + eTag = eTag.substring(1); + } + if (eTag.endsWith("\"")) { + eTag = eTag.substring(0, eTag.length() - 1); + } + } + String json = ProprietaryReaderFactory.getReader(String.class, urlConnection.getContentType()) + .readFrom(urlConnection.getInputStream(), urlConnection.getContentType()); + CachedCommandModel commandModel = parseMetadata(json, eTag, detached, notify); + if (commandModel == null) { + throw new InvalidCommandException( + "Command model could not be parsed from JSON metadata received from server."); + } + LOG.log(DEBUG, "Command model for {0} command fetched from remote server. Duration: {1} nanos", + commandName, System.nanoTime() - startNanos); + try { + StringBuilder forCache = new StringBuilder(json.length() + 40); + forCache.append("ETag: ").append(eTag); + forCache.append("\n"); + forCache.append(json); + AdminCacheUtils.getCache().put(commandCacheKey, forCache.toString()); + } catch (Exception ex) { + LOG.log(WARNING, AdminLoggerInfo.mCantPutToCache, commandCacheKey); + } + return commandModel; + } + + static CommandModel fromCache(String key, boolean detached, boolean notify) { + final String cachedModel = getCachedModel(key); + final int ind = cachedModel == null ? -1 : cachedModel.indexOf('\n'); + if (ind < 0) { + return null; + } + final String eTag = toEtag(cachedModel, ind); + LOG.log(DEBUG, () -> "Cached command model ETag is " + eTag); + final String content = cachedModel.substring(ind + 1).trim(); + return parseMetadata(content, eTag, detached, notify); + } + + private static String getCachedModel(String key) { + String cachedModel = AdminCacheUtils.getCache().get(key, String.class); + if (cachedModel == null) { + return null; + } + return cachedModel.trim(); + } + + private static String toEtag(String cachedModel, int ind) { + String eTag = cachedModel.substring(0, ind); + if (!eTag.startsWith("ETag:")) { + return null; + } + return eTag.substring(5).trim(); + } + + + /** + * Parse the JSon metadata for the command. + * + * @param str the string + * @return the etag to compare the command cache model + */ + private static CachedCommandModel parseMetadata(String str, String etag, boolean detached, boolean notify) { + if (LOG.isLoggable(TRACE)) { + LOG.log(TRACE, "------- RAW METADATA RESPONSE ---------"); + LOG.log(TRACE, "ETag: {0}", etag); + LOG.log(TRACE, str); + LOG.log(TRACE, "------- RAW METADATA RESPONSE ---------"); + } + if (str == null) { + return null; + } + try { + boolean sawFile = false; + JSONObject obj = new JSONObject(str); + obj = obj.getJSONObject("command"); + CachedCommandModel cm = new CachedCommandModel(obj.getString("@name"), etag); + cm.dashOk = obj.optBoolean("@unknown-options-are-operands", false); + cm.managedJob = obj.optBoolean("@managed-job", false); + cm.setUsage(obj.optString("usage", null)); + Object optns = obj.opt("option"); + if (!JSONObject.NULL.equals(optns)) { + JSONArray jsonOptions; + if (optns instanceof JSONArray) { + jsonOptions = (JSONArray) optns; + } else { + jsonOptions = new JSONArray(); + jsonOptions.put(optns); + } + for (int i = 0; i < jsonOptions.length(); i++) { + JSONObject jsOpt = jsonOptions.getJSONObject(i); + String type = jsOpt.getString("@type"); + ParamModelData opt = new ParamModelData(jsOpt.getString("@name"), typeOf(type), jsOpt.optBoolean("@optional", false), + jsOpt.optString("@default"), jsOpt.optString("@short"), jsOpt.optBoolean("@obsolete", false), + jsOpt.optString("@alias")); + opt.param._acceptableValues = jsOpt.optString("@acceptable-values"); + if ("PASSWORD".equals(type)) { + opt.param._password = true; + opt.prompt = jsOpt.optString("@prompt"); + opt.promptAgain = jsOpt.optString("@prompt-again"); + } else if ("FILE".equals(type)) { + sawFile = true; + } + if (jsOpt.optBoolean("@primary", false)) { + opt.param._primary = true; + } + if (jsOpt.optBoolean("@multiple", false)) { + if (opt.type == File.class) { + opt.type = File[].class; + } else { + opt.type = List.class; + } + opt.param._multiple = true; + } + cm.add(opt); + } + } + if (sawFile) { + cm.add(new ParamModelData("upload", Boolean.class, true, null)); + cm.setAddedUploadOption(true); + } + if (notify) { + cm.add(new ParamModelData("notify", Boolean.class, false, "false")); + } + if (detached) { + cm.add(new ParamModelData("detach", Boolean.class, false, "false")); + } + return cm; + } catch (JSONException e) { + LOG.log(DEBUG, "Can not parse command metadata", e); + return null; + } + } + + private static Class typeOf(String type) { + if (type.equals("STRING")) { + return String.class; + } else if (type.equals("BOOLEAN")) { + return Boolean.class; + } else if (type.equals("FILE")) { + return File.class; + } else if (type.equals("PASSWORD")) { + return String.class; + } else if (type.equals("PROPERTIES")) { + return Properties.class; + } else { + return String.class; + } + } +} diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ExecHttpCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ExecHttpCommand.java new file mode 100644 index 00000000000..d87147f3b83 --- /dev/null +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ExecHttpCommand.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package com.sun.enterprise.admin.remote; + +import com.sun.enterprise.admin.remote.RestPayloadImpl.Outbound; +import com.sun.enterprise.admin.remote.reader.CliActionReport; +import com.sun.enterprise.admin.remote.reader.ProprietaryReader; +import com.sun.enterprise.admin.remote.reader.ProprietaryReaderFactory; +import com.sun.enterprise.admin.remote.sse.GfSseEventReceiver; +import com.sun.enterprise.admin.remote.sse.GfSseEventReceiverProprietaryReader; +import com.sun.enterprise.admin.remote.sse.GfSseInboundEvent; +import com.sun.enterprise.admin.remote.writer.ProprietaryWriter; +import com.sun.enterprise.admin.remote.writer.ProprietaryWriterFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.System.Logger; +import java.net.HttpURLConnection; +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import org.glassfish.admin.payload.PayloadFilesManager; +import org.glassfish.api.ActionReport; +import org.glassfish.api.ActionReport.ExitCode; +import org.glassfish.api.admin.AdminCommandState; +import org.glassfish.api.admin.CommandException; +import org.glassfish.api.admin.ParameterMap; +import org.glassfish.api.admin.Payload; + +import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.INFO; +import static java.lang.System.Logger.Level.TRACE; + + +/** + * + */ +public class ExecHttpCommand implements HttpCommand { + + private static final String MEDIATYPE_JSON = "application/json"; + private static final String MEDIATYPE_MULTIPART = "multipart/*"; + private static final String MEDIATYPE_SSE = "text/event-stream"; + + private static final Logger LOG = System.getLogger(ExecHttpCommand.class.getName()); + + private final ParameterMap params; + private final boolean detached; + private final boolean useSSE; + private final AtomicBoolean closeSSE; + private final boolean doUpload; + private final Outbound payload; + private final File fileOutputDir; + private final Consumer eventConsumer; + private final Consumer jobPayloadDownloader; + + public ExecHttpCommand(final ParameterMap params, boolean detached, boolean useSSE, AtomicBoolean closeSSE, boolean doUpload, + RestPayloadImpl.Outbound payload, File fileOutputDir, Consumer eventConsumer, + Consumer jobPayloadDownloader) { + this.params = params; + this.detached = detached; + this.useSSE = useSSE; + this.closeSSE = closeSSE; + this.doUpload = doUpload; + this.payload = payload; + this.fileOutputDir = fileOutputDir; + this.eventConsumer = eventConsumer; + this.jobPayloadDownloader = jobPayloadDownloader; + } + + @Override + public void prepareConnection(HttpURLConnection urlConnection) throws IOException { + if (useSSE) { + urlConnection.addRequestProperty("Accept", MEDIATYPE_SSE); + } else { + urlConnection.addRequestProperty("Accept", MEDIATYPE_JSON + "; q=0.8, " + MEDIATYPE_MULTIPART + "; q=0.9"); + } + // add any user-specified headers +// for (Header h : requestHeaders) { +// urlConnection.addRequestProperty(h.getName(), h.getValue()); +// } + //Write data + ParamsWithPayload pwp; + if (doUpload) { + urlConnection.setChunkedStreamingMode(0); + pwp = new ParamsWithPayload(payload, params); + } else { + pwp = new ParamsWithPayload(null, params); + } + ProprietaryWriter writer = ProprietaryWriterFactory.getWriter(pwp); + LOG.log(DEBUG, () -> "Writer to use " + writer.getClass().getName()); + writer.writeTo(pwp, urlConnection); + } + + + @Override + public ActionReport useConnection(HttpURLConnection urlConnection) throws CommandException, IOException { + final String resultMediaType = urlConnection.getContentType(); + LOG.log(DEBUG, "Result type is {0}", resultMediaType); + LOG.log(DEBUG, "URL connection is {0}", urlConnection.getClass().getName()); + if (resultMediaType != null && resultMediaType.startsWith(MEDIATYPE_SSE)) { + return processSSE(urlConnection, resultMediaType); + } + + final ProprietaryReader reader = ProprietaryReaderFactory.getReader(ParamsWithPayload.class, resultMediaType); + if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) { + return reportInternalError(urlConnection, resultMediaType, reader); + } + + final ParamsWithPayload pwp = reader.readFrom(urlConnection.getInputStream(), resultMediaType); + if (pwp.getPayloadInbound() == null) { + return pwp.getActionReport(); + } + + if (resultMediaType != null && resultMediaType.startsWith("multipart/")) { + RestPayloadImpl.Inbound inbound = pwp.getPayloadInbound(); + ActionReport report = pwp.getActionReport(); + if (LOG.isLoggable(TRACE)) { + LOG.log(TRACE, "------ PAYLOAD ------"); + Iterator parts = inbound.parts(); + while (parts.hasNext()) { + Payload.Part part = parts.next(); + LOG.log(TRACE, " - {0} [{1}]", part.getName(), part.getContentType()); + } + LOG.log(TRACE, "---- END PAYLOAD ----"); + } + PayloadFilesManager downloadedFilesMgr = new PayloadFilesManager.Perm(fileOutputDir, null, null); + try { + downloadedFilesMgr.processParts(inbound); + } catch (CommandException cex) { + throw cex; + } catch (Exception ex) { + throw new CommandException(ex.getMessage(), ex); + } + return report; + } + throw new IllegalStateException("Unknown media type: " + resultMediaType); + } + + private ActionReport processSSE(HttpURLConnection urlConnection, String resultMediaType) throws CommandException { + String instanceId = null; + boolean retryableCommand = false; + try (GfSseEventReceiver eventReceiver = openEventReceiver(urlConnection, resultMediaType)) { + LOG.log(DEBUG, "Response is SSE - about to read events"); + GfSseInboundEvent event; + do { + event = eventReceiver.readEvent(); + if (event != null) { + LOG.log(DEBUG, "Event name: {0}", event.getName()); + eventConsumer.accept(event); + if (AdminCommandState.EVENT_STATE_CHANGED.equals(event.getName())) { + final AdminCommandState state = event.getData(AdminCommandState.class, MEDIATYPE_JSON); + if (state.getId() == null) { + if (detached && !closeSSE.get()) { + // If detached command, ignore everything else, we want just the ID. + LOG.log(TRACE, "Command instance job ID missing, waiting for another message."); + continue; + } + } else { + instanceId = state.getId(); + LOG.log(DEBUG, "Command instance job ID: {0}", instanceId); + } + if (closeSSE.get()) { + LOG.log(TRACE, "DetachListener already did its job."); + // See DetachListener, the eventConsumer leads there + return null; + } + if (state.getState() == AdminCommandState.State.COMPLETED + || state.getState() == AdminCommandState.State.RECORDED + || state.getState() == AdminCommandState.State.REVERTED) { + if (!state.isOutboundPayloadEmpty()) { + LOG.log(DEBUG, "Remote command holds data. Must load it"); + jobPayloadDownloader.accept(instanceId); + } + closeSSE.set(true); + return state.getActionReport(); + } else if (state.getState() == AdminCommandState.State.FAILED_RETRYABLE) { + LOG.log(INFO, "Command is parked. Continue in it using command \"continue " + state.getId() + + "\" or revert using \"revert " + state.getId() + "\"."); + closeSSE.set(true); + return state.getActionReport(); + } else if (state.getState() == AdminCommandState.State.RUNNING_RETRYABLE) { + LOG.log(DEBUG, "Command stores checkpoint and is retryable"); + retryableCommand = true; + } + } + } + } while (event != null && !eventReceiver.isClosed() && !closeSSE.get()); + return null; + } catch (IOException e) { + if (instanceId == null || !"Premature EOF".equals(e.getMessage())) { + throw new CommandException(e.getMessage(), e); + } + if (retryableCommand) { + throw new CommandException("Connection to the server lost." + + " \nIf the server is not running, the command will be resumed automatically" + + " at next server startup. Result can be seen in server.log or by reconnecting" + + " using subcommand attach " + instanceId, e); + } + throw new CommandException( + "Connection to the server lost." + + "\nIf server is still running, it is possible to reconnect using subcommand attach " + instanceId, + e); + } catch (Exception e) { + throw new CommandException(e.getMessage(), e); + } + } + + private GfSseEventReceiver openEventReceiver(HttpURLConnection urlConnection, String resultMediaType) { + final ProprietaryReader reader = new GfSseEventReceiverProprietaryReader(); + try { + InputStream inputStream = urlConnection.getInputStream(); + return reader.readFrom(inputStream, resultMediaType); + } catch (IOException e) { + throw new IllegalStateException("Failed to open the even receiver.", e); + } + } + + + private ActionReport reportInternalError(HttpURLConnection urlConnection, String resultMediaType, + ProprietaryReader reader) throws IOException { + ActionReport report; + if (reader != null) { + return reader.readFrom(urlConnection.getErrorStream(), resultMediaType).getActionReport(); + } + report = new CliActionReport(); + report.setActionExitCode(ExitCode.FAILURE); + report.setMessage(urlConnection.getResponseMessage()); + return report; + } +} diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/HttpCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/HttpCommand.java new file mode 100644 index 00000000000..a57d9d14de4 --- /dev/null +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/HttpCommand.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package com.sun.enterprise.admin.remote; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.glassfish.api.admin.CommandException; + +/** + * Interface to enable factoring out common HTTP connection management code. + *

+ * The implementation of this interface must implement + *

    + *
  • {@link #prepareConnection} - to perform all pre-connection configuration - set headers, chunking, etc. as well as + * writing any payload to the outbound connection. In short anything needed prior to the URLConnection#connect + * invocation. + *

    + * The caller will invoke this method after it has invoked {@link URL#openConnection} but before it invokes + * {@link URL#connect}. + *

  • {@link #useConnection} - to read from the input stream, etc. The caller will invoke this method after it has + * successfully invoked {@link URL#connect}. + *
+ * Because the caller might have to work with multiple URLConnection objects (as it follows redirection, for example) + * this contract allows the caller to delegate to the HttpCommand implementation multiple times to configure each of the + * URLConnections objects, then to invoke useConnection only once after it has the "final" URLConnection object. For + * this reason be sure to implement prepareConnection so that it can be invoked multiple times. + * + */ +interface HttpCommand { + + /** + * Configures the HttpURLConnection (headers, chuncking, etc.) according to the needs of this use of the connection and + * then writes any required outbound payload to the connection. + *

+ * This method might be invoked multiple times before the connection is actually connected, so it should be serially + * reentrant. Note that the caller will + * + * @param urlConnection the connection to be configured + */ + void prepareConnection(HttpURLConnection urlConnection) throws IOException; + + /** + * Uses the configured and connected connection to read data, process it, etc. + * + * @param urlConnection the connection to be used + * @throws CommandException + * @throws IOException + */ + T useConnection(HttpURLConnection urlConnection) throws CommandException, IOException; +} diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/LocalStrings.properties b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/LocalStrings.properties index 0e202504e42..d2b183bb1eb 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/LocalStrings.properties +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/LocalStrings.properties @@ -19,10 +19,8 @@ AdminUserPasswordPrompt=Enter admin password for user "{0}"> AdminPasswordPrompt=Enter admin password> badHttpCode=Bad HTTP code received from server: {0} internal=Internal Error: {0} -emptyResponse=Empty response from server. unknownResponse=Unknown Response: {0} unknownFormat=Corrupt Manifest object. The response we received from the server was not understood: {0} -unknownError=Unknown error NotHttpResponse=Got non-HTTP response when connecting to host {0}, port {1}. Is that the correct host and port? BadResponse=HTTP connection failed with code {0}, message: {1} IOError=I/O Error: {0} @@ -44,9 +42,4 @@ NoRemoteManPage=Can't find remote man page, looking locally... CantUploadDirectory=CLI031: Can't upload a directory, specify --upload=false. NoPayloadSupport=No support for payload with content type {0} UploadedFileNotFound=Could not read the file {0} to upload it. -remote.failure.prefix=remote failure: -remote.sse.canNotGetPayload=Cannot retrieve payload. {0} tooManyOptions=Option {0} can be specified only once -remotecommand.failedretryable=Command is parked. Continue in it using command "continue {0}" or revert using "revert {0}". -remotecommand.lostConnection=Connection to the server lost. If server is still running, it is possible to reconnect using subcommand "attach {0}". -remotecommand.lostConnection.retryableCommand=Connection to the server lost. \nIf the server is not running, the command will be resumed automatically at next server startup. Result can be seen in server.log or by reconnecting using subcommand "attach {0}". diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ManPageHttpCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ManPageHttpCommand.java new file mode 100644 index 00000000000..fa25d2e4c9c --- /dev/null +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/ManPageHttpCommand.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package com.sun.enterprise.admin.remote; + +import com.sun.enterprise.admin.remote.reader.ProprietaryReaderFactory; + +import java.io.IOException; +import java.net.HttpURLConnection; + +import org.glassfish.api.admin.CommandException; + +/** + * HTTP Command to get the manual page. + */ +class ManPageHttpCommand implements HttpCommand { + + private static final String MEDIATYPE_TXT = "text/plain"; + + @Override + public void prepareConnection(HttpURLConnection urlConnection) { + urlConnection.setRequestProperty("Accept", MEDIATYPE_TXT); + } + + @Override + public String useConnection(HttpURLConnection urlConnection) throws CommandException, IOException { + return ProprietaryReaderFactory. getReader(String.class, urlConnection.getContentType()) + .readFrom(urlConnection.getInputStream(), urlConnection.getContentType()); + } +} diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java index 9f90807db22..270bbb9570b 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteAdminCommand.java @@ -565,31 +565,25 @@ public void prepareConnection(final HttpURLConnection urlConnection) throws IOEx @Override public void useConnection(final HttpURLConnection urlConnection) throws CommandException, IOException { - InputStream in = urlConnection.getInputStream(); - - String responseContentType = urlConnection.getContentType(); - - Payload.Inbound inboundPayload = PayloadImpl.Inbound.newInstance(responseContentType, in); - - if (inboundPayload == null) { - throw new IOException(strings.get("NoPayloadSupport", responseContentType)); - } - PayloadFilesManager downloadedFilesMgr = new PayloadFilesManager.Perm(fileOutputDir, null, - new PayloadFilesManager.ActionReportHandler() { - - @Override - public void handleReport(InputStream reportStream) throws Exception { + try (InputStream in = urlConnection.getInputStream()) { + String responseContentType = urlConnection.getContentType(); + Payload.Inbound inboundPayload = PayloadImpl.Inbound.newInstance(responseContentType, in); + if (inboundPayload == null) { + throw new IOException(strings.get("NoPayloadSupport", responseContentType)); + } + PayloadFilesManager downloadedFilesMgr = new PayloadFilesManager.Perm(fileOutputDir, null, + reportStream -> { int responseCode = urlConnection.getResponseCode(); Charset charset = HttpParser.getCharsetFromHeader(responseContentType); handleResponse(options, reportStream, charset, responseCode, userOut); - } - }); - try { - downloadedFilesMgr.processParts(inboundPayload); - } catch (CommandException cex) { - throw cex; - } catch (Exception ex) { - throw new CommandException(ex.getMessage(), ex); + }); + try { + downloadedFilesMgr.processParts(inboundPayload); + } catch (CommandException cex) { + throw cex; + } catch (Exception ex) { + throw new CommandException(ex.getMessage(), ex); + } } } }); @@ -613,7 +607,6 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd) * @throws CommandException if anything goes wrong */ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, boolean isForMetadata) throws CommandException { - HttpURLConnection urlConnection; /* * There are various reasons we might retry the command - an authentication * challenges from the DAS, shifting from an insecure connection to @@ -659,87 +652,76 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, */ shouldTryCommandAgain = false; try { + final AuthenticationInfo authInfo = authenticationInfo(); if (logger.isLoggable(FINER)) { logger.log(FINER, "URI: {0}", uriString); - logger.log(FINER, "URL: {0}", url.toString()); logger.log(FINER, "URL: {0}", url.toURL(uriString).toString()); + logger.log(FINER, "Method: {0}", httpMethod); logger.log(FINER, "Password options: {0}", passwordOptions); - logger.log(FINER, "Using auth info: User: {0}, Password: {1}", - new Object[] { user, (password != null && password.length > 0) ? "" : "" }); + logger.log(FINER, "Using auth info: {0}", authInfo); } - final AuthenticationInfo authInfo = authenticationInfo(); if (authInfo != null) { url.setAuthenticationInfo(authInfo); } - urlConnection = (HttpURLConnection) url.openConnection(uriString); - urlConnection.setRequestProperty("User-Agent", responseFormatType); - if (passwordOptions != null) { - urlConnection.setRequestProperty("X-passwords", passwordOptions.toString()); - } - - if (authToken != null) { - /* - * If this request is for metadata then we expect to reuse - * the auth token. - */ - urlConnection.setRequestProperty(SecureAdmin.ADMIN_ONE_TIME_AUTH_TOKEN_HEADER_NAME, - (isForMetadata ? AuthTokenManager.markTokenForReuse(authToken) : authToken)); - } - if (commandModel != null && isCommandModelFromCache() && commandModel instanceof CachedCommandModel) { - urlConnection.setRequestProperty(COMMAND_MODEL_MATCH_HEADER, ((CachedCommandModel) commandModel).getETag()); - if (logger.isLoggable(FINER)) { - logger.log(FINER, "CommandModel ETag: {0}", ((CachedCommandModel) commandModel).getETag()); + final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(uriString); + try { + urlConnection.setRequestProperty("User-Agent", responseFormatType); + urlConnection.addRequestProperty("Cache-Control", "no-cache"); + urlConnection.addRequestProperty("Pragma", "no-cache"); + if (passwordOptions != null) { + urlConnection.setRequestProperty("X-passwords", passwordOptions.toString()); } - } - urlConnection.setRequestMethod(httpMethod); - urlConnection.setReadTimeout(readTimeout); - if (connectTimeout >= 0) { - urlConnection.setConnectTimeout(connectTimeout); - } - addAdditionalHeaders(urlConnection); - - cmd.prepareConnection(urlConnection); - urlConnection.connect(); - /* - * We must handle redirection from http to https explicitly - * because, even if the HttpURLConnection's followRedirect is - * set to true, the Java SE implementation does not do so if the - * procotols are different. - */ - String redirection = checkConnect(urlConnection); - if (redirection != null) { - /* - * Log at FINER; at FINE it would appear routinely when used from - * asadmin. - */ - logger.log(FINER, "Following redirection to " + redirection); - url = followRedirection(url, redirection); - shouldTryCommandAgain = true; - /* - * Record that, during the retry of this request, we should - * use https. - */ - shouldUseSecure = url.isSecure(); + if (authToken != null) { + /* + * If this request is for metadata then we expect to reuse + * the auth token. + */ + urlConnection.setRequestProperty(SecureAdmin.ADMIN_ONE_TIME_AUTH_TOKEN_HEADER_NAME, + (isForMetadata ? AuthTokenManager.markTokenForReuse(authToken) : authToken)); + } + if (commandModel != null && isCommandModelFromCache() && commandModel instanceof CachedCommandModel) { + urlConnection.setRequestProperty(COMMAND_MODEL_MATCH_HEADER, ((CachedCommandModel) commandModel).getETag()); + if (logger.isLoggable(FINER)) { + logger.log(FINER, "CommandModel ETag: {0}", ((CachedCommandModel) commandModel).getETag()); + } + } + urlConnection.setRequestMethod(httpMethod); + urlConnection.setReadTimeout(readTimeout); + if (connectTimeout >= 0) { + urlConnection.setConnectTimeout(connectTimeout); + } + addAdditionalHeaders(urlConnection); + cmd.prepareConnection(urlConnection); + urlConnection.connect(); /* - * Record that, if this is a metadata request, the real - * request should use https also. + * We must handle redirection from http to https explicitly + * because, even if the HttpURLConnection's followRedirect is + * set to true, the Java SE implementation does not do so if the + * procotols are different. */ - secure = true; + String redirection = checkConnect(urlConnection); + if (redirection != null) { + // Log at FINER; at FINE it would appear routinely when used from asadmin. + logger.log(FINER, () -> "Following redirection to " + redirection); + url = followRedirection(url, redirection); + shouldTryCommandAgain = true; + // Record that, during the retry of this request, we should use https. + shouldUseSecure = url.isSecure(); + + // Record that, if this is a metadata request, the real request should use https also. + secure = true; + continue; + } + // No redirection, so we have established the connection. + // Now delegate again to the command processing to use the now-created connection. + cmd.useConnection(urlConnection); + processHeaders(urlConnection); + logger.finer("doHttpCommand succeeds"); + } finally { urlConnection.disconnect(); - - continue; } - - /* - * No redirection, so we have established the connection. - * Now delegate again to the command processing to use the - * now-created connection. - */ - cmd.useConnection(urlConnection); - processHeaders(urlConnection); - logger.finer("doHttpCommand succeeds"); } catch (AuthenticationException authEx) { logger.log(FINER, "DAS has challenged for credentials"); @@ -789,8 +771,6 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, logger.log(FINER, "Was able to update the credentials so will retry with the updated ones"); askedUserForCredentials = true; shouldTryCommandAgain = true; - continue; - } catch (ConnectException ce) { logger.finer("doHttpCommand: connect exception " + ce); // this really means nobody was listening on the remote server @@ -1068,7 +1048,7 @@ private void handleResponse(ParameterMap params, InputStream in, Charset charset /** * Fetch the command metadata from the remote server. */ - protected void fetchCommandModel() throws CommandException { + public void fetchCommandModel() throws CommandException { long startNanos = System.nanoTime(); commandModel = null; //For sure not be used during request header construction @@ -1121,7 +1101,7 @@ public void useConnection(HttpURLConnection urlConnection) throws CommandExcepti }); if (commandModel == null) { if (metadataErrors == null) { - throw new InvalidCommandException(strings.get("unknownError")); + throw new InvalidCommandException("Unknown error - no metadata errors available."); } throw new InvalidCommandException(metadataErrors.toString()); } diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteResponseManager.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteResponseManager.java index d7ea5a1ab77..7be69081a42 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteResponseManager.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteResponseManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -82,7 +82,7 @@ public RemoteResponseManager(InputStream in, Charset charset, int code, Logger l response = baos.toString(charset); if (!ok(response)) { - throw new RemoteFailureException(strings.get("emptyResponse")); + throw new RemoteFailureException("Empty response from server."); } logger.finer("------- RAW RESPONSE ---------"); diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteRestAdminCommand.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteRestAdminCommand.java index d3a34d25544..6df94ac0000 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteRestAdminCommand.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/remote/RemoteRestAdminCommand.java @@ -19,17 +19,12 @@ import com.sun.enterprise.admin.event.AdminCommandEventBrokerImpl; import com.sun.enterprise.admin.remote.reader.CliActionReport; -import com.sun.enterprise.admin.remote.reader.ProprietaryReader; import com.sun.enterprise.admin.remote.reader.ProprietaryReaderFactory; -import com.sun.enterprise.admin.remote.sse.GfSseEventReceiver; -import com.sun.enterprise.admin.remote.sse.GfSseEventReceiverProprietaryReader; import com.sun.enterprise.admin.remote.sse.GfSseInboundEvent; -import com.sun.enterprise.admin.remote.writer.ProprietaryWriter; import com.sun.enterprise.admin.remote.writer.ProprietaryWriterFactory; import com.sun.enterprise.admin.util.AdminLoggerInfo; import com.sun.enterprise.admin.util.AuthenticationInfo; import com.sun.enterprise.admin.util.CachedCommandModel; -import com.sun.enterprise.admin.util.CommandModelData.ParamModelData; import com.sun.enterprise.admin.util.HttpConnectorAddress; import com.sun.enterprise.admin.util.cache.AdminCacheUtils; import com.sun.enterprise.config.serverbeans.SecureAdmin; @@ -53,22 +48,16 @@ import java.net.URLConnection; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import javax.net.ssl.SSLException; -import org.codehaus.jettison.json.JSONArray; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; -import org.glassfish.admin.payload.PayloadFilesManager; import org.glassfish.api.ActionReport; import org.glassfish.api.ActionReport.ExitCode; -import org.glassfish.api.admin.AdminCommandState; import org.glassfish.api.admin.AuthenticationException; import org.glassfish.api.admin.CommandException; import org.glassfish.api.admin.CommandModel; @@ -76,13 +65,11 @@ import org.glassfish.api.admin.CommandValidationException; import org.glassfish.api.admin.InvalidCommandException; import org.glassfish.api.admin.ParameterMap; -import org.glassfish.api.admin.Payload; import org.glassfish.common.util.admin.AuthTokenManager; import org.glassfish.main.jdke.i18n.LocalStringsImpl; import static java.util.logging.Level.FINER; import static java.util.logging.Level.FINEST; -import static java.util.logging.Level.INFO; import static java.util.logging.Level.SEVERE; import static java.util.logging.Level.WARNING; @@ -117,10 +104,6 @@ public class RemoteRestAdminCommand extends AdminCommandEventBrokerImpl attrs; - private boolean doUpload = false; - private boolean addedUploadOption = false; + private boolean doUpload; private RestPayloadImpl.Outbound outboundPayload; - private String usage; private File fileOutputDir; private StringBuilder passwordOptions; private String manpage; @@ -140,12 +121,12 @@ public class RemoteRestAdminCommand extends AdminCommandEventBrokerImpl operands; private CommandModel commandModel; - private boolean commandModelFromCache = false; + private boolean commandModelFromCache; private int readTimeout = defaultReadTimeout; private int connectTimeout = -1; private boolean interactive = true; - private final List

requestHeaders = new ArrayList<>(); - private boolean closeSse = false; +// private final List
requestHeaders = new ArrayList<>(); + private final AtomicBoolean closeSse = new AtomicBoolean(); private boolean enableCommandModelCache = true; - private OutputStream userOut; + private final String commandCacheKey; /* * Set a default read timeout for URL connections. @@ -190,49 +171,6 @@ public class RemoteRestAdminCommand extends AdminCommandEventBrokerImpl - * The implementation of this interface must implement - *
    - *
  • {@link #prepareConnection} - to perform all pre-connection configuration - set headers, chunking, etc. as well as - * writing any payload to the outbound connection. In short anything needed prior to the URLConnection#connect - * invocation. - *

    - * The caller will invoke this method after it has invoked {@link URL#openConnection} but before it invokes - * {@link URL#connect}. - *

  • {@link #useConnection} - to read from the input stream, etc. The caller will invoke this method after it has - * successfully invoked {@link URL#connect}. - *
- * Because the caller might have to work with multiple URLConnection objects (as it follows redirection, for example) - * this contract allows the caller to delegate to the HttpCommand implementation multiple times to configure each of the - * URLConnections objects, then to invoke useConnection only once after it has the "final" URLConnection object. For - * this reason be sure to implement prepareConnection so that it can be invoked multiple times. - * - */ - interface HttpCommand { - - /** - * Configures the HttpURLConnection (headers, chuncking, etc.) according to the needs of this use of the connection and - * then writes any required outbound payload to the connection. - *

- * This method might be invoked multiple times before the connection is actually connected, so it should be serially - * reentrant. Note that the caller will - * - * @param urlConnection the connection to be configured - */ - void prepareConnection(HttpURLConnection urlConnection) throws IOException; - - /** - * Uses the configured and connected connection to read data, process it, etc. - * - * @param urlConnection the connection to be used - * @throws CommandException - * @throws IOException - */ - void useConnection(HttpURLConnection urlConnection) throws CommandException, IOException; - } - public RemoteRestAdminCommand(String name, String host, int port, boolean secure, String user, char[] password, Logger logger, boolean notify, boolean detach) throws CommandException { this(name, host, port, secure, user, password, logger, null, null, false, notify, detach); @@ -258,6 +196,7 @@ public RemoteRestAdminCommand(String name, String host, int port, boolean secure this.authToken = authToken; this.prohibitDirectoryUploads = prohibitDirectoryUploads; checkName(); + this.commandCacheKey = AdminCacheUtils.createCommandCacheKey(name, getCanonicalHost(), port); } /** @@ -274,7 +213,7 @@ public void closeSse(String message, ActionReport.ExitCode exitCode) { report.setMessage(message); report.setActionExitCode(exitCode); setActionReport(report); - this.closeSse = true; + this.closeSse.set(true); } /** @@ -289,7 +228,6 @@ public void setResponseFormatType(String responseFormatType) { * If set, the raw response from the command is written to the specified stream. */ public void setUserOut(OutputStream userOut) { - this.userOut = userOut; } /** @@ -349,7 +287,7 @@ public CommandModel getCommandModel() throws CommandException { if (commandModel == null && enableCommandModelCache) { long startNanos = System.nanoTime(); try { - commandModel = getCommandModelFromCache(); + commandModel = CommandModelHttpCommand.fromCache(commandCacheKey, detach, notify); if (commandModel != null) { this.commandModelFromCache = true; if (logger.isLoggable(FINEST)) { @@ -363,9 +301,7 @@ public CommandModel getCommandModel() throws CommandException { } } } catch (Exception ex) { - if (logger.isLoggable(FINEST)) { - logger.log(FINEST, "Can not get data from cache under key " + createCommandCacheKey(), ex); - } + logger.log(FINEST, "Can not get data from cache under key " + commandCacheKey, ex); } } if (commandModel == null) { @@ -374,109 +310,6 @@ public CommandModel getCommandModel() throws CommandException { return commandModel; } - private CommandModel getCommandModelFromCache() { - String cachedModel = AdminCacheUtils.getCache().get(createCommandCacheKey(), String.class); - if (cachedModel == null) { - return null; - } - cachedModel = cachedModel.trim(); - int ind = cachedModel.indexOf('\n'); - if (ind < 0) { - return null; - } - String eTag = cachedModel.substring(0, ind); - if (!eTag.startsWith("ETag:")) { - return null; - } - eTag = eTag.substring(5).trim(); - if (logger.isLoggable(FINEST)) { - logger.log(FINEST, "Cached command model ETag is {0}", eTag); - } - String content = cachedModel.substring(ind + 1).trim(); - CachedCommandModel result = parseMetadata(content, eTag); - return result; - } - - /** - * Parse the JSon metadata for the command. - * - * @param str the string - * @return the etag to compare the command cache model - */ - private CachedCommandModel parseMetadata(String str, String etag) { - if (logger.isLoggable(FINER)) { // XXX - assume "debug" == "FINER" - logger.finer("------- RAW METADATA RESPONSE ---------"); - logger.log(FINER, "ETag: {0}", etag); - logger.finer(str); - logger.finer("------- RAW METADATA RESPONSE ---------"); - } - if (str == null) { - return null; - } - try { - boolean sawFile = false; - JSONObject obj = new JSONObject(str); - obj = obj.getJSONObject("command"); - CachedCommandModel cm = new CachedCommandModel(obj.getString("@name"), etag); - cm.dashOk = obj.optBoolean("@unknown-options-are-operands", false); - cm.managedJob = obj.optBoolean("@managed-job", false); - cm.setUsage(obj.optString("usage", null)); - Object optns = obj.opt("option"); - if (!JSONObject.NULL.equals(optns)) { - JSONArray jsonOptions; - if (optns instanceof JSONArray) { - jsonOptions = (JSONArray) optns; - } else { - jsonOptions = new JSONArray(); - jsonOptions.put(optns); - } - for (int i = 0; i < jsonOptions.length(); i++) { - JSONObject jsOpt = jsonOptions.getJSONObject(i); - String type = jsOpt.getString("@type"); - ParamModelData opt = new ParamModelData(jsOpt.getString("@name"), typeOf(type), jsOpt.optBoolean("@optional", false), - jsOpt.optString("@default"), jsOpt.optString("@short"), jsOpt.optBoolean("@obsolete", false), - jsOpt.optString("@alias")); - opt.param._acceptableValues = jsOpt.optString("@acceptable-values"); - if ("PASSWORD".equals(type)) { - opt.param._password = true; - opt.prompt = jsOpt.optString("@prompt"); - opt.promptAgain = jsOpt.optString("@prompt-again"); - } else if ("FILE".equals(type)) { - sawFile = true; - } - if (jsOpt.optBoolean("@primary", false)) { - opt.param._primary = true; - } - if (jsOpt.optBoolean("@multiple", false)) { - if (opt.type == File.class) { - opt.type = File[].class; - } else { - opt.type = List.class; - } - opt.param._multiple = true; - } - cm.add(opt); - } - } - if (sawFile) { - cm.add(new ParamModelData("upload", Boolean.class, true, null)); - addedUploadOption = true; - cm.setAddedUploadOption(true); - } - if (notify) { - cm.add(new ParamModelData("notify", Boolean.class, false, "false")); - } - if (detach) { - cm.add(new ParamModelData("detach", Boolean.class, false, "false")); - } - this.usage = cm.getUsage(); - return cm; - } catch (JSONException ex) { - logger.log(FINER, "Can not parse command metadata", ex); - return null; - } - } - /** * If command model was load from local cache. */ @@ -490,13 +323,13 @@ public boolean isCommandModelFromCache() { public void setFileOutputDirectory(File dir) { fileOutputDir = dir; } - - /** - * Return a modifiable list of headers to be added to the request. - */ - public List

headers() { - return requestHeaders; - } +// +// /** +// * Return a modifiable list of headers to be added to the request. +// */ +// public List
headers() { +// return requestHeaders; +// } protected boolean useSse() throws CommandException { return getCommandModel().isManagedJob(); @@ -690,155 +523,21 @@ protected String getCommandURI() { * Actually execute the remote command. */ private void executeRemoteCommand(final ParameterMap params) throws CommandException { - doHttpCommand(getCommandURI(), "POST", new HttpCommand() { - - @Override - public void prepareConnection(final HttpURLConnection urlConnection) throws IOException { - try { - if (useSse()) { - urlConnection.addRequestProperty("Accept", MEDIATYPE_SSE); - } else { - urlConnection.addRequestProperty("Accept", MEDIATYPE_JSON + "; q=0.8, " + MEDIATYPE_MULTIPART + "; q=0.9"); - } - } catch (CommandException cex) { - throw new IOException(cex.getLocalizedMessage(), cex); - } - // add any user-specified headers - for (Header h : requestHeaders) { - urlConnection.addRequestProperty(h.getName(), h.getValue()); - } - //Write data - ParamsWithPayload pwp; - if (doUpload) { - urlConnection.setChunkedStreamingMode(0); - pwp = new ParamsWithPayload(outboundPayload, params); - } else { - pwp = new ParamsWithPayload(null, params); - } - ProprietaryWriter writer = ProprietaryWriterFactory.getWriter(pwp); - logger.log(FINER, () -> "Writer to use " + writer.getClass().getName()); - writer.writeTo(pwp, urlConnection); + final ExecHttpCommand command = new ExecHttpCommand(params, detach, useSse(), closeSse, doUpload, + outboundPayload, fileOutputDir, e -> fireEvent(e.getName(), e), this::downloadPayloadFromManaged); + final ActionReport report = doHttpCommand(getCommandURI(), "POST", command); + if (report == null) { + // if closeSse was set by closeSse method, it is ok, + // DetachListener set the job id and the report and we are done. + if (!closeSse.get()) { + this.output = null; + throw new CommandException("Empty response from server."); } - - @Override - public void useConnection(final HttpURLConnection urlConnection) throws CommandException, IOException { - String resultMediaType = urlConnection.getContentType(); - if (logger.isLoggable(FINER)) { - logger.log(FINER, "Result type is {0}", resultMediaType); - logger.log(FINER, "URL connection is {0}", urlConnection.getClass().getName()); - } - if (resultMediaType != null && resultMediaType.startsWith(MEDIATYPE_SSE)) { - String instanceId = null; - boolean retryableCommand = false; - try { - logger.log(FINEST, "Response is SSE - about to read events"); - closeSse = false; - final ProprietaryReader reader = new GfSseEventReceiverProprietaryReader(); - final GfSseEventReceiver eventReceiver = reader.readFrom(urlConnection.getInputStream(), resultMediaType); - GfSseInboundEvent event; - do { - event = eventReceiver.readEvent(); - if (event != null) { - logger.log(FINEST, "Event: {0}", event.getName()); - fireEvent(event.getName(), event); - if (AdminCommandState.EVENT_STATE_CHANGED.equals(event.getName())) { - AdminCommandState acs = event.getData(AdminCommandState.class, MEDIATYPE_JSON); - if (acs.getId() != null) { - instanceId = acs.getId(); - logger.log(FINEST, "Command instance ID: {0}", instanceId); - } - if (acs.getState() == AdminCommandState.State.COMPLETED - || acs.getState() == AdminCommandState.State.RECORDED - || acs.getState() == AdminCommandState.State.REVERTED) { - if (acs.getActionReport() != null) { - setActionReport(acs.getActionReport()); - } - closeSse = true; - if (!acs.isOutboundPayloadEmpty()) { - logger.log(FINEST, "Romote command holds data. Must load it"); - downloadPayloadFromManaged(instanceId); - } - } else if (acs.getState() == AdminCommandState.State.FAILED_RETRYABLE) { - logger.log(INFO, strings.get("remotecommand.failedretryable", acs.getId())); - if (acs.getActionReport() != null) { - setActionReport(acs.getActionReport()); - } - closeSse = true; - } else if (acs.getState() == AdminCommandState.State.RUNNING_RETRYABLE) { - logger.log(FINEST, "Command stores checkpoint and is retryable"); - retryableCommand = true; - } - } - } - } while (event != null && !eventReceiver.isClosed() && !closeSse); - if (closeSse) { - try { - eventReceiver.close(); - } catch (Exception exc) { - } - } - } catch (IOException ioex) { - if (instanceId != null && "Premature EOF".equals(ioex.getMessage())) { - if (retryableCommand) { - throw new CommandException( - strings.get("remotecommand.lostConnection.retryableCommand", new Object[] { instanceId }), ioex); - } else { - throw new CommandException(strings.get("remotecommand.lostConnection", new Object[] { instanceId }), ioex); - } - } else { - throw new CommandException(ioex.getMessage(), ioex); - } - } catch (Exception ex) { - throw new CommandException(ex.getMessage(), ex); - } - } else { - ProprietaryReader reader = ProprietaryReaderFactory.getReader(ParamsWithPayload.class, - resultMediaType); - if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) { - ActionReport report; - if (reader == null) { - report = new CliActionReport(); - report.setActionExitCode(ExitCode.FAILURE); - report.setMessage(urlConnection.getResponseMessage()); - } else { - report = reader.readFrom(urlConnection.getErrorStream(), resultMediaType).getActionReport(); - } - setActionReport(report); - } else { - ParamsWithPayload pwp = reader.readFrom(urlConnection.getInputStream(), resultMediaType); - if (pwp.getPayloadInbound() == null) { - setActionReport(pwp.getActionReport()); - } else if (resultMediaType.startsWith("multipart/")) { - RestPayloadImpl.Inbound inbound = pwp.getPayloadInbound(); - setActionReport(pwp.getActionReport()); - if (logger.isLoggable(FINER)) { - logger.log(FINER, "------ PAYLOAD ------"); - Iterator parts = inbound.parts(); - while (parts.hasNext()) { - Payload.Part part = parts.next(); - logger.log(FINER, " - {0} [{1}]", new Object[] { part.getName(), part.getContentType() }); - } - logger.log(FINER, "---- END PAYLOAD ----"); - } - PayloadFilesManager downloadedFilesMgr = new PayloadFilesManager.Perm(fileOutputDir, null, null); - try { - downloadedFilesMgr.processParts(inbound); - } catch (CommandException cex) { - throw cex; - } catch (Exception ex) { - throw new CommandException(ex.getMessage(), ex); - } - } - } - } + } else { + setActionReport(report); + if (report.getActionExitCode() == ExitCode.FAILURE) { + throw new CommandException("Remote failure: " + this.output); } - }); - if (actionReport == null) { - this.output = null; - throw new CommandException(strings.get("emptyResponse")); - } - if (actionReport.getActionExitCode() == ExitCode.FAILURE) { - throw new CommandException(strings.getString("remote.failure.prefix", "remote failure:") + " " + this.output); } } @@ -853,22 +552,23 @@ private void downloadPayloadFromManaged(String jobId) { params.add("DEFAULT", jobId); command.executeCommand(params); } catch (CommandException ex) { - logger.log(WARNING, strings.getString("remote.sse.canNotGetPayload", "Cannot retrieve payload. {0}"), ex.getMessage()); + logger.log(WARNING, "Cannot retrieve payload.", ex); } } - protected void setActionReport(ActionReport ar) { - this.actionReport = ar; - if (ar == null) { + protected void setActionReport(ActionReport report) { + logger.log(FINEST, "setActionReport(report={0})", report); + this.actionReport = report; + if (report == null) { this.output = null; } else { StringBuilder sb = new StringBuilder(); - if (ar instanceof CliActionReport) { - addCombinedMessages((CliActionReport) ar, sb); - } else if (ar.getMessage() != null) { - sb.append(ar.getMessage()); + if (report instanceof CliActionReport) { + addCombinedMessages((CliActionReport) report, sb); + } else if (report.getMessage() != null) { + sb.append(report.getMessage()); } - addSubMessages("", ar.getTopMessagePart(), sb); + addSubMessages("", report.getTopMessagePart(), sb); this.output = sb.toString(); if (logger.isLoggable(FINER)) { logger.log(FINER, "------ ACTION REPORT ------"); @@ -932,8 +632,8 @@ private static void addCombinedMessages(CliActionReport aReport, StringBuilder s } } - private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd) throws CommandException { - doHttpCommand(uriString, httpMethod, cmd, false /* isForMetadata */); + private T doHttpCommand(String uriString, String httpMethod, HttpCommand cmd) throws CommandException { + return doHttpCommand(uriString, httpMethod, cmd, false /* isForMetadata */); } /** @@ -949,8 +649,7 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd) * @param cmd the HttpCommand object * @throws CommandException if anything goes wrong */ - private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, boolean isForMetadata) throws CommandException { - HttpURLConnection urlConnection; + private T doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, boolean isForMetadata) throws CommandException { /* * There are various reasons we might retry the command - an authentication * challenges from the DAS, shifting from an insecure connection to @@ -981,7 +680,7 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, */ HttpConnectorAddress url = getHttpConnectorAddress(host, port, shouldUseSecure); url.setInteractive(interactive); - + T result = null; do { /* * Any code that wants to trigger a retry will say so explicitly. @@ -999,77 +698,67 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, if (authInfo != null) { url.setAuthenticationInfo(authInfo); } - urlConnection = (HttpURLConnection) url.openConnection(uriString); - urlConnection.setRequestProperty("User-Agent", responseFormatType); - if (passwordOptions != null) { - urlConnection.setRequestProperty("X-passwords", passwordOptions.toString()); - } - urlConnection.addRequestProperty("Cache-Control", "no-cache"); - urlConnection.addRequestProperty("Pragma", "no-cache"); - - if (authToken != null) { - /* - * If this request is for metadata then we expect to reuse - * the auth token. - */ - urlConnection.setRequestProperty(SecureAdmin.ADMIN_ONE_TIME_AUTH_TOKEN_HEADER_NAME, - (isForMetadata ? AuthTokenManager.markTokenForReuse(authToken) : authToken)); - } - if (commandModel != null && isCommandModelFromCache() && commandModel instanceof CachedCommandModel) { - urlConnection.setRequestProperty(COMMAND_MODEL_MATCH_HEADER, ((CachedCommandModel) commandModel).getETag()); - if (logger.isLoggable(FINER)) { - logger.log(FINER, "CommandModel ETag: {0}", ((CachedCommandModel) commandModel).getETag()); + final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(uriString); + try { + urlConnection.setRequestProperty("User-Agent", responseFormatType); + urlConnection.addRequestProperty("Cache-Control", "no-cache"); + urlConnection.addRequestProperty("Pragma", "no-cache"); + if (passwordOptions != null) { + urlConnection.setRequestProperty("X-passwords", passwordOptions.toString()); } - } - urlConnection.setRequestMethod(httpMethod); - urlConnection.setReadTimeout(readTimeout); - if (connectTimeout >= 0) { - urlConnection.setConnectTimeout(connectTimeout); - } - addAdditionalHeaders(urlConnection); - urlConnection.addRequestProperty("X-Requested-By", "cli"); - cmd.prepareConnection(urlConnection); - urlConnection.connect(); - /* - * We must handle redirection from http to https explicitly - * because, even if the HttpURLConnection's followRedirect is - * set to true, the Java SE implementation does not do so if the - * procotols are different. - */ - String redirection = checkConnect(urlConnection); - if (redirection != null) { - /* - * Log at FINER; at FINE it would appear routinely when used from - * asadmin. - */ - logger.log(FINER, "Following redirection to " + redirection); - url = followRedirection(url, redirection); - shouldTryCommandAgain = true; + if (authToken != null) { + /* + * If this request is for metadata then we expect to reuse + * the auth token. + */ + urlConnection.setRequestProperty(SecureAdmin.ADMIN_ONE_TIME_AUTH_TOKEN_HEADER_NAME, + (isForMetadata ? AuthTokenManager.markTokenForReuse(authToken) : authToken)); + } + if (commandModel != null && isCommandModelFromCache() && commandModel instanceof CachedCommandModel) { + urlConnection.setRequestProperty(COMMAND_MODEL_MATCH_HEADER, ((CachedCommandModel) commandModel).getETag()); + if (logger.isLoggable(FINER)) { + logger.log(FINER, "CommandModel ETag: {0}", ((CachedCommandModel) commandModel).getETag()); + } + } + urlConnection.setRequestMethod(httpMethod); + urlConnection.setReadTimeout(readTimeout); + if (connectTimeout >= 0) { + urlConnection.setConnectTimeout(connectTimeout); + } + addAdditionalHeaders(urlConnection); + urlConnection.addRequestProperty("X-Requested-By", "cli"); + cmd.prepareConnection(urlConnection); + urlConnection.connect(); /* - * Record that, during the retry of this request, we should - * use https. + * We must handle redirection from http to https explicitly + * because, even if the HttpURLConnection's followRedirect is + * set to true, the Java SE implementation does not do so if the + * procotols are different. */ - shouldUseSecure = url.isSecure(); + String redirection = checkConnect(urlConnection); + if (redirection != null) { + // Log at FINER; at FINE it would appear routinely when used from asadmin. + logger.log(FINER, () -> "Following redirection to " + redirection); + url = followRedirection(url, redirection); + shouldTryCommandAgain = true; + // During the retry of this request, we should use https. + shouldUseSecure = url.isSecure(); + // If this is a metadata request, the real request should use https. + secure = true; + continue; + } /* - * Record that, if this is a metadata request, the real - * request should use https also. + * No redirection, so we have established the connection. + * Now delegate again to the command processing to use the + * now-created connection. */ - secure = true; - + result = cmd.useConnection(urlConnection); + processHeaders(urlConnection); + logger.finer("doHttpCommand succeeds"); + } finally { urlConnection.disconnect(); - - continue; } - - /* - * No redirection, so we have established the connection. - * Now delegate again to the command processing to use the - * now-created connection. - */ - cmd.useConnection(urlConnection); - processHeaders(urlConnection); - logger.finer("doHttpCommand succeeds"); } catch (AuthenticationException authEx) { logger.log(FINER, "DAS has challenged for credentials"); @@ -1140,6 +829,7 @@ private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, } } while (shouldTryCommandAgain); outboundPayload = null; // no longer needed + return result; } /** @@ -1274,7 +964,7 @@ private boolean isStatusRedirection(final int returnCode) { * @return usage text */ public String getUsage() { - return usage; + return commandModel instanceof CachedCommandModel ? ((CachedCommandModel) commandModel).getUsage() : null; } /** @@ -1319,86 +1009,22 @@ private void addFileOption(ParameterMap params, String optionName, String filena /** * Fetch the command metadata from the remote server. */ - protected void fetchCommandModel() throws CommandException { - final long startNanos = System.nanoTime(); - commandModel = null; //For sure not be used during request header construction - doHttpCommand(getCommandURI(), "GET", new HttpCommand() { - - @Override - public void prepareConnection(HttpURLConnection urlConnection) { - urlConnection.setRequestProperty("Accept", MEDIATYPE_JSON); - } - - @Override - public void useConnection(HttpURLConnection urlConnection) throws CommandException, IOException { - String eTag = urlConnection.getHeaderField("ETag"); - if (eTag != null) { - eTag = eTag.trim(); - if (eTag.startsWith("W/")) { - eTag = eTag.substring(2).trim(); - } - if (eTag.startsWith("\"")) { - eTag = eTag.substring(1); - } - if (eTag.endsWith("\"")) { - eTag = eTag.substring(0, eTag.length() - 1); - } - } - String json = ProprietaryReaderFactory.getReader(String.class, urlConnection.getContentType()) - .readFrom(urlConnection.getInputStream(), urlConnection.getContentType()); - commandModel = parseMetadata(json, eTag); - if (commandModel != null) { - commandModelFromCache = false; - if (logger.isLoggable(FINEST)) { - logger.log(FINEST, "Command model for {0} command fetched from remote server. [Duration: {1} nanos]", - new Object[] { name, System.nanoTime() - startNanos }); - } - try { - StringBuilder forCache = new StringBuilder(json.length() + 40); - forCache.append("ETag: ").append(eTag); - forCache.append("\n"); - forCache.append(json); - AdminCacheUtils.getCache().put(createCommandCacheKey(), forCache.toString()); - } catch (Exception ex) { - if (logger.isLoggable(WARNING)) { - logger.log(WARNING, AdminLoggerInfo.mCantPutToCache, new Object[] { createCommandCacheKey() }); - } - } - } else { - throw new InvalidCommandException(strings.get("unknownError")); - } - } - }); + public final void fetchCommandModel() throws CommandException { + // For sure not be used during request header construction + commandModel = null; + CommandModelHttpCommand httpCommand = new CommandModelHttpCommand(name, commandCacheKey, detach, notify); + commandModelFromCache = false; + commandModel = doHttpCommand(getCommandURI(), "GET", httpCommand); } public String getManPage() throws CommandException { if (manpage == null) { - doHttpCommand(getCommandURI() + "/manpage", "GET", new HttpCommand() { - - @Override - public void prepareConnection(HttpURLConnection urlConnection) { - urlConnection.setRequestProperty("Accept", MEDIATYPE_TXT); - } - - @Override - public void useConnection(HttpURLConnection urlConnection) throws CommandException, IOException { - manpage = ProprietaryReaderFactory.getReader(String.class, urlConnection.getContentType()) - .readFrom(urlConnection.getInputStream(), urlConnection.getContentType()); - } - }); + manpage = doHttpCommand(getCommandURI() + "/manpage", "GET", new ManPageHttpCommand()); } return manpage; } - private String createCommandCacheKey() { - StringBuilder result = new StringBuilder(getCanonicalHost().length() + name.length() + 12); - result.append("cache/"); - result.append(getCanonicalHost()).append('_').append(port); - result.append('/').append(name); - return result.toString(); - } - - protected String getCanonicalHost() { + private String getCanonicalHost() { if (canonicalHostCache == null) { try { InetAddress address = InetAddress.getByName(host); @@ -1413,22 +1039,6 @@ protected String getCanonicalHost() { return canonicalHostCache; } - private Class typeOf(String type) { - if (type.equals("STRING")) { - return String.class; - } else if (type.equals("BOOLEAN")) { - return Boolean.class; - } else if (type.equals("FILE")) { - return File.class; - } else if (type.equals("PASSWORD")) { - return String.class; - } else if (type.equals("PROPERTIES")) { - return Properties.class; - } else { - return String.class; - } - } - /** * Search all the parameters that were actually specified to see if any of them are FILE type parameters. If so, check * for the "--upload" option. @@ -1484,7 +1094,7 @@ private void initializeDoUpload() throws CommandException { } } - if (addedUploadOption) { + if (commandModel instanceof CachedCommandModel && ((CachedCommandModel) commandModel).isAddedUploadOption()) { logger.finer("removing --upload option"); //options.remove("upload"); // remove it // XXX - no remove method, have to copy it @@ -1574,5 +1184,4 @@ public void run() { thread.setDaemon(true); thread.start(); } - } diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/HttpConnectorAddress.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/HttpConnectorAddress.java index 95efd81d239..4f329f40c58 100755 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/HttpConnectorAddress.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/HttpConnectorAddress.java @@ -221,11 +221,11 @@ public synchronized SSLSocketFactory getSSLSocketFactory() { } private String getUser() { - return authInfo != null ? authInfo.getUser() : ""; + return authInfo == null ? "" : authInfo.getUser(); } private char[] getPassword() { - return authInfo != null ? authInfo.getPassword() : "".toCharArray(); + return authInfo == null ? "".toCharArray() : authInfo.getPassword(); } private URLConnection openConnection(URL url) throws IOException { @@ -239,9 +239,8 @@ private URLConnection makeConnection(URL url) throws IOException { private URLConnection setOptions(URLConnection uc) { uc.setDoOutput(true); uc.setUseCaches(false); - //uc.setRequestProperty("Content-type", "application/octet-stream"); - uc.setRequestProperty("Connection", "Keep-Alive"); - return this.setAuthentication(uc); + uc.setRequestProperty("Connection", "close"); + return setAuthentication(uc); } private URLConnection setAuthentication(URLConnection uc) { diff --git a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/cache/AdminCacheUtils.java b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/cache/AdminCacheUtils.java index 7de62170fd9..ce5ff9dc10b 100644 --- a/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/cache/AdminCacheUtils.java +++ b/nucleus/admin/util/src/main/java/com/sun/enterprise/admin/util/cache/AdminCacheUtils.java @@ -44,35 +44,17 @@ private AdminCacheUtils() { public DataProvider getProvider(final Class clazz) { DataProvider result = providers.get(clazz); - if (result == null) { - //Use hardcoded data providers - fastest and not problematic - for (DataProvider provider : allProviders) { - if (provider.accept(clazz)) { - providers.put(clazz, provider); - return provider; - } - } - // ServiceLocator habitat = Globals.getDefaultHabitat(); - // if (habitat != null) { - // List allServices = habitat.getAllServices(DataProvider.class); - // for (DataProvider provider : allServices) { - // if (provider.accept(clazz)) { - // providers.put(clazz, provider); - // return provider; - // } - // } - // } - // for (DataProvider provider : dataProviderLoader) { - // if (provider.accept(clazz)) { - // providers.put(clazz, provider); - // return provider; - // } - // } - - return null; - } else { + if (result != null) { return result; } + //Use hardcoded data providers - fastest and not problematic + for (DataProvider provider : allProviders) { + if (provider.accept(clazz)) { + providers.put(clazz, provider); + return provider; + } + } + return null; } public final boolean validateKey(final String key) { @@ -90,4 +72,11 @@ public static AdminCacheUtils getInstance() { return instance; } + public static String createCommandCacheKey(String name, String host, int port) { + StringBuilder result = new StringBuilder(host.length() + name.length() + 12); + result.append("cache/"); + result.append(host).append('_').append(port); + result.append('/').append(name); + return result.toString(); + } } diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/universal/process/ProcessUtils.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/universal/process/ProcessUtils.java index ba22b686fb0..032ef880006 100644 --- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/universal/process/ProcessUtils.java +++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/universal/process/ProcessUtils.java @@ -26,14 +26,10 @@ import java.io.IOException; import java.lang.ProcessHandle.Info; import java.lang.System.Logger; -import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import java.nio.channels.ClosedByInterruptException; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.SocketChannel; import java.text.MessageFormat; import java.time.Duration; import java.time.Instant; @@ -169,6 +165,8 @@ public static boolean isAlive(final ProcessHandle process) { public static boolean waitWhileListening(HostAndPort endpoint, Duration timeout, boolean printDots) { final Supplier action = () -> { try (Socket server = new Socket()) { + // Force RST on close + server.setSoLinger(true, 0); server.setSoTimeout(timeout == null ? 0 : (int) timeout.toMillis()); try { server.connect(endpoint.toInetSocketAddress(), SOCKET_CONNECT_TIMEOUT); @@ -214,24 +212,14 @@ public static boolean waitWhileListening(HostAndPort endpoint, Duration timeout, * @return true if the endpoint is listening on socket */ public static boolean isListening(HostAndPort endpoint) { - try (SocketChannel channel = SocketChannel.open()) { - channel.configureBlocking(false); - channel.connect(new InetSocketAddress(endpoint.getHost(), endpoint.getPort())); - - try (Selector selector = Selector.open()) { - channel.register(selector, SelectionKey.OP_CONNECT); - if (selector.select(SOCKET_CONNECT_TIMEOUT) == 0) { - // Timeout - return false; - } - channel.finishConnect(); - // Successfully connected = port is listening - return true; - } + try (Socket socket = new Socket()) { + // Force RST on close + socket.setSoLinger(true, 0); + socket.connect(endpoint.toInetSocketAddress(), SOCKET_CONNECT_TIMEOUT); + return true; } catch (IOException e) { LOG.log(TRACE, "An attempt to open a socket to " + endpoint + " resulted in exception. Therefore we assume the server has stopped.", e); - // Connection failed return false; } } diff --git a/nucleus/common/common-util/src/main/java/org/glassfish/common/util/admin/GlassFishErrorServiceImpl.java b/nucleus/common/common-util/src/main/java/org/glassfish/common/util/admin/GlassFishErrorServiceImpl.java index 4a309baf121..099f77c0ad7 100644 --- a/nucleus/common/common-util/src/main/java/org/glassfish/common/util/admin/GlassFishErrorServiceImpl.java +++ b/nucleus/common/common-util/src/main/java/org/glassfish/common/util/admin/GlassFishErrorServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024 Contributors to Eclipse Foundation. + * Copyright (c) 2021, 2025 Contributors to Eclipse Foundation. * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ORBLocator.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ORBLocator.java index fcb666f4c03..a233772fa75 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ORBLocator.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ORBLocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -60,7 +60,5 @@ public interface ORBLocator { */ ORB getORB(); - int getORBPort(ORB orb); - - String getORBHost(ORB orb); + int getORBPort(); } diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/adapter/AdminConsoleAdapter.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/adapter/AdminConsoleAdapter.java index 271f9122918..3f5d8846e9a 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/adapter/AdminConsoleAdapter.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/admin/adapter/AdminConsoleAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation. + * Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -33,9 +33,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; -import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -502,9 +502,11 @@ void initRest() { URL url = new URL(SecureAdmin.isEnabled(secureAdmin) ? "https" : "http", adminListener.getAddress(), Integer.parseInt(adminListener.getPort()), "/management/domain"); - URLConnection connection = url.openConnection(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try (InputStream ignored = connection.getInputStream()) { isRestStarted = true; + } finally { + connection.disconnect(); } } catch (Exception e) { logger.log(Level.FINE, null, e); diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/AppServerStartup.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/AppServerStartup.java index 185971dc8ed..2547294e7e6 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/AppServerStartup.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/AppServerStartup.java @@ -339,7 +339,6 @@ private boolean postStartupJob() { String wallClockStart = System.getProperty("WALL_CLOCK_START"); if (wallClockStart != null) { try { - // it will only be set when called from AsadminMain and the env. variable AS_DEBUG is set to true Instant realstart = Instant.parse(wallClockStart); long duration = Duration.between(realstart, Instant.now()).toMillis(); logger.log(Level.INFO, KernelLoggerInfo.startupTotalTime, duration); diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java index ef5cd0a0b06..cf66bde750c 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation. + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2008, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -117,6 +117,7 @@ import org.glassfish.internal.deployment.DeploymentTracing; import org.glassfish.internal.deployment.ExtendedDeploymentContext; import org.glassfish.kernel.KernelLoggerInfo; +import org.glassfish.main.jul.record.GlassFishLogRecord; import org.glassfish.server.ServerEnvironmentImpl; import org.jvnet.hk2.annotations.Optional; import org.jvnet.hk2.annotations.Service; @@ -1052,8 +1053,8 @@ protected boolean startContainers(Collection> containersInfo, L try { container = engineInfo.getContainer(); } catch (Exception e) { - LogRecord log = new LogRecord(SEVERE, KernelLoggerInfo.cantStartContainer); - log.setParameters(new Object[]{engineInfo.getSniffer().getModuleType()}); + LogRecord log = new GlassFishLogRecord(SEVERE, KernelLoggerInfo.cantStartContainer, true); + log.setParameters(new Object[] {engineInfo.getSniffer().getModuleType()}); log.setThrown(e); LOG.log(log); return false; @@ -2218,7 +2219,7 @@ private boolean loadOnCurrentInstance(DeploymentContext context) { } private String getApplicationType(ApplicationInfo appInfo) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); if (appInfo.getSniffers().size() > 0) { for (Sniffer sniffer : appInfo.getSniffers()) { if (sniffer.isUserVisible()) { diff --git a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/GrizzlyConfigTest.java b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/GrizzlyConfigTest.java index 09b86ce506c..d85c63b2fce 100644 --- a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/GrizzlyConfigTest.java +++ b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/GrizzlyConfigTest.java @@ -79,9 +79,9 @@ public void processConfig() throws IOException, InstantiationException { for (GrizzlyListener listener : grizzlyConfig.getListeners()) { helper.addStaticHttpHandler((GenericGrizzlyListener) listener, count++); } - final String content = helper.getContent(new URL("http://localhost:38082").openConnection()); - final String content2 = helper.getContent(new URL("http://localhost:38083").openConnection()); - final String content3 = helper.getContent(new URL("http://localhost:38084").openConnection()); + final String content = helper.getContent(new URL("http://localhost:38082")); + final String content2 = helper.getContent(new URL("http://localhost:38083")); + final String content3 = helper.getContent(new URL("http://localhost:38084")); assertEquals("You've found the server on port 38082", content); assertEquals("You've found the server on port 38083", content2); assertEquals("You've found the server on port 38084", content3); @@ -247,13 +247,13 @@ public void ssl() throws URISyntaxException, IOException { } assertEquals("You've found the server on port 38082", - helper.getContent(new URL("https://localhost:38082").openConnection())); + helper.getContent(new URL("https://localhost:38082"))); assertEquals("You've found the server on port 38083", - helper.getContent(new URL("https://localhost:38083").openConnection())); + helper.getContent(new URL("https://localhost:38083"))); assertEquals("You've found the server on port 38084", - helper.getContent(new URL("https://localhost:38084").openConnection())); + helper.getContent(new URL("https://localhost:38084"))); assertEquals("You've found the server on port 38085", - helper.getContent(new URL("https://localhost:38085").openConnection())); + helper.getContent(new URL("https://localhost:38085"))); } finally { if (grizzlyConfig != null) { grizzlyConfig.shutdown(); @@ -358,8 +358,8 @@ public void service(Request request, Response response) throws Exception { }); } - final String content = helper.getContent(new URL("http://localhost:38082").openConnection()); - final String content2 = helper.getContent(new URL("http://localhost:38083").openConnection()); + final String content = helper.getContent(new URL("http://localhost:38082")); + final String content2 = helper.getContent(new URL("http://localhost:38083")); assertEquals("http", content); assertEquals("https", content2); diff --git a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/PUGrizzlyConfigTest.java b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/PUGrizzlyConfigTest.java index 222bd1c781e..72f4e0e16df 100644 --- a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/PUGrizzlyConfigTest.java +++ b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/PUGrizzlyConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -72,7 +72,7 @@ public void puConfig() throws Exception { for (GrizzlyListener listener : grizzlyConfig.getListeners()) { helper.addStaticHttpHandler((GenericGrizzlyListener) listener, count++); } - final String httpContent = helper.getContent(new URL("http://localhost:38082").openConnection()); + final String httpContent = helper.getContent(new URL("http://localhost:38082")); assertEquals("You've found the server on port 38082", httpContent); final String xProtocolContent = getXProtocolContent("localhost", 38082); @@ -93,11 +93,11 @@ public void puHttpHttpsSamePortConfig() throws Exception { for (GrizzlyListener listener : grizzlyConfig.getListeners()) { helper.addStaticHttpHandler((GenericGrizzlyListener) listener, count++); } - final String httpContent1 = helper.getContent(new URL("http://localhost:38082").openConnection()); + final String httpContent1 = helper.getContent(new URL("http://localhost:38082")); assertEquals("You've found the server on port 38082", httpContent1); HttpsURLConnection.setDefaultSSLSocketFactory(helper.getSSLSocketFactory()); - final String httpContent2 = helper.getContent(new URL("https://localhost:38082").openConnection()); + final String httpContent2 = helper.getContent(new URL("https://localhost:38082")); assertEquals("You've found the server on port 38082", httpContent2); } finally { if (grizzlyConfig != null) { diff --git a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/test/GrizzlyConfigTestHelper.java b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/test/GrizzlyConfigTestHelper.java index b611e120b7b..636286cf2e5 100644 --- a/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/test/GrizzlyConfigTestHelper.java +++ b/nucleus/grizzly/config/src/test/java/org/glassfish/grizzly/config/test/GrizzlyConfigTestHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation. + * Copyright (c) 2021, 2025 Contributors to the Eclipse Foundation. * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -20,7 +20,8 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.net.URLConnection; +import java.net.HttpURLConnection; +import java.net.URL; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.List; @@ -47,11 +48,12 @@ public GrizzlyConfigTestHelper(final Class test) { } - public String getContent(URLConnection connection) { + public String getContent(URL url) throws IOException { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { return new String(connection.getInputStream().readAllBytes(), UTF_8); - } catch (IOException e) { - throw new IllegalStateException("Cannot get content from " + connection, e); + } finally { + connection.disconnect(); } }