YARN-7523. Introduce description and version field in Service record. Contributed by Chandni Singh

(cherry picked from commit e1f5251f3c)
This commit is contained in:
Billie Rinaldi 2018-03-10 07:49:10 -08:00
parent 4b9eb2188b
commit 8f27c35da8
22 changed files with 108 additions and 4 deletions

View File

@ -123,8 +123,8 @@ public class ApiServer {
return null;
}
});
serviceStatus.setDiagnostics("Service "+service.getName() +
" saved.");
serviceStatus.setDiagnostics("Service " + service.getName() +
" version " + service.getVersion() + " saved.");
} else {
ApplicationId applicationId = ugi
.doAs(new PrivilegedExceptionAction<ApplicationId>() {

View File

@ -21,6 +21,8 @@ POST URL - http://localhost:9191/ws/v1/services
```json
{
"name": "hello-world",
"version": "1.0.0",
"description": "hello world example",
"components" :
[
{
@ -48,6 +50,8 @@ Note, lifetime value of -1 means unlimited lifetime.
```json
{
"name": "hello-world",
"version": "1.0.0",
"description": "hello world example",
"id": "application_1503963985568_0002",
"lifetime": -1,
"components": [
@ -154,6 +158,8 @@ POST URL - http://localhost:9191:/ws/v1/services/hbase-app-1
```json
{
"name": "hbase-app-1",
"version": "1.0.0",
"description": "hbase service",
"lifetime": "3600",
"components": [
{

View File

@ -197,10 +197,17 @@ definitions:
description: a service resource has the following attributes.
required:
- name
- version
properties:
name:
type: string
description: A unique service name. If Registry DNS is enabled, the max length is 63 characters.
version:
type: string
description: Version of the service.
description:
type: string
description: Description of the service.
id:
type: string
description: A unique service id.

View File

@ -93,6 +93,7 @@ public class TestApiServer {
public void testGoodCreateService() {
Service service = new Service();
service.setName("jenkins");
service.setVersion("v1");
Artifact artifact = new Artifact();
artifact.setType(TypeEnum.DOCKER);
artifact.setId("jenkins:latest");

View File

@ -1,5 +1,6 @@
{
"name": "example-app",
"version": "1.0.0",
"components" :
[
{

View File

@ -1,5 +1,6 @@
{
"name": "httpd-service-no-dns",
"version": "1.0.0",
"lifetime": "3600",
"components": [
{

View File

@ -1,5 +1,6 @@
{
"name": "httpd-service",
"version": "1.0.0",
"lifetime": "3600",
"components": [
{

View File

@ -1,5 +1,6 @@
{
"name": "sleeper-service",
"version": "1.0.0",
"components" :
[
{

View File

@ -47,8 +47,8 @@ import java.util.Objects;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "name", "state", "resource", "number_of_containers",
"lifetime", "containers" })
@JsonPropertyOrder({ "name", "version", "description", "state", "resource",
"number_of_containers", "lifetime", "containers" })
public class Service extends BaseResource {
private static final long serialVersionUID = -4491694636566094885L;
@ -74,6 +74,8 @@ public class Service extends BaseResource {
@JsonProperty("kerberos_principal")
@XmlElement(name = "kerberos_principal")
private KerberosPrincipal kerberosPrincipal = new KerberosPrincipal();
private String version = null;
private String description = null;
/**
* A unique service name.
@ -111,6 +113,43 @@ public class Service extends BaseResource {
this.id = id;
}
@ApiModelProperty(example = "null", required = true,
value = "Version of the service.")
@JsonProperty("version")
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
/**
* Version of the service.
*/
public Service version(String version) {
this.version = version;
return this;
}
@ApiModelProperty(example = "null", value = "Description of the service.")
@JsonProperty("description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* Description of the service.
*/
public Service description(String description) {
this.description = description;
return this;
}
/**
* Artifact of single-component services. Mandatory if components
* attribute is not specified.
@ -380,6 +419,9 @@ public class Service extends BaseResource {
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" version: ").append(toIndentedString(version)).append("\n");
sb.append(" description: ").append(toIndentedString(description))
.append("\n");
sb.append(" artifact: ").append(toIndentedString(artifact)).append("\n");
sb.append(" resource: ").append(toIndentedString(resource)).append("\n");
sb.append(" launchTime: ").append(toIndentedString(launchTime))

View File

@ -20,6 +20,8 @@ package org.apache.hadoop.yarn.service.exceptions;
public interface RestApiErrorMessages {
String ERROR_APPLICATION_NAME_INVALID =
"Service name is either empty or not provided";
String ERROR_APPLICATION_VERSION_INVALID =
"Version of service %s is either empty or not provided";
String ERROR_APPLICATION_NAME_INVALID_FORMAT =
"Service name %s is not valid - only lower case letters, digits, " +
"and hyphen are allowed, and the name must be no more " +

View File

@ -89,6 +89,12 @@ public class ServiceApiUtil {
RestApiErrorMessages.ERROR_APPLICATION_NAME_INVALID);
}
if (StringUtils.isEmpty(service.getVersion())) {
throw new IllegalArgumentException(String.format(
RestApiErrorMessages.ERROR_APPLICATION_VERSION_INVALID,
service.getName()));
}
validateNameFormat(service.getName(), conf);
// If the service has no components, throw error

View File

@ -81,6 +81,7 @@ public class ServiceTestUtils {
protected Service createExampleApplication() {
Service exampleApp = new Service();
exampleApp.setName("example-app");
exampleApp.setVersion("v1");
exampleApp.addComponent(createComponent("compa"));
exampleApp.addComponent(createComponent("compb"));
return exampleApp;

View File

@ -85,6 +85,17 @@ public class TestServiceApiUtil {
assertEquals(ERROR_APPLICATION_NAME_INVALID, e.getMessage());
}
app.setName("test");
// no version
try {
ServiceApiUtil.validateAndResolveService(app, sfs, CONF_DNS_ENABLED);
Assert.fail(EXCEPTION_PREFIX + " service with no version");
} catch (IllegalArgumentException e) {
assertEquals(String.format(ERROR_APPLICATION_VERSION_INVALID,
app.getName()), e.getMessage());
}
app.setVersion("v1");
// bad format name
String[] badNames = {"4finance", "Finance", "finance@home", LEN_64_STR};
for (String badName : badNames) {
@ -202,6 +213,7 @@ public class TestServiceApiUtil {
Service app = new Service();
app.setName("service1");
app.setVersion("v1");
Resource res = new Resource();
app.setResource(res);
res.setMemory("512M");
@ -268,6 +280,7 @@ public class TestServiceApiUtil {
private static Service createValidApplication(String compName) {
Service app = new Service();
app.setName("name");
app.setVersion("v1");
app.setResource(createValidResource());
if (compName != null) {
app.addComponent(createValidComponent(compName));

View File

@ -144,6 +144,7 @@ public class TestYarnNativeServices extends ServiceTestUtils {
ServiceClient client = createClient();
Service exampleApp = new Service();
exampleApp.setName("teststartorder");
exampleApp.setVersion("v1");
exampleApp.addComponent(createComponent("compa", 2, "sleep 1000"));
Component compb = createComponent("compb", 2, "sleep 1000");
@ -173,9 +174,12 @@ public class TestYarnNativeServices extends ServiceTestUtils {
Service userAApp = new Service();
userAApp.setName(sameAppName);
userAApp.setVersion("v1");
userAApp.addComponent(createComponent("comp", 1, "sleep 1000"));
Service userBApp = new Service();
userBApp.setName(sameAppName);
userBApp.setVersion("v1");
userBApp.addComponent(createComponent("comp", 1, "sleep 1000"));
File userABasePath = null, userBBasePath = null;
@ -221,9 +225,12 @@ public class TestYarnNativeServices extends ServiceTestUtils {
Service appA = new Service();
appA.setName(sameAppName);
appA.setVersion("v1");
appA.addComponent(createComponent("comp", 1, "sleep 1000"));
Service appB = new Service();
appB.setName(sameAppName);
appB.setVersion("v1");
appB.addComponent(createComponent("comp", 1, "sleep 1000"));
try {

View File

@ -1,5 +1,6 @@
{
"name": "example-app",
"version": "1.0.0",
"components" :
[
{

View File

@ -1,5 +1,6 @@
{
"name": "app-1",
"version": "1.0.0",
"lifetime": "3600",
"configuration": {
"properties": {

View File

@ -1,5 +1,6 @@
{
"name": "app-1",
"version": "1.0.0",
"id" : "application_1503358878042_0011",
"lifetime": "3600",
"configuration": {

View File

@ -340,6 +340,8 @@ a service resource has the following attributes.
|Name|Description|Required|Schema|Default|
|----|----|----|----|----|
|name|A unique service name. If Registry DNS is enabled, the max length is 63 characters.|true|string||
|version|Version of the service.|true|string||
|description|Description of the service.|false|string||
|id|A unique service id.|false|string||
|artifact|The default artifact for all components of the service except the components which has Artifact type set to SERVICE (optional).|false|Artifact||
|resource|The default resource for all components of the service (optional).|false|Resource||
@ -384,6 +386,8 @@ POST URL - http://localhost:8088/app/v1/services
```json
{
"name": "hello-world",
"version": "1.0.0",
"description": "hello world example",
"components" :
[
{
@ -417,6 +421,8 @@ Note, lifetime value of -1 means unlimited lifetime.
```json
{
"name": "hello-world",
"version": "1.0.0",
"description": "hello world example",
"id": "application_1503963985568_0002",
"lifetime": -1,
"components": [
@ -523,6 +529,8 @@ POST URL - http://localhost:8088:/app/v1/services/hbase-app-1
```json
{
"name": "hbase-app-1",
"version": "1.0.0",
"description": "hbase service",
"lifetime": "3600",
"components": [
{