Code review comment: Create application is only intended to be called before the first instance for a given application name is deployed. The instance id validation must be performed somewhere else.

Code before review:
public Application createApplication(ApplicationId id, Optional<NToken> token) {
if ( ! (id.instance().value().equals("default") || id.instance().value().matches("\\d+")))
throw new UnsupportedOperationException("Only the instance names 'default' and names which are just the PR number are supported at the moment");
try (Lock lock = lock(id)) {
com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId.validate(id.application().value());
Optional<Tenant> tenant = controller.tenants().tenant(new TenantId(id.tenant().value()));
if ( ! tenant.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': This tenant does not exist");
if (get(id).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application already exists");
if (get(dashToUnderscore(id)).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application " + dashToUnderscore(id) + " already exists");
if (tenant.get().isAthensTenant()) {
if ( ! token.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': No NToken provided");
ZmsClient zmsClient = zmsClientFactory.createZmsClientWithAuthorizedServiceToken(token.get());
try {
zmsClient.deleteApplication(tenant.get().getAthensDomain().get(),
new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
catch (ZmsException ignored) { }
zmsClient.addApplication(tenant.get().getAthensDomain().get(),
new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
LockedApplication application = new LockedApplication(new Application(id), lock);
store(application);
log.info("Created " + application);
return application;
}
}

Line under review: if ( ! (id.instance().value().equals("default") || id.instance().value().matches("\\d+")))

Code after addressing the review:
public Application createApplication(ApplicationId id, Optional<NToken> token) {
if ( ! (id.instance().isDefault() || id.instance().value().matches("\\d+")))
throw new UnsupportedOperationException("Only the instance names 'default' and names which are just the PR number are supported at the moment");
try (Lock lock = lock(id)) {
if (asList(id.tenant()).stream().noneMatch(application -> application.id().application().equals(id.application())))
com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId.validate(id.application().value());
Optional<Tenant> tenant = controller.tenants().tenant(new TenantId(id.tenant().value()));
if ( ! tenant.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': This tenant does not exist");
if (get(id).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application already exists");
if (get(dashToUnderscore(id)).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application " + dashToUnderscore(id) + " already exists");
if (id.instance().isDefault() && tenant.get().isAthensTenant()) {
if ( ! token.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': No NToken provided");
ZmsClient zmsClient = zmsClientFactory.createZmsClientWithAuthorizedServiceToken(token.get());
zmsClient.addApplication(tenant.get().getAthensDomain().get(),
new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
LockedApplication application = new LockedApplication(new Application(id), lock);
store(application);
log.info("Created " + application);
return application;
}
}