Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAYARA-3718 Adds EJB over HTTP client config via system properties #3930

Merged
Expand Up @@ -111,9 +111,52 @@ public class RemoteEJBContextFactory implements InitialContextFactory {
@Deprecated
public static final String FISH_PAYARA_CLIENT_ADAPTER = CLIENT_ADAPTER;

/**
* The keys checked when creating a {@link Context} with {@link #getInitialContext(Hashtable)}. If these are not set
* in the environment they are initialised to a {@link System#getProperty(String)} if present.
*
* The name of the property is the same as the environment variable name.
*/
private String[] SYSTEM_PROPERTY_KEYS = {
Context.INITIAL_CONTEXT_FACTORY,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System properties are read as Strings, but surely majority of factory's properties are of different type. But I realized they are converted in the context where reasonable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought but all of these in the list are defined as some String value according to the javadoc that is converted later on.

Context.OBJECT_FACTORIES,
Context.STATE_FACTORIES,
Context.URL_PKG_PREFIXES,
Context.PROVIDER_URL,
Context.DNS_URL,
Context.AUTHORITATIVE,
Context.BATCHSIZE,
Context.REFERRAL,
Context.SECURITY_PROTOCOL,
Context.SECURITY_AUTHENTICATION,
Context.SECURITY_PRINCIPAL,
Context.SECURITY_CREDENTIALS,
Context.LANGUAGE,
JAXRS_CLIENT_CONFIG,
JAXRS_CLIENT_CONNECT_TIMEOUT,
JAXRS_CLIENT_EXECUTOR_SERVICE,
JAXRS_CLIENT_HOSTNAME_VERIFIER,
JAXRS_CLIENT_KEY_STORE,
JAXRS_CLIENT_READ_TIMEOUT,
JAXRS_CLIENT_SCHEDULED_EXECUTOR_SERVICE,
JAXRS_CLIENT_SSL_CONTEXT,
JAXRS_CLIENT_TRUST_STORE};

@SuppressWarnings("unchecked")
@Override
public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
applySystemPropertiesFallbacks((Hashtable<String, Object>) environment);
return new RemoteEJBContext(environment);
}


private void applySystemPropertiesFallbacks(Hashtable<String, Object> environment) {
for (String environmentVariable : SYSTEM_PROPERTY_KEYS) {
if (!environment.containsKey(environmentVariable)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method name update... suggests that you can actually update the environment map from system properties. But this if allows only to set missing values. Maybe complete... would be a better name for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed it.

String value = System.getProperty(environmentVariable, null);
if (value != null) {
environment.put(environmentVariable, value);
}
}
}
}
}
@@ -0,0 +1,119 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://github.com/payara/Payara/blob/master/LICENSE.txt
* See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* The Payara Foundation designates this particular file as subject to the "Classpath"
* exception as provided by the Payara Foundation in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package fish.payara.ejb.http.client;

import static fish.payara.ejb.http.client.RemoteEJBContextFactory.JAXRS_CLIENT_CONNECT_TIMEOUT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Hashtable;

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

import org.junit.After;
import org.junit.Test;

/**
* Tests the {@link System} property fallback for the {@link RemoteEJBContextFactory}.
*
* @author Jan Bernitt
* @since 5.192
*/
public class RemoteEJBContextFactoryTest {

private static final String FISH_PAYARA_EJB_HTTP_CLIENT_PROVIDER_URL = Context.PROVIDER_URL;
private static final String FISH_PAYARA_EJB_HTTP_CLIENT_SSLCONTEXT = RemoteEJBContextFactory.JAXRS_CLIENT_SSL_CONTEXT;

@After
public void clean() {
System.clearProperty(FISH_PAYARA_EJB_HTTP_CLIENT_PROVIDER_URL);
System.clearProperty(FISH_PAYARA_EJB_HTTP_CLIENT_SSLCONTEXT);
System.clearProperty(JAXRS_CLIENT_CONNECT_TIMEOUT);
}

@Test
public void whenPayaraSpecificEnvironmentVariableIsSetThePrefixIsEnlarged() throws NamingException {
System.setProperty(FISH_PAYARA_EJB_HTTP_CLIENT_PROVIDER_URL, "http://custom.url");
Context context = new RemoteEJBContextFactory().getInitialContext(new Hashtable<>());
assertEquals("http://custom.url", context.getEnvironment().get(Context.PROVIDER_URL));
}

@Test
public void whenNamingEnvironmentVariableIsSetThePrefixIsReplaced() throws NamingException {
System.setProperty(FISH_PAYARA_EJB_HTTP_CLIENT_SSLCONTEXT, "custom-SSL-context");
Context context = new RemoteEJBContextFactory().getInitialContext(new Hashtable<>());
assertEquals("custom-SSL-context", context.getEnvironment().get(RemoteEJBContextFactory.JAXRS_CLIENT_SSL_CONTEXT));
}

@Test
public void whenEnvironmentVariableIsAlreadySetItIsNotReplacedWithSystemProperty() throws NamingException {
System.setProperty(FISH_PAYARA_EJB_HTTP_CLIENT_PROVIDER_URL, "http://custom.url");
System.setProperty(FISH_PAYARA_EJB_HTTP_CLIENT_SSLCONTEXT, "custom-SSL-context");
Hashtable<String, Object> environment = new Hashtable<>();
environment.put(Context.PROVIDER_URL, "http://existing.url");
environment.put(RemoteEJBContextFactory.JAXRS_CLIENT_SSL_CONTEXT, "existing-SSL-context");
Context context = new RemoteEJBContextFactory().getInitialContext(environment);
assertEquals("http://existing.url", context.getEnvironment().get(Context.PROVIDER_URL));
assertEquals("existing-SSL-context", context.getEnvironment().get(RemoteEJBContextFactory.JAXRS_CLIENT_SSL_CONTEXT));
}

@Test
public void systemPropertiesWorkWithJNDI() throws NamingException {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteEJBContextFactory.FACTORY_CLASS);
System.setProperty(Context.PROVIDER_URL, "http://localhost:8080");
System.setProperty(JAXRS_CLIENT_CONNECT_TIMEOUT, "90");
ExposingInitialContext context = new ExposingInitialContext();
assertTrue("RemoteEJBContext was created", context.getDefaultInitCtx() instanceof RemoteEJBContext);
assertEquals("90", context.getEnvironment().get(JAXRS_CLIENT_CONNECT_TIMEOUT));
}

static class ExposingInitialContext extends InitialContext {

public ExposingInitialContext() throws NamingException {
}

@Override
protected Context getDefaultInitCtx() throws NamingException {
return super.getDefaultInitCtx();
}
}
}