This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-validation-impl.git
commit 97830b256a117cf0855b03184b7015146485f6fb Author: Konrad Windszus <[email protected]> AuthorDate: Fri Mar 3 10:35:10 2017 +0000 SLING-6598 expose english validation error in InvalidResourceException also add an IT relying on Teleporters git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1785260 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 103 +++++++++++++++++++- .../validation/InvalidResourceException.java | 16 +-- .../validation/impl/it/ModelValidationIT.java | 107 +++++++++++++++++++++ .../it/ResourceType1ModelValidationRequired.java | 26 +++++ src/test/provisioning/model.txt | 45 +++++++++ .../apps/sling/validation/content.json | 3 + .../sling/validation/content/contentInvalid.json | 6 ++ .../sling/validation/content/contentValid.json | 6 ++ .../apps/sling/validation/models.json | 3 + .../apps/sling/validation/models/model1.json | 22 +++++ 10 files changed, 324 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 0e105ce..6619201 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ <properties> <sling.java.version>8</sling.java.version> + <http.host>localhost</http.host> </properties> <scm> @@ -52,6 +53,100 @@ <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> </plugin> + <plugin> + <!-- Find free ports to run our server --> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>reserve-server-port</id> + <goals> + <goal>reserve-network-port</goal> + </goals> + <phase>pre-integration-test</phase> + <configuration> + <portNames> + <!-- used port name must be stored in property because it must be used for the base url --> + <portName>http.port</portName> + </portNames> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <!-- the Sling instance is provisioned from the model in src/main/provisioning/model.txt --> + <groupId>org.apache.sling</groupId> + <artifactId>slingstart-maven-plugin</artifactId> + <version>1.7.2</version> + <extensions>true</extensions> + <executions> + <execution> + <id>prepare-launchpad-package</id> + <goals> + <goal>prepare-package</goal> + </goals> + <phase>pre-integration-test</phase> + </execution> + <execution> + <id>build-launchpad-package</id> + <goals> + <goal>package</goal> + </goals> + <phase>pre-integration-test</phase> + </execution> + <execution> + <id>start-container-before-IT</id> + <goals> + <goal>start</goal> + </goals> + <configuration> + </configuration> + </execution> + <execution> + <id>stop-container-after-IT</id> + <goals> + <goal>stop</goal> + </goals> + <configuration> + <shouldBlockUntilKeyIsPressed>true</shouldBlockUntilKeyIsPressed> + </configuration> + </execution> + </executions> + <configuration> + <servers> + <server> + <id>singleinstance</id> + <port>${http.port}</port> + <vmOpts>${sling.vm.options}</vmOpts> + <stdOutFile>sling/logs/stdout.log</stdOutFile> + </server> + </servers> + <disableExtendingMavenClasspath>true</disableExtendingMavenClasspath> + <keepLaunchpadRunning>false</keepLaunchpadRunning> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + <configuration> + <systemPropertyVariables> + <ClientSideTeleporter.baseUrl>http://${http.host}:${http.port}/</ClientSideTeleporter.baseUrl> + <ClientSideTeleporter.testReadyTimeoutSeconds>20</ClientSideTeleporter.testReadyTimeoutSeconds> + <ClientSideTeleporter.testBundleDirectory>${project.build.directory}/test-bundles</ClientSideTeleporter.testBundleDirectory> + <ClientSideTeleporter.enableLogging>true</ClientSideTeleporter.enableLogging> + <ClientSideTeleporter.additionalBundleHeaders>Sling-Initial-Content:SLING-CONTENT;overwrite:=true,Sling-Model-Packages:org.apache.sling.models.validation.impl.it</ClientSideTeleporter.additionalBundleHeaders> + <ClientSideTeleporter.includeDependencyPrefixes>org.apache.sling.models.validation.impl.it</ClientSideTeleporter.includeDependencyPrefixes> + </systemPropertyVariables> + </configuration> + </plugin> </plugins> </build> <dependencies> @@ -74,7 +169,7 @@ <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> - <version>2.2.0</version> + <version>2.5.0</version> <scope>provided</scope> </dependency> <dependency> @@ -109,5 +204,11 @@ <artifactId>slf4j-simple</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.junit.teleporter</artifactId> + <version>1.0.12</version> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/src/main/java/org/apache/sling/models/validation/InvalidResourceException.java b/src/main/java/org/apache/sling/models/validation/InvalidResourceException.java index 352d0f4..796bad8 100644 --- a/src/main/java/org/apache/sling/models/validation/InvalidResourceException.java +++ b/src/main/java/org/apache/sling/models/validation/InvalidResourceException.java @@ -16,10 +16,6 @@ */ package org.apache.sling.models.validation; -import java.util.ResourceBundle; - -import javax.annotation.Nonnull; - import org.apache.sling.models.factory.InvalidModelException; import org.apache.sling.validation.ValidationFailure; import org.apache.sling.validation.ValidationResult; @@ -42,6 +38,7 @@ public class InvalidResourceException extends InvalidModelException { this.result = result; this.path = path; } + /** * * @return the underlying {@link ValidationResult} @@ -57,17 +54,12 @@ public class InvalidResourceException extends InvalidModelException { public String getPath() { return path; } - - /** - * This is not the regular {@link Exception#getMessage()} as it requires an additional resourceBundle parameter to look up the localized message. - * @param resourceBundle - * @return the localized validation messages bound to the {@link ValidationResult} wrapped by this exception - */ - public String getMessage(@Nonnull ResourceBundle resourceBundle) { + + public String getMessage() { StringBuilder builder = new StringBuilder("Validation errors for "); builder.append("'" + path +"':"); for (ValidationFailure failure : result.getFailures()) { - builder.append("\n" + failure.getLocation() + ":" + failure.getMessage(resourceBundle) + "\n\t"); + builder.append("\n" + failure.getLocation() + ":" + failure.getMessage(null) + "\n\t"); } return builder.toString(); } diff --git a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java b/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java new file mode 100644 index 0000000..124c21a --- /dev/null +++ b/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.sling.models.validation.impl.it; + +import java.io.IOException; + +import org.apache.sling.api.resource.LoginException; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.commons.json.JSONException; +import org.apache.sling.junit.rules.TeleporterRule; +import org.apache.sling.models.factory.ModelFactory; +import org.apache.sling.models.validation.InvalidResourceException; +import org.apache.sling.validation.ValidationService; +import org.apache.sling.validation.model.ValidationModel; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +/** These tests leverage the {@link ValidationPostOperation} to validate the given request parameters. The according validation model + * enforces the properties "field1" matching regex=^\\\p{Upper}$ and "field2" (having an arbitrary value). */ +public class ModelValidationIT { + + @Rule + public final TeleporterRule teleporter = TeleporterRule.forClass(getClass()).withResources("/SLING-CONTENT/"); + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + private ValidationService validationService; + + private ValidationModel validationModel; + + private ModelFactory modelFactory; + + private ResourceResolverFactory resourceResolverFactory; + + private ResourceResolver resourceResolver = null; + + private static final int MODEL_AVAILABLE_TIMEOUT_SECONDS = Integer.getInteger("ValidationServiceIT.ModelAvailabelTimeoutSeconds", 10); + + @Before + public void setUp() throws InterruptedException, LoginException { + validationService = teleporter.getService(ValidationService.class); + + long timeoutMs = System.currentTimeMillis() + MODEL_AVAILABLE_TIMEOUT_SECONDS * 1000l; + // wait for the model to become available (internally relies on search, is therefore asynchronous) + do { + validationModel = validationService.getValidationModel("validation/test/resourceType1", + "/validation/testing/fakeFolder1/resource", false); + if (validationModel == null) { + Thread.sleep(500); + } + } while (validationModel == null && System.currentTimeMillis() < timeoutMs); + Assert.assertNotNull("Could not get validation model for resource type 'validation/test/resourceType1' within " + + MODEL_AVAILABLE_TIMEOUT_SECONDS + " seconds", validationModel); + modelFactory = teleporter.getService(ModelFactory.class); + resourceResolverFactory = teleporter.getService(ResourceResolverFactory.class); + resourceResolver = resourceResolverFactory.getServiceResourceResolver(null); + } + + @After + public void tearDown() { + if (resourceResolver != null) { + resourceResolver.close(); + } + } + + @Test + public void testValidModel() throws IOException, JSONException { + // create a valid resource + Resource contentResource = resourceResolver.getResource("/apps/sling/validation/content/contentValid"); + Assert.assertNotNull("Content resource must exist", contentResource); + // generate a model + ResourceType1ModelValidationRequired model = modelFactory.createModel(contentResource, ResourceType1ModelValidationRequired.class); + Assert.assertNotNull("model must have been created", model); + } + + @Test + public void testInvalidModel() throws IOException, JSONException { + // create a valid resource + Resource contentResource = resourceResolver.getResource("/apps/sling/validation/content/contentInvalid"); + Assert.assertNotNull("Content resource must exist", contentResource); + expectedEx.expect(InvalidResourceException.class); + expectedEx.expectMessage("Validation errors for '/apps/sling/validation/content/contentInvalid':\nfield1:Property does not match the pattern \"^\\p{Upper}+$\""); + // generate a model + modelFactory.createModel(contentResource, ResourceType1ModelValidationRequired.class); + } +} diff --git a/src/test/java/org/apache/sling/models/validation/impl/it/ResourceType1ModelValidationRequired.java b/src/test/java/org/apache/sling/models/validation/impl/it/ResourceType1ModelValidationRequired.java new file mode 100644 index 0000000..f844c38 --- /dev/null +++ b/src/test/java/org/apache/sling/models/validation/impl/it/ResourceType1ModelValidationRequired.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.sling.models.validation.impl.it; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.ValidationStrategy; + +@Model(validation=ValidationStrategy.REQUIRED, adaptables = { Resource.class }) +public class ResourceType1ModelValidationRequired { + +} diff --git a/src/test/provisioning/model.txt b/src/test/provisioning/model.txt new file mode 100644 index 0000000..60d480c --- /dev/null +++ b/src/test/provisioning/model.txt @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# +[feature name=models.validation-impl.it] +# Dependencies +[artifacts] + org.apache.sling/org.apache.sling.launchpad/9-SNAPSHOT/slingstart + # this is necessary to execute the tests + org.apache.sling/org.apache.sling.junit.core/1.0.23 + # deploy the validation framework + org.apache.sling/org.apache.sling.validation.api/1.0.0-SNAPSHOT + org.apache.sling/org.apache.sling.validation.core/1.0.0-SNAPSHOT + # deploy the to be tested bundle as well + org.apache.sling/org.apache.sling.models.validation-impl/1.0.0-SNAPSHOT + +[configurations] + # configure service user mapping for validation framework + org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-validation + user.mapping=[ \ + "org.apache.sling.validation.core\=sling-readall", \ + ] + + # configure service user mapping for junit core (being used in the IT itself) + org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-junit + user.mapping=[ \ + "org.apache.sling.junit.core\=sling-readall", \ + ] + +[settings] + org.apache.sling.commons.log.julenabled=true diff --git a/src/test/resources/SLING-CONTENT/apps/sling/validation/content.json b/src/test/resources/SLING-CONTENT/apps/sling/validation/content.json new file mode 100644 index 0000000..225e5ce --- /dev/null +++ b/src/test/resources/SLING-CONTENT/apps/sling/validation/content.json @@ -0,0 +1,3 @@ +{ + "jcr:primaryType" : "sling:Folder" +} diff --git a/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentInvalid.json b/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentInvalid.json new file mode 100644 index 0000000..ef99b86 --- /dev/null +++ b/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentInvalid.json @@ -0,0 +1,6 @@ +{ + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "validation/test/resourceType1", + "field1": "invalid", + "field2": "anything" +} diff --git a/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentValid.json b/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentValid.json new file mode 100644 index 0000000..6f1fb1e --- /dev/null +++ b/src/test/resources/SLING-CONTENT/apps/sling/validation/content/contentValid.json @@ -0,0 +1,6 @@ +{ + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "validation/test/resourceType1", + "field1": "HELLOWORLD", + "field2": "anything" +} diff --git a/src/test/resources/SLING-CONTENT/apps/sling/validation/models.json b/src/test/resources/SLING-CONTENT/apps/sling/validation/models.json new file mode 100644 index 0000000..225e5ce --- /dev/null +++ b/src/test/resources/SLING-CONTENT/apps/sling/validation/models.json @@ -0,0 +1,3 @@ +{ + "jcr:primaryType" : "sling:Folder" +} diff --git a/src/test/resources/SLING-CONTENT/apps/sling/validation/models/model1.json b/src/test/resources/SLING-CONTENT/apps/sling/validation/models/model1.json new file mode 100644 index 0000000..cb46377 --- /dev/null +++ b/src/test/resources/SLING-CONTENT/apps/sling/validation/models/model1.json @@ -0,0 +1,22 @@ +{ + "validatedResourceType": "validation/test/resourceType1", + "sling:resourceType": "sling/validation/model", + "properties": { + "jcr:primaryType" : "nt:unstructured", + "field1": { + "jcr:primaryType" : "nt:unstructured", + "propertyType": "string", + "validators": { + "jcr:primaryType" : "nt:unstructured", + "org.apache.sling.validation.core.RegexValidator": { + "jcr:primaryType" : "nt:unstructured", + "validatorArguments" : ["regex=^\\\p{Upper}+$"], + "severity" : "10" + } + } + }, + "field2" : { + "jcr:primaryType" : "nt:unstructured" + } + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
