diff --git a/src/prerna/engine/impl/SmssUtilities.java b/src/prerna/engine/impl/SmssUtilities.java index 0f07d5a414..4fe95856ea 100644 --- a/src/prerna/engine/impl/SmssUtilities.java +++ b/src/prerna/engine/impl/SmssUtilities.java @@ -174,7 +174,7 @@ public static File getInsightsRdbmsFile(Properties prop) { return null; } String rdbmsInsightsType = prop.getProperty(Constants.RDBMS_INSIGHTS_TYPE, "H2_DB"); - RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.valueOf(rdbmsInsightsType); + RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsInsightsType); String baseFolder = Utility.getBaseFolder(); String rdbmsInsights = Utility.normalizePath(baseFolder) + DIR_SEPARATOR @@ -559,7 +559,7 @@ public static File createTemporaryProjectSmss(String projectId, String projectNa // default will be h2 rdbmsTypeStr = "H2_DB"; } - rdbmsType = RdbmsTypeEnum.valueOf(rdbmsTypeStr); + rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsTypeStr); } bufferedWriter.write( @@ -637,7 +637,7 @@ public static File createTemporaryAssetSmss(String projectId, String projectName // default will be h2 rdbmsTypeStr = "H2_DB"; } - rdbmsType = RdbmsTypeEnum.valueOf(rdbmsTypeStr); + rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsTypeStr); } // this smss is only ever generated for a user asset project @@ -707,7 +707,7 @@ public static RDBMSNativeEngine generateInsightsDatabase(String projectId, Strin // default will be h2 rdbmsTypeStr = "H2_DB"; } - RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.valueOf(rdbmsTypeStr); + RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsTypeStr); Properties insightSmssProp = new Properties(); /* diff --git a/src/prerna/project/impl/ProjectHelper.java b/src/prerna/project/impl/ProjectHelper.java index 75b4274b5b..3db5dd1b32 100644 --- a/src/prerna/project/impl/ProjectHelper.java +++ b/src/prerna/project/impl/ProjectHelper.java @@ -280,7 +280,7 @@ public static IRDBMSEngine loadInsightsEngine(Properties mainEngineProp, Logger String projectName = mainEngineProp.getProperty(Constants.PROJECT_ALIAS); String rdbmsInsightsTypeStr = mainEngineProp.getProperty(Constants.RDBMS_INSIGHTS_TYPE, "H2_DB"); - RdbmsTypeEnum rdbmsInsightsType = RdbmsTypeEnum.valueOf(rdbmsInsightsTypeStr); + RdbmsTypeEnum rdbmsInsightsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsInsightsTypeStr); String insightDatabaseLoc = SmssUtilities.getInsightsRdbmsFile(mainEngineProp).getAbsolutePath(); return loadInsightsDatabase(projectId, projectName, rdbmsInsightsType, insightDatabaseLoc, logger); } diff --git a/src/prerna/util/InsightsRDBMSUtils.java b/src/prerna/util/InsightsRDBMSUtils.java index 1b686894dc..dd441b5504 100644 --- a/src/prerna/util/InsightsRDBMSUtils.java +++ b/src/prerna/util/InsightsRDBMSUtils.java @@ -69,7 +69,7 @@ public static IRDBMSEngine generateInsightsDatabase(String projectId, String pro // default will be h2 rdbmsTypeStr = "H2_DB"; } - RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.valueOf(rdbmsTypeStr); + RdbmsTypeEnum rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsTypeStr); Properties insightSmssProp = new Properties(); /* @@ -253,7 +253,7 @@ public static RDBMSNativeEngine generateInsightsDatabase(String projectId, Rdbms // default will be h2 rdbmsTypeStr = "H2_DB"; } - rdbmsType = RdbmsTypeEnum.valueOf(rdbmsTypeStr); + rdbmsType = RdbmsTypeEnum.getEnumFromStringOrThrow(rdbmsTypeStr); } Properties insightSmssProp = new Properties(); diff --git a/src/prerna/util/sql/RdbmsTypeEnum.java b/src/prerna/util/sql/RdbmsTypeEnum.java index e45c3cbd0c..6bb399b4d2 100644 --- a/src/prerna/util/sql/RdbmsTypeEnum.java +++ b/src/prerna/util/sql/RdbmsTypeEnum.java @@ -27,6 +27,8 @@ *******************************************************************************/ package prerna.util.sql; +import java.util.Arrays; + public enum RdbmsTypeEnum { // @formatter:off @@ -144,6 +146,27 @@ public static RdbmsTypeEnum getEnumFromString(String type) { return null; } + /** + * Get the enum based on the type, normalizing surrounding whitespace and case + * first. Unlike {@link #getEnumFromString(String)}, this throws a clear, + * actionable exception naming the invalid configured value and the valid + * constants instead of silently returning null when the type cannot be + * resolved. + * + * @param type + * @return + */ + public static RdbmsTypeEnum getEnumFromStringOrThrow(String type) { + String normalizedType = type == null ? null : type.trim(); + RdbmsTypeEnum foundType = (normalizedType == null || normalizedType.isEmpty()) ? null + : getEnumFromString(normalizedType); + if (foundType == null) { + throw new IllegalArgumentException( + "Unknown rdbms type '" + type + "'. Valid values are: " + Arrays.toString(RdbmsTypeEnum.values())); + } + return foundType; + } + /** * Get the enum from the driver * diff --git a/test/prerna/engine/impl/SmssUtilitiesUnitTests.java b/test/prerna/engine/impl/SmssUtilitiesUnitTests.java index 63ba239374..c58f53dc71 100644 --- a/test/prerna/engine/impl/SmssUtilitiesUnitTests.java +++ b/test/prerna/engine/impl/SmssUtilitiesUnitTests.java @@ -569,4 +569,81 @@ void testConcealSmssSensitiveInfo_NoSensitiveKeys() { assertEquals(curr, SmssUtilities.concealSmssSensitiveInfo(curr)); } + @Test + void testGetInsightsRdbmsFileInvalidConfiguredRdbmsType() { + Properties prop = new Properties(); + prop.setProperty(Constants.RDBMS_INSIGHTS, "@PROJECT@" + File.separator + "data"); + prop.setProperty(Constants.RDBMS_INSIGHTS_TYPE, "NOT_A_REAL_RDBMS_TYPE"); + + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> SmssUtilities.getInsightsRdbmsFile(prop)); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + + @Test + void testCreateTempProjectSmssInvalidConfiguredRdbmsType() throws IOException { + Path base = tempDir.resolve("Semoss"); + Files.createDirectories(base); + Properties coreProp = new Properties(); + coreProp.setProperty(Constants.BASE_FOLDER, base.toAbsolutePath().toString()); + coreProp.setProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "NOT_A_REAL_RDBMS_TYPE"); + DIHelper.getInstance().setCoreProp(coreProp); + + Path project = base.resolve("project"); + Files.createDirectories(project); + + // passing a null forceInsightDatabaseType forces this method to fall back to + // the configured DEFAULT_INSIGHTS_RDBMS property + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> SmssUtilities.createTemporaryProjectSmss("pid", "pname", IProject.PROJECT_TYPE.INSIGHTS, + "github", "github.com", null)); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + + @Test + void testCreateTempAssetInvalidConfiguredRdbmsType() throws IOException { + Path base = tempDir.resolve("Semoss"); + Files.createDirectories(base); + Properties coreProp = new Properties(); + coreProp.setProperty(Constants.BASE_FOLDER, base.toAbsolutePath().toString()); + coreProp.setProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "NOT_A_REAL_RDBMS_TYPE"); + DIHelper.getInstance().setCoreProp(coreProp); + + Path user = base.resolve("user"); + Files.createDirectories(user); + + // passing a null forceInsightDatabaseType forces this method to fall back to + // the configured DEFAULT_INSIGHTS_RDBMS property + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> SmssUtilities.createTemporaryAssetSmss("pid", "pname", null)); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + + @Test + void testGenerateInsightsDatabaseInvalidConfiguredRdbmsType() { + Properties coreProp = new Properties(); + coreProp.setProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "NOT_A_REAL_RDBMS_TYPE"); + DIHelper.getInstance().setCoreProp(coreProp); + + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> SmssUtilities.generateInsightsDatabase("pid", "pname")); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + } diff --git a/test/prerna/project/impl/ProjectHelperUnitTests.java b/test/prerna/project/impl/ProjectHelperUnitTests.java new file mode 100644 index 0000000000..fd9626c5a7 --- /dev/null +++ b/test/prerna/project/impl/ProjectHelperUnitTests.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2015 Defense Health Agency (DHA) + * + * If your use of this software does not include any GPLv2 components: + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---------------------------------------------------------------------------- + * If your use of this software includes any GPLv2 components: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *******************************************************************************/ +package prerna.project.impl; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Properties; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import prerna.SemossUnitTest; +import prerna.util.Constants; + +public class ProjectHelperUnitTests extends SemossUnitTest { + + private static final Logger logger = LogManager.getLogger(ProjectHelperUnitTests.class); + + @Test + void testLoadInsightsEngineInvalidConfiguredRdbmsType() { + Properties mainEngineProp = new Properties(); + mainEngineProp.setProperty(Constants.PROJECT, "pid"); + mainEngineProp.setProperty(Constants.PROJECT_ALIAS, "pname"); + mainEngineProp.setProperty(Constants.RDBMS_INSIGHTS_TYPE, "NOT_A_REAL_RDBMS_TYPE"); + + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> ProjectHelper.loadInsightsEngine(mainEngineProp, logger)); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + +} diff --git a/test/prerna/util/InsightsRDBMSUtilsUnitTests.java b/test/prerna/util/InsightsRDBMSUtilsUnitTests.java new file mode 100644 index 0000000000..90f840ef48 --- /dev/null +++ b/test/prerna/util/InsightsRDBMSUtilsUnitTests.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 2015 Defense Health Agency (DHA) + * + * If your use of this software does not include any GPLv2 components: + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---------------------------------------------------------------------------- + * If your use of this software includes any GPLv2 components: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *******************************************************************************/ +package prerna.util; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import prerna.SemossUnitTest; +import prerna.util.sql.RdbmsTypeEnum; + +public class InsightsRDBMSUtilsUnitTests extends SemossUnitTest { + + @AfterEach + void resetDefaultInsightsRdbmsProperty() { + DIHelper.getInstance().putProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "H2_DB"); + } + + @Test + void testGenerateInsightsDatabaseInvalidConfiguredRdbmsType() { + DIHelper.getInstance().putProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "NOT_A_REAL_RDBMS_TYPE"); + + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> InsightsRDBMSUtils.generateInsightsDatabase("pid", "pname")); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + + @Test + void testGenerateInsightsDatabaseFolderOverloadInvalidConfiguredRdbmsType() { + DIHelper.getInstance().putProperty(Constants.DEFAULT_INSIGHTS_RDBMS, "NOT_A_REAL_RDBMS_TYPE"); + + // passing a null RdbmsTypeEnum forces this overload to fall back to the + // configured DEFAULT_INSIGHTS_RDBMS property, same as the 2-arg overload + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> InsightsRDBMSUtils.generateInsightsDatabase("pid", (RdbmsTypeEnum) null, "folder")); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + +} diff --git a/test/prerna/util/sql/RdbmsTypeEnumUnitTests.java b/test/prerna/util/sql/RdbmsTypeEnumUnitTests.java new file mode 100644 index 0000000000..e0164390f5 --- /dev/null +++ b/test/prerna/util/sql/RdbmsTypeEnumUnitTests.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2015 Defense Health Agency (DHA) + * + * If your use of this software does not include any GPLv2 components: + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---------------------------------------------------------------------------- + * If your use of this software includes any GPLv2 components: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *******************************************************************************/ +package prerna.util.sql; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +public class RdbmsTypeEnumUnitTests { + + @Test + void testGetEnumFromStringOrThrowExactMatch() { + assertEquals(RdbmsTypeEnum.H2_DB, RdbmsTypeEnum.getEnumFromStringOrThrow("H2_DB")); + } + + @ParameterizedTest + @ValueSource(strings = { "h2_db", " H2_DB", "H2_DB ", " h2_db " }) + void testGetEnumFromStringOrThrowNormalizesCaseAndWhitespace(String input) { + assertEquals(RdbmsTypeEnum.H2_DB, RdbmsTypeEnum.getEnumFromStringOrThrow(input)); + } + + @Test + void testGetEnumFromStringOrThrowResolvesByLabel() { + // MARIADB's enum constant name does not match its label "MARIA_DB" + assertEquals(RdbmsTypeEnum.MARIADB, RdbmsTypeEnum.getEnumFromStringOrThrow("MARIA_DB")); + } + + @Test + void testGetEnumFromStringOrThrowInvalidValue() { + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, + () -> RdbmsTypeEnum.getEnumFromStringOrThrow("NOT_A_REAL_RDBMS_TYPE")); + + assertTrue(e.getMessage().contains("NOT_A_REAL_RDBMS_TYPE"), + "Error message should name the invalid configured value, was: " + e.getMessage()); + assertTrue(e.getMessage().contains("H2_DB"), + "Error message should list the valid RdbmsTypeEnum constants, was: " + e.getMessage()); + } + + @Test + void testGetEnumFromStringOrThrowBlankValue() { + assertThrows(IllegalArgumentException.class, () -> RdbmsTypeEnum.getEnumFromStringOrThrow(" ")); + } + + @ParameterizedTest + @NullAndEmptySource + void testGetEnumFromStringOrThrowNullOrEmpty(String input) { + assertThrows(IllegalArgumentException.class, () -> RdbmsTypeEnum.getEnumFromStringOrThrow(input)); + } + +}