diff --git a/appserver/jdbc/jdbc-runtime/pom.xml b/appserver/jdbc/jdbc-runtime/pom.xml
index 03638a68be3..d6b340fcaa6 100644
--- a/appserver/jdbc/jdbc-runtime/pom.xml
+++ b/appserver/jdbc/jdbc-runtime/pom.xml
@@ -105,6 +105,11 @@
jakarta.el
test
-
+
+ org.mockito
+ mockito-core
+ test
+
+
diff --git a/appserver/jdbc/jdbc-runtime/src/main/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionHandler.java b/appserver/jdbc/jdbc-runtime/src/main/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionHandler.java
index 6c05822a5cc..cb531064bdc 100644
--- a/appserver/jdbc/jdbc-runtime/src/main/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionHandler.java
+++ b/appserver/jdbc/jdbc-runtime/src/main/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionHandler.java
@@ -48,6 +48,7 @@
import org.glassfish.apf.AnnotationInfo;
import org.glassfish.apf.AnnotationProcessorException;
import org.glassfish.apf.HandlerProcessingResult;
+import org.glassfish.config.support.TranslatedConfigView;
import org.glassfish.deployment.common.JavaEEResourceType;
import org.glassfish.deployment.common.RootDeploymentDescriptor;
import org.jvnet.hk2.annotations.Service;
@@ -236,12 +237,12 @@ private void merge(Set dsdDescs, DataSourceDefinition defn)
if (desc.getName().equals(defn.name())) {
if (desc.getClassName() == null) {
- desc.setClassName(defn.className());
+ desc.setClassName(TranslatedConfigView.expandValue(defn.className()));
}
if (desc.getDescription() == null) {
if (defn.description() != null && !defn.description().equals("")) {
- desc.setDescription(defn.description());
+ desc.setDescription(TranslatedConfigView.expandValue(defn.description()));
}
}
@@ -255,7 +256,7 @@ private void merge(Set dsdDescs, DataSourceDefinition defn)
if (!desc.isServerNameSet() && desc.getUrl() == null) {
//localhost is the default value (even in the descriptor)
if (defn.serverName() != null && !defn.serverName().equals("localhost")) {
- desc.setServerName(defn.serverName());
+ desc.setServerName(TranslatedConfigView.expandValue(defn.serverName()));
}
}
@@ -269,7 +270,7 @@ private void merge(Set dsdDescs, DataSourceDefinition defn)
//try only when URL is not set
if (desc.getDatabaseName() == null && desc.getUrl() == null) {
if (defn.databaseName() != null && !defn.databaseName().equals("")) {
- desc.setDatabaseName(defn.databaseName());
+ desc.setDatabaseName(TranslatedConfigView.expandValue(defn.databaseName()));
}
}
@@ -278,20 +279,20 @@ private void merge(Set dsdDescs, DataSourceDefinition defn)
!(desc.getPortNumber() != -1 && desc.getServerName() != null &&
(desc.getDatabaseName() != null))) {
if (defn.url() != null && !defn.url().equals("")) {
- desc.setUrl(defn.url());
+ desc.setUrl(TranslatedConfigView.expandValue(defn.url()));
}
}
if (desc.getUser() == null) {
if (defn.user() != null && !defn.user().equals("")) {
- desc.setUser(defn.user());
+ desc.setUser(TranslatedConfigView.expandValue(defn.user()));
}
}
if (desc.getPassword() == null) {
if (defn.password() != null /*ALLOW EMPTY PASSWORDS && !defn.password().equals("")*/) {
- desc.setPassword(defn.password());
+ desc.setPassword(TranslatedConfigView.expandValue(defn.password()));
}
}
@@ -357,7 +358,7 @@ private void merge(Set dsdDescs, DataSourceDefinition defn)
String value = property.substring(index + 1);
//add to properties only when not already present
if (properties.get(name) == null) {
- properties.put(name, value);
+ properties.put(name, TranslatedConfigView.expandValue(value));
}
}
}
@@ -374,15 +375,15 @@ DataSourceDefinitionDescriptor createDescriptor(DataSourceDefinition defn) {
DataSourceDefinitionDescriptor desc = new DataSourceDefinitionDescriptor();
desc.setMetadataSource(MetadataSource.ANNOTATION);
- desc.setName(defn.name());
- desc.setClassName(defn.className());
+ desc.setName(TranslatedConfigView.expandValue(defn.name()));
+ desc.setClassName(TranslatedConfigView.expandValue(defn.className()));
if (defn.description() != null && !defn.description().equals("")) {
- desc.setDescription(defn.description());
+ desc.setDescription(TranslatedConfigView.expandValue(defn.description()));
}
if (defn.serverName() != null && !defn.serverName().equals("localhost")) {
- desc.setServerName(defn.serverName());
+ desc.setServerName(TranslatedConfigView.expandValue(defn.serverName()));
}
if (defn.portNumber() != -1) {
@@ -391,28 +392,28 @@ DataSourceDefinitionDescriptor createDescriptor(DataSourceDefinition defn) {
if (defn.databaseName() != null && !defn.databaseName().equals("")) {
- desc.setDatabaseName(defn.databaseName());
+ desc.setDatabaseName(TranslatedConfigView.expandValue(defn.databaseName()));
}
if (desc.getPortNumber() != -1 && desc.getDatabaseName() != null && desc.getServerName() != null) {
//standard properties are set, ignore URL
} else {
if (defn.url() != null && !defn.url().equals("")) {
- desc.setUrl(defn.url());
+ desc.setUrl(TranslatedConfigView.expandValue(defn.url()));
desc.setServerName(null); //To prevent serverName overriding the URL, always use the URL if the standard properties are not set
}
}
if (defn.user() != null && !defn.user().equals("")) {
- desc.setUser(defn.user());
+ desc.setUser(TranslatedConfigView.expandValue(defn.user()));
}
if (defn.password() != null /*ALLOW EMPTY PASSWORDS && !defn.password().equals("")*/) {
- desc.setPassword(defn.password());
+ desc.setPassword(TranslatedConfigView.expandValue(defn.password()));
}
if (defn.isolationLevel() != -1) {
- desc.setIsolationLevel(String.valueOf(defn.isolationLevel()));
+ desc.setIsolationLevel(TranslatedConfigView.expandValue(String.valueOf(defn.isolationLevel())));
}
if (defn.transactional()) {
@@ -443,7 +444,6 @@ DataSourceDefinitionDescriptor createDescriptor(DataSourceDefinition defn) {
desc.setLoginTimeout(String.valueOf(defn.loginTimeout()));
}
-
if (defn.properties() != null) {
Properties properties = desc.getProperties();
@@ -455,7 +455,7 @@ DataSourceDefinitionDescriptor createDescriptor(DataSourceDefinition defn) {
if (index > -1 && index != 0 && index < property.length() - 1) {
String name = property.substring(0, index);
String value = property.substring(index + 1);
- properties.put(name, value);
+ properties.put(name, TranslatedConfigView.expandValue(value));
}
}
}
diff --git a/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionTest.java b/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionTest.java
index 1dab489ef32..7ac40bf86b8 100644
--- a/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionTest.java
+++ b/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/DataSourceDefinitionTest.java
@@ -40,17 +40,93 @@
package org.glassfish.jdbcruntime.deployment.annotation.handlers;
import com.sun.enterprise.deployment.DataSourceDefinitionDescriptor;
-import java.lang.annotation.Annotation;
-import javax.annotation.sql.DataSourceDefinition;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.annotation.sql.DataSourceDefinition;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.when;
/**
* Test for DataSourceDefinition processing in DataSourceDefinitionHandler
* @author jonathan coustick
*/
+@RunWith(MockitoJUnitRunner.class)
public class DataSourceDefinitionTest {
-
+
+ @Mock
+ private DataSourceDefinition dataSourceDefinition;
+
+ @Before
+ public void before() {
+ when(dataSourceDefinition.portNumber()).thenReturn(-1);
+ when(dataSourceDefinition.isolationLevel()).thenReturn(-1);
+ when(dataSourceDefinition.transactional()).thenReturn(false);
+ when(dataSourceDefinition.initialPoolSize()).thenReturn(-1);
+ when(dataSourceDefinition.maxPoolSize()).thenReturn(-1);
+ when(dataSourceDefinition.minPoolSize()).thenReturn(-1);
+ when(dataSourceDefinition.maxIdleTime()).thenReturn(-1);
+ when(dataSourceDefinition.maxStatements()).thenReturn(-1);
+ when(dataSourceDefinition.loginTimeout()).thenReturn(-1);
+ }
+
+ @Test
+ public void test_environment_variable_expansion_works() throws Exception {
+ String url = "url";
+ String serverName = "server name";
+ String className = "class name";
+ String name = "name";
+ String description = "description";
+ String user = "user";
+ String password = "password";
+ String databaseName = "database name";
+ String property1 = "property 1";
+ String property2 = "property 2";
+
+ Map env = new HashMap<>();
+ env.put("DB_URL", url);
+ env.put("DB_SERVER_NAME", serverName);
+ env.put("DB_CLASS_NAME", className);
+ env.put("DB_NAME", name);
+ env.put("DB_DESCRIPTION", description);
+ env.put("DB_USER", user);
+ env.put("DB_PASSWORD", password);
+ env.put("DB_DATABASE_NAME", databaseName);
+ env.put("DB_PROPERTY1", property1);
+ env.put("DB_PROPERTY2", property2);
+ EnvironmentUtil.setEnv(env);
+ DataSourceDefinitionHandler handler = new DataSourceDefinitionHandler();
+
+ when(dataSourceDefinition.url()).thenReturn("${ENV=DB_URL}");
+ when(dataSourceDefinition.serverName()).thenReturn("${ENV=DB_SERVER_NAME}");
+ when(dataSourceDefinition.className()).thenReturn("${ENV=DB_CLASS_NAME}");
+ when(dataSourceDefinition.name()).thenReturn("${ENV=DB_NAME}");
+ when(dataSourceDefinition.description()).thenReturn("${ENV=DB_DESCRIPTION}");
+ when(dataSourceDefinition.user()).thenReturn("${ENV=DB_USER}");
+ when(dataSourceDefinition.password()).thenReturn("${ENV=DB_PASSWORD}");
+ when(dataSourceDefinition.databaseName()).thenReturn("${ENV=DB_DATABASE_NAME}");
+ when(dataSourceDefinition.properties()).thenReturn(new String[]{"property1=${ENV=DB_PROPERTY1}", "property2=${ENV=DB_PROPERTY2}"});
+
+ DataSourceDefinitionDescriptor descriptor = handler.createDescriptor(dataSourceDefinition);
+
+ Assert.assertEquals(url,descriptor.getUrl());
+ Assert.assertNull(descriptor.getServerName()); // because url is set
+ Assert.assertEquals(className,descriptor.getClassName());
+ Assert.assertEquals(name,descriptor.getName());
+ Assert.assertEquals(description,descriptor.getDescription());
+ Assert.assertEquals(user,descriptor.getUser());
+ Assert.assertEquals(password,descriptor.getPassword());
+ Assert.assertEquals(databaseName,descriptor.getDatabaseName());
+ Assert.assertEquals(property1,descriptor.getProperty("property1"));
+ Assert.assertEquals(property2,descriptor.getProperty("property2"));
+ }
+
/**
* Test to ensure that if the URL has been set, it will override the default serverName of localhost
* and cause that to be set to null.
@@ -58,126 +134,23 @@ public class DataSourceDefinitionTest {
@Test
public void testServerAndURL() {
DataSourceDefinitionHandler handler = new DataSourceDefinitionHandler();
-
+
+ String url = "http://database:5432/demo";
+ String serverName = "localhost";
+
//Check url overrides serverName and sets it to null
- DataSourceDefinition definition = new DataSourceDefinitionImpl() {
- @Override
- public String url() {
- return "http://database:5432/demo";
- }
-
- @Override
- public String serverName() {
- return "localhost";
- }
-
- };
- DataSourceDefinitionDescriptor descriptor = handler.createDescriptor(definition);
+ when(dataSourceDefinition.url()).thenReturn(url);
+ when(dataSourceDefinition.serverName()).thenReturn(serverName);
+
+ DataSourceDefinitionDescriptor descriptor = handler.createDescriptor(dataSourceDefinition);
+
Assert.assertNull(descriptor.getServerName());
-
-
+
//Check if url is not set then serverName is left as-is
- definition = new DataSourceDefinitionImpl() {
- @Override
- public String url() {
- return null;
- }
-
- @Override
- public String serverName() {
- return "localhost";
- }
- };
- descriptor = handler.createDescriptor(definition);
+ when(dataSourceDefinition.url()).thenReturn(null);
+
+ descriptor = handler.createDescriptor(dataSourceDefinition );
+
Assert.assertEquals("localhost", descriptor.getServerName());
}
-
- abstract class DataSourceDefinitionImpl implements DataSourceDefinition {
- @Override
- public String name() {
- return null;
- }
-
- @Override
- public String className() {
- return null;
- }
-
- @Override
- public String description() {
- return null;
- }
-
- @Override
- public String user() {
- return null;
- }
-
- @Override
- public String password() {
- return null;
- }
-
- @Override
- public String databaseName() {
- return null;
- }
-
- @Override
- public int portNumber() {
- return -1;
- }
-
- @Override
- public int isolationLevel() {
- return -1;
- }
-
- @Override
- public boolean transactional() {
- return false;
- }
-
- @Override
- public int initialPoolSize() {
- return -1;
- }
-
- @Override
- public int maxPoolSize() {
- return -1;
- }
-
- @Override
- public int minPoolSize() {
- return -1;
- }
-
- @Override
- public int maxIdleTime() {
- return -1;
- }
-
- @Override
- public int maxStatements() {
- return -1;
- }
-
- @Override
- public String[] properties() {
- return null;
- }
-
- @Override
- public int loginTimeout() {
- return -1;
- }
-
- @Override
- public Class extends Annotation> annotationType() {
- return DataSourceDefinition.class;
- }
- }
-
-
}
diff --git a/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/EnvironmentUtil.java b/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/EnvironmentUtil.java
new file mode 100644
index 00000000000..688303917db
--- /dev/null
+++ b/appserver/jdbc/jdbc-runtime/src/test/java/org/glassfish/jdbcruntime/deployment/annotation/handlers/EnvironmentUtil.java
@@ -0,0 +1,76 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://github.com/payara/Payara/blob/master/LICENSE.txt
+ * See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * The Payara Foundation designates this particular file as subject to the "Classpath"
+ * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package org.glassfish.jdbcruntime.deployment.annotation.handlers;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Map;
+
+class EnvironmentUtil {
+ static void setEnv(Map newenv) throws Exception {
+ try {
+ Class> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
+ Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
+ theEnvironmentField.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Map env = (Map) theEnvironmentField.get(null);
+ env.putAll(newenv);
+ Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
+ theCaseInsensitiveEnvironmentField.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Map cienv = (Map) theCaseInsensitiveEnvironmentField.get(null);
+ cienv.putAll(newenv);
+ } catch (NoSuchFieldException e) {
+ Class[] classes = Collections.class.getDeclaredClasses();
+ Map env = System.getenv();
+ for(Class cl : classes) {
+ if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
+ Field field = cl.getDeclaredField("m");
+ field.setAccessible(true);
+ Object obj = field.get(env);
+ @SuppressWarnings("unchecked")
+ Map map = (Map) obj;
+ map.clear();
+ map.putAll(newenv);
+ }
+ }
+ }
+ }
+}