diff --git a/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java b/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java index 372e7d3c..923a943f 100644 --- a/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java +++ b/common/src/main/java/org/apache/sqoop/model/ConfigUtils.java @@ -20,6 +20,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.utils.ClassUtils; +import org.apache.sqoop.validation.ConfigValidationRunner; import org.apache.sqoop.validation.Message; import org.apache.sqoop.validation.Status; import org.apache.sqoop.validation.ConfigValidator; @@ -207,6 +208,38 @@ private static Field getFieldFromName(Class klass, String name) { return configField; } + /** + * Convenience method to directly validate given model classes without the need to + * manually create the configuration instance. + * + * @param configs Model representation with filled values + * @param configClass Configuration class + * @return Validation result + */ + public static ConfigValidationResult validateConfigs(List configs, Class configClass) { + ConfigValidationRunner validationRunner = new ConfigValidationRunner(); + Object configInstance = fromConfigs(configs, configClass); + return validationRunner.validate(configInstance); + } + + /** + * Convenience method to convert given model structure into configuration object + * that will be created from given class. + * + * @param configs Model representation with filled values + * @param configClass Configuration class + * @return Created instance based on the class with filled values + */ + public static Object fromConfigs(List configs, Class configClass) { + Object configInstance = ClassUtils.instantiate(configClass); + if(configInstance == null) { + throw new SqoopException(ModelError.MODEL_016, configClass.getCanonicalName()); + } + + fromConfigs(configs, configInstance); + return configInstance; + } + /** * Move config values from config list into corresponding configuration object. * diff --git a/common/src/main/java/org/apache/sqoop/model/ModelError.java b/common/src/main/java/org/apache/sqoop/model/ModelError.java index 35a89438..a9917816 100644 --- a/common/src/main/java/org/apache/sqoop/model/ModelError.java +++ b/common/src/main/java/org/apache/sqoop/model/ModelError.java @@ -52,7 +52,9 @@ public enum ModelError implements ErrorCode { MODEL_014("Form name attribute cannot be more than 30 characters long"), - MODEL_015("Can't get value from object") + MODEL_015("Can't get value from object"), + + MODEL_016("Can't instantiate class"), ; diff --git a/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java b/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java index 2a7281a3..64ffdd10 100644 --- a/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java +++ b/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java @@ -111,6 +111,15 @@ public void testFillValues() { assertEquals("value", config.aConfig.a1); } + public void testFromConfigWithClass() { + List configs = getConfigs(); + + ((MStringInput)configs.get(0).getInputs().get(0)).setValue("value"); + + TestConfiguration config = (TestConfiguration) ConfigUtils.fromConfigs(configs, TestConfiguration.class); + assertEquals("value", config.aConfig.a1); + } + public void testFillValuesObjectReuse() { List configs = getConfigs(); diff --git a/core/src/main/java/org/apache/sqoop/repository/Repository.java b/core/src/main/java/org/apache/sqoop/repository/Repository.java index bd2a3bea..fcee48bb 100644 --- a/core/src/main/java/org/apache/sqoop/repository/Repository.java +++ b/core/src/main/java/org/apache/sqoop/repository/Repository.java @@ -21,7 +21,9 @@ import java.util.List; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import org.apache.sqoop.common.Direction; import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.connector.ConnectorManager; import org.apache.sqoop.connector.spi.ConnectorConfigurableUpgrader; @@ -41,9 +43,8 @@ import org.apache.sqoop.model.MPersistableEntity; import org.apache.sqoop.model.MSubmission; import org.apache.sqoop.model.MToConfig; -import org.apache.sqoop.utils.ClassUtils; -import org.apache.sqoop.validation.ConfigValidator; -import org.apache.sqoop.validation.Validator; +import org.apache.sqoop.validation.ConfigValidationResult; +import org.apache.sqoop.validation.Message; /** @@ -402,7 +403,6 @@ public final void upgradeConnector(MConnector oldConnector, MConnector newConnec SqoopConnector connector = ConnectorManager.getInstance().getSqoopConnector( newConnector.getUniqueName()); - Validator connectorConfigValidator = connector.getConfigValidator(); boolean upgradeSuccessful = true; // 1. Get an upgrader for the connector ConnectorConfigurableUpgrader upgrader = connector.getConfigurableUpgrader(); @@ -430,19 +430,17 @@ public final void upgradeConnector(MConnector oldConnector, MConnector newConnec upgrader.upgradeLinkConfig(oldLinkConfig, newLinkConfig); MLink newlink = new MLink(link, newLinkConfig); - Object newConfigurationObject = ClassUtils.instantiate(connector - .getLinkConfigurationClass()); - ConfigUtils.fromConfigs(newlink.getConnectorLinkConfig().getConfigs(), - newConfigurationObject); // 7. Run link config validation - ConfigValidator configValidator = connectorConfigValidator - .validateConfigForLink(newConfigurationObject); - if (configValidator.getStatus().canProceed()) { + ConfigValidationResult validationResult = ConfigUtils.validateConfigs( + newlink.getConnectorLinkConfig().getConfigs(), + connector.getLinkConfigurationClass() + ); + if (validationResult.getStatus().canProceed()) { updateLink(newlink, tx); } else { // If any invalid links or jobs detected, throw an exception // and stop the bootup of Sqoop server - logInvalidModelObject("link", newlink, configValidator); + logInvalidModelObject("link", newlink, validationResult); upgradeSuccessful = false; } } @@ -461,10 +459,20 @@ public final void upgradeConnector(MConnector oldConnector, MConnector newConnec // create a job with new FROM direction configs but old TO direction // configs MJob newJob = new MJob(job, newFromConfig, oldToConfig, job.getDriverConfig()); - // TODO( jarcec) : will add the job config validation logic similar - // to the link config validation before updating job - updateJob(newJob, tx); + + ConfigValidationResult validationResult = ConfigUtils.validateConfigs( + newJob.getFromJobConfig().getConfigs(), + connector.getJobConfigurationClass(Direction.FROM) + ); + + if(validationResult.getStatus().canProceed()) { + updateJob(newJob, tx); + } else { + logInvalidModelObject("job", newJob, validationResult); + upgradeSuccessful = false; + } } + List toConfig = newConnector.getToConfig().clone(false).getConfigs(); if (job.getToConnectorId() == newConnector.getPersistenceId()) { MToConfig oldToConfig = job.getToJobConfig(); @@ -474,9 +482,18 @@ public final void upgradeConnector(MConnector oldConnector, MConnector newConnec // create a job with old FROM direction configs but new TO direction // configs MJob newJob = new MJob(job, oldFromConfig, newToConfig, job.getDriverConfig()); - // TODO( jarcec) : will add the job config validation logic similar - // to the link config validation before updating job - updateJob(newJob, tx); + + ConfigValidationResult validationResult = ConfigUtils.validateConfigs( + newJob.getToJobConfig().getConfigs(), + connector.getJobConfigurationClass(Direction.TO) + ); + + if(validationResult.getStatus().canProceed()) { + updateJob(newJob, tx); + } else { + logInvalidModelObject("job", newJob, validationResult); + upgradeSuccessful = false; + } } } } @@ -512,7 +529,6 @@ public final void upgradeDriver(MDriver driver) { DriverUpgrader upgrader = Driver.getInstance().getConfigurableUpgrader(); //2. find all jobs in the system List existingJobs = findJobs(); - Validator validator = Driver.getInstance().getValidator(); boolean upgradeSuccessful = true; // -- BEGIN TXN -- @@ -533,16 +549,16 @@ public final void upgradeDriver(MDriver driver) { // create a new job with old FROM and TO configs but new driver configs MJob newJob = new MJob(job, job.getFromJobConfig(), job.getToJobConfig(), newDriver.getDriverConfig()); - Object newConfigurationObject = ClassUtils.instantiate(Driver.getInstance().getDriverJobConfigurationClass()); - ConfigUtils.fromConfigs(newJob.getDriverConfig().getConfigs(), newConfigurationObject); - // 5. validate configs - ConfigValidator validation = validator.validateConfigForJob(newConfigurationObject); - if (validation.getStatus().canProceed()) { + ConfigValidationResult validationResult = ConfigUtils.validateConfigs( + newJob.getDriverConfig().getConfigs(), + Driver.getInstance().getDriverJobConfigurationClass() + ); + if (validationResult.getStatus().canProceed()) { // 6. update job updateJob(newJob, tx); } else { - logInvalidModelObject("job", newJob, validation); + logInvalidModelObject("job", newJob, validationResult); upgradeSuccessful = false; } } @@ -570,11 +586,12 @@ public final void upgradeDriver(MDriver driver) { } } - private void logInvalidModelObject(String objectType, MPersistableEntity entity, ConfigValidator validation) { - LOG.error("Upgrader created invalid " + objectType + " with id" + entity.getPersistenceId()); + private void logInvalidModelObject(String objectType, MPersistableEntity entity, ConfigValidationResult validation) { + LOG.error("Upgrader created invalid " + objectType + " with id " + entity.getPersistenceId()); + LOG.error("Validation errors:"); - for(Map.Entry entry : validation.getMessages().entrySet()) { - LOG.error("\t" + entry.getKey() + ": " + entry.getValue()); + for(Map.Entry> entry : validation.getMessages().entrySet()) { + LOG.error("\t" + entry.getKey() + ": " + StringUtils.join(entry.getValue(), ",")); } } } \ No newline at end of file diff --git a/core/src/test/java/org/apache/sqoop/repository/TestJdbcRepository.java b/core/src/test/java/org/apache/sqoop/repository/TestJdbcRepository.java index e11fd102..a1e734ea 100644 --- a/core/src/test/java/org/apache/sqoop/repository/TestJdbcRepository.java +++ b/core/src/test/java/org/apache/sqoop/repository/TestJdbcRepository.java @@ -21,7 +21,6 @@ import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -43,6 +42,7 @@ import org.apache.sqoop.common.Direction; import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.connector.ConnectorManager; +import org.apache.sqoop.connector.common.EmptyConfiguration; import org.apache.sqoop.connector.spi.ConnectorConfigurableUpgrader; import org.apache.sqoop.connector.spi.SqoopConnector; import org.apache.sqoop.driver.Driver; @@ -59,9 +59,9 @@ import org.apache.sqoop.model.MLink; import org.apache.sqoop.model.MLinkConfig; import org.apache.sqoop.model.MToConfig; -import org.apache.sqoop.validation.ConfigValidator; +import org.apache.sqoop.model.Validator; import org.apache.sqoop.validation.Status; -import org.apache.sqoop.validation.Validator; +import org.apache.sqoop.validation.validators.AbstractValidator; import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; @@ -73,20 +73,15 @@ public class TestJdbcRepository { private ConnectorManager connectorMgrMock; private Driver driverMock; private JdbcRepositoryHandler repoHandlerMock; - private Validator validatorMock; private ConnectorConfigurableUpgrader connectorUpgraderMock; private DriverUpgrader driverUpgraderMock; - private ConfigValidator validRepoMock; - private ConfigValidator invalidRepoMock; - @Before public void setUp() throws Exception { repoTransactionMock = mock(JdbcRepositoryTransaction.class); connectorMgrMock = mock(ConnectorManager.class); driverMock = mock(Driver.class); repoHandlerMock = mock(JdbcRepositoryHandler.class); - validatorMock = mock(Validator.class); connectorUpgraderMock = mock(ConnectorConfigurableUpgrader.class); driverUpgraderMock = mock(DriverUpgrader.class); repoSpy = spy(new JdbcRepository(repoHandlerMock, null)); @@ -96,11 +91,6 @@ public void setUp() throws Exception { ConnectorManager.setInstance(connectorMgrMock); Driver.setInstance(driverMock); - validRepoMock = mock(ConfigValidator.class); - when(validRepoMock.getStatus()).thenReturn(Status.ACCEPTABLE); - invalidRepoMock = mock(ConfigValidator.class); - when(invalidRepoMock.getStatus()).thenReturn(Status.UNACCEPTABLE); - doNothing().when(connectorUpgraderMock).upgradeLinkConfig(any(MLinkConfig.class), any(MLinkConfig.class)); doNothing().when(connectorUpgraderMock).upgradeFromJobConfig(any(MFromConfig.class), @@ -223,13 +213,9 @@ public void testConnectorConfigUpgradeWithValidLinksAndJobs() { // prepare the sqoop connector SqoopConnector sqconnector = mock(SqoopConnector.class); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(validRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(validRepoMock); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); - when(sqconnector.getLinkConfigurationClass()).thenReturn(EmptyLinkConfiguration.class); - when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn( - EmptyJobConfiguration.class); + when(sqconnector.getLinkConfigurationClass()).thenReturn(EmptyConfiguration.class); + when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn(EmptyConfiguration.class); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); // prepare the links and jobs @@ -249,7 +235,6 @@ public void testConnectorConfigUpgradeWithValidLinksAndJobs() { InOrder repoOrder = inOrder(repoSpy); InOrder txOrder = inOrder(repoTransactionMock); InOrder upgraderOrder = inOrder(connectorUpgraderMock); - InOrder validatorOrder = inOrder(validatorMock); repoOrder.verify(repoSpy, times(1)).findLinksForConnector(anyLong()); repoOrder.verify(repoSpy, times(1)).findJobsForConnector(anyLong()); @@ -272,9 +257,6 @@ public void testConnectorConfigUpgradeWithValidLinksAndJobs() { upgraderOrder.verify(connectorUpgraderMock, times(1)).upgradeFromJobConfig(any(MFromConfig.class), any(MFromConfig.class)); upgraderOrder.verify(connectorUpgraderMock, times(1)).upgradeToJobConfig(any(MToConfig.class), any(MToConfig.class)); upgraderOrder.verifyNoMoreInteractions(); - validatorOrder.verify(validatorMock, times(2)).validateConfigForLink(anyObject()); - validatorOrder.verify(validatorMock, times(0)).validateConfigForJob(anyObject()); - validatorOrder.verifyNoMoreInteractions(); } /** @@ -285,11 +267,8 @@ public void testConnectorConfigUpgradeWithValidLinksAndJobs() { public void testDriverConfigUpgradeWithValidJobs() { MDriver newDriverConfig = driver(); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(validRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(validRepoMock); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); - when(driverMock.getDriverJobConfigurationClass()).thenReturn(EmptyJobConfiguration.class); + when(driverMock.getDriverJobConfigurationClass()).thenReturn(ValidConfiguration.class); List jobList = jobs(job(1,1,1,1,1), job(2,1,1,2,1)); doReturn(jobList).when(repoSpy).findJobs(); @@ -302,7 +281,6 @@ public void testDriverConfigUpgradeWithValidJobs() { InOrder repoOrder = inOrder(repoSpy); InOrder txOrder = inOrder(repoTransactionMock); InOrder upgraderOrder = inOrder(driverUpgraderMock); - InOrder validatorOrder = inOrder(validatorMock); repoOrder.verify(repoSpy, times(1)).findJobs(); repoOrder.verify(repoSpy, times(1)).getTransaction(); @@ -317,8 +295,6 @@ public void testDriverConfigUpgradeWithValidJobs() { txOrder.verifyNoMoreInteractions(); upgraderOrder.verify(driverUpgraderMock, times(2)).upgradeJobConfig(any(MDriverConfig.class), any(MDriverConfig.class)); upgraderOrder.verifyNoMoreInteractions(); - validatorOrder.verify(validatorMock, times(2)).validateConfigForJob(anyObject()); - validatorOrder.verifyNoMoreInteractions(); } /** @@ -329,11 +305,8 @@ public void testDriverConfigUpgradeWithValidJobs() { public void testDriverConfigUpgradeWithInvalidJobs() { MDriver newDriverConfig = driver(); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(invalidRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(invalidRepoMock); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); - when(driverMock.getDriverJobConfigurationClass()).thenReturn(EmptyJobConfiguration.class); + when(driverMock.getDriverJobConfigurationClass()).thenReturn(InvalidConfiguration.class); List jobList = jobs(job(1,1,1,1,1), job(2,1,1,2,1)); doReturn(jobList).when(repoSpy).findJobs(); @@ -348,7 +321,6 @@ public void testDriverConfigUpgradeWithInvalidJobs() { InOrder repoOrder = inOrder(repoSpy); InOrder txOrder = inOrder(repoTransactionMock); InOrder upgraderOrder = inOrder(driverUpgraderMock); - InOrder validatorOrder = inOrder(validatorMock); repoOrder.verify(repoSpy, times(1)).findJobs(); repoOrder.verify(repoSpy, times(1)).getTransaction(); @@ -362,9 +334,6 @@ public void testDriverConfigUpgradeWithInvalidJobs() { txOrder.verifyNoMoreInteractions(); upgraderOrder.verify(driverUpgraderMock, times(2)).upgradeJobConfig(any(MDriverConfig.class), any(MDriverConfig.class)); upgraderOrder.verifyNoMoreInteractions(); - // driver configs are per job. - validatorOrder.verify(validatorMock, times(2)).validateConfigForJob(anyObject()); - validatorOrder.verifyNoMoreInteractions(); return ; } @@ -381,7 +350,6 @@ public void testConnectorConfigUpgradeHandlerWithFindLinksForConnectorError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); @@ -411,7 +379,6 @@ public void testConnectorConfigUpgradeHandlerWithFindJobsForConnectorError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); @@ -445,7 +412,6 @@ public void testConnectorConfigUpgradeHandlerWithDeleteJobInputsError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); @@ -482,7 +448,6 @@ public void testConnectorConfigUpgradeHandlerWithDeleteLinkInputsError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); @@ -521,7 +486,6 @@ public void testConnectorConfigUpgradeHandlerWithUpdateConnectorError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); @@ -562,12 +526,9 @@ public void testConnectorConfigUpgradeHandlerWithUpdateLinkError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(validRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(validRepoMock); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); - when(sqconnector.getLinkConfigurationClass()).thenReturn(EmptyLinkConfiguration.class); - when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn(EmptyJobConfiguration.class); + when(sqconnector.getLinkConfigurationClass()).thenReturn(ValidConfiguration.class); + when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn(ValidConfiguration.class); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); List linkList = links(link(1,1), link(2,1)); @@ -611,12 +572,9 @@ public void testConnectorConfigUpgradeHandlerWithUpdateJobError() { MConnector oldConnector = connector(1); SqoopConnector sqconnector = mock(SqoopConnector.class); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(validRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(validRepoMock); - when(sqconnector.getConfigValidator()).thenReturn(validatorMock); when(sqconnector.getConfigurableUpgrader()).thenReturn(connectorUpgraderMock); - when(sqconnector.getLinkConfigurationClass()).thenReturn(EmptyLinkConfiguration.class); - when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn(EmptyJobConfiguration.class); + when(sqconnector.getLinkConfigurationClass()).thenReturn(ValidConfiguration.class); + when(sqconnector.getJobConfigurationClass(any(Direction.class))).thenReturn(ValidConfiguration.class); when(connectorMgrMock.getSqoopConnector(anyString())).thenReturn(sqconnector); List linkList = links(link(1,1), link(2,1)); @@ -662,7 +620,6 @@ public void testConnectorConfigUpgradeHandlerWithUpdateJobError() { public void testDriverConfigUpgradeHandlerWithFindJobsError() { MDriver newDriverConfig = driver(); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); SqoopException exception = new SqoopException(RepositoryError.JDBCREPO_0000, @@ -689,7 +646,6 @@ public void testDriverConfigUpgradeHandlerWithFindJobsError() { public void testDriverConfigUpgradeHandlerWithDeleteJobInputsError() { MDriver newDriverConfig = driver(); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); List jobList = jobs(job(1,1,1,1,1), job(2,1,1,2,1)); @@ -720,7 +676,6 @@ public void testDriverConfigUpgradeHandlerWithDeleteJobInputsError() { public void testDriverConfigUpgradeHandlerWithUpdateDriverConfigError() { MDriver newDriverConfig = driver(); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); List jobList = jobs(job(1,1,1,1,1), job(2,1,1,2,1)); @@ -755,11 +710,8 @@ public void testDriverConfigUpgradeHandlerWithUpdateDriverConfigError() { public void testDriverConfigUpgradeHandlerWithUpdateJobError() { MDriver driverConfig = driver(); - when(validatorMock.validateConfigForLink(any(MLink.class))).thenReturn(validRepoMock); - when(validatorMock.validateConfigForJob(any(MJob.class))).thenReturn(validRepoMock); - when(driverMock.getValidator()).thenReturn(validatorMock); when(driverMock.getConfigurableUpgrader()).thenReturn(driverUpgraderMock); - when(driverMock.getDriverJobConfigurationClass()).thenReturn(EmptyJobConfiguration.class); + when(driverMock.getDriverJobConfigurationClass()).thenReturn(ValidConfiguration.class); List jobList = jobs(job(1,1,1,1,1), job(2,1,1,2,1)); doReturn(jobList).when(repoHandlerMock).findJobs(any(Connection.class)); doNothing().when(repoHandlerMock).deleteJobInputs(anyLong(), any(Connection.class)); @@ -789,8 +741,8 @@ public void testDriverConfigUpgradeHandlerWithUpdateJobError() { private MConnector connector(long connectorId, String version) { MConnector connector = new MConnector("A" + connectorId, "A" + connectorId, version + connectorId, new MLinkConfig(new LinkedList()), - new MFromConfig(ConfigUtils.toConfigs(EmptyJobConfiguration.class)), - new MToConfig(ConfigUtils.toConfigs(EmptyJobConfiguration.class))); + new MFromConfig(ConfigUtils.toConfigs(ValidConfiguration.class)), + new MToConfig(ConfigUtils.toConfigs(ValidConfiguration.class))); connector.setPersistenceId(connectorId); return connector; } @@ -840,9 +792,16 @@ private List jobs(MJob ... js) { } @ConfigurationClass - public static class EmptyLinkConfiguration { + public static class ValidConfiguration { } - @ConfigurationClass - public static class EmptyJobConfiguration { + + @ConfigurationClass(validators = { @Validator(InvalidConfiguration.InternalValidator.class)}) + public static class InvalidConfiguration { + public static class InternalValidator extends AbstractValidator { + @Override + public void validate(Object instance) { + addMessage(Status.UNACCEPTABLE, "Simply because."); + } + } } } \ No newline at end of file diff --git a/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java b/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java index 61b16103..fdb7c26c 100644 --- a/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java +++ b/server/src/main/java/org/apache/sqoop/handler/JobRequestHandler.java @@ -191,27 +191,24 @@ private JsonBean createUpdateJob(RequestContext ctx, boolean update) { + " does not support TO direction."); } - // We need translate configs - Object fromConfigObject = ClassUtils.instantiate(fromConnector.getJobConfigurationClass(Direction.FROM)); - Object toConfigObject = ClassUtils.instantiate(toConnector.getJobConfigurationClass(Direction.TO)); + // Validate user supplied data + ConfigValidationResult fromConfigValidator = ConfigUtils.validateConfigs( + job.getJobConfig(Direction.FROM).getConfigs(), + fromConnector.getJobConfigurationClass(Direction.FROM) + ); + ConfigValidationResult toConfigValidator = ConfigUtils.validateConfigs( + job.getJobConfig(Direction.TO).getConfigs(), + toConnector.getJobConfigurationClass(Direction.TO) + ); + ConfigValidationResult driverConfigValidator = ConfigUtils.validateConfigs( + job.getDriverConfig().getConfigs(), + Driver.getInstance().getDriverJobConfigurationClass() + ); - Object driverConfigObject = ClassUtils.instantiate(Driver.getInstance().getDriverJobConfigurationClass()); - - ConfigUtils.fromConfigs(job.getJobConfig(Direction.FROM).getConfigs(), fromConfigObject); - ConfigUtils.fromConfigs(job.getJobConfig(Direction.TO).getConfigs(), toConfigObject); - ConfigUtils.fromConfigs(job.getDriverConfig().getConfigs(), driverConfigObject); - - // Validate all configs - ConfigValidationRunner validationRunner = new ConfigValidationRunner(); - ConfigValidationResult fromConfigvalidator = validationRunner.validate(fromConfigObject); - ConfigValidationResult toConfigValidator = validationRunner.validate(toConfigObject); - ConfigValidationResult driverConfigValidator = validationRunner.validate(driverConfigObject); - - - Status finalStatus = Status.getWorstStatus(fromConfigvalidator.getStatus(), toConfigValidator.getStatus(), driverConfigValidator.getStatus()); + Status finalStatus = Status.getWorstStatus(fromConfigValidator.getStatus(), toConfigValidator.getStatus(), driverConfigValidator.getStatus()); // Return back validations in all cases - ValidationResultBean validationResultBean = new ValidationResultBean(fromConfigvalidator, toConfigValidator); + ValidationResultBean validationResultBean = new ValidationResultBean(fromConfigValidator, toConfigValidator); // If we're good enough let's perform the action if(finalStatus.canProceed()) { diff --git a/server/src/main/java/org/apache/sqoop/handler/LinkRequestHandler.java b/server/src/main/java/org/apache/sqoop/handler/LinkRequestHandler.java index b715ad37..823426a5 100644 --- a/server/src/main/java/org/apache/sqoop/handler/LinkRequestHandler.java +++ b/server/src/main/java/org/apache/sqoop/handler/LinkRequestHandler.java @@ -168,22 +168,17 @@ private JsonBean createUpdateLink(RequestContext ctx, boolean update) { // Responsible connector for this session SqoopConnector connector = ConnectorManager.getInstance().getSqoopConnector(link.getConnectorId()); - // We need translate configs - Object connectorLinkConfig = ClassUtils.instantiate(connector.getLinkConfigurationClass()); - - ConfigUtils.fromConfigs(link.getConnectorLinkConfig().getConfigs(), connectorLinkConfig); - - // Validate both parts - ConfigValidationRunner validationRunner = new ConfigValidationRunner(); - ConfigValidationResult connectorLinkValidation = validationRunner.validate(connectorLinkConfig); - - Status finalStatus = Status.getWorstStatus(connectorLinkValidation.getStatus()); + // Validate user supplied data + ConfigValidationResult connectorLinkValidation = ConfigUtils.validateConfigs( + link.getConnectorLinkConfig().getConfigs(), + connector.getLinkConfigurationClass() + ); // Return back validations in all cases ValidationResultBean outputBean = new ValidationResultBean(connectorLinkValidation); // If we're good enough let's perform the action - if(finalStatus.canProceed()) { + if(connectorLinkValidation.getStatus().canProceed()) { if(update) { AuditLoggerManager.getInstance() .logAuditEvent(ctx.getUserName(), ctx.getRequest().getRemoteAddr(),