You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by db...@apache.org on 2016/04/13 14:22:45 UTC
[1/2] ambari git commit: AMBARI-15829. Files View: Extract the
directory viewer UI component so that other views can use it. (dipayanb)
Repository: ambari
Updated Branches:
refs/heads/trunk 33ef653dd -> 281307fce
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
new file mode 100644
index 0000000..66a7b20
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "hdfs-directory-viewer",
+ "version": "0.1.0",
+ "description": "The hdfs directory viewer addon to be used by ambari views",
+ "directories": {
+ "doc": "doc",
+ "test": "tests"
+ },
+ "scripts": {
+ "build": "ember build",
+ "start": "ember server",
+ "test": "ember try:testall"
+ },
+ "repository": "",
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "author": "",
+ "license": "MIT",
+ "devDependencies": {
+ "broccoli-asset-rev": "^2.2.0",
+ "ember-ajax": "0.7.1",
+ "ember-cli": "2.2.0-beta.4",
+ "ember-cli-app-version": "^1.0.0",
+ "ember-cli-dependency-checker": "^1.2.0",
+ "ember-cli-font-awesome": "1.5.0",
+ "ember-cli-htmlbars": "^1.0.1",
+ "ember-cli-htmlbars-inline-precompile": "^0.3.1",
+ "ember-cli-inject-live-reload": "^1.3.1",
+ "ember-cli-qunit": "^1.1.0",
+ "ember-cli-release": "0.2.8",
+ "ember-cli-sri": "^2.0.0",
+ "ember-cli-uglify": "^1.2.0",
+ "ember-data": "^2.2.1",
+ "ember-disable-prototype-extensions": "^1.0.0",
+ "ember-disable-proxy-controllers": "^1.0.1",
+ "ember-export-application-global": "^1.0.4",
+ "ember-resolver": "^2.0.3",
+ "ember-try": "~0.0.8"
+ },
+ "keywords": [
+ "ember-addon"
+ ],
+ "dependencies": {
+ "ember-cli-babel": "^5.1.5",
+ "ember-cli-htmlbars": "^1.0.1"
+ },
+ "ember-addon": {
+ "configPath": "tests/dummy/config"
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/testem.json
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/testem.json b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/testem.json
new file mode 100644
index 0000000..0f35392
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/testem.json
@@ -0,0 +1,12 @@
+{
+ "framework": "qunit",
+ "test_page": "tests/index.html?hidepassed",
+ "disable_watching": true,
+ "launch_in_ci": [
+ "PhantomJS"
+ ],
+ "launch_in_dev": [
+ "PhantomJS",
+ "Chrome"
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/.jshintrc
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/.jshintrc b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/.jshintrc
new file mode 100644
index 0000000..6ec0b7c
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/.jshintrc
@@ -0,0 +1,52 @@
+{
+ "predef": [
+ "document",
+ "window",
+ "location",
+ "setTimeout",
+ "$",
+ "-Promise",
+ "define",
+ "console",
+ "visit",
+ "exists",
+ "fillIn",
+ "click",
+ "keyEvent",
+ "triggerEvent",
+ "find",
+ "findWithAssert",
+ "wait",
+ "DS",
+ "andThen",
+ "currentURL",
+ "currentPath",
+ "currentRouteName"
+ ],
+ "node": false,
+ "browser": false,
+ "boss": true,
+ "curly": true,
+ "debug": false,
+ "devel": false,
+ "eqeqeq": true,
+ "evil": true,
+ "forin": false,
+ "immed": false,
+ "laxbreak": false,
+ "newcap": true,
+ "noarg": true,
+ "noempty": false,
+ "nonew": false,
+ "nomen": false,
+ "onevar": false,
+ "plusplus": false,
+ "regexp": false,
+ "undef": true,
+ "sub": true,
+ "strict": false,
+ "white": false,
+ "eqnull": true,
+ "esnext": true,
+ "unused": true
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/app.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/app.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/app.js
new file mode 100644
index 0000000..fb4695c
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/app.js
@@ -0,0 +1,36 @@
+/**
+ * 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';
+import Resolver from 'ember-resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+
+let App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+ modulePrefix: config.modulePrefix,
+ podModulePrefix: config.podModulePrefix,
+ Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+
+export default App;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/components/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/components/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/components/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/application.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/application.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/application.js
new file mode 100644
index 0000000..b9b52f7
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/controllers/application.js
@@ -0,0 +1,32 @@
+/**
+ * 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';
+import MyViewerConfig from '../utils/my-viewer-config';
+
+export default Ember.Controller.extend({
+ config: MyViewerConfig.create(),
+ actions: {
+ viewerError: function() {
+ console.log("Failed to fetch the content!!!");
+ },
+ viewerSelectedPath: function(data) {
+ console.log(`User selected: path: ${data.path}, isDirectory: ${data.isDirectory}`);
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/helpers/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/helpers/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/helpers/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/index.html
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/index.html b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/index.html
new file mode 100644
index 0000000..fba56f90
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/index.html
@@ -0,0 +1,43 @@
+<!--
+ * 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.
+-->
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title>Dummy</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ {{content-for "head"}}
+
+ <link rel="stylesheet" href="assets/vendor.css">
+ <link rel="stylesheet" href="assets/dummy.css">
+
+ {{content-for "head-footer"}}
+ </head>
+ <body>
+ {{content-for "body"}}
+
+ <script src="assets/vendor.js"></script>
+ <script src="assets/dummy.js"></script>
+
+ {{content-for "body-footer"}}
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/models/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/models/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/models/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/router.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/router.js
new file mode 100644
index 0000000..3b44118
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/router.js
@@ -0,0 +1,29 @@
+/**
+ * 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';
+import config from './config/environment';
+
+const Router = Ember.Router.extend({
+ location: config.locationType
+});
+
+Router.map(function() {
+});
+
+export default Router;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/routes/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/routes/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/routes/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/styles/app.css
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/styles/app.css b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/styles/app.css
new file mode 100644
index 0000000..1c922ba
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/styles/app.css
@@ -0,0 +1,23 @@
+/**
+ * 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.
+ */
+
+.directory-viewer-wrap {
+ width: 600px;
+ height: 500px;
+ border: 1px solid darkgray;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/application.hbs b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/application.hbs
new file mode 100644
index 0000000..0263b2c
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/application.hbs
@@ -0,0 +1,36 @@
+{{!
+* 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.
+}}
+
+<h2 id="title">Ambari HDFS Directory Viewer example</h2>
+<p>
+ This will require Ambari installation with a file view instance created.<br/>
+ <strong>Instance name: files
+ <br/>Files view version used is: 1.0.0</strong>
+</p>
+
+
+<div class="directory-viewer-wrap">
+ {{directory-viewer
+ config=config
+ errorAction="viewerError"
+ pathSelectAction="viewerSelectedPath"
+ }}
+</div>
+
+
+{{outlet}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/components/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/components/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/templates/components/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/utils/my-viewer-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/utils/my-viewer-config.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/utils/my-viewer-config.js
new file mode 100644
index 0000000..e029e1a
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/app/utils/my-viewer-config.js
@@ -0,0 +1,35 @@
+/**
+ * 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';
+import ViewerConfig from 'hdfs-directory-viewer/utils/viewer-config';
+
+export default ViewerConfig.extend({
+ showOnlyDirectories: true,
+
+ expandIcon: 'fa fa-chevron-right',
+ collapseIcon: 'fa fa-chevron-down',
+
+ getHeaders() {
+ return Ember.merge({"Authorization": "Basic YWRtaW46YWRtaW4="}, this._super());
+ },
+
+ listDirectoryUrl(pathParams) {
+ return `/api/v1/views/FILES/versions/1.0.0/instances/files/resources/files/fileops/listdir?${pathParams}`;
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/config/environment.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/config/environment.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/config/environment.js
new file mode 100644
index 0000000..1445079
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/config/environment.js
@@ -0,0 +1,65 @@
+/**
+ * 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.
+ */
+
+/* jshint node: true */
+
+module.exports = function(environment) {
+ var ENV = {
+ modulePrefix: 'dummy',
+ environment: environment,
+ baseURL: '/',
+ locationType: 'auto',
+ EmberENV: {
+ FEATURES: {
+ // Here you can enable experimental features on an ember canary build
+ // e.g. 'with-controller': true
+ }
+ },
+
+ APP: {
+ // Here you can pass flags/options to your application instance
+ // when it is created
+ }
+ };
+
+ if (environment === 'development') {
+ // ENV.APP.LOG_RESOLVER = true;
+ // ENV.APP.LOG_ACTIVE_GENERATION = true;
+ // ENV.APP.LOG_TRANSITIONS = true;
+ // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
+ // ENV.APP.LOG_VIEW_LOOKUPS = true;
+ }
+
+ if (environment === 'test') {
+ // Testem prefers this...
+ ENV.baseURL = '/';
+ ENV.locationType = 'none';
+
+ // keep test console output quieter
+ ENV.APP.LOG_ACTIVE_GENERATION = false;
+ ENV.APP.LOG_VIEW_LOOKUPS = false;
+
+ ENV.APP.rootElement = '#ember-testing';
+ }
+
+ if (environment === 'production') {
+
+ }
+
+ return ENV;
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/crossdomain.xml
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/crossdomain.xml b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/crossdomain.xml
new file mode 100644
index 0000000..0c16a7a
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/crossdomain.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
+<cross-domain-policy>
+ <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
+
+ <!-- Most restrictive policy: -->
+ <site-control permitted-cross-domain-policies="none"/>
+
+ <!-- Least restrictive policy: -->
+ <!--
+ <site-control permitted-cross-domain-policies="all"/>
+ <allow-access-from domain="*" to-ports="*" secure="false"/>
+ <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
+ -->
+</cross-domain-policy>
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/robots.txt
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/robots.txt b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/robots.txt
new file mode 100644
index 0000000..f591645
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/dummy/public/robots.txt
@@ -0,0 +1,3 @@
+# http://www.robotstxt.org
+User-agent: *
+Disallow:
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/destroy-app.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/destroy-app.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/destroy-app.js
new file mode 100644
index 0000000..dfabf85
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/destroy-app.js
@@ -0,0 +1,23 @@
+/**
+ * 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 function destroyApp(application) {
+ Ember.run(application, 'destroy');
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/module-for-acceptance.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/module-for-acceptance.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/module-for-acceptance.js
new file mode 100644
index 0000000..05aa014
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/module-for-acceptance.js
@@ -0,0 +1,41 @@
+/**
+ * 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 { module } from 'qunit';
+import startApp from '../helpers/start-app';
+import destroyApp from '../helpers/destroy-app';
+
+export default function(name, options = {}) {
+ module(name, {
+ beforeEach() {
+ this.application = startApp();
+
+ if (options.beforeEach) {
+ options.beforeEach.apply(this, arguments);
+ }
+ },
+
+ afterEach() {
+ destroyApp(this.application);
+
+ if (options.afterEach) {
+ options.afterEach.apply(this, arguments);
+ }
+ }
+ });
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/resolver.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/resolver.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/resolver.js
new file mode 100644
index 0000000..b7193ba
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/resolver.js
@@ -0,0 +1,29 @@
+/**
+ * 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 Resolver from 'ember-resolver';
+import config from '../../config/environment';
+
+const resolver = Resolver.create();
+
+resolver.namespace = {
+ modulePrefix: config.modulePrefix,
+ podModulePrefix: config.podModulePrefix
+};
+
+export default resolver;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/start-app.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/start-app.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/start-app.js
new file mode 100644
index 0000000..7b25773
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/helpers/start-app.js
@@ -0,0 +1,36 @@
+/**
+ * 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';
+import Application from '../../app';
+import config from '../../config/environment';
+
+export default function startApp(attrs) {
+ let application;
+
+ let attributes = Ember.merge({}, config.APP);
+ attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
+
+ Ember.run(() => {
+ application = Application.create(attributes);
+ application.setupForTesting();
+ application.injectTestHelpers();
+ });
+
+ return application;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/index.html
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/index.html b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/index.html
new file mode 100644
index 0000000..5251332
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/index.html
@@ -0,0 +1,52 @@
+<!--
+ * 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.
+-->
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title>Dummy Tests</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ {{content-for "head"}}
+ {{content-for "test-head"}}
+
+ <link rel="stylesheet" href="assets/vendor.css">
+ <link rel="stylesheet" href="assets/dummy.css">
+ <link rel="stylesheet" href="assets/test-support.css">
+
+ {{content-for "head-footer"}}
+ {{content-for "test-head-footer"}}
+ </head>
+ <body>
+ {{content-for "body"}}
+ {{content-for "test-body"}}
+
+ <script src="testem.js" integrity=""></script>
+ <script src="assets/vendor.js"></script>
+ <script src="assets/test-support.js"></script>
+ <script src="assets/dummy.js"></script>
+ <script src="assets/tests.js"></script>
+ <script src="assets/test-loader.js"></script>
+
+ {{content-for "body-footer"}}
+ {{content-for "test-body-footer"}}
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/integration/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/integration/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/integration/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/test-helper.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/test-helper.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/test-helper.js
new file mode 100644
index 0000000..96975ee
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/test-helper.js
@@ -0,0 +1,24 @@
+/**
+ * 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 resolver from './helpers/resolver';
+import {
+ setResolver
+} from 'ember-qunit';
+
+setResolver(resolver);
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/unit/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/unit/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/tests/unit/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/vendor/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/vendor/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/vendor/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/files/pom.xml b/contrib/views/files/pom.xml
index 13ff5e1..383d90d 100644
--- a/contrib/views/files/pom.xml
+++ b/contrib/views/files/pom.xml
@@ -97,6 +97,11 @@
<version>2.0.0.0-SNAPSHOT</version>
</dependency>
<dependency>
+ <groupId>org.apache.ambari.contrib.views</groupId>
+ <artifactId>ambari-views-commons</artifactId>
+ <version>2.0.0.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
index 95a07b5..4b8a546 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
@@ -47,14 +47,14 @@ import javax.ws.rs.core.UriInfo;
import javax.xml.bind.annotation.XmlElement;
import com.google.gson.Gson;
-import org.apache.ambari.view.filebrowser.utils.MisconfigurationFormattedException;
-import org.apache.ambari.view.filebrowser.utils.NotFoundFormattedException;
-import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
+import org.apache.ambari.view.commons.exceptions.MisconfigurationFormattedException;
+import org.apache.ambari.view.commons.exceptions.NotFoundFormattedException;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.commons.hdfs.HdfsService;
import org.apache.ambari.view.utils.hdfs.HdfsApi;
import org.apache.ambari.view.utils.hdfs.HdfsApiException;
import org.apache.ambari.view.utils.hdfs.HdfsUtil;
import org.apache.hadoop.fs.FSDataInputStream;
-import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.ambari.view.ViewContext;
import org.apache.hadoop.security.AccessControlException;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java
index fd1c710..adaa6c9 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java
@@ -23,6 +23,9 @@ import javax.ws.rs.Path;
import org.apache.ambari.view.ViewContext;
import com.google.inject.Inject;
+import org.apache.ambari.view.commons.hdfs.FileOperationService;
+import org.apache.ambari.view.commons.hdfs.UploadService;
+import org.apache.ambari.view.commons.hdfs.UserService;
/**
* Root files service
@@ -42,7 +45,7 @@ public class FileBrowserService {
}
/**
- * @see org.apache.ambari.view.filebrowser.UploadService
+ * @see UploadService
* @return service
*/
@Path("/upload")
@@ -51,7 +54,7 @@ public class FileBrowserService {
}
/**
- * @see org.apache.ambari.view.filebrowser.FileOperationService
+ * @see org.apache.ambari.view.commons.hdfs.FileOperationService
* @return service
*/
@Path("/fileops")
@@ -68,6 +71,12 @@ public class FileBrowserService {
return new HelpService(context);
}
+ /**
+ * @see org.apache.ambari.view.commons.hdfs.UserService
+ * @return service
+ */
+ @Path("/user")
+ public UserService userService() { return new UserService(context); }
/**
* @see org.apache.ambari.view.filebrowser.FilePreviewService
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
deleted file mode 100644
index a0793ac..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import javax.ws.rs.core.UriInfo;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-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.apache.ambari.view.utils.hdfs.HdfsApiException;
-import org.json.simple.JSONObject;
-
-/**
- * File operations service
- */
-public class FileOperationService extends HdfsService {
-
- /**
- * Constructor
- * @param context View Context instance
- */
- public FileOperationService(ViewContext context) {
- super(context);
- }
-
- /**
- * List dir
- * @param path path
- * @return response with dir content
- */
- @GET
- @Path("/listdir")
- @Produces(MediaType.APPLICATION_JSON)
- public Response listdir(@QueryParam("path") String path) {
- try {
- JSONObject response = new JSONObject();
- response.put("files", getApi(context).fileStatusToJSON(getApi(context).listdir(path)));
- response.put("meta", getApi(context).fileStatusToJSON(getApi(context).getFileStatus(path)));
- return Response.ok(response).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (FileNotFoundException ex) {
- throw new NotFoundFormattedException(ex.getMessage(), ex);
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Rename
- * @param request rename request
- * @return response with success
- */
- @POST
- @Path("/rename")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response rename(final SrcDstFileRequest request) {
- try {
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- if (api.rename(request.src, request.dst)) {
- result = Response.ok(getApi(context).fileStatusToJSON(api
- .getFileStatus(request.dst)));
- } else {
- result = Response.ok(new FileOperationResult(false, "Can't move '" + request.src + "' to '" + request.dst + "'")).status(422);
- }
- return result.build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Chmod
- * @param request chmod request
- * @return response with success
- */
- @POST
- @Path("/chmod")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response chmod(final ChmodRequest request) {
- try {
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- if (api.chmod(request.path, request.mode)) {
- result = Response.ok(getApi(context).fileStatusToJSON(api
- .getFileStatus(request.path)));
- } else {
- result = Response.ok(new FileOperationResult(false, "Can't chmod '" + request.path + "'")).status(422);
- }
- return result.build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Copy file
- * @param request source and destination request
- * @return response with success
- */
- @POST
- @Path("/move")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response move(final MultiSrcDstFileRequest request,
- @Context HttpHeaders headers, @Context UriInfo ui) {
- try {
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- String message = "";
-
- List<String> sources = request.sourcePaths;
- String destination = request.destinationPath;
- if(sources.isEmpty()) {
- result = Response.ok(new FileOperationResult(false, "Can't move 0 file/folder to '" + destination + "'")).
- status(422);
- return result.build();
- }
-
- int index = 0;
- for (String src : sources) {
- String fileName = getFileName(src);
- String finalDestination = getDestination(destination, fileName);
- try {
- if (api.rename(src, finalDestination)) {
- index ++;
- } else {
- message = "Failed to move '" + src + "' to '" + finalDestination + "'";
- break;
- }
- } catch (IOException exception) {
- message = exception.getMessage();
- logger.error("Failed to move '{}' to '{}'. Exception: {}", src, finalDestination,
- exception.getMessage());
- break;
- }
- }
- if (index == sources.size()) {
- result = Response.ok(new FileOperationResult(true)).status(200);
- } else {
- FileOperationResult errorResult = getFailureFileOperationResult(sources, index, message);
- result = Response.ok(errorResult).status(422);
- }
- return result.build();
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Copy file
- * @param request source and destination request
- * @return response with success
- */
- @POST
- @Path("/copy")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response copy(final MultiSrcDstFileRequest request,
- @Context HttpHeaders headers, @Context UriInfo ui) {
- try {
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- String message = "";
-
- List<String> sources = request.sourcePaths;
- String destination = request.destinationPath;
- if(sources.isEmpty()) {
- result = Response.ok(new FileOperationResult(false, "Can't copy 0 file/folder to '" + destination + "'")).
- status(422);
- return result.build();
- }
-
- int index = 0;
- for (String src : sources) {
- String fileName = getFileName(src);
- String finalDestination = getDestination(destination, fileName);
- try {
- api.copy(src, finalDestination);
- index ++;
- } catch (IOException|HdfsApiException exception) {
- message = exception.getMessage();
- logger.error("Failed to copy '{}' to '{}'. Exception: {}", src, finalDestination,
- exception.getMessage());
- break;
- }
- }
- if (index == sources.size()) {
- result = Response.ok(new FileOperationResult(true)).status(200);
- } else {
- FileOperationResult errorResult = getFailureFileOperationResult(sources, index, message);
- result = Response.ok(errorResult).status(422);
- }
- return result.build();
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Make directory
- * @param request make directory request
- * @return response with success
- */
- @PUT
- @Path("/mkdir")
- @Produces(MediaType.APPLICATION_JSON)
- public Response mkdir(final MkdirRequest request) {
- try{
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- if (api.mkdir(request.path)) {
- result = Response.ok(getApi(context).fileStatusToJSON(api.getFileStatus(request.path)));
- } else {
- result = Response.ok(new FileOperationResult(false, "Can't create dir '" + request.path + "'")).status(422);
- }
- return result.build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Empty trash
- * @return response with success
- */
- @DELETE
- @Path("/trash/emptyTrash")
- @Produces(MediaType.APPLICATION_JSON)
- public Response emptyTrash() {
- try {
- HdfsApi api = getApi(context);
- api.emptyTrash();
- return Response.ok(new FileOperationResult(true)).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Move to trash
- * @param request remove request
- * @return response with success
- */
- @DELETE
- @Path("/moveToTrash")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response moveToTrash(MultiRemoveRequest request) {
- try {
- ResponseBuilder result;
- HdfsApi api = getApi(context);
- String trash = api.getTrashDirPath();
- String message = "";
-
- if (request.paths.size() == 0) {
- result = Response.ok(new FileOperationResult(false, "No path entries provided.")).status(422);
- } else {
- if (!api.exists(trash)) {
- if (!api.mkdir(trash)) {
- result = Response.ok(new FileOperationResult(false, "Trash dir does not exists. Can't create dir for " +
- "trash '" + trash + "'")).status(422);
- return result.build();
- }
- }
-
- int index = 0;
- for (MultiRemoveRequest.PathEntry entry : request.paths) {
- String trashFilePath = api.getTrashDirPath(entry.path);
- try {
- if (api.rename(entry.path, trashFilePath)) {
- index ++;
- } else {
- message = "Failed to move '" + entry.path + "' to '" + trashFilePath + "'";
- break;
- }
- } catch (IOException exception) {
- message = exception.getMessage();
- logger.error("Failed to move '{}' to '{}'. Exception: {}", entry.path, trashFilePath,
- exception.getMessage());
- break;
- }
- }
- if (index == request.paths.size()) {
- result = Response.ok(new FileOperationResult(true)).status(200);
- } else {
- FileOperationResult errorResult = getFailureFileOperationResult(getPathsFromPathsEntries(request.paths), index, message);
- result = Response.ok(errorResult).status(422);
- }
- }
- return result.build();
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Remove
- * @param request remove request
- * @return response with success
- */
- @DELETE
- @Path("/remove")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response remove(MultiRemoveRequest request, @Context HttpHeaders headers,
- @Context UriInfo ui) {
- try {
- HdfsApi api = getApi(context);
- ResponseBuilder result;
- String message = "";
- if(request.paths.size() == 0) {
- result = Response.ok(new FileOperationResult(false, "No path entries provided."));
- } else {
- int index = 0;
- for (MultiRemoveRequest.PathEntry entry : request.paths) {
- try {
- if (api.delete(entry.path, entry.recursive)) {
- index++;
- } else {
- message = "Failed to remove '" + entry.path + "'";
- break;
- }
- } catch (IOException exception) {
- message = exception.getMessage();
- logger.error("Failed to remove '{}'. Exception: {}", entry.path, exception.getMessage());
- break;
- }
-
- }
- if (index == request.paths.size()) {
- result = Response.ok(new FileOperationResult(true)).status(200);
- } else {
- FileOperationResult errorResult = getFailureFileOperationResult(getPathsFromPathsEntries(request.paths), index, message);
- result = Response.ok(errorResult).status(422);
- }
- }
- return result.build();
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- private List<String> getPathsFromPathsEntries(List<MultiRemoveRequest.PathEntry> paths) {
- List<String> entries = new ArrayList<>();
- for(MultiRemoveRequest.PathEntry path: paths) {
- entries.add(path.path);
- }
- return entries;
- }
-
- private FileOperationResult getFailureFileOperationResult(List<String> paths, int failedIndex, String message) {
- List<String> succeeded = new ArrayList<>();
- List<String> unprocessed = new ArrayList<>();
- List<String> failed = new ArrayList<>();
- ListIterator<String> iter = paths.listIterator();
- while (iter.hasNext()) {
- int index = iter.nextIndex();
- String path = iter.next();
- if (index < failedIndex) {
- succeeded.add(path);
- } else if (index == failedIndex) {
- failed.add(path);
- } else {
- unprocessed.add(path);
- }
- }
- return new FileOperationResult(false, message, succeeded, failed, unprocessed);
- }
-
- private String getDestination(String baseDestination, String fileName) {
- if(baseDestination.endsWith("/")) {
- return baseDestination + fileName;
- } else {
- return baseDestination + "/" + fileName;
- }
- }
-
- private String getFileName(String srcPath) {
- return srcPath.substring(srcPath.lastIndexOf('/') + 1);
- }
-
-
- /**
- * Wrapper for json mapping of mkdir request
- */
- @XmlRootElement
- public static class MkdirRequest {
- @XmlElement(nillable = false, required = true)
- public String path;
- }
-
- /**
- * Wrapper for json mapping of chmod request
- */
- @XmlRootElement
- public static class ChmodRequest {
- @XmlElement(nillable = false, required = true)
- public String path;
- @XmlElement(nillable = false, required = true)
- public String mode;
- }
-
- /**
- * Wrapper for json mapping of request with
- * source and destination
- */
- @XmlRootElement
- public static class SrcDstFileRequest {
- @XmlElement(nillable = false, required = true)
- public String src;
- @XmlElement(nillable = false, required = true)
- public String dst;
- }
-
- /**
- * Wrapper for json mapping of request with multiple
- * source and destination
- */
- @XmlRootElement
- public static class MultiSrcDstFileRequest {
- @XmlElement(nillable = false, required = true)
- public List<String> sourcePaths = new ArrayList<>();
- @XmlElement(nillable = false, required = true)
- public String destinationPath;
- }
-
- /**
- * Wrapper for json mapping of remove request
- */
- @XmlRootElement
- public static class MultiRemoveRequest {
- @XmlElement(nillable = false, required = true)
- public List<PathEntry> paths = new ArrayList<>();
- public static class PathEntry {
- @XmlElement(nillable = false, required = true)
- public String path;
- public boolean recursive;
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java
index 0c1344d..3585516 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java
@@ -19,8 +19,9 @@
package org.apache.ambari.view.filebrowser;
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.commons.exceptions.NotFoundFormattedException;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.commons.hdfs.HdfsService;
import org.apache.ambari.view.utils.hdfs.HdfsApi;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
@@ -37,7 +38,7 @@ import java.io.InputStream;
/**
* File Preview Service
*/
-public class FilePreviewService extends HdfsService{
+public class FilePreviewService extends HdfsService {
private CompressionCodecFactory compressionCodecFactory;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
deleted file mode 100644
index 93105d9..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser;
-
-import javax.ws.rs.WebApplicationException;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.ambari.view.ViewContext;
-import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
-import org.apache.ambari.view.utils.hdfs.HdfsApi;
-import org.apache.ambari.view.utils.hdfs.HdfsUtil;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Base Hdfs service
- */
-public abstract class HdfsService {
-
- protected static final Logger logger = LoggerFactory.getLogger(HdfsService.class);
-
- protected final ViewContext context;
-
- /**
- * Constructor
- * @param context View Context instance
- */
- public HdfsService(ViewContext context) {
- this.context = context;
- }
-
- /**
- * Wrapper for json mapping of result of Multi Remove Request
- */
- @XmlRootElement
- public static class FileOperationResult {
- public boolean success;
- public String message;
- public List<String> succeeded;
- public List<String> failed;
- public List<String> unprocessed;
-
- public FileOperationResult(boolean success) {
- this.success = success;
- }
-
- public FileOperationResult(boolean success, String message) {
- this(success);
- this.message = message;
- }
-
- public FileOperationResult(boolean success, String message, List<String> succeeded, List<String> failed, List<String> unprocessed) {
- this(success, message);
- this.succeeded = succeeded;
- this.failed = failed;
- this.unprocessed = unprocessed;
- }
-
- }
-
- private HdfsApi _api = null;
-
- /**
- * Ger HdfsApi instance
- * @param context View Context instance
- * @return HdfsApi business delegate
- */
- public HdfsApi getApi(ViewContext context) {
- if (_api == null) {
- try {
- _api = HdfsUtil.connectToHDFSApi(context);
- } catch (Exception ex) {
- throw new ServiceFormattedException("HdfsApi connection failed. Check \"webhdfs.url\" property", ex);
- }
- }
- return _api;
- }
-
- private static Map<String, String> getHdfsAuthParams(ViewContext context) {
- String auth = context.getProperties().get("webhdfs.auth");
- Map<String, String> params = new HashMap<String, String>();
- if (auth == null || auth.isEmpty()) {
- auth = "auth=SIMPLE";
- }
- for(String param : auth.split(";")) {
- String[] keyvalue = param.split("=");
- if (keyvalue.length != 2) {
- logger.error("Can not parse authentication param " + param + " in " + auth);
- continue;
- }
- params.put(keyvalue[0], keyvalue[1]);
- }
- return params;
- }
-
- /**
- * Get doAs username to use in HDFS
- * @param context View Context instance
- * @return user name
- */
- public String getDoAsUsername(ViewContext context) {
- String username = context.getProperties().get("webhdfs.username");
- if (username == null || username.isEmpty())
- username = context.getUsername();
- 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
- * @return user name
- */
- public String getRealUsername(ViewContext context) {
- String username = context.getProperties().get("webhdfs.proxyuser");
- if (username == null || username.isEmpty())
- try {
- username = UserGroupInformation.getCurrentUser().getShortUserName();
- } catch (IOException e) {
- throw new ServiceFormattedException("HdfsApi connection failed. Can't get current user", e);
- }
- return username;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java
index b49130b..92af2d5 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HelpService.java
@@ -18,19 +18,14 @@
package org.apache.ambari.view.filebrowser;
-import java.io.FileNotFoundException;
-
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
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.apache.ambari.view.commons.hdfs.HdfsService;
import org.json.simple.JSONObject;
/**
@@ -100,64 +95,4 @@ public class HelpService extends HdfsService {
return Response.ok().entity(response).type(MediaType.APPLICATION_JSON).build();
}
- /**
- * Returns home directory
- * @return home directory
- */
- @GET
- @Path("/home")
- @Produces(MediaType.APPLICATION_JSON)
- public Response homeDir() {
- try {
- HdfsApi api = getApi(context);
- return Response
- .ok(getApi(context).fileStatusToJSON(api.getFileStatus(api.getHomeDir()
- .toString()))).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Is trash enabled
- * @return is trash enabled
- */
- @GET
- @Path("/trash/enabled")
- @Produces(MediaType.APPLICATION_JSON)
- public Response trashEnabled() {
- try {
- HdfsApi api = getApi(context);
- return Response.ok(new FileOperationResult(api.trashEnabled())).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Trash dir
- * @return trash dir
- */
- @GET
- @Path("/trashDir")
- @Produces(MediaType.APPLICATION_JSON)
- public Response trashdir() {
- try {
- HdfsApi api = getApi(context);
- return Response.ok(
- getApi(context).fileStatusToJSON(api.getFileStatus(api.getTrashDir()
- .toString()))).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (FileNotFoundException ex) {
- throw new NotFoundFormattedException(ex.getMessage(), ex);
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/UploadService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/UploadService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/UploadService.java
deleted file mode 100644
index eb5c0c7..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/UploadService.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.ambari.view.ViewContext;
-import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
-import org.apache.ambari.view.utils.hdfs.HdfsApi;
-import org.apache.hadoop.fs.FSDataOutputStream;
-
-import com.sun.jersey.core.header.FormDataContentDisposition;
-import com.sun.jersey.multipart.FormDataParam;
-
-/**
- * Upload service
- */
-public class UploadService extends HdfsService {
-
- /**
- * Constructor
- * @param context View Context instance
- */
- public UploadService(ViewContext context) {
- super(context);
- }
-
- private void uploadFile(final String filePath, InputStream uploadedInputStream)
- throws IOException, InterruptedException {
- int read;
- byte[] chunk = new byte[1024];
- FSDataOutputStream out = null;
- try {
- out = getApi(context).create(filePath, false);
- while ((read = uploadedInputStream.read(chunk)) != -1) {
- out.write(chunk, 0, read);
- }
- } finally {
- if (out != null) {
- out.close();
- }
- }
- }
-
- /**
- * Upload file
- * @param uploadedInputStream file input stream
- * @param contentDisposition content disposition
- * @param path path
- * @return file status
- */
- @PUT
- @Consumes(MediaType.MULTIPART_FORM_DATA)
- @Produces(MediaType.APPLICATION_JSON)
- public Response uploadFile(
- @FormDataParam("file") InputStream uploadedInputStream,
- @FormDataParam("file") FormDataContentDisposition contentDisposition,
- @FormDataParam("path") String path) {
- try {
- if (!path.endsWith("/"))
- path = path + "/";
- String filePath = path + contentDisposition.getFileName();
- uploadFile(filePath, uploadedInputStream);
- return Response.ok(
- getApi(context).fileStatusToJSON(getApi(context).getFileStatus(filePath)))
- .build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Upload zip and unpack
- * @param uploadedInputStream file input stream
- * @param contentDisposition content disposition
- * @param path path
- * @return files statuses
- * @throws IOException
- * @throws Exception
- */
- @PUT
- @Path("/zip")
- @Consumes(MediaType.MULTIPART_FORM_DATA)
- @Produces(MediaType.APPLICATION_JSON)
- public Response uploadZip(
- @FormDataParam("file") InputStream uploadedInputStream,
- @FormDataParam("file") FormDataContentDisposition contentDisposition,
- @FormDataParam("path") String path) {
- try {
- if (!path.endsWith("/"))
- path = path + "/";
- ZipInputStream zip = new ZipInputStream(uploadedInputStream);
- ZipEntry ze = zip.getNextEntry();
- HdfsApi api = getApi(context);
- while (ze != null) {
- String filePath = path + ze.getName();
- if (ze.isDirectory()) {
- api.mkdir(filePath);
- } else {
- uploadFile(filePath, zip);
- }
- ze = zip.getNextEntry();
- }
- return Response.ok(getApi(context).fileStatusToJSON(api.listdir(path))).build();
- } catch (WebApplicationException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new ServiceFormattedException(ex.getMessage(), ex);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/MisconfigurationFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/MisconfigurationFormattedException.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/MisconfigurationFormattedException.java
deleted file mode 100644
index 584bbac..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/MisconfigurationFormattedException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser.utils;
-
-import org.json.simple.JSONObject;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.HashMap;
-
-public class MisconfigurationFormattedException extends WebApplicationException {
- private final static int STATUS = 500;
- private final static String message = "Parameter \"%s\" is set to null";
-
- public MisconfigurationFormattedException(String name) {
- super(errorEntity(name));
- }
-
- protected static Response errorEntity(String name) {
- HashMap<String, Object> response = new HashMap<String, Object>();
- response.put("message", String.format(message, name));
- response.put("trace", null);
- response.put("status", STATUS);
- return Response.status(STATUS).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/NotFoundFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/NotFoundFormattedException.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/NotFoundFormattedException.java
deleted file mode 100644
index f4353cd..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/NotFoundFormattedException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser.utils;
-
-public class NotFoundFormattedException extends ServiceFormattedException {
- private final static int STATUS = 404;
-
- public NotFoundFormattedException(String message, Throwable exception) {
- super(message, exception, STATUS);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/ServiceFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/ServiceFormattedException.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/ServiceFormattedException.java
deleted file mode 100644
index 5cb7dea..0000000
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/utils/ServiceFormattedException.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.ambari.view.filebrowser.utils;
-
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.json.simple.JSONObject;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.security.AccessControlException;
-import java.util.HashMap;
-
-public class ServiceFormattedException extends WebApplicationException {
- public ServiceFormattedException(String message, Throwable exception) {
- super(errorEntity(message, exception, suggestStatus(exception)));
- }
-
- public ServiceFormattedException(String message, Throwable exception, int status) {
- super(errorEntity(message, exception, status));
- }
-
- private static int suggestStatus(Throwable exception) {
- int status = 500;
- if (exception instanceof AccessControlException) {
- status = 403;
- }
- return status;
- }
-
- protected static Response errorEntity(String message, Throwable e, int status) {
- HashMap<String, Object> response = new HashMap<String, Object>();
- response.put("message", message);
- String trace = null;
- if (e != null)
- trace = ExceptionUtils.getStackTrace(e);
- response.put("trace", trace);
- response.put("status", status);
- return Response.status(status).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/resources/ui/app/services/file-operation.js
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/resources/ui/app/services/file-operation.js b/contrib/views/files/src/main/resources/ui/app/services/file-operation.js
index abb3000..09bb67f 100644
--- a/contrib/views/files/src/main/resources/ui/app/services/file-operation.js
+++ b/contrib/views/files/src/main/resources/ui/app/services/file-operation.js
@@ -170,12 +170,12 @@ export default Ember.Service.extend(FileOperationMixin, {
getHome: function () {
var adapter = this.get('store').adapterFor('file');
- return adapter.ajax(this._getMiscUrl("/help/home"), "GET");
+ return adapter.ajax(this._getMiscUrl("/user/home"), "GET");
},
getTrash: function () {
var adapter = this.get('store').adapterFor('file');
- return adapter.ajax(this._getMiscUrl("/help/trashDir"), "GET");
+ return adapter.ajax(this._getMiscUrl("/user/trashDir"), "GET");
},
_getMiscUrl: function (segment) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/main/resources/ui/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/resources/ui/package.json b/contrib/views/files/src/main/resources/ui/package.json
index d15c5c9..5bf3e93 100644
--- a/contrib/views/files/src/main/resources/ui/package.json
+++ b/contrib/views/files/src/main/resources/ui/package.json
@@ -20,6 +20,11 @@
},
"author": "",
"license": "MIT",
+ "ember-addon": {
+ "paths": [
+ "../../../../../commons/src/main/resources/ui/hdfs-directory-viewer"
+ ]
+ },
"devDependencies": {
"bower": "1.7.2",
"broccoli-asset-rev": "^2.2.0",
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
index da804d1..f431f66 100644
--- a/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
+++ b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
@@ -38,6 +38,7 @@ import javax.ws.rs.core.UriInfo;
import org.apache.ambari.view.ViewContext;
import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.commons.hdfs.FileOperationService;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hdfs.MiniDFSCluster;
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pom.xml b/contrib/views/pom.xml
index 18141c6..da12899 100644
--- a/contrib/views/pom.xml
+++ b/contrib/views/pom.xml
@@ -43,6 +43,7 @@
<module>tez</module>
<module>storm</module>
<module>zeppelin</module>
+ <module>commons</module>
</modules>
<build>
<pluginManagement>
[2/2] ambari git commit: AMBARI-15829. Files View: Extract the
directory viewer UI component so that other views can use it. (dipayanb)
Posted by db...@apache.org.
AMBARI-15829. Files View: Extract the directory viewer UI component so that other views can use it. (dipayanb)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/281307fc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/281307fc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/281307fc
Branch: refs/heads/trunk
Commit: 281307fceb533c1a557d9972991263546288bb41
Parents: 33ef653
Author: Dipayan Bhowmick <di...@gmail.com>
Authored: Wed Apr 13 17:52:01 2016 +0530
Committer: Dipayan Bhowmick <di...@gmail.com>
Committed: Wed Apr 13 17:52:01 2016 +0530
----------------------------------------------------------------------
contrib/views/commons/README.md | 84 ++++
contrib/views/commons/pom.xml | 140 ++++++
.../MisconfigurationFormattedException.java | 43 ++
.../exceptions/NotFoundFormattedException.java | 27 ++
.../exceptions/ServiceFormattedException.java | 57 +++
.../view/commons/hdfs/FileOperationService.java | 479 ++++++++++++++++++
.../ambari/view/commons/hdfs/HdfsService.java | 160 ++++++
.../ambari/view/commons/hdfs/UploadService.java | 138 ++++++
.../ambari/view/commons/hdfs/UserService.java | 106 ++++
.../resources/ui/hdfs-directory-viewer/.bowerrc | 4 +
.../ui/hdfs-directory-viewer/.editorconfig | 34 ++
.../ui/hdfs-directory-viewer/.ember-cli | 27 ++
.../ui/hdfs-directory-viewer/.gitignore | 17 +
.../ui/hdfs-directory-viewer/.jshintrc | 32 ++
.../ui/hdfs-directory-viewer/.npmignore | 30 ++
.../ui/hdfs-directory-viewer/.travis.yml | 50 ++
.../ui/hdfs-directory-viewer/.watchmanconfig | 21 +
.../ui/hdfs-directory-viewer/LICENSE.md | 28 ++
.../ui/hdfs-directory-viewer/README.md | 97 ++++
.../ui/hdfs-directory-viewer/addon/.gitkeep | 0
.../addon/components/directory-viewer.js | 196 ++++++++
.../templates/components/directory-viewer.hbs | 18 +
.../addon/utils/viewer-config.js | 59 +++
.../ui/hdfs-directory-viewer/app/.gitkeep | 0
.../app/components/directory-viewer.js | 19 +
.../app/utils/viewer-config.js | 19 +
.../ui/hdfs-directory-viewer/bower.json | 19 +
.../hdfs-directory-viewer/config/ember-try.js | 54 +++
.../hdfs-directory-viewer/config/environment.js | 24 +
.../ui/hdfs-directory-viewer/ember-cli-build.js | 36 ++
.../resources/ui/hdfs-directory-viewer/index.js | 32 ++
.../ui/hdfs-directory-viewer/package.json | 51 ++
.../ui/hdfs-directory-viewer/testem.json | 12 +
.../ui/hdfs-directory-viewer/tests/.jshintrc | 52 ++
.../tests/dummy/app/app.js | 36 ++
.../tests/dummy/app/components/.gitkeep | 0
.../tests/dummy/app/controllers/.gitkeep | 0
.../tests/dummy/app/controllers/application.js | 32 ++
.../tests/dummy/app/helpers/.gitkeep | 0
.../tests/dummy/app/index.html | 43 ++
.../tests/dummy/app/models/.gitkeep | 0
.../tests/dummy/app/router.js | 29 ++
.../tests/dummy/app/routes/.gitkeep | 0
.../tests/dummy/app/styles/app.css | 23 +
.../tests/dummy/app/templates/application.hbs | 36 ++
.../dummy/app/templates/components/.gitkeep | 0
.../tests/dummy/app/utils/my-viewer-config.js | 35 ++
.../tests/dummy/config/environment.js | 65 +++
.../tests/dummy/public/crossdomain.xml | 15 +
.../tests/dummy/public/robots.txt | 3 +
.../tests/helpers/destroy-app.js | 23 +
.../tests/helpers/module-for-acceptance.js | 41 ++
.../tests/helpers/resolver.js | 29 ++
.../tests/helpers/start-app.js | 36 ++
.../ui/hdfs-directory-viewer/tests/index.html | 52 ++
.../tests/integration/.gitkeep | 0
.../hdfs-directory-viewer/tests/test-helper.js | 24 +
.../hdfs-directory-viewer/tests/unit/.gitkeep | 0
.../ui/hdfs-directory-viewer/vendor/.gitkeep | 0
contrib/views/files/pom.xml | 5 +
.../view/filebrowser/DownloadService.java | 8 +-
.../view/filebrowser/FileBrowserService.java | 13 +-
.../view/filebrowser/FileOperationService.java | 484 -------------------
.../view/filebrowser/FilePreviewService.java | 7 +-
.../ambari/view/filebrowser/HdfsService.java | 160 ------
.../ambari/view/filebrowser/HelpService.java | 67 +--
.../ambari/view/filebrowser/UploadService.java | 137 ------
.../MisconfigurationFormattedException.java | 43 --
.../utils/NotFoundFormattedException.java | 27 --
.../utils/ServiceFormattedException.java | 57 ---
.../resources/ui/app/services/file-operation.js | 4 +-
.../files/src/main/resources/ui/package.json | 5 +
.../view/filebrowser/FilebrowserTest.java | 1 +
contrib/views/pom.xml | 1 +
74 files changed, 2721 insertions(+), 985 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/README.md
----------------------------------------------------------------------
diff --git a/contrib/views/commons/README.md b/contrib/views/commons/README.md
new file mode 100644
index 0000000..b956fbd
--- /dev/null
+++ b/contrib/views/commons/README.md
@@ -0,0 +1,84 @@
+<!---
+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](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.
+-->
+
+#Ambari Views Commons Module
+
+Have this as a dependency in the view which need the functionality.
+
+This has common code for:
+
+* HDFS access
+
+**Note: More to be added later**
+
+### How to Include it in dependant project
+
+In the service class for the project use `commons` projects code in the way described in the below example for `files` view.
+
+```java
+package org.apache.ambari.view.filebrowser;
+
+import javax.ws.rs.Path;
+
+import org.apache.ambari.view.ViewContext;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.commons.hdfs.FileOperationService;
+import org.apache.ambari.view.commons.hdfs.UploadService;
+import org.apache.ambari.view.commons.hdfs.UserService;
+
+/**
+ * Root files service
+ */
+public class FileBrowserService {
+
+ @Inject
+ ViewContext context;
+
+ /**
+ * @see UploadService
+ * @return service
+ */
+ @Path("/upload")
+ public UploadService upload() {
+ return new UploadService(context);
+ }
+
+ /**
+ * @see org.apache.ambari.view.commons.hdfs.FileOperationService
+ * @return service
+ */
+ @Path("/fileops")
+ public FileOperationService fileOps() {
+ return new FileOperationService(context);
+ }
+
+ /**
+ * @see org.apache.ambari.view.commons.hdfs.UserService
+ * @return service
+ */
+ @Path("/user")
+ public UserService userService() { return new UserService(context); }
+
+}
+```
+
+
+####Also, look into the various ember addons that are included in `src/main/resources/ui`.
+Currently we have:
+
+* hdfs-directory-viewer
+
+**More to be added later**
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/commons/pom.xml b/contrib/views/commons/pom.xml
new file mode 100644
index 0000000..5018d46
--- /dev/null
+++ b/contrib/views/commons/pom.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>ambari-views-commons</artifactId>
+ <version>2.0.0.0-SNAPSHOT</version>
+ <name>Ambari View Commons</name>
+
+ <parent>
+ <artifactId>ambari-contrib-views</artifactId>
+ <groupId>org.apache.ambari.contrib.views</groupId>
+ <version>2.0.0.0-SNAPSHOT</version>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ambari.contrib.views</groupId>
+ <artifactId>ambari-views-utils</artifactId>
+ <version>2.0.0.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-views</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs</artifactId>
+ <version>${hadoop.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-runtime</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-common</artifactId>
+ <version>${hadoop.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-runtime</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.jersey.contribs</groupId>
+ <artifactId>jersey-multipart</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>com.sun.jersey.jersey-test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-minicluster</artifactId>
+ <version>${hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources/</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>ui/**</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+
+ <properties>
+ <ambari.dir>${project.parent.parent.parent.basedir}</ambari.dir>
+ </properties>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/MisconfigurationFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/MisconfigurationFormattedException.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/MisconfigurationFormattedException.java
new file mode 100644
index 0000000..b7ce938
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/MisconfigurationFormattedException.java
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.exceptions;
+
+import org.json.simple.JSONObject;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.HashMap;
+
+public class MisconfigurationFormattedException extends WebApplicationException {
+ private final static int STATUS = 500;
+ private final static String message = "Parameter \"%s\" is set to null";
+
+ public MisconfigurationFormattedException(String name) {
+ super(errorEntity(name));
+ }
+
+ protected static Response errorEntity(String name) {
+ HashMap<String, Object> response = new HashMap<String, Object>();
+ response.put("message", String.format(message, name));
+ response.put("trace", null);
+ response.put("status", STATUS);
+ return Response.status(STATUS).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/NotFoundFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/NotFoundFormattedException.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/NotFoundFormattedException.java
new file mode 100644
index 0000000..a8c51f7
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/NotFoundFormattedException.java
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.exceptions;
+
+public class NotFoundFormattedException extends ServiceFormattedException {
+ private final static int STATUS = 404;
+
+ public NotFoundFormattedException(String message, Throwable exception) {
+ super(message, exception, STATUS);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/ServiceFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/ServiceFormattedException.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/ServiceFormattedException.java
new file mode 100644
index 0000000..bb77404
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/exceptions/ServiceFormattedException.java
@@ -0,0 +1,57 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.exceptions;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.json.simple.JSONObject;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.security.AccessControlException;
+import java.util.HashMap;
+
+public class ServiceFormattedException extends WebApplicationException {
+ public ServiceFormattedException(String message, Throwable exception) {
+ super(errorEntity(message, exception, suggestStatus(exception)));
+ }
+
+ public ServiceFormattedException(String message, Throwable exception, int status) {
+ super(errorEntity(message, exception, status));
+ }
+
+ private static int suggestStatus(Throwable exception) {
+ int status = 500;
+ if (exception instanceof AccessControlException) {
+ status = 403;
+ }
+ return status;
+ }
+
+ protected static Response errorEntity(String message, Throwable e, int status) {
+ HashMap<String, Object> response = new HashMap<String, Object>();
+ response.put("message", message);
+ String trace = null;
+ if (e != null)
+ trace = ExceptionUtils.getStackTrace(e);
+ response.put("trace", trace);
+ response.put("status", status);
+ return Response.status(status).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/FileOperationService.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/FileOperationService.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/FileOperationService.java
new file mode 100644
index 0000000..bc3d11d
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/FileOperationService.java
@@ -0,0 +1,479 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.hdfs;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.commons.exceptions.NotFoundFormattedException;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.utils.hdfs.HdfsApi;
+import org.apache.ambari.view.utils.hdfs.HdfsApiException;
+import org.json.simple.JSONObject;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * File operations service
+ */
+public class FileOperationService extends HdfsService {
+
+ /**
+ * Constructor
+ * @param context View Context instance
+ */
+ public FileOperationService(ViewContext context) {
+ super(context);
+ }
+
+ /**
+ * List dir
+ * @param path path
+ * @return response with dir content
+ */
+ @GET
+ @Path("/listdir")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response listdir(@QueryParam("path") String path) {
+ try {
+ JSONObject response = new JSONObject();
+ response.put("files", getApi(context).fileStatusToJSON(getApi(context).listdir(path)));
+ response.put("meta", getApi(context).fileStatusToJSON(getApi(context).getFileStatus(path)));
+ return Response.ok(response).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (FileNotFoundException ex) {
+ throw new NotFoundFormattedException(ex.getMessage(), ex);
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Rename
+ * @param request rename request
+ * @return response with success
+ */
+ @POST
+ @Path("/rename")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response rename(final SrcDstFileRequest request) {
+ try {
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ if (api.rename(request.src, request.dst)) {
+ result = Response.ok(getApi(context).fileStatusToJSON(api
+ .getFileStatus(request.dst)));
+ } else {
+ result = Response.ok(new FileOperationResult(false, "Can't move '" + request.src + "' to '" + request.dst + "'")).status(422);
+ }
+ return result.build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Chmod
+ * @param request chmod request
+ * @return response with success
+ */
+ @POST
+ @Path("/chmod")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response chmod(final ChmodRequest request) {
+ try {
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ if (api.chmod(request.path, request.mode)) {
+ result = Response.ok(getApi(context).fileStatusToJSON(api
+ .getFileStatus(request.path)));
+ } else {
+ result = Response.ok(new FileOperationResult(false, "Can't chmod '" + request.path + "'")).status(422);
+ }
+ return result.build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Copy file
+ * @param request source and destination request
+ * @return response with success
+ */
+ @POST
+ @Path("/move")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response move(final MultiSrcDstFileRequest request,
+ @Context HttpHeaders headers, @Context UriInfo ui) {
+ try {
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ String message = "";
+
+ List<String> sources = request.sourcePaths;
+ String destination = request.destinationPath;
+ if(sources.isEmpty()) {
+ result = Response.ok(new FileOperationResult(false, "Can't move 0 file/folder to '" + destination + "'")).
+ status(422);
+ return result.build();
+ }
+
+ int index = 0;
+ for (String src : sources) {
+ String fileName = getFileName(src);
+ String finalDestination = getDestination(destination, fileName);
+ try {
+ if (api.rename(src, finalDestination)) {
+ index ++;
+ } else {
+ message = "Failed to move '" + src + "' to '" + finalDestination + "'";
+ break;
+ }
+ } catch (IOException exception) {
+ message = exception.getMessage();
+ logger.error("Failed to move '{}' to '{}'. Exception: {}", src, finalDestination,
+ exception.getMessage());
+ break;
+ }
+ }
+ if (index == sources.size()) {
+ result = Response.ok(new FileOperationResult(true)).status(200);
+ } else {
+ FileOperationResult errorResult = getFailureFileOperationResult(sources, index, message);
+ result = Response.ok(errorResult).status(422);
+ }
+ return result.build();
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Copy file
+ * @param request source and destination request
+ * @return response with success
+ */
+ @POST
+ @Path("/copy")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response copy(final MultiSrcDstFileRequest request,
+ @Context HttpHeaders headers, @Context UriInfo ui) {
+ try {
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ String message = "";
+
+ List<String> sources = request.sourcePaths;
+ String destination = request.destinationPath;
+ if(sources.isEmpty()) {
+ result = Response.ok(new FileOperationResult(false, "Can't copy 0 file/folder to '" + destination + "'")).
+ status(422);
+ return result.build();
+ }
+
+ int index = 0;
+ for (String src : sources) {
+ String fileName = getFileName(src);
+ String finalDestination = getDestination(destination, fileName);
+ try {
+ api.copy(src, finalDestination);
+ index ++;
+ } catch (IOException|HdfsApiException exception) {
+ message = exception.getMessage();
+ logger.error("Failed to copy '{}' to '{}'. Exception: {}", src, finalDestination,
+ exception.getMessage());
+ break;
+ }
+ }
+ if (index == sources.size()) {
+ result = Response.ok(new FileOperationResult(true)).status(200);
+ } else {
+ FileOperationResult errorResult = getFailureFileOperationResult(sources, index, message);
+ result = Response.ok(errorResult).status(422);
+ }
+ return result.build();
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Make directory
+ * @param request make directory request
+ * @return response with success
+ */
+ @PUT
+ @Path("/mkdir")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response mkdir(final MkdirRequest request) {
+ try{
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ if (api.mkdir(request.path)) {
+ result = Response.ok(getApi(context).fileStatusToJSON(api.getFileStatus(request.path)));
+ } else {
+ result = Response.ok(new FileOperationResult(false, "Can't create dir '" + request.path + "'")).status(422);
+ }
+ return result.build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Empty trash
+ * @return response with success
+ */
+ @DELETE
+ @Path("/trash/emptyTrash")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response emptyTrash() {
+ try {
+ HdfsApi api = getApi(context);
+ api.emptyTrash();
+ return Response.ok(new FileOperationResult(true)).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Move to trash
+ * @param request remove request
+ * @return response with success
+ */
+ @DELETE
+ @Path("/moveToTrash")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response moveToTrash(MultiRemoveRequest request) {
+ try {
+ ResponseBuilder result;
+ HdfsApi api = getApi(context);
+ String trash = api.getTrashDirPath();
+ String message = "";
+
+ if (request.paths.size() == 0) {
+ result = Response.ok(new FileOperationResult(false, "No path entries provided.")).status(422);
+ } else {
+ if (!api.exists(trash)) {
+ if (!api.mkdir(trash)) {
+ result = Response.ok(new FileOperationResult(false, "Trash dir does not exists. Can't create dir for " +
+ "trash '" + trash + "'")).status(422);
+ return result.build();
+ }
+ }
+
+ int index = 0;
+ for (MultiRemoveRequest.PathEntry entry : request.paths) {
+ String trashFilePath = api.getTrashDirPath(entry.path);
+ try {
+ if (api.rename(entry.path, trashFilePath)) {
+ index ++;
+ } else {
+ message = "Failed to move '" + entry.path + "' to '" + trashFilePath + "'";
+ break;
+ }
+ } catch (IOException exception) {
+ message = exception.getMessage();
+ logger.error("Failed to move '{}' to '{}'. Exception: {}", entry.path, trashFilePath,
+ exception.getMessage());
+ break;
+ }
+ }
+ if (index == request.paths.size()) {
+ result = Response.ok(new FileOperationResult(true)).status(200);
+ } else {
+ FileOperationResult errorResult = getFailureFileOperationResult(getPathsFromPathsEntries(request.paths), index, message);
+ result = Response.ok(errorResult).status(422);
+ }
+ }
+ return result.build();
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Remove
+ * @param request remove request
+ * @return response with success
+ */
+ @DELETE
+ @Path("/remove")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response remove(MultiRemoveRequest request, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ try {
+ HdfsApi api = getApi(context);
+ ResponseBuilder result;
+ String message = "";
+ if(request.paths.size() == 0) {
+ result = Response.ok(new FileOperationResult(false, "No path entries provided."));
+ } else {
+ int index = 0;
+ for (MultiRemoveRequest.PathEntry entry : request.paths) {
+ try {
+ if (api.delete(entry.path, entry.recursive)) {
+ index++;
+ } else {
+ message = "Failed to remove '" + entry.path + "'";
+ break;
+ }
+ } catch (IOException exception) {
+ message = exception.getMessage();
+ logger.error("Failed to remove '{}'. Exception: {}", entry.path, exception.getMessage());
+ break;
+ }
+
+ }
+ if (index == request.paths.size()) {
+ result = Response.ok(new FileOperationResult(true)).status(200);
+ } else {
+ FileOperationResult errorResult = getFailureFileOperationResult(getPathsFromPathsEntries(request.paths), index, message);
+ result = Response.ok(errorResult).status(422);
+ }
+ }
+ return result.build();
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ private List<String> getPathsFromPathsEntries(List<MultiRemoveRequest.PathEntry> paths) {
+ List<String> entries = new ArrayList<>();
+ for(MultiRemoveRequest.PathEntry path: paths) {
+ entries.add(path.path);
+ }
+ return entries;
+ }
+
+ private FileOperationResult getFailureFileOperationResult(List<String> paths, int failedIndex, String message) {
+ List<String> succeeded = new ArrayList<>();
+ List<String> unprocessed = new ArrayList<>();
+ List<String> failed = new ArrayList<>();
+ ListIterator<String> iter = paths.listIterator();
+ while (iter.hasNext()) {
+ int index = iter.nextIndex();
+ String path = iter.next();
+ if (index < failedIndex) {
+ succeeded.add(path);
+ } else if (index == failedIndex) {
+ failed.add(path);
+ } else {
+ unprocessed.add(path);
+ }
+ }
+ return new FileOperationResult(false, message, succeeded, failed, unprocessed);
+ }
+
+ private String getDestination(String baseDestination, String fileName) {
+ if(baseDestination.endsWith("/")) {
+ return baseDestination + fileName;
+ } else {
+ return baseDestination + "/" + fileName;
+ }
+ }
+
+ private String getFileName(String srcPath) {
+ return srcPath.substring(srcPath.lastIndexOf('/') + 1);
+ }
+
+
+ /**
+ * Wrapper for json mapping of mkdir request
+ */
+ @XmlRootElement
+ public static class MkdirRequest {
+ @XmlElement(nillable = false, required = true)
+ public String path;
+ }
+
+ /**
+ * Wrapper for json mapping of chmod request
+ */
+ @XmlRootElement
+ public static class ChmodRequest {
+ @XmlElement(nillable = false, required = true)
+ public String path;
+ @XmlElement(nillable = false, required = true)
+ public String mode;
+ }
+
+ /**
+ * Wrapper for json mapping of request with
+ * source and destination
+ */
+ @XmlRootElement
+ public static class SrcDstFileRequest {
+ @XmlElement(nillable = false, required = true)
+ public String src;
+ @XmlElement(nillable = false, required = true)
+ public String dst;
+ }
+
+ /**
+ * Wrapper for json mapping of request with multiple
+ * source and destination
+ */
+ @XmlRootElement
+ public static class MultiSrcDstFileRequest {
+ @XmlElement(nillable = false, required = true)
+ public List<String> sourcePaths = new ArrayList<>();
+ @XmlElement(nillable = false, required = true)
+ public String destinationPath;
+ }
+
+ /**
+ * Wrapper for json mapping of remove request
+ */
+ @XmlRootElement
+ public static class MultiRemoveRequest {
+ @XmlElement(nillable = false, required = true)
+ public List<PathEntry> paths = new ArrayList<>();
+ public static class PathEntry {
+ @XmlElement(nillable = false, required = true)
+ public String path;
+ public boolean recursive;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/HdfsService.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/HdfsService.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/HdfsService.java
new file mode 100644
index 0000000..91eebcf
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/HdfsService.java
@@ -0,0 +1,160 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.hdfs;
+
+import javax.ws.rs.WebApplicationException;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.utils.hdfs.HdfsApi;
+import org.apache.ambari.view.utils.hdfs.HdfsUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base Hdfs service
+ */
+public abstract class HdfsService {
+
+ protected static final Logger logger = LoggerFactory.getLogger(HdfsService.class);
+
+ protected final ViewContext context;
+
+ /**
+ * Constructor
+ * @param context View Context instance
+ */
+ public HdfsService(ViewContext context) {
+ this.context = context;
+ }
+
+ /**
+ * Wrapper for json mapping of result of Multi Remove Request
+ */
+ @XmlRootElement
+ public static class FileOperationResult {
+ public boolean success;
+ public String message;
+ public List<String> succeeded;
+ public List<String> failed;
+ public List<String> unprocessed;
+
+ public FileOperationResult(boolean success) {
+ this.success = success;
+ }
+
+ public FileOperationResult(boolean success, String message) {
+ this(success);
+ this.message = message;
+ }
+
+ public FileOperationResult(boolean success, String message, List<String> succeeded, List<String> failed, List<String> unprocessed) {
+ this(success, message);
+ this.succeeded = succeeded;
+ this.failed = failed;
+ this.unprocessed = unprocessed;
+ }
+
+ }
+
+ private HdfsApi _api = null;
+
+ /**
+ * Ger HdfsApi instance
+ * @param context View Context instance
+ * @return HdfsApi business delegate
+ */
+ public HdfsApi getApi(ViewContext context) {
+ if (_api == null) {
+ try {
+ _api = HdfsUtil.connectToHDFSApi(context);
+ } catch (Exception ex) {
+ throw new ServiceFormattedException("HdfsApi connection failed. Check \"webhdfs.url\" property", ex);
+ }
+ }
+ return _api;
+ }
+
+ private static Map<String, String> getHdfsAuthParams(ViewContext context) {
+ String auth = context.getProperties().get("webhdfs.auth");
+ Map<String, String> params = new HashMap<String, String>();
+ if (auth == null || auth.isEmpty()) {
+ auth = "auth=SIMPLE";
+ }
+ for(String param : auth.split(";")) {
+ String[] keyvalue = param.split("=");
+ if (keyvalue.length != 2) {
+ logger.error("Can not parse authentication param " + param + " in " + auth);
+ continue;
+ }
+ params.put(keyvalue[0], keyvalue[1]);
+ }
+ return params;
+ }
+
+ /**
+ * Get doAs username to use in HDFS
+ * @param context View Context instance
+ * @return user name
+ */
+ public String getDoAsUsername(ViewContext context) {
+ String username = context.getProperties().get("webhdfs.username");
+ if (username == null || username.isEmpty())
+ username = context.getUsername();
+ 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
+ * @return user name
+ */
+ public String getRealUsername(ViewContext context) {
+ String username = context.getProperties().get("webhdfs.proxyuser");
+ if (username == null || username.isEmpty())
+ try {
+ username = UserGroupInformation.getCurrentUser().getShortUserName();
+ } catch (IOException e) {
+ throw new ServiceFormattedException("HdfsApi connection failed. Can't get current user", e);
+ }
+ return username;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UploadService.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UploadService.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UploadService.java
new file mode 100644
index 0000000..97253ad
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UploadService.java
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.hdfs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.commons.hdfs.HdfsService;
+import org.apache.ambari.view.utils.hdfs.HdfsApi;
+import org.apache.hadoop.fs.FSDataOutputStream;
+
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import com.sun.jersey.multipart.FormDataParam;
+
+/**
+ * Upload service
+ */
+public class UploadService extends HdfsService {
+
+ /**
+ * Constructor
+ * @param context View Context instance
+ */
+ public UploadService(ViewContext context) {
+ super(context);
+ }
+
+ private void uploadFile(final String filePath, InputStream uploadedInputStream)
+ throws IOException, InterruptedException {
+ int read;
+ byte[] chunk = new byte[1024];
+ FSDataOutputStream out = null;
+ try {
+ out = getApi(context).create(filePath, false);
+ while ((read = uploadedInputStream.read(chunk)) != -1) {
+ out.write(chunk, 0, read);
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Upload file
+ * @param uploadedInputStream file input stream
+ * @param contentDisposition content disposition
+ * @param path path
+ * @return file status
+ */
+ @PUT
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response uploadFile(
+ @FormDataParam("file") InputStream uploadedInputStream,
+ @FormDataParam("file") FormDataContentDisposition contentDisposition,
+ @FormDataParam("path") String path) {
+ try {
+ if (!path.endsWith("/"))
+ path = path + "/";
+ String filePath = path + contentDisposition.getFileName();
+ uploadFile(filePath, uploadedInputStream);
+ return Response.ok(
+ getApi(context).fileStatusToJSON(getApi(context).getFileStatus(filePath)))
+ .build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Upload zip and unpack
+ * @param uploadedInputStream file input stream
+ * @param contentDisposition content disposition
+ * @param path path
+ * @return files statuses
+ * @throws IOException
+ * @throws Exception
+ */
+ @PUT
+ @Path("/zip")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response uploadZip(
+ @FormDataParam("file") InputStream uploadedInputStream,
+ @FormDataParam("file") FormDataContentDisposition contentDisposition,
+ @FormDataParam("path") String path) {
+ try {
+ if (!path.endsWith("/"))
+ path = path + "/";
+ ZipInputStream zip = new ZipInputStream(uploadedInputStream);
+ ZipEntry ze = zip.getNextEntry();
+ HdfsApi api = getApi(context);
+ while (ze != null) {
+ String filePath = path + ze.getName();
+ if (ze.isDirectory()) {
+ api.mkdir(filePath);
+ } else {
+ uploadFile(filePath, zip);
+ }
+ ze = zip.getNextEntry();
+ }
+ return Response.ok(getApi(context).fileStatusToJSON(api.listdir(path))).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UserService.java
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UserService.java b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UserService.java
new file mode 100644
index 0000000..dc303ce
--- /dev/null
+++ b/contrib/views/commons/src/main/java/org/apache/ambari/view/commons/hdfs/UserService.java
@@ -0,0 +1,106 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.commons.hdfs;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.commons.exceptions.NotFoundFormattedException;
+import org.apache.ambari.view.commons.exceptions.ServiceFormattedException;
+import org.apache.ambari.view.utils.hdfs.HdfsApi;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.FileNotFoundException;
+
+/**
+ * User related info service
+ */
+public class UserService extends HdfsService {
+
+ /**
+ * Constructor
+ * @param context View Context instance
+ */
+ public UserService(ViewContext context) {
+ super(context);
+ }
+
+ /**
+ * Returns home directory
+ * @return home directory
+ */
+ @GET
+ @Path("/home")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response homeDir() {
+ try {
+ HdfsApi api = getApi(context);
+ return Response
+ .ok(getApi(context).fileStatusToJSON(api.getFileStatus(api.getHomeDir()
+ .toString()))).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Is trash enabled
+ * @return is trash enabled
+ */
+ @GET
+ @Path("/trash/enabled")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response trashEnabled() {
+ try {
+ HdfsApi api = getApi(context);
+ return Response.ok(new FileOperationResult(api.trashEnabled())).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Trash dir
+ * @return trash dir
+ */
+ @GET
+ @Path("/trashDir")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response trashdir() {
+ try {
+ HdfsApi api = getApi(context);
+ return Response.ok(
+ getApi(context).fileStatusToJSON(api.getFileStatus(api.getTrashDir()
+ .toString()))).build();
+ } catch (WebApplicationException ex) {
+ throw ex;
+ } catch (FileNotFoundException ex) {
+ throw new NotFoundFormattedException(ex.getMessage(), ex);
+ } catch (Exception ex) {
+ throw new ServiceFormattedException(ex.getMessage(), ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.bowerrc
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.bowerrc b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.bowerrc
new file mode 100644
index 0000000..959e169
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.bowerrc
@@ -0,0 +1,4 @@
+{
+ "directory": "bower_components",
+ "analytics": false
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.editorconfig
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.editorconfig b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.editorconfig
new file mode 100644
index 0000000..47c5438
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.editorconfig
@@ -0,0 +1,34 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.hbs]
+insert_final_newline = false
+indent_style = space
+indent_size = 2
+
+[*.css]
+indent_style = space
+indent_size = 2
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{diff,md}]
+trim_trailing_whitespace = false
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.ember-cli
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.ember-cli b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.ember-cli
new file mode 100644
index 0000000..5a339b9
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.ember-cli
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+
+{
+ /**
+ Ember CLI sends analytics information by default. The data is completely
+ anonymous, but there are times when you might want to disable this behavior.
+
+ Setting `disableAnalytics` to true will prevent any data from being sent.
+ */
+ "disableAnalytics": false
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.gitignore
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.gitignore b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.gitignore
new file mode 100644
index 0000000..86fceae
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.gitignore
@@ -0,0 +1,17 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+
+# dependencies
+/node_modules
+/bower_components
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage/*
+/libpeerconnection.log
+npm-debug.log
+testem.log
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.jshintrc
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.jshintrc b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.jshintrc
new file mode 100644
index 0000000..08096ef
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.jshintrc
@@ -0,0 +1,32 @@
+{
+ "predef": [
+ "document",
+ "window",
+ "-Promise"
+ ],
+ "browser": true,
+ "boss": true,
+ "curly": true,
+ "debug": false,
+ "devel": true,
+ "eqeqeq": true,
+ "evil": true,
+ "forin": false,
+ "immed": false,
+ "laxbreak": false,
+ "newcap": true,
+ "noarg": true,
+ "noempty": false,
+ "nonew": false,
+ "nomen": false,
+ "onevar": false,
+ "plusplus": false,
+ "regexp": false,
+ "undef": true,
+ "sub": true,
+ "strict": false,
+ "white": false,
+ "eqnull": true,
+ "esnext": true,
+ "unused": true
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.npmignore
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.npmignore b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.npmignore
new file mode 100644
index 0000000..fea9ccc
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.npmignore
@@ -0,0 +1,30 @@
+# 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.
+
+bower_components/
+tests/
+tmp/
+dist/
+
+.bowerrc
+.editorconfig
+.ember-cli
+.travis.yml
+.npmignore
+**/.gitkeep
+bower.json
+Brocfile.js
+testem.json
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.travis.yml
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.travis.yml b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.travis.yml
new file mode 100644
index 0000000..dbc0990
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.travis.yml
@@ -0,0 +1,50 @@
+# 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.
+
+---
+language: node_js
+node_js:
+ - "0.12"
+
+sudo: false
+
+cache:
+ directories:
+ - node_modules
+
+env:
+ - EMBER_TRY_SCENARIO=default
+ - EMBER_TRY_SCENARIO=ember-release
+ - EMBER_TRY_SCENARIO=ember-beta
+ - EMBER_TRY_SCENARIO=ember-canary
+
+matrix:
+ fast_finish: true
+ allow_failures:
+ - env: EMBER_TRY_SCENARIO=ember-canary
+
+before_install:
+ - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
+ - "npm config set spin false"
+ - "npm install -g npm@^2"
+
+install:
+ - npm install -g bower
+ - npm install
+ - bower install
+
+script:
+ - ember try $EMBER_TRY_SCENARIO test
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.watchmanconfig
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.watchmanconfig b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.watchmanconfig
new file mode 100644
index 0000000..6ec27cc
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/.watchmanconfig
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+{
+ "ignore_dirs": ["tmp", "dist"]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/LICENSE.md
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/LICENSE.md b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/LICENSE.md
new file mode 100644
index 0000000..c1f9da4
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/LICENSE.md
@@ -0,0 +1,28 @@
+<!---
+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](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.
+-->
+
+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](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.
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/README.md
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/README.md b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/README.md
new file mode 100644
index 0000000..d383a93
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/README.md
@@ -0,0 +1,97 @@
+<!---
+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](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.
+-->
+
+# Hdfs-directory-viewer
+
+Ember Addon to view the HDFS file system.
+
+Different Ambari views can use this in their view. Common code should be usable in every view.
+
+# How to use it
+
+### Including it in dependant project
+Add the following code in package.json of the dependant view
+
+```javascript
+"name": "files",
+"ember-addon": {
+ "paths": [
+ "../../../../../commons/src/main/resources/ui/hdfs-directory-viewer"
+ ]
+}
+```
+
+`paths` is an array which includes all the addons shares in ```commons``` library. The entries should be the relative path to the addon in this ```commons``` repository.
+
+### Including the UI dependencies in the dependent project
+As we are going to include the component using the `ember-addon` config in `package.json` and not by the `ember install` way, the UI dependencies also has to be included in the dependent projects `bower.json` file if not already added.
+
+```
+"bootstrap": "~3.3.6",
+"bootstrap-treeview": "~1.2.0",
+"font-awesome": "~4.5.0"
+```
+
+### Overriding configs in dependant project
+
+Create a util object in `utils` directory using `ember generate util <object name>` and override it as follows:
+
+```javascript
+import ViewerConfig from 'hdfs-directory-viewer/utils/viewer-config';
+
+export default ViewerConfig.extend({
+ showOnlyDirectories: true,
+
+ expandIcon: 'fa fa-chevron-right',
+ collapseIcon: 'fa fa-chevron-down',
+
+ listDirectoryUrl(pathParams) {
+ return `/api/v1/views/FILES/versions/1.0.0/instances/files/resources/files/fileops/listdir?${pathParams}`;
+ }
+});
+```
+
+All the functions and attributes in `hdfs-directory-viewer/utils/viewer-config` can be overriden
+
+### Passing the object to the view template
+
+```javascript
+import Ember from 'ember';
+import MyViewerConfig from '../utils/my-viewer-config';
+
+export default Ember.Controller.extend({
+ config: MyViewerConfig.create(),
+ actions: {
+ viewerError: function() {
+ console.log("Failed to fetch the content!!!");
+ },
+ viewerSelectedPath: function(data) {
+ console.log(`User selected: path: ${data.path}, isDirectory: ${data.isDirectory}`);
+ }
+ }
+});
+```
+
+```html
+...
+<div class="directory-viewer-wrap">
+ {{directory-viewer
+ config=config
+ errorAction="viewerError"
+ pathSelectAction="viewerSelectedPath"
+ }}
+</div>
+...
+```
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
new file mode 100644
index 0000000..991d122
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
@@ -0,0 +1,196 @@
+/**
+ * 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';
+import layout from '../templates/components/directory-viewer';
+
+export default Ember.Component.extend({
+ layout,
+ config: Ember.Object.create({}),
+ classNames: ['directory-viewer'],
+ startPath: '/',
+ treeData: Ember.A(),
+ currentPath: Ember.computed.oneWay('startPath'),
+ currentQueryParam: Ember.computed('currentPath', function() {
+ return Ember.$.param({path: this.get('currentPath')});
+ }),
+
+ startFetch: Ember.on('didInitAttrs', function() {
+ this.fetchData();
+ }),
+
+
+ fetchData: function() {
+ this.listPath(this.get('currentQueryParam')).then(
+ (response) => {
+ let list = this.filterDirectoriesIfRequired(response.files);
+ this.modifyTreeViewData(list);
+ }, (error) => {
+ this.sendAction('errorAction', error);
+ }
+ );
+ },
+
+ /**
+ * Makes a XHR call and returns a promise.
+ */
+ listPath: function(params) {
+ let config = this.get('config');
+ let listUrl = config.listDirectoryUrl(params);
+ let headers = config.getHeaders();
+ return Ember.$.ajax(listUrl, {
+ headers: headers
+ });
+ },
+
+ filterDirectoriesIfRequired: function(files) {
+ let showOnlyDirectories = this.get('config.showOnlyDirectories');
+ return files.filter((entry) => {
+ return (!(showOnlyDirectories) || entry.isDirectory);
+ });
+ },
+
+ modifyTreeViewData: function(response) {
+ let paths = response.map((entry) => {
+ let isDirectory = entry.isDirectory;
+ let icon = isDirectory ? this.get('config.folderIcon') : this.get('config.fileIcon');
+ let data = {
+ path: entry.path,
+ pathSegment: this.getNameForPath(entry.path),
+ isDirectory: isDirectory,
+ icon: icon,
+ text: this.getNameForPath(entry.path)
+ };
+ if(isDirectory) {
+ data.nodes = Ember.A();
+ }
+ return data;
+ });
+
+ var currentPath = this.get('currentPath');
+ var newTreeData = Ember.copy(this.get('treeData'), true);
+ if(currentPath === '/') {
+ newTreeData = paths;
+ } else {
+ this.insertPathToTreeData(newTreeData, paths, currentPath.substring(1));
+ }
+
+ this.set('treeData', newTreeData);
+ this.send('refreshTreeView');
+ },
+
+ insertPathToTreeData(treeData, paths, pathSegment) {
+ let firstPathSegment;
+ if (pathSegment.indexOf('/') !== -1) {
+ firstPathSegment = pathSegment.substring(0, pathSegment.indexOf('/'));
+ } else {
+ firstPathSegment = pathSegment;
+ }
+
+ if(treeData.length === 0) {
+ treeData.pushObjects(paths);
+ } else {
+ treeData.forEach((entry) => {
+ entry.state = {};
+ if (entry.pathSegment === firstPathSegment) {
+ entry.state.expanded = true;
+ if(entry.nodes.length === 0) {
+ paths.forEach((pathEntry) => {
+ entry.nodes.push(pathEntry);
+ });
+ } else {
+ this.insertPathToTreeData(entry.nodes, paths, pathSegment.substring(pathSegment.indexOf('/') + 1));
+ }
+ } else {
+ this.collapseAll(entry);
+ }
+ });
+ }
+ },
+
+ collapseAll: function(node) {
+ if (Ember.isNone(node.state)) {
+ node.state = {};
+ }
+ node.state.expanded = false;
+ if(!Ember.isNone(node.nodes)) {
+ node.nodes.forEach((entry) => {
+ this.collapseAll(entry);
+ });
+ }
+ },
+
+ getNameForPath: function(path) {
+ return path.substring(path.lastIndexOf("/") + 1);
+ },
+
+ collapseAllExceptPath: function(pathSegment) {
+ let collapseAll = function(nodes, pathSegment) {
+ var firstPathSegment;
+ if (pathSegment.indexOf('/') !== -1) {
+ firstPathSegment = pathSegment.substring(0, pathSegment.indexOf('/'));
+ } else {
+ firstPathSegment = pathSegment;
+ }
+
+ nodes.forEach((entry) => {
+ if (Ember.isNone(entry.state)) {
+ entry.state = {};
+ }
+ if(firstPathSegment !== entry.pathSegment) {
+ entry.state.expanded = false;
+ } else {
+ entry.state.expanded = true;
+ collapseAll(entry.nodes, pathSegment.substring(pathSegment.indexOf('/') + 1));
+ }
+ });
+ };
+ var newTreeData = this.get('treeData');
+ collapseAll(newTreeData, pathSegment);
+ this.set('treeData', newTreeData);
+ this.send('refreshTreeView');
+ },
+
+ actions: {
+ refreshTreeView() {
+ Ember.run.later(() => {
+ this.$().treeview({
+ data: this.get('treeData'),
+ expandIcon: this.get('config.expandIcon'),
+ collapseIcon: this.get('config.collapseIcon'),
+ //emptyIcon: "fa",
+ showBorder: false,
+ onNodeSelected: (event, data) => {
+ this.set('currentPath', data.path);
+ this.sendAction('pathSelectAction', {path: data.path, isDirectory: data.isDirectory});
+ },
+ onNodeExpanded: (event, data) => {
+ this.set('currentPath', data.path);
+ if (!Ember.isNone(data.nodes) && data.nodes.length === 0) {
+ var node = this.$().treeview('getNode', data.nodeId);
+ node.icon = "fa fa-refresh fa-spin";
+ this.fetchData();
+ } else {
+ this.collapseAllExceptPath(data.path.substring(1));
+ }
+ }
+ });
+ });
+ }
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
new file mode 100644
index 0000000..75339c5
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
new file mode 100644
index 0000000..64773c6
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
@@ -0,0 +1,59 @@
+/**
+ * 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.Object.extend({
+
+ /**
+ * Set this to true, if only directory listing is required.
+ */
+ showOnlyDirectories: false,
+
+ /**
+ * Set this to true, if refresh of current path is required.
+ */
+ showRefreshButton: false,
+
+ /**
+ * Override these for different Icon. Refer https://github.com/jonmiles/bootstrap-treeview
+ */
+ expandIcon: "fa fa-plus",
+ collapseIcon: "fa fa-minus",
+ //Custom
+ fileIcon: "fa fa-file",
+ folderIcon: "fa fa-folder",
+
+ /**
+ * Override to return the headers add to the XHR call made for various operations.
+ * The Overriding object can also merge its result with the default in this object.
+ */
+ getHeaders() {
+ return {"X-Requested-By": "ambari"};
+ },
+
+ /**
+ * Return the URL endpoint for XHR call meant for listing Directories
+ * @param pathParams
+ * @returns {string}
+ */
+ listDirectoryUrl(pathParams) {
+ return `/listdir?${pathParams}`;
+ }
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/.gitkeep
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/.gitkeep b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/.gitkeep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/components/directory-viewer.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/components/directory-viewer.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/components/directory-viewer.js
new file mode 100644
index 0000000..e704ef7
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/components/directory-viewer.js
@@ -0,0 +1,19 @@
+/**
+ * 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.
+ */
+
+export { default } from 'hdfs-directory-viewer/components/directory-viewer';
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/utils/viewer-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/utils/viewer-config.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/utils/viewer-config.js
new file mode 100644
index 0000000..f175b6c
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/app/utils/viewer-config.js
@@ -0,0 +1,19 @@
+/**
+ * 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.
+ */
+
+export { default } from 'hdfs-directory-viewer/utils/viewer-config';
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
new file mode 100644
index 0000000..f016904
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
@@ -0,0 +1,19 @@
+{
+ "name": "hdfs-directory-viewer",
+ "dependencies": {
+ "ember": "2.2.0",
+ "ember-cli-shims": "0.1.0",
+ "ember-cli-test-loader": "0.2.2",
+ "ember-load-initializers": "0.1.7",
+ "ember-qunit-notifications": "0.1.0",
+ "jquery": "1.11.3",
+ "loader.js": "^3.5.0",
+ "qunit": "~1.20.0",
+ "bootstrap": "~3.3.6",
+ "bootstrap-treeview": "~1.2.0",
+ "font-awesome": "~4.5.0"
+ },
+ "resolutions": {
+ "ember": "2.2.0"
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/ember-try.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/ember-try.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/ember-try.js
new file mode 100644
index 0000000..252dff2
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/ember-try.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+/*jshint node:true*/
+module.exports = {
+ scenarios: [
+ {
+ name: 'default',
+ dependencies: { }
+ },
+ {
+ name: 'ember-release',
+ dependencies: {
+ 'ember': 'components/ember#release'
+ },
+ resolutions: {
+ 'ember': 'release'
+ }
+ },
+ {
+ name: 'ember-beta',
+ dependencies: {
+ 'ember': 'components/ember#beta'
+ },
+ resolutions: {
+ 'ember': 'beta'
+ }
+ },
+ {
+ name: 'ember-canary',
+ dependencies: {
+ 'ember': 'components/ember#canary'
+ },
+ resolutions: {
+ 'ember': 'canary'
+ }
+ }
+ ]
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/environment.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/environment.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/environment.js
new file mode 100644
index 0000000..4a4b263
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/config/environment.js
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+/*jshint node:true*/
+'use strict';
+
+module.exports = function(/* environment, appConfig */) {
+ return { };
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/ember-cli-build.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/ember-cli-build.js
new file mode 100644
index 0000000..f6aac28
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/ember-cli-build.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+/*jshint node:true*/
+/* global require, module */
+var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
+
+module.exports = function(defaults) {
+ var app = new EmberAddon(defaults, {
+ // Add options here
+ });
+
+ /*
+ This build file specifies the options for the dummy test app of this
+ addon, located in `/tests/dummy`
+ This build file does *not* influence how the addon or the app using it
+ behave. You most likely want to be modifying `./index.js` or app's build file
+ */
+
+ return app.toTree();
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/281307fc/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
new file mode 100644
index 0000000..dc074d7
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+/* jshint node: true */
+'use strict';
+
+module.exports = {
+ name: 'hdfs-directory-viewer',
+ included: function(app) {
+ this._super.included(app);
+
+ app.import(app.bowerDirectory + '/bootstrap/dist/css/bootstrap.css');
+ app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
+ app.import(app.bowerDirectory + '/bootstrap-treeview/src/js/bootstrap-treeview.js');
+ app.import(app.bowerDirectory + '/bootstrap-treeview/dist/bootstrap-treeview.min.css');
+ }
+};