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 2017/01/09 06:14:01 UTC
ambari git commit: AMBARI-19379. Hive View 2.0: Ability to delete a
table from UI. (dipayanb)
Repository: ambari
Updated Branches:
refs/heads/branch-2.5 d346558c1 -> 1e2fe429b
AMBARI-19379. Hive View 2.0: Ability to delete a table from UI. (dipayanb)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1e2fe429
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1e2fe429
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1e2fe429
Branch: refs/heads/branch-2.5
Commit: 1e2fe429b88e1963d1cf40285dd5cf248fc556fd
Parents: d346558
Author: Dipayan Bhowmick <di...@gmail.com>
Authored: Mon Jan 9 11:43:36 2017 +0530
Committer: Dipayan Bhowmick <di...@gmail.com>
Committed: Mon Jan 9 11:43:36 2017 +0530
----------------------------------------------------------------------
.../ambari/view/hive20/ConnectionSystem.java | 4 +
.../view/hive20/actor/DatabaseManager.java | 44 ++++-
.../ambari/view/hive20/actor/JdbcConnector.java | 6 +
.../view/hive20/actor/MetaDataManager.java | 3 +
.../view/hive20/actor/MetaDataRetriever.java | 12 +-
.../ambari/view/hive20/actor/message/Ping.java | 10 +
.../hive20/resources/browser/DDLService.java | 4 +-
.../utils/MetaDataManagerEventSubmitter.java | 43 +++++
.../src/main/resources/ui/app/adapters/table.js | 7 +-
.../ui/app/routes/databases/database/tables.js | 5 +
.../app/routes/databases/database/tables/new.js | 25 ++-
.../routes/databases/database/tables/table.js | 53 ++++-
.../resources/ui/app/services/create-table.js | 182 -----------------
.../ui/app/services/table-operations.js | 193 +++++++++++++++++++
.../app/templates/components/jobs-browser.hbs | 2 +-
.../databases/database/tables/table.hbs | 20 +-
.../databases/database/tables/table/details.hbs | 2 +-
.../databases/database/tables/table/storage.hbs | 2 +-
18 files changed, 411 insertions(+), 206 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/ConnectionSystem.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/ConnectionSystem.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/ConnectionSystem.java
index 40b4c04..a6c7334 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/ConnectionSystem.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/ConnectionSystem.java
@@ -124,6 +124,10 @@ public class ConnectionSystem {
return metaDataManager;
}
+ public synchronized Optional<ActorRef> getMetaDataManagerIfPresent(String instanceName) {
+ return Optional.fromNullable(metaDataManagerMap.get(instanceName));
+ }
+
private ActorRef createMetaDataManager(SafeViewContext safeViewContext) {
return actorSystem.actorOf(MetaDataManager.props(safeViewContext));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/DatabaseManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/DatabaseManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/DatabaseManager.java
index 6dc4ad9..bd7c6bd 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/DatabaseManager.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/DatabaseManager.java
@@ -75,7 +75,7 @@ public class DatabaseManager extends HiveActor {
Object message = hiveMessage.getMessage();
if (message instanceof Refresh) {
- handleRefresh();
+ handleRefresh((Refresh) message);
} else if (message instanceof SelfRefresh) {
handleSelfRefresh();
} else if (message instanceof MetaDataRetriever.DBRefreshed) {
@@ -83,7 +83,7 @@ public class DatabaseManager extends HiveActor {
} else if (message instanceof MetaDataRetriever.TableRefreshed) {
handleTableRefreshed((MetaDataRetriever.TableRefreshed) message);
} else if (message instanceof MetaDataRetriever.AllTableRefreshed) {
- handleAllTableRefeshed((MetaDataRetriever.AllTableRefreshed) message);
+ handleAllTableRefreshed((MetaDataRetriever.AllTableRefreshed) message);
} else if (message instanceof GetDatabases) {
handleGetDatabases((GetDatabases) message);
}
@@ -96,11 +96,11 @@ public class DatabaseManager extends HiveActor {
getSelf(), new SelfRefresh(), getContext().dispatcher(), getSelf());
} else {
selfRefreshQueued = false;
- refresh();
+ refresh(true);
}
}
- private void handleRefresh() {
+ private void handleRefresh(Refresh message) {
if (refreshInProgress && selfRefreshQueued) {
return; // We will not honor refresh message when a refresh is going on and another self refresh is queued in mailbox
} else if (refreshInProgress) {
@@ -108,7 +108,7 @@ public class DatabaseManager extends HiveActor {
getContext().system().scheduler().scheduleOnce(Duration.create(500, TimeUnit.MILLISECONDS),
getSelf(), new SelfRefresh(), getContext().dispatcher(), getSelf());
} else {
- refresh();
+ refresh(message.initiateScheduler());
}
}
@@ -157,8 +157,9 @@ public class DatabaseManager extends HiveActor {
databaseChangeNotifier.tell(new DatabaseChangeNotifier.TableUpdated(message.getTable()), getSelf());
}
- private void handleAllTableRefeshed(MetaDataRetriever.AllTableRefreshed message) {
+ private void handleAllTableRefreshed(MetaDataRetriever.AllTableRefreshed message) {
ActorRef databaseChangeNotifier = getDatabaseChangeNotifier(message.getDatabase());
+ updateRemovedTables(message.getDatabase(), message.getCurrentTableNames());
databaseChangeNotifier.tell(new DatabaseChangeNotifier.AllTablesUpdated(message.getDatabase()), getSelf());
if (checkIfAllTablesOfAllDatabaseRefeshed(message)) {
refreshInProgress = false;
@@ -193,12 +194,14 @@ public class DatabaseManager extends HiveActor {
return databaseChangeNotifier;
}
- private void refresh() {
+ private void refresh(boolean initiateScheduler) {
LOG.info("Received refresh for user");
refreshInProgress = true;
metaDataRetriever.tell(new MetaDataRetriever.RefreshDB(), getSelf());
- scheduleRefreshAfter(1, TimeUnit.MINUTES);
+ if (initiateScheduler) {
+ scheduleRefreshAfter(1, TimeUnit.MINUTES);
+ }
}
private void scheduleRefreshAfter(long time, TimeUnit timeUnit) {
@@ -220,6 +223,20 @@ public class DatabaseManager extends HiveActor {
}
}
+ private void updateRemovedTables(String database, Set<String> currentTableNames) {
+ DatabaseWrapper wrapper = databases.get(database);
+ HashSet<TableInfo> notRemovedTables = new HashSet<>();
+ if (wrapper != null) {
+ DatabaseInfo info = wrapper.getDatabase();
+ for (TableInfo tableInfo : info.getTables()) {
+ if (currentTableNames.contains(tableInfo.getName())) {
+ notRemovedTables.add(tableInfo);
+ }
+ }
+ info.setTables(notRemovedTables);
+ }
+ }
+
public static Props props(ViewContext context) {
ConnectionConfig config = ConnectionFactory.create(context);
Connectable connectable = new HiveConnectionWrapper(config.getJdbcUrl(), config.getUsername(), config.getPassword(), new AuthParams(context));
@@ -228,14 +245,25 @@ public class DatabaseManager extends HiveActor {
public static class Refresh {
private final String username;
+ private final boolean initiateScheduler;
+
public Refresh(String username) {
+ this(username, true);
+ }
+
+ public Refresh(String username, boolean initiateScheduler) {
this.username = username;
+ this.initiateScheduler = initiateScheduler;
}
public String getUsername() {
return username;
}
+
+ public boolean initiateScheduler() {
+ return initiateScheduler;
+ }
}
private static class SelfRefresh {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/JdbcConnector.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/JdbcConnector.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/JdbcConnector.java
index ce58c8c..1855afc 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/JdbcConnector.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/JdbcConnector.java
@@ -57,6 +57,7 @@ import org.apache.ambari.view.hive20.persistence.utils.ItemNotFound;
import org.apache.ambari.view.hive20.resources.jobs.viewJobs.Job;
import org.apache.ambari.view.hive20.resources.jobs.viewJobs.JobImpl;
import org.apache.ambari.view.hive20.utils.HiveActorConfiguration;
+import org.apache.ambari.view.hive20.utils.MetaDataManagerEventSubmitter;
import org.apache.ambari.view.utils.hdfs.HdfsApi;
import org.apache.hive.jdbc.HiveConnection;
import org.slf4j.Logger;
@@ -132,6 +133,7 @@ public class JdbcConnector extends HiveActor {
*/
private final HiveActorConfiguration actorConfiguration;
private String username;
+ private String instanceName;
private Optional<String> jobId = Optional.absent();
private Optional<String> logFile = Optional.absent();
private int statementsCount = 0;
@@ -157,6 +159,7 @@ public class JdbcConnector extends HiveActor {
this.storage = storage;
this.lastActivityTimestamp = System.currentTimeMillis();
resultSetIterator = null;
+ this.instanceName = viewContext.getInstanceName();
authParams = new AuthParams(viewContext);
actorConfiguration = new HiveActorConfiguration(viewContext);
@@ -287,6 +290,9 @@ public class JdbcConnector extends HiveActor {
LOG.info("Finished processing SQL statements for Job id : {}", jobId.or("SYNC JOB"));
if (isAsync() && jobId.isPresent()) {
updateJobStatus(jobId.get(), Job.JOB_STATE_FINISHED);
+
+ LOG.info("Sending event to refresh meta information for user {} and instance {}", username, instanceName);
+ MetaDataManagerEventSubmitter.sendDBRefresh(username, instanceName);
}
if (resultSetOptional.isPresent()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataManager.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataManager.java
index d63b3a0..43733e4 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataManager.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataManager.java
@@ -72,6 +72,9 @@ public class MetaDataManager extends HiveActor {
databaseManagers.put(context.getUsername(), databaseManager);
databaseManager.tell(new DatabaseManager.Refresh(context.getUsername()), getSelf());
} else {
+ if(message.isImmediate()) {
+ databaseManager.tell(new DatabaseManager.Refresh(context.getUsername(), false), getSelf());
+ }
cancelTerminationScheduler(message.getUsername());
}
scheduleTermination(context.getUsername());
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataRetriever.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataRetriever.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataRetriever.java
index 7323a0a..64cd69c 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataRetriever.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/MetaDataRetriever.java
@@ -91,13 +91,15 @@ public class MetaDataRetriever extends HiveActor {
private void refreshTablesInfo(String database) throws ConnectionException, SQLException {
HiveConnection connection = getHiveConnection();
+ Set<String> currentTableNames = new HashSet<>();
try (ResultSet tables = connection.getMetaData().getTables("", database, null, null)) {
while (tables.next()) {
TableInfo info = new TableInfo(tables.getString(3), tables.getString(4));
+ currentTableNames.add(info.getName());
getSender().tell(new TableRefreshed(info, database), getSelf());
}
}
- getSender().tell(new AllTableRefreshed(database), getSelf());
+ getSender().tell(new AllTableRefreshed(database, currentTableNames), getSelf());
}
public static Props props(Connectable connectable) {
@@ -153,13 +155,19 @@ public class MetaDataRetriever extends HiveActor {
public static class AllTableRefreshed {
private final String database;
+ private final Set<String> currentTableNames;
- public AllTableRefreshed(String database) {
+ public AllTableRefreshed(String database, Set<String> currentTableNames) {
this.database = database;
+ this.currentTableNames = currentTableNames;
}
public String getDatabase() {
return database;
}
+
+ public Set<String> getCurrentTableNames() {
+ return currentTableNames;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/message/Ping.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/message/Ping.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/message/Ping.java
index c8449dc..61df87a 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/message/Ping.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/actor/message/Ping.java
@@ -24,10 +24,16 @@ package org.apache.ambari.view.hive20.actor.message;
public class Ping {
private final String username;
private final String instanceName;
+ private final boolean immediate;
public Ping(String username, String instanceName) {
+ this(username, instanceName, false);
+ }
+
+ public Ping(String username, String instanceName, boolean immediate) {
this.username = username;
this.instanceName = instanceName;
+ this.immediate = immediate;
}
public String getUsername() {
@@ -37,4 +43,8 @@ public class Ping {
public String getInstanceName() {
return instanceName;
}
+
+ public boolean isImmediate() {
+ return immediate;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/browser/DDLService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/browser/DDLService.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/browser/DDLService.java
index b278983..65647ee 100644
--- a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/browser/DDLService.java
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/resources/browser/DDLService.java
@@ -114,7 +114,7 @@ public class DDLService extends BaseService {
Job job = proxy.createTable(databaseName, request.tableInfo, getResourceManager());
JSONObject response = new JSONObject();
response.put("job", job);
- return Response.status(Response.Status.ACCEPTED).entity(job).build();
+ return Response.status(Response.Status.ACCEPTED).entity(response).build();
} catch (ServiceException e) {
LOG.error("Exception occurred while creatint table for db {} with details : {}", databaseName, request.tableInfo, e);
throw new ServiceFormattedException(e);
@@ -192,7 +192,7 @@ public class DDLService extends BaseService {
Job job = proxy.alterTable(context, hiveConnectionConfig, databaseName, oldTableName, tableMetaRequest.tableInfo, getResourceManager());
JSONObject response = new JSONObject();
response.put("job", job);
- return Response.status(Response.Status.ACCEPTED).entity(job).build();
+ return Response.status(Response.Status.ACCEPTED).entity(response).build();
} catch (ServiceException e) {
LOG.error("Exception occurred while creatint table for db {} with details : {}", databaseName, tableMetaRequest.tableInfo, e);
throw new ServiceFormattedException(e);
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/utils/MetaDataManagerEventSubmitter.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/utils/MetaDataManagerEventSubmitter.java b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/utils/MetaDataManagerEventSubmitter.java
new file mode 100644
index 0000000..b23e06e
--- /dev/null
+++ b/contrib/views/hive20/src/main/java/org/apache/ambari/view/hive20/utils/MetaDataManagerEventSubmitter.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hive20.utils;
+
+import akka.actor.ActorRef;
+import com.google.common.base.Optional;
+import org.apache.ambari.view.hive20.ConnectionSystem;
+import org.apache.ambari.view.hive20.actor.message.Ping;
+
+/**
+ * Static class to submit event to the MetaData Manager.
+ */
+public final class MetaDataManagerEventSubmitter {
+
+ /**
+ * Send a ping message to the MetaDataManager Actor for that instance
+ * @param username Logged-in username
+ * @param instanceName current instance name
+ */
+ public static void sendDBRefresh(String username, String instanceName) {
+ Optional<ActorRef> metaDataManagerOptional = ConnectionSystem.getInstance().getMetaDataManagerIfPresent(instanceName);
+ if(metaDataManagerOptional.isPresent()) {
+ ActorRef metaDataManager = metaDataManagerOptional.get();
+ metaDataManager.tell(new Ping(username, instanceName, true), ActorRef.noSender());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/adapters/table.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/adapters/table.js b/contrib/views/hive20/src/main/resources/ui/app/adapters/table.js
index f4d1615..9a4692d 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/adapters/table.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/adapters/table.js
@@ -41,8 +41,11 @@ export default DDLAdapter.extend({
createTable(tableMetaInfo) {
let postURL = this.buildURL('table', null, null, 'query', {databaseId: tableMetaInfo.database});
- console.log(postURL);
- console.log(tableMetaInfo);
return this.ajax(postURL, 'POST', { data: {tableInfo: tableMetaInfo} });
+ },
+
+ deleteTable(database, tableName) {
+ let deletURL = this.buildURL('table', null, null, 'query', {databaseId: database, tableName: tableName});
+ return this.ajax(deletURL, 'DELETE');
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables.js b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables.js
index a121b88..92f483f 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables.js
@@ -44,4 +44,9 @@ export default Ember.Route.extend({
this.transitionTo('databases.database.tables.table', table.get('name'));
}
}
+
+
+
+
+
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/new.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/new.js b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/new.js
index f648ef6..6dfdf29 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/new.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/new.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
import tabs from '../../../../configs/create-table-tabs';
export default Ember.Route.extend({
- createTable: Ember.inject.service(),
+ tableOperations: Ember.inject.service(),
setupController(controller, model) {
this._super(controller, model);
@@ -34,20 +34,21 @@ export default Ember.Route.extend({
},
create(settings) {
- debugger;
this.controller.set('showCreateTableModal', true);
this.controller.set('createTableMessage', 'Submitting request to create table');
let databaseModel = this.controllerFor('databases.database').get('model');
- this.get('createTable').submitCreateTable(databaseModel.get('name'), settings)
+ this.get('tableOperations').submitCreateTable(databaseModel.get('name'), settings)
.then((job) => {
console.log('Created job: ', job.get('id'));
this.controller.set('createTableMessage', 'Waiting for the table to be created');
- this.get('createTable').waitForJobToComplete(job.get('id'), 5 * 1000)
+ this.get('tableOperations').waitForJobToComplete(job.get('id'), 5 * 1000)
.then((status) => {
this.controller.set('createTableMessage', "Successfully created table");
Ember.run.later(() => {
this.controller.set('showCreateTableModal', false);
this.controller.set('createTableMessage');
+ this._addTableToStoreLocally(databaseModel, settings.name);
+ this._resetModelInTablesController(databaseModel.get('tables'));
this._transitionToCreatedTable(databaseModel.get('name'), settings.name);
}, 2 * 1000);
}, (error) => {
@@ -67,5 +68,21 @@ export default Ember.Route.extend({
_transitionToCreatedTable(database, table) {
this.transitionTo('databases.database.tables.table', database, table);
+ },
+
+ _addTableToStoreLocally(database, table) {
+ this.store.createRecord('table', {
+ id: `${database.get('name')}/${table}`,
+ name: `${table}`,
+ type: 'TABLE',
+ selected: true,
+ database: database
+ });
+ },
+
+ _resetModelInTablesController(tables) {
+ let tablesController = this.controllerFor('databases.database.tables');
+ tablesController.get('model').setEach('selected', false);
+ tablesController.set('model', tables);
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/table.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/table.js b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/table.js
index 5a88bd2..88f1e7e 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/table.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/databases/database/tables/table.js
@@ -20,6 +20,7 @@ import Ember from 'ember';
import tabs from '../../../../configs/table-level-tabs';
export default Ember.Route.extend({
+ tableOperations: Ember.inject.service(),
model(params) {
let database = this.modelFor('databases.database').get('name');
let table = params.name;
@@ -40,5 +41,55 @@ export default Ember.Route.extend({
controller.set('tabs', newTabs);
},
- actions: {}
+ actions: {
+ deleteTable(table) {
+ this.deleteTable(table);
+ },
+
+ editTable(table) {
+ console.log("Edit table");
+ }
+ },
+
+ deleteTable(tableInfo) {
+ this.controller.set('showDeleteTableModal', true);
+ this.controller.set('deleteTableMessage', 'Submitting request to delete table');
+ let databaseModel = this.controllerFor('databases.database').get('model');
+ this.get('tableOperations').deleteTable(databaseModel.get('name'), tableInfo.get('table'))
+ .then((job) => {
+ this.controller.set('deleteTableMessage', 'Waiting for the table to be deleted');
+ this.get('tableOperations').waitForJobToComplete(job.get('id'), 5 * 1000)
+ .then((status) => {
+ this.controller.set('deleteTableMessage', "Successfully Deleted table");
+ Ember.run.later(() => {
+ this.controller.set('showDeleteTableModal', false);
+ this.controller.set('deleteTableMessage');
+ this._removeTableLocally(databaseModel.get('name'), tableInfo.get('table'));
+ this._resetModelInTablesController(databaseModel.get('name'), tableInfo.get('table'));
+ this.transitionTo('databases.database', databaseModel.get('name'));
+ }, 2 * 1000);
+ }, (error) => {
+ // TODO: handle error
+ Ember.run.later(() => {
+ this.controller.set('showDeleteTableModal', false);
+ this.controller.set('deleteTableMessage');
+ this.transitionTo('databases.database', databaseModel.get('name'));
+ }, 2 * 1000);
+ });
+ }, (error) => {
+ console.log("Error encountered", error);
+ this.controller.set('showDeleteTableModal', true);
+ });
+ },
+
+ _removeTableLocally(database, table) {
+ let tableToBeRemoved = this.store.peekRecord('table', `${database}/${table}`);
+ this.store.deleteRecord(tableToBeRemoved);
+ },
+
+ _resetModelInTablesController(database, tables) {
+ let tablesController = this.controllerFor('databases.database.tables');
+ let currentTables = this.store.peekRecord('database', database).get('tables');
+ tablesController.set('model', currentTables);
+ }
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/services/create-table.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/services/create-table.js b/contrib/views/hive20/src/main/resources/ui/app/services/create-table.js
deleted file mode 100644
index 135f96a..0000000
--- a/contrib/views/hive20/src/main/resources/ui/app/services/create-table.js
+++ /dev/null
@@ -1,182 +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.
- */
-
-import Ember from 'ember';
-
-export default Ember.Service.extend({
- store: Ember.inject.service(),
-
- submitCreateTable(database, settings) {
- let detailedInfo = this._getDetailedInfo(settings);
- let storageInfo = this._getStorageInfo(settings);
- let columns = this._getColumns(settings);
- let partitionColumns = this._getPartitionColumns(settings);
-
- let tableInfo = Ember.Object.create({
- database: database,
- table: settings.name,
- columns: columns,
- partitionInfo: { columns: partitionColumns },
- detailedInfo: detailedInfo,
- storageInfo: storageInfo
- });
- return new Promise((resolve, reject) => {
- this.get('store').adapterFor('table').createTable(tableInfo).then((data) => {
- this.get('store').pushPayload({job: data});
- resolve(this.get('store').peekRecord('job', data.id));
- }, (err) => {
- reject(err);
- });
- });
- },
-
- waitForJobToComplete(jobId, after) {
- return new Ember.RSVP.Promise((resolve, reject) => {
- Ember.run.later(() => {
- this.get('store').findRecord('job', jobId, {reload: true})
- .then((job) => {
- let status = job.get('status').toLowerCase();
- if (status === 'succeeded') {
- this._fetchDummyResult(jobId);
- resolve();
- } else if (status === 'error') {
- reject()
- } else {
- resolve(this.waitForJobToComplete(jobId, after));
- }
- }, (error) => {
- reject(error);
- });
- }, after);
- });
- },
-
- _fetchDummyResult(jobId) {
- this.get('store').adapterFor('job').fetchResult(jobId);
- },
-
- _getDetailedInfo(settings) {
- let detailedInfo = {};
- detailedInfo['parameters'] = this._getTableProperties(settings);
-
- if (!Ember.isEmpty(settings.settings.location)) {
- detailedInfo['location'] = settings.settings.location;
- }
-
- return detailedInfo;
-
- },
-
- _getStorageInfo(settings) {
- const storageSettings = settings.settings;
- let storageInfo = {};
- let parameters = {};
-
-
-
- if (!(Ember.isEmpty(storageSettings.fileFormat) || Ember.isEmpty(storageSettings.fileFormat.type))) {
- storageInfo.fileFormat = storageSettings.fileFormat.type;
- if (storageSettings.fileFormat.type === 'CUSTOM Serde') {
- storageInfo.inputFormat = storageSettings.inputFormat;
- storageInfo.outputFormat = storageSettings.outputFormat;
- }
- }
-
- if (!Ember.isEmpty(storageSettings.rowFormat)) {
- let addParameters = false;
- if (!Ember.isEmpty(storageSettings.rowFormat.fieldTerminatedBy)) {
- parameters['field.delim'] = String.fromCharCode(storageSettings.rowFormat.fieldTerminatedBy.id);
- addParameters = true;
- }
-
- if (!Ember.isEmpty(storageSettings.rowFormat.linesTerminatedBy)) {
- parameters['line.delim'] = String.fromCharCode(storageSettings.rowFormat.linesTerminatedBy.id);
- addParameters = true;
- }
-
- if (!Ember.isEmpty(storageSettings.rowFormat.nullDefinedAs)) {
- parameters['serialization.null.format'] = String.fromCharCode(storageSettings.rowFormat.fieldTerminatedBy.id);
- addParameters = true;
- }
-
- if (!Ember.isEmpty(storageSettings.rowFormat.escapeDefinedAs)) {
- parameters['escape.delim'] = String.fromCharCode(storageSettings.rowFormat.linesTerminatedBy.id);
- addParameters = true;
- }
-
- if (addParameters) {
- storageInfo.parameters = parameters;
- }
- }
-
- if (!Ember.isEmpty(settings.settings.numBuckets)) {
- storageInfo['numBuckets'] = settings.settings.numBuckets;
- }
-
- let clusteredColumnNames = settings.columns.filterBy('isClustered', true).map((column) => {
- return column.get('name');
- });
-
- if (clusteredColumnNames.length > 0) {
- storageInfo['bucketCols'] = clusteredColumnNames;
- }
-
- return storageInfo;
- },
-
- _getColumns(settings) {
- return settings.columns.filterBy('isPartitioned', false).map((column) => {
- return {
- name: column.get('name'),
- type: column.get('type.label'),
- comment: column.get('comment'),
- precision: column.get('precision'),
- scale: column.get('scale')
- }
- });
- },
-
- _getPartitionColumns(settings) {
- return settings.columns.filterBy('isPartitioned', true).map((column) => {
- return {
- name: column.get('name'),
- type: column.get('type.label'),
- comment: column.get('comment'),
- precision: column.get('precision'),
- scale: column.get('scale')
- }
- });
- },
-
- _getTableProperties(settings) {
- let properties = {};
- settings.properties.forEach(function (property) {
- properties[property.key] = property.value;
- });
-
- if (settings.settings.transactional) {
- if (Ember.isEmpty(properties['transactional'])) {
- properties['transactional'] = true;
- }
- }
-
- return properties;
- }
-
-
-});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/services/table-operations.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/services/table-operations.js b/contrib/views/hive20/src/main/resources/ui/app/services/table-operations.js
new file mode 100644
index 0000000..81b0430
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/services/table-operations.js
@@ -0,0 +1,193 @@
+/**
+ * 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.Service.extend({
+ store: Ember.inject.service(),
+
+ submitCreateTable(database, settings) {
+ let detailedInfo = this._getDetailedInfo(settings);
+ let storageInfo = this._getStorageInfo(settings);
+ let columns = this._getColumns(settings);
+ let partitionColumns = this._getPartitionColumns(settings);
+
+ let tableInfo = Ember.Object.create({
+ database: database,
+ table: settings.name,
+ columns: columns,
+ partitionInfo: { columns: partitionColumns },
+ detailedInfo: detailedInfo,
+ storageInfo: storageInfo
+ });
+ return new Promise((resolve, reject) => {
+ this.get('store').adapterFor('table').createTable(tableInfo).then((data) => {
+ this.get('store').pushPayload(data);
+ resolve(this.get('store').peekRecord('job', data.job.id));
+ }, (err) => {
+ reject(err);
+ });
+ });
+ },
+
+ deleteTable(database, table) {
+ return new Promise((resolve, reject) => {
+ this.get('store').adapterFor('table').deleteTable(database, table).then((data) => {
+ this.get('store').pushPayload(data);
+ resolve(this.get('store').peekRecord('job', data.job.id));
+ }, (err) => {
+ reject(err);
+ });
+ })
+ },
+
+ waitForJobToComplete(jobId, after) {
+ return new Ember.RSVP.Promise((resolve, reject) => {
+ Ember.run.later(() => {
+ this.get('store').findRecord('job', jobId, {reload: true})
+ .then((job) => {
+ let status = job.get('status').toLowerCase();
+ if (status === 'succeeded') {
+ this._fetchDummyResult(jobId);
+ resolve();
+ } else if (status === 'error') {
+ reject()
+ } else {
+ resolve(this.waitForJobToComplete(jobId, after));
+ }
+ }, (error) => {
+ reject(error);
+ });
+ }, after);
+ });
+ },
+
+ _fetchDummyResult(jobId) {
+ this.get('store').adapterFor('job').fetchResult(jobId);
+ },
+
+ _getDetailedInfo(settings) {
+ let detailedInfo = {};
+ detailedInfo['parameters'] = this._getTableProperties(settings);
+
+ if (!Ember.isEmpty(settings.settings.location)) {
+ detailedInfo['location'] = settings.settings.location;
+ }
+
+ return detailedInfo;
+
+ },
+
+ _getStorageInfo(settings) {
+ const storageSettings = settings.settings;
+ let storageInfo = {};
+ let parameters = {};
+
+
+
+ if (!(Ember.isEmpty(storageSettings.fileFormat) || Ember.isEmpty(storageSettings.fileFormat.type))) {
+ storageInfo.fileFormat = storageSettings.fileFormat.type;
+ if (storageSettings.fileFormat.type === 'CUSTOM Serde') {
+ storageInfo.inputFormat = storageSettings.inputFormat;
+ storageInfo.outputFormat = storageSettings.outputFormat;
+ }
+ }
+
+ if (!Ember.isEmpty(storageSettings.rowFormat)) {
+ let addParameters = false;
+ if (!Ember.isEmpty(storageSettings.rowFormat.fieldTerminatedBy)) {
+ parameters['field.delim'] = String.fromCharCode(storageSettings.rowFormat.fieldTerminatedBy.id);
+ addParameters = true;
+ }
+
+ if (!Ember.isEmpty(storageSettings.rowFormat.linesTerminatedBy)) {
+ parameters['line.delim'] = String.fromCharCode(storageSettings.rowFormat.linesTerminatedBy.id);
+ addParameters = true;
+ }
+
+ if (!Ember.isEmpty(storageSettings.rowFormat.nullDefinedAs)) {
+ parameters['serialization.null.format'] = String.fromCharCode(storageSettings.rowFormat.fieldTerminatedBy.id);
+ addParameters = true;
+ }
+
+ if (!Ember.isEmpty(storageSettings.rowFormat.escapeDefinedAs)) {
+ parameters['escape.delim'] = String.fromCharCode(storageSettings.rowFormat.linesTerminatedBy.id);
+ addParameters = true;
+ }
+
+ if (addParameters) {
+ storageInfo.parameters = parameters;
+ }
+ }
+
+ if (!Ember.isEmpty(settings.settings.numBuckets)) {
+ storageInfo['numBuckets'] = settings.settings.numBuckets;
+ }
+
+ let clusteredColumnNames = settings.columns.filterBy('isClustered', true).map((column) => {
+ return column.get('name');
+ });
+
+ if (clusteredColumnNames.length > 0) {
+ storageInfo['bucketCols'] = clusteredColumnNames;
+ }
+
+ return storageInfo;
+ },
+
+ _getColumns(settings) {
+ return settings.columns.filterBy('isPartitioned', false).map((column) => {
+ return {
+ name: column.get('name'),
+ type: column.get('type.label'),
+ comment: column.get('comment'),
+ precision: column.get('precision'),
+ scale: column.get('scale')
+ }
+ });
+ },
+
+ _getPartitionColumns(settings) {
+ return settings.columns.filterBy('isPartitioned', true).map((column) => {
+ return {
+ name: column.get('name'),
+ type: column.get('type.label'),
+ comment: column.get('comment'),
+ precision: column.get('precision'),
+ scale: column.get('scale')
+ }
+ });
+ },
+
+ _getTableProperties(settings) {
+ let properties = {};
+ settings.properties.forEach(function (property) {
+ properties[property.key] = property.value;
+ });
+
+ if (settings.settings.transactional) {
+ if (Ember.isEmpty(properties['transactional'])) {
+ properties['transactional'] = true;
+ }
+ }
+
+ return properties;
+ }
+
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/templates/components/jobs-browser.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/components/jobs-browser.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/components/jobs-browser.hbs
index 84f16a7..47b499a 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/components/jobs-browser.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/components/jobs-browser.hbs
@@ -45,7 +45,7 @@
<thead>
<tr>
<th width="10%">Job Id</th>
- <th width="30%">Title <span class="pull-right">Dipayan</span> </th>
+ <th width="30%">Title</th>
<th width="10%">status</th>
<th width="25%">Start time</th>
<th width="20%" >Duration</th>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table.hbs
index 258f687..2d1d075 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table.hbs
@@ -25,12 +25,26 @@
{{fa-icon "navicon"}}
</button>
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenu1">
- <li><a href="#" class="text-uppercase">{{fa-icon "edit"}} Edit</a></li>
- <li><a href="#" class="text-uppercase">{{fa-icon "trash"}} Delete</a></li>
+ <li><a href="#" class="text-uppercase" {{action "editTable" model}}>{{fa-icon "edit"}} Edit</a></li>
+ <li><a href="#" class="text-uppercase" {{action "deleteTable" model}}>{{fa-icon "trash"}} Delete</a></li>
</ul>
</div>
</div>
</div>
+ {{#if showDeleteTableModal}}
+ {{#modal-dialog
+ translucentOverlay=true
+ container-class="modal-dialog modal-sm"}}
+ <div class="modal-content">
+ <div class="modal-header text-danger">
+ <p class="modal-title">{{fa-icon "minus"}} Delete table</p>
+ </div>
+ <div class="modal-body text-center text-primary">
+ <p>{{deleteTableMessage}}</p>
+ </div>
+ </div><!-- /.modal-content -->
+ {{/modal-dialog}}
+ {{/if}}
<div class="table-body">
{{#tabs-pane tabs=tabs inverse= true as |tab|}}
{{tabs-item tab=tab tabs=tabs}}
@@ -39,4 +53,6 @@
</div>
+
+
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/details.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/details.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/details.hbs
index 1577fec..225b6eb 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/details.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/details.hbs
@@ -56,7 +56,7 @@
</tr>
<tr>
<th>Parameters</th>
- <td><pre class="table-info-json">{{toJson info.parameters}}</pre></td>
+ <td><pre class="table-info-json">{{to-json info.parameters}}</pre></td>
</tr>
</tbody>
{{/with}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1e2fe429/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/storage.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/storage.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/storage.hbs
index 6e76741..52209ac 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/storage.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/databases/database/tables/table/storage.hbs
@@ -56,7 +56,7 @@
</tr>
<tr>
<th>Parameters</th>
- <td><pre class="table-info-json">{{toJson info.parameters}}</pre></td>
+ <td><pre class="table-info-json">{{to-json info.parameters}}</pre></td>
</tr>
</tbody>
{{/with}}