You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by bi...@apache.org on 2019/04/13 15:57:21 UTC
[hadoop] branch trunk updated: YARN-9281. Add express upgrade
button to Appcatalog UI. Contributed by Eric Yang
This is an automated email from the ASF dual-hosted git repository.
billie pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git
The following commit(s) were added to refs/heads/trunk by this push:
new b2cdf80 YARN-9281. Add express upgrade button to Appcatalog UI. Contributed by Eric Yang
b2cdf80 is described below
commit b2cdf809bce10f680048cacf45806f0abb4f4804
Author: Billie Rinaldi <bi...@apache.org>
AuthorDate: Sat Apr 13 18:55:11 2019 +0300
YARN-9281. Add express upgrade button to Appcatalog UI. Contributed by Eric Yang
---
.../pom.xml | 1 -
.../application/AppCatalogSolrClient.java | 83 +++++++++++----
.../appcatalog/application/YarnServiceClient.java | 22 ++++
.../controller/AppDetailsController.java | 34 ++++++
.../src/main/javascript/app.js | 3 +
.../src/main/javascript/controllers.js | 54 ++++++++++
.../src/main/webapp/css/bootstrap-hadoop.css | 5 +
.../src/main/webapp/partials/details.html | 3 +-
.../src/main/webapp/partials/upgrade.html | 114 +++++++++++++++++++++
.../src/main/webapp/theme.html | 2 +-
.../application/TestAppCatalogSolrClient.java | 19 ++++
.../controller/AppDetailsControllerTest.java | 19 ++++
.../configsets/exampleCollection/conf/schema.xml | 1 +
13 files changed, 336 insertions(+), 24 deletions(-)
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/pom.xml
index 58646bc..1ca403a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/pom.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/pom.xml
@@ -487,5 +487,4 @@
</build>
</profile>
</profiles>
-
</project>
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/AppCatalogSolrClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/AppCatalogSolrClient.java
index f3532ae..b1515a5 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/AppCatalogSolrClient.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/AppCatalogSolrClient.java
@@ -291,13 +291,12 @@ public class AppCatalogSolrClient {
docs.add(request);
}
- // Commit Solr changes.
- UpdateResponse detailsResponse = solr.add(docs);
- if (detailsResponse.getStatus() != 0) {
+ try {
+ commitSolrChanges(solr, docs);
+ } catch (IOException e) {
throw new IOException("Unable to register docker instance "
- + "with application entry.");
+ + "with application entry.", e);
}
- solr.commit();
}
private SolrInputDocument incrementDownload(SolrDocument doc,
@@ -350,16 +349,10 @@ public class AppCatalogSolrClient {
buffer.setField("yarnfile_s", mapper.writeValueAsString(yarnApp));
docs.add(buffer);
- // Commit Solr changes.
- UpdateResponse detailsResponse = solr.add(docs);
- if (detailsResponse.getStatus() != 0) {
- throw new IOException("Unable to register application " +
- "in Application Store.");
- }
- solr.commit();
+ commitSolrChanges(solr, docs);
} catch (SolrServerException | IOException e) {
throw new IOException("Unable to register application " +
- "in Application Store. "+ e.getMessage());
+ "in Application Store. ", e);
}
}
@@ -389,16 +382,64 @@ public class AppCatalogSolrClient {
buffer.setField("yarnfile_s", mapper.writeValueAsString(yarnApp));
docs.add(buffer);
- // Commit Solr changes.
- UpdateResponse detailsResponse = solr.add(docs);
- if (detailsResponse.getStatus() != 0) {
- throw new IOException("Unable to register application " +
- "in Application Store.");
- }
- solr.commit();
+ commitSolrChanges(solr, docs);
} catch (SolrServerException | IOException e) {
throw new IOException("Unable to register application " +
- "in Application Store. "+ e.getMessage());
+ "in Application Store. ", e);
}
}
+
+ public void upgradeApp(Service service) throws IOException,
+ SolrServerException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ Collection<SolrInputDocument> docs = new HashSet<SolrInputDocument>();
+ SolrClient solr = getSolrClient();
+ if (service!=null) {
+ String name = service.getName();
+ String app = "";
+ SolrQuery query = new SolrQuery();
+ query.setQuery("id:" + name);
+ query.setFilterQueries("type_s:AppEntry");
+ query.setRows(1);
+
+ QueryResponse response;
+ try {
+ response = solr.query(query);
+ Iterator<SolrDocument> appList = response.getResults().listIterator();
+ while (appList.hasNext()) {
+ SolrDocument d = appList.next();
+ app = d.get("app_s").toString();
+ }
+ } catch (SolrServerException | IOException e) {
+ LOG.error("Error in finding deployed application: " + name, e);
+ }
+ // Register deployed application instance with AppList
+ SolrInputDocument request = new SolrInputDocument();
+ request.addField("type_s", "AppEntry");
+ request.addField("id", name);
+ request.addField("name_s", name);
+ request.addField("app_s", app);
+ request.addField("yarnfile_s", mapper.writeValueAsString(service));
+ docs.add(request);
+ }
+ try {
+ commitSolrChanges(solr, docs);
+ } catch (IOException e) {
+ throw new IOException("Unable to register docker instance "
+ + "with application entry.", e);
+ }
+ }
+
+ private void commitSolrChanges(SolrClient solr,
+ Collection<SolrInputDocument> docs)
+ throws IOException, SolrServerException {
+ // Commit Solr changes.
+ UpdateResponse detailsResponse = solr.add(docs);
+ if (detailsResponse.getStatus() != 0) {
+ throw new IOException("Failed to commit document in solr, status code: "
+ + detailsResponse.getStatus());
+ }
+ solr.commit();
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/YarnServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/YarnServiceClient.java
index 667d218..3a6c67d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/YarnServiceClient.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/application/YarnServiceClient.java
@@ -27,6 +27,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.appcatalog.model.AppEntry;
import org.apache.hadoop.yarn.service.api.records.Service;
+import org.apache.hadoop.yarn.service.api.records.ServiceState;
import org.apache.hadoop.yarn.service.api.records.KerberosPrincipal;
import org.apache.hadoop.yarn.service.client.ApiServiceClient;
@@ -171,4 +172,25 @@ public class YarnServiceClient {
LOG.error("Error in fetching application status: ", e);
}
}
+
+ public void upgradeApp(Service app) throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ String appInstanceId = app.getName();
+ app.setState(ServiceState.EXPRESS_UPGRADING);
+ String yarnFile = mapper.writeValueAsString(app);
+ ClientResponse response;
+ try {
+ response = asc.getApiClient(asc.getServicePath(appInstanceId))
+ .put(ClientResponse.class, yarnFile);
+ if (response.getStatus() >= 299) {
+ String message = response.getEntity(String.class);
+ throw new RuntimeException("Failed : HTTP error code : "
+ + response.getStatus() + " error: " + message);
+ }
+ } catch (UniformInterfaceException | ClientHandlerException
+ | IOException e) {
+ LOG.error("Error in stopping application: ", e);
+ }
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsController.java
index db6973d..63aefa6 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsController.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsController.java
@@ -18,8 +18,12 @@
package org.apache.hadoop.yarn.appcatalog.controller;
+import java.io.IOException;
+
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -32,6 +36,7 @@ import org.apache.hadoop.yarn.appcatalog.application.YarnServiceClient;
import org.apache.hadoop.yarn.appcatalog.model.AppEntry;
import org.apache.hadoop.yarn.service.api.records.Service;
import org.apache.hadoop.yarn.service.api.records.ServiceState;
+import org.apache.solr.client.solrj.SolrServerException;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -262,4 +267,33 @@ public class AppDetailsController {
}
return Response.ok().build();
}
+
+ /**
+ * Upgrade an application.
+ *
+ * @apiGroup AppDetailController
+ * @apiName upgradeApp
+ * @api {put} /app_details/upgrade/{id} Upgrade one instance of application.
+ * @apiParam {String} id Application Name to upgrade.
+ * @apiSuccess {String} text
+ * @apiError BadRequest Requested application does not upgrade.
+ * @return Web response code
+ */
+ @Path("upgrade/{id}")
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response upgradeApp(@PathParam("id") String id, Service app) {
+ try {
+ AppCatalogSolrClient sc = new AppCatalogSolrClient();
+ sc.upgradeApp(app);
+ YarnServiceClient yc = new YarnServiceClient();
+ yc.upgradeApp(app);
+ } catch (IOException | SolrServerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.toString()).build();
+ }
+ String output = "{\"status\":\"Application upgrade requested.\",\"id\":\"" +
+ app.getName() + "\"}";
+ return Response.status(Status.ACCEPTED).entity(output).build();
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/app.js
index 0a7b6db..4cab2b4 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/app.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/app.js
@@ -53,6 +53,9 @@ app.config(['$routeProvider',
}).when('/deploy/:id', {
templateUrl: 'partials/deploy.html',
controller: 'DeployAppController'
+ }).when('/upgrade/:id', {
+ templateUrl: 'partials/upgrade.html',
+ controller: 'UpgradeAppController'
}).otherwise({
redirectTo: '/'
});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/controllers.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/controllers.js
index 241f15d..4d9e42d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/controllers.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/javascript/controllers.js
@@ -127,6 +127,10 @@ controllers.controller("AppDetailsController", [ '$scope', '$interval', '$rootSc
}, errorCallback);
}
+ $scope.upgradeApp = function(id) {
+ window.location = '/#!/upgrade/' + id;
+ }
+
$scope.canDeployApp = function() {
return true;
};
@@ -306,6 +310,56 @@ controllers.controller("DeployAppController", [ '$scope', '$rootScope', '$http',
}]);
+controllers.controller("UpgradeAppController", [ '$scope', '$rootScope', '$http',
+ '$routeParams', function($scope, $rootScope, $http, $routeParams) {
+ $scope.message = null;
+ $scope.error = null;
+ $scope.appName = $routeParams.id;
+ $scope.refreshAppDetails = function() {
+ $http({
+ method : 'GET',
+ url : '/v1/app_details/status/' + $scope.appName
+ }).then(successCallback, errorCallback);
+ }
+
+ $scope.upgradeApp = function(app) {
+ $rootScope.$emit("showLoadScreen", {});
+ $http({
+ method : 'PUT',
+ url : '/v1/app_details/upgrade/' + $scope.appName,
+ data : JSON.stringify($scope.details)
+ }).then(function(data, status, headers, config) {
+ $rootScope.$emit("RefreshAppList", {});
+ window.location = '/#!/app/' + data.data.id;
+ }, function(data, status, headers, config) {
+ $rootScope.$emit("hideLoadScreen", {});
+ $scope.error = data.data;
+ $('#error-message').html(data.data);
+ $('#myModal').modal('show');
+ console.log('error', data, status);
+ });
+ }
+
+ function successCallback(response) {
+ if (response.data.yarnfile.components.length!=0) {
+ $scope.details = response.data.yarnfile;
+ } else {
+ // When application is in accepted or failed state, it does not
+ // have components detail, hence we update states only.
+ $scope.details.state = response.data.yarnfile.state;
+ }
+ }
+
+ function errorCallback(response) {
+ $rootScope.$emit("hideLoadScreen", {});
+ $scope.error = "Error in getting application detail.";
+ $('#error-message').html($scope.error);
+ $('#myModal').modal('show');
+ }
+
+ $scope.refreshAppDetails();
+}]);
+
controllers.controller("LoadScreenController", [ '$scope', '$rootScope', '$http', function($scope, $rootScope, $http) {
$scope.loadScreen = "hide";
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/css/bootstrap-hadoop.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/css/bootstrap-hadoop.css
index 5aa6e46..231f9a9 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/css/bootstrap-hadoop.css
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/css/bootstrap-hadoop.css
@@ -184,6 +184,11 @@
background-color: #FFF;
box-shadow: 0 0 2px 0 #1391c1;
}
+.btn-secondary:visited {
+ color: #429929;
+ background-color: #FFF;
+ box-shadow: 0 0 2px 0 #1391c1;
+}
.btn-secondary[disabled],
.btn-secondary:focus[disabled],
.btn-secondary.disabled,
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/details.html b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/details.html
index 69ef912..8624440 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/details.html
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/details.html
@@ -14,8 +14,9 @@
<div class="container content">
<div class="row">
<div class="col-xs-12 col-md-12 col-lg-12">
+ <a ng-click="restartApp(appName)" class="btn btn-secondary"><span class="glyphicon glyphicon-play"></span> Start</a>
<a ng-click="stopApp(appName)" class="btn btn-secondary"><span class="glyphicon glyphicon-stop"></span> Stop</a>
- <a ng-click="restartApp(appName)" class="btn btn-secondary"><span class="glyphicon glyphicon-refresh"></span> Start</a>
+ <a ng-click="upgradeApp(appName)" class="btn btn-secondary"><span class="glyphicon glyphicon-circle-arrow-up"></span> Upgrade</a>
<div style="display:inline-block;" ng-repeat="(key, value) in details.yarnfile.quicklinks">
<a href="{{value}}" class="btn btn-secondary" ng-hide="checkServiceLink()"><span class="glyphicon glyphicon-new-window"></span> {{key}}</a>
</div>
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/upgrade.html b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/upgrade.html
new file mode 100644
index 0000000..2453aab
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/partials/upgrade.html
@@ -0,0 +1,114 @@
+<!---
+ Licensed 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. See accompanying LICENSE file.
+-->
+<div class="container content">
+ <div class="row">
+ <div class="col-xs-12 col-md-12 col-lg-12">
+ <div class="form-group">
+ <h1>Upgrade Application</h1>
+ </div>
+ <div class="form-group">
+ <label>Application Name</label>
+ <input type=text name="name" class="form-control" ng-model="details.name" readonly />
+ </div>
+ <div class="form-group">
+ <label>Version</label>
+ <input type=text name="version" class="form-control" ng-model="details.version" />
+ </div>
+ <div class="form-group">
+ <label>Quick Link</label>
+ <textarea json-text name="quicklink" class="form-control" ng-model="details.quicklinks"/></textarea>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-xs-12 col-md-12 col-lg-12" ng-repeat="docker in details.components track by $index">
+ <div class="panel">
+ <div class="form-group">
+ <label>Component Name</label>
+ <input type=text name="name" class="form-control" ng-model="docker.name" readonly />
+ </div>
+ <div class="form-group">
+ <label>Artifact</label>
+ <input type=text name="artifact_id" class="form-control" ng-model="docker.artifact.id" />
+ </div>
+ <div class="form-group">
+ <label>Number of containers</label>
+ <input type=text name="artifact_id" class="form-control" ng-model="docker.number_of_containers" readonly />
+ </div>
+ <div class="form-group">
+ <label>Launch Command</label>
+ <input type=text name="launch_command" class="form-control" ng-model="docker.launch_command" />
+ </div>
+ <div class="form-group">
+ <label>CPU</label>
+ <input type=text name="cpus" class="form-control" ng-model="docker.resource.cpus" readonly />
+ </div>
+ <div class="form-group">
+ <label>Memory</label>
+ <input type=text name="memory" class="form-control" ng-model="docker.resource.memory" readonly />
+ </div>
+ <div class="form-group">
+ <input type="checkbox" ng-attr-id="{{'checkbox-priv-' + $index}}" ng-model="docker.run_privileged_container">
+ <label for="checkbox-priv-{{$index}}"> Privileged Container</label>
+ </div>
+ <div class="form-group">
+ <label>Dependencies</label>
+ <input json-text type=text name="dependencies" class="form-control" ng-model="docker.dependencies" />
+ </div>
+ <div class="form-group">
+ <label>Placement Policy</label>
+ <input type=text name="placement" class="form-control" ng-model="docker.placement_policy.constraints" readonly />
+ </div>
+ <div class="form-group">
+ <label>Environments</label>
+ <textarea json-text name="env" class="form-control" ng-model="docker.configuration.env"/></textarea>
+ </div>
+ <div class="form-group">
+ <label>Properties</label>
+ <textarea json-text name="properties" class="form-control" ng-model="docker.configuration.properties"/></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <br>
+ <div class="row">
+ <div class="col-xs-12 col-md-12 col-lg-12">
+ <p>
+ <a class="btn btn-secondary" ng-click="upgradeApp(details)">Upgrade</a>
+ <a class="btn btn-secondary" href="/#!/app/{{details.name}}">CANCEL</a>
+ </div>
+ </div>
+
+ <div class="modal fade" id="myModal" role="dialog">
+ <div class="modal-dialog">
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">×</button>
+ <h4 class="modal-title" ng-if="message">Info</h4>
+ <h4 class="modal-title" ng-if="error">Error</h4>
+ </div>
+ <div class="modal-body">
+ <p class="infobox bg-info" ng-if="message">{{message}}</p>
+ <div id="error-message"></div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/theme.html b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/theme.html
index a8a2a2d..57982d1 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/theme.html
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/main/webapp/theme.html
@@ -29,7 +29,7 @@
<!-- Custom styles for this template -->
<link href="css/theme.css" rel="stylesheet">
- <link href="css/bootstrap-hadoop.min.css" rel="stylesheet">
+ <link href="css/bootstrap-hadoop.css" rel="stylesheet">
</head>
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/application/TestAppCatalogSolrClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/application/TestAppCatalogSolrClient.java
index 16bf7fb..d902de5 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/application/TestAppCatalogSolrClient.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/application/TestAppCatalogSolrClient.java
@@ -18,6 +18,7 @@
package org.apache.hadoop.yarn.appcatalog.application;
+import org.apache.hadoop.yarn.appcatalog.model.AppEntry;
import org.apache.hadoop.yarn.appcatalog.model.AppStoreEntry;
import org.apache.hadoop.yarn.appcatalog.model.Application;
import org.apache.solr.client.solrj.SolrClient;
@@ -127,4 +128,22 @@ public class TestAppCatalogSolrClient {
}
}
+ @Test
+ public void testUpgradeApp() throws Exception {
+ Application example = new Application();
+ String expected = "2.0";
+ String actual = "";
+ example.setOrganization("jenkins-ci.org");
+ example.setVersion("1.0");
+ example.setName("jenkins");
+ example.setDescription("World leading open source automation system.");
+ example.setIcon("/css/img/feather.png");
+ spy.register(example);
+ spy.deployApp("test", example);
+ example.setVersion("2.0");
+ spy.upgradeApp(example);
+ List<AppEntry> appEntries = spy.listAppEntries();
+ actual = appEntries.get(appEntries.size() -1).getYarnfile().getVersion();
+ assertEquals(expected, actual);
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsControllerTest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsControllerTest.java
index ca4fba9..437d50b 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsControllerTest.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/java/org/apache/hadoop/yarn/appcatalog/controller/AppDetailsControllerTest.java
@@ -135,4 +135,23 @@ public class AppDetailsControllerTest {
is("/app_details"));
}
+ @Test
+ public void testUpgradeApp() throws Exception {
+ String id = "application1";
+ AppDetailsController ac = Mockito.mock(AppDetailsController.class);
+
+ Service yarnfile = new Service();
+ yarnfile.setVersion("1.0");
+ Component comp = new Component();
+ Container c = new Container();
+ c.setId("container-1");
+ List<Container> containers = new ArrayList<Container>();
+ containers.add(c);
+ comp.setContainers(containers);
+ yarnfile.addComponent(comp);
+ Response expected = Response.ok().build();
+ when(ac.upgradeApp(id, yarnfile)).thenReturn(Response.ok().build());
+ final Response actual = ac.upgradeApp(id, yarnfile);
+ assertEquals(expected.getStatus(), actual.getStatus());
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/resources/configsets/exampleCollection/conf/schema.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/resources/configsets/exampleCollection/conf/schema.xml
index 20acbc9..0921e13 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/resources/configsets/exampleCollection/conf/schema.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp/src/test/resources/configsets/exampleCollection/conf/schema.xml
@@ -23,6 +23,7 @@
<field name="type_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
<field name="org_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
<field name="name_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
+ <field name="app_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
<field name="desc_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
<field name="icon_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
<field name="yarnfile_s" type="string" indexed="true" stored="true" required="false" multiValued="false" docValues="true" />
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org