Bläddra i källkod

AMBARI-15756. File browser view should have some checks before starting similar to pig view (pallavkul)

Pallav Kulshreshtha 9 år sedan
förälder
incheckning
81497776ee

+ 16 - 0
contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java

@@ -18,6 +18,7 @@
 
 package org.apache.ambari.view.filebrowser;
 
+import javax.ws.rs.WebApplicationException;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.ambari.view.ViewContext;
@@ -126,6 +127,21 @@ public abstract class HdfsService {
     return username;
   }
 
+  /**
+   * Checks connection to HDFS
+   * @param context View Context
+   */
+  public static void hdfsSmokeTest(ViewContext context) {
+    try {
+      HdfsApi api = HdfsUtil.connectToHDFSApi(context);
+      api.getStatus();
+    } catch (WebApplicationException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new ServiceFormattedException(ex.getMessage(), ex);
+    }
+  }
+
   /**
    * Get proxyuser username to use in HDFS
    * @param context View Context instance

+ 21 - 0
contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java

@@ -31,6 +31,7 @@ import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.filebrowser.utils.NotFoundFormattedException;
 import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
 import org.apache.ambari.view.utils.hdfs.HdfsApi;
+import org.json.simple.JSONObject;
 
 /**
  * Help service
@@ -79,6 +80,26 @@ public class HelpService extends HdfsService {
         context.getProperties().get("webhdfs.url")).build();
   }
 
+  /**
+   * HDFS Status
+   * @return status
+   */
+  @GET
+  @Path("/hdfsStatus")
+  @Produces(MediaType.APPLICATION_JSON)
+  public Response hdfsStatus(){
+    HdfsService.hdfsSmokeTest(context);
+    return getOKResponse();
+  }
+
+  private Response getOKResponse() {
+    JSONObject response = new JSONObject();
+    response.put("message", "OK");
+    response.put("trace", null);
+    response.put("status", "200");
+    return Response.ok().entity(response).type(MediaType.APPLICATION_JSON).build();
+  }
+
   /**
    * Returns home directory
    * @return home directory

+ 99 - 0
contrib/views/files/src/main/resources/ui/app/controllers/splash.js

@@ -0,0 +1,99 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  store: Ember.inject.service('store'),
+  isExpanded: false,
+  errors: "",
+  stackTrace: "",
+  startTests: function() {
+
+    var model = this.get('model');
+
+    var adapter = this.get('store').adapterFor('application');
+    var baseURL = adapter.buildURL()
+    var baseURLArr = baseURL.split('/');
+
+    baseURLArr[baseURLArr.length - 1] = undefined;
+    baseURL = baseURLArr.join('/');
+
+    var url = baseURL + 'help/'
+
+    var self = this;
+
+    var processResponse = function(name, data) {
+
+      model.set(name + 'Test', data.status == 200);
+
+      if (data.status != 200) {
+        var checkFailedMessage = "Service '" + name + "' check failed";
+        var errors = self.get("errors");
+        errors += checkFailedMessage;
+        errors += (data.message)?(': <i>' + data.message + '</i><br>'):'<br>';
+        self.set("errors", errors);
+      }
+
+      if (data.trace != null) {
+        var stackTrace = self.get("stackTrace");
+        stackTrace += checkFailedMessage + ':\n' + data.trace;
+        self.set("stackTrace", stackTrace);
+      }
+
+      model.set(name + 'TestDone', true);
+
+      var percent = model.get('percent');
+      model.set('percent', percent + 100);
+    };
+
+    var promises = ['hdfs'].map(function(name) {
+
+      return Ember.$.getJSON( url + name + 'Status')
+        .then(
+          function(data) {
+            processResponse(name, data);
+          },
+          function(reason) {
+            processResponse(name, reason.responseJSON);
+          }
+        );
+    });
+
+    return Ember.RSVP.all(promises);
+  },
+
+  progressBarStyle: function() {
+    return 'width: ' + this.get("model").get("percent") +  '%;';
+  }.property("model.percent"),
+
+  modelhdfsTestDone: function() {
+    return this.get('model.hdfsTestDone');
+  }.property('model.hdfsTestDone' ),
+
+  modelhdfsTest: function() {
+    return this.get('model.hdfsTest');
+  }.property('model.hdfsTest' ),
+
+  actions: {
+    toggleStackTrace:function () {
+      var value = this.get('isExpanded');
+      this.set('isExpanded', !value);
+    }
+  }
+});

+ 1 - 0
contrib/views/files/src/main/resources/ui/app/router.js

@@ -28,6 +28,7 @@ Router.map(function() {
   this.route('messages', function() {
     this.route('message', {path: '/:message_id'});
   });
+  this.route('splash');
 });
 
 export default Router;

+ 1 - 1
contrib/views/files/src/main/resources/ui/app/routes/index.js

@@ -20,6 +20,6 @@ import Ember from 'ember';
 
 export default Ember.Route.extend({
   beforeModel: function(transition) {
-    this.transitionTo('files');
+    this.transitionTo('splash');
   }
 });

+ 56 - 0
contrib/views/files/src/main/resources/ui/app/routes/splash.js

@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+
+  model: function() {
+    return Ember.Object.create({
+      hdfsTest: null,
+      hdfsTestDone: null,
+      percent: 0
+    });
+  },
+
+  setupController: function(controller, model) {
+
+    if (!model) {
+      return;
+    }
+
+    controller.set('model', model);
+    var self = this;
+    controller.startTests().then(function() {
+
+      if (model.get("hdfsTest")) {
+        Ember.run.later(this, function() {
+          self.send('transition');
+        }, 3000);
+      }
+    });
+  },
+
+  actions: {
+    transition: function() {
+      this.transitionTo('files');
+    }
+  }
+
+});
+

+ 66 - 0
contrib/views/files/src/main/resources/ui/app/templates/splash.hbs

@@ -0,0 +1,66 @@
+{{!
+* 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.
+}}
+
+<div class="spinner"></div>
+<div class="container-fluid">
+  <h1>Welcome to the File Browser View</h1>
+  <h2>Please wait...</h2>
+
+  <div class="progress progress-striped active">
+    <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style={{progressBarStyle}}>
+    </div>
+  </div>
+
+  <table class="table">
+    <tbody>
+    <tr>
+      <td>
+        {{#if modelhdfsTestDone}}
+          {{#if modelhdfsTest}}
+            <i class="fa fa-check"></i>
+          {{else}}
+            <i class="fa fa-remove"></i>
+          {{/if}}
+        {{else}}
+          <i class="fa fa-arrow-right"></i>
+        {{/if}}
+      </td>
+      <td>hdfs service test</td>
+    </tr>
+    </tbody>
+  </table>
+
+  {{#if errors}}
+    <h3>Issues detected</h3>
+    <p>{{{errors}}}</p>
+  {{/if}}
+  {{#if stackTrace}}
+    <a href="#" {{action "toggleStackTrace" post}}>
+      {{#if isExpanded}}
+        <i class="fa fa-minus"></i> Collapse Stack Trace
+      {{else}}
+        <<i class="fa fa-plus"></i> Expand Stack Trace
+      {{/if}}
+    </a>
+    {{#if isExpanded}}
+      <pre class="prettyprint">
+        {{stackTrace}}
+      </pre>
+    {{/if}}
+  {{/if}}
+</div>