diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java index 6dc51ec..dbaf482 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java @@ -33,6 +33,7 @@ import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.io.nativeio.NativeIO; import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.registry.client.api.RegistryConstants; import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.ExitUtil; @@ -378,7 +379,8 @@ public static File requiredFile(String filename, String role) throws * @return true iff it is valid */ public static boolean isClusternameValid(String name) { - return name != null && clusternamePattern.matches(name); + return name != null && name.length() <= RegistryConstants + .MAX_FQDN_LABEL_LENGTH && clusternamePattern.matches(name); } public static boolean oldIsClusternameValid(String name) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/RestApiErrorMessages.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/RestApiErrorMessages.java index 676db82..09c5668 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/RestApiErrorMessages.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/RestApiErrorMessages.java @@ -21,8 +21,13 @@ String ERROR_APPLICATION_NAME_INVALID = "Application name is either empty or not provided"; String ERROR_APPLICATION_NAME_INVALID_FORMAT = - "Application name %s is not valid - only lower case letters, digits," - + " underscore and hyphen are allowed"; + "Application name %s is not valid - only lower case letters, digits, " + + "underscore and hyphen are allowed, and the name must be no more " + + "than 63 characters"; + String ERROR_COMPONENT_NAME_INVALID = + "Component name must be no more than 63 characters: %s"; + String ERROR_USER_NAME_INVALID = + "User name must be no more than 63 characters"; String ERROR_APPLICATION_NOT_RUNNING = "Application not running"; String ERROR_APPLICATION_DOES_NOT_EXIST = "Application not found"; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/ServiceApiUtil.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/ServiceApiUtil.java index 80a31c0..b73600d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/ServiceApiUtil.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/util/ServiceApiUtil.java @@ -22,6 +22,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.registry.client.api.RegistryConstants; +import org.apache.hadoop.registry.client.binding.RegistryUtils; import org.apache.slider.api.resource.Application; import org.apache.slider.api.resource.Artifact; import org.apache.slider.api.resource.Component; @@ -57,6 +59,11 @@ public static void setJsonSerDeser(JsonSerDeser jsd) { @VisibleForTesting public static void validateAndResolveApplication(Application application, SliderFileSystem fs) throws IOException { + if (RegistryUtils.currentUser().length() > RegistryConstants + .MAX_FQDN_LABEL_LENGTH) { + throw new IllegalArgumentException(RestApiErrorMessages + .ERROR_USER_NAME_INVALID); + } if (StringUtils.isEmpty(application.getName())) { throw new IllegalArgumentException( RestApiErrorMessages.ERROR_APPLICATION_NAME_INVALID); @@ -104,6 +111,10 @@ public static void validateAndResolveApplication(Application application, List componentsToRemove = new ArrayList<>(); List componentsToAdd = new ArrayList<>(); for (Component comp : application.getComponents()) { + if (comp.getName().length() > RegistryConstants.MAX_FQDN_LABEL_LENGTH) { + throw new IllegalArgumentException(String.format(RestApiErrorMessages + .ERROR_COMPONENT_NAME_INVALID, comp.getName())); + } if (componentNames.contains(comp.getName())) { throw new IllegalArgumentException("Component name collision: " + comp.getName()); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/java/org/apache/slider/utils/TestServiceApiUtil.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/java/org/apache/slider/utils/TestServiceApiUtil.java index 9ca3242..1c108bf 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/java/org/apache/slider/utils/TestServiceApiUtil.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/test/java/org/apache/slider/utils/TestServiceApiUtil.java @@ -73,7 +73,8 @@ public void testResourceValidation() throws Exception { } // bad format name - String[] badNames = {"4finance", "Finance", "finance@home"}; + String[] badNames = {"4finance", "Finance", "finance@home", + "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01"}; for (String badName : badNames) { app.setName(badName); try { @@ -86,7 +87,8 @@ public void testResourceValidation() throws Exception { } // launch command not specified - app.setName("finance_home"); + app.setName( + "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0"); try { ServiceApiUtil.validateAndResolveApplication(app, sfs); Assert.fail(EXCEPTION_PREFIX + "application with no launch command"); @@ -390,4 +392,23 @@ public void testExternalComponent() throws IOException { // original component replaced by external component assertNotNull(app.getComponent("comp1")); } + + @Test + public void testInvalidComponent() throws IOException { + SliderFileSystem sfs = initMock(null); + + String compName = + "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01"; + Application app = createValidApplication(compName); + app.addComponent(createValidComponent(compName)); + + // invalid component name fails + try { + ServiceApiUtil.validateAndResolveApplication(app, sfs); + Assert.fail(EXCEPTION_PREFIX + "application with invalid component name"); + } catch (IllegalArgumentException e) { + assertEquals(String.format(RestApiErrorMessages + .ERROR_COMPONENT_NAME_INVALID, compName), e.getMessage()); + } + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/client/api/RegistryConstants.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/client/api/RegistryConstants.java index f4fecfd..e66a761 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/client/api/RegistryConstants.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/client/api/RegistryConstants.java @@ -78,6 +78,11 @@ String KEY_DNS_DOMAIN = DNS_PREFIX + "domain-name"; /** + * Max length of a label (node delimited by a dot in the FQDN). + */ + int MAX_FQDN_LABEL_LENGTH = 63; + + /** * DNS bind address. */ String KEY_DNS_BIND_ADDRESS = DNS_PREFIX + "bind-address";