You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2012/10/08 03:38:08 UTC
svn commit: r1395430 [3/13] - in /incubator/ambari/branches/AMBARI-666: ./
ambari-agent/src/main/puppet/manifestloader/
ambari-agent/src/main/puppet/modules/configgenerator/manifests/
ambari-agent/src/main/puppet/modules/hdp-hadoop/manifests/ ambari-ag...
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCManagementController.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCManagementController.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCManagementController.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCManagementController.java Mon Oct 8 01:37:59 2012
@@ -18,121 +18,656 @@
package org.apache.ambari.api.controller.jdbc;
-import org.apache.ambari.api.controller.spi.ManagementController;
-import org.apache.ambari.api.controller.spi.Predicate;
-import org.apache.ambari.api.controller.spi.Request;
-import org.apache.ambari.api.controller.spi.Resource;
-
+import org.apache.ambari.api.controller.internal.PropertyIdImpl;
+import org.apache.ambari.api.controller.internal.ResourceImpl;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ClusterRequest;
+import org.apache.ambari.server.controller.ClusterResponse;
+import org.apache.ambari.server.controller.HostRequest;
+import org.apache.ambari.server.controller.HostResponse;
+import org.apache.ambari.server.controller.ServiceComponentHostRequest;
+import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.controller.ServiceComponentRequest;
+import org.apache.ambari.server.controller.ServiceComponentResponse;
+import org.apache.ambari.server.controller.ServiceRequest;
+import org.apache.ambari.server.controller.ServiceResponse;
+import org.apache.ambari.server.controller.TrackActionResponse;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.EqualsPredicate;
+import org.apache.ambari.server.controller.predicate.PredicateVisitorAcceptor;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.api.controller.utilities.PredicateHelper;
+import org.apache.ambari.api.controller.utilities.Properties;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
/**
* Generic JDBC implementation of a management controller.
*/
-public class JDBCManagementController implements ManagementController {
-
+public class JDBCManagementController implements AmbariManagementController {
+ /**
+ * The connection factory.
+ */
private final ConnectionFactory connectionFactory;
- public JDBCManagementController(ConnectionFactory connectionFactory) {
+ /**
+ * Mapping of resource type to the name of the primary table for the resource.
+ */
+ private final Map<Resource.Type, String> resourceTables;
+
+ /**
+ * Primary key mappings.
+ */
+ private final Map<String, Set<PropertyId>> primaryKeys = new HashMap<String, Set<PropertyId>>();
+
+ /**
+ * Key mappings used for joins.
+ */
+ private final Map<String, Map<PropertyId, PropertyId>> importedKeys = new HashMap<String, Map<PropertyId, PropertyId>>();
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a new JDBC management controller with the given JDBC connection.
+ *
+ * @param connectionFactory the connection factory
+ */
+ public JDBCManagementController(ConnectionFactory connectionFactory, Map<Resource.Type, String> resourceTables) {
this.connectionFactory = connectionFactory;
+ this.resourceTables = resourceTables;
}
+ // ----- AmbariManagementController ----------------------------------------
+
@Override
- public void createClusters(Request request) {
- JDBCHelper.createResources(connectionFactory, request);
+ public TrackActionResponse createCluster(ClusterRequest request) throws AmbariException {
+// createResources(Resource.Type.Cluster, request);
+ return null;
}
@Override
- public void createServices(Request request) {
- JDBCHelper.createResources(connectionFactory, request);
+ public TrackActionResponse createService(ServiceRequest request) throws AmbariException {
+ return null;
}
@Override
- public void createComponents(Request request) {
- JDBCHelper.createResources(connectionFactory, request);
+ public TrackActionResponse createComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
}
@Override
- public void createHosts(Request request) {
- JDBCHelper.createResources(connectionFactory, request);
+ public TrackActionResponse createHost(HostRequest request) throws AmbariException {
+ return null;
}
@Override
- public void createHostComponents(Request request) {
- JDBCHelper.createResources(connectionFactory, request);
+ public TrackActionResponse createHostComponent(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
}
@Override
- public Set<Resource> getClusters(Request request, Predicate predicate) {
- return JDBCHelper.getResources(connectionFactory, Resource.Type.Cluster, request, predicate);
+ public Set<ClusterResponse> getClusters(ClusterRequest request) throws AmbariException {
+// return getResources(Resource.Type.Cluster, request, predicate);
+ return null;
}
@Override
- public Set<Resource> getServices(Request request, Predicate predicate) {
- return JDBCHelper.getResources(connectionFactory, Resource.Type.Service, request, predicate);
+ public Set<ServiceResponse> getServices(ServiceRequest request) throws AmbariException {
+ return null;
}
@Override
- public Set<Resource> getComponents(Request request, Predicate predicate) {
- return JDBCHelper.getResources(connectionFactory, Resource.Type.Component, request, predicate);
+ public Set<ServiceComponentResponse> getComponents(ServiceComponentRequest request) throws AmbariException {
+ return null;
}
@Override
- public Set<Resource> getHosts(Request request, Predicate predicate) {
- return JDBCHelper.getResources(connectionFactory, Resource.Type.Host, request, predicate);
+ public Set<HostResponse> getHosts(HostRequest request) throws AmbariException {
+ return null;
}
@Override
- public Set<Resource> getHostComponents(Request request, Predicate predicate) {
- return JDBCHelper.getResources(connectionFactory, Resource.Type.HostComponent, request, predicate);
+ public Set<ServiceComponentHostResponse> getHostComponents(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
}
@Override
- public void updateClusters(Request request, Predicate predicate) {
- JDBCHelper.updateResources(connectionFactory, request, predicate);
+ public TrackActionResponse updateCluster(ClusterRequest request) throws AmbariException {
+// updateResources(Resource.Type.Cluster, request, predicate);
+ return null;
}
@Override
- public void updateServices(Request request, Predicate predicate) {
- JDBCHelper.updateResources(connectionFactory, request, predicate);
+ public TrackActionResponse updateService(ServiceRequest request) throws AmbariException {
+ return null;
}
@Override
- public void updateComponents(Request request, Predicate predicate) {
- JDBCHelper.updateResources(connectionFactory, request, predicate);
+ public TrackActionResponse updateComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
}
@Override
- public void updateHosts(Request request, Predicate predicate) {
- JDBCHelper.updateResources(connectionFactory, request, predicate);
+ public TrackActionResponse updateHost(HostRequest request) throws AmbariException {
+ return null;
}
@Override
- public void updateHostComponents(Request request, Predicate predicate) {
- JDBCHelper.updateResources(connectionFactory, request, predicate);
+ public TrackActionResponse updateHostComponent(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
}
@Override
- public void deleteClusters(Predicate predicate) {
- JDBCHelper.deleteResources(connectionFactory, predicate);
+ public TrackActionResponse deleteCluster(ClusterRequest request) throws AmbariException {
+// deleteResources(Resource.Type.Cluster, predicate);
+ return null;
}
@Override
- public void deleteServices(Predicate predicate) {
- JDBCHelper.deleteResources(connectionFactory, predicate);
+ public TrackActionResponse deleteService(ServiceRequest request) throws AmbariException {
+ return null;
}
@Override
- public void deleteComponents(Predicate predicate) {
- JDBCHelper.deleteResources(connectionFactory, predicate);
+ public TrackActionResponse deleteComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
}
@Override
- public void deleteHosts(Predicate predicate) {
- JDBCHelper.deleteResources(connectionFactory, predicate);
+ public TrackActionResponse deleteHost(HostRequest request) throws AmbariException {
+ return null;
}
@Override
- public void deleteHostComponents(Predicate predicate) {
- JDBCHelper.deleteResources(connectionFactory, predicate);
+ public TrackActionResponse deleteHostComponent(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
+ }
+
+
+ // ----- Helper methods ----------------------------------------------------
+
+ /**
+ * Create the resources defined by the properties in the given request object.
+ *
+ * @param type the resource type
+ * @param request the request object which defines the set of properties
+ * for the resource to be created
+ */
+ private void createResources(Resource.Type type, Request request) {
+ try {
+ Connection connection = connectionFactory.getConnection();
+
+ try {
+
+ Set<Map<PropertyId, Object>> propertySet = request.getProperties();
+
+ for (Map<PropertyId, Object> properties : propertySet) {
+ String sql = getInsertSQL(resourceTables.get(type), properties);
+
+ Statement statement = connection.createStatement();
+
+ statement.execute(sql);
+ }
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+ /**
+ * Get a set of {@link Resource resources} based on the given request and predicate
+ * information.
+ *
+ * @param type the resource type
+ * @param request the request object which defines the desired set of properties
+ * @param predicate the predicate object which can be used to filter which
+ * resources are returned
+ * @return a set of resources based on the given request and predicate information
+ */
+ private Set<Resource> getResources(Resource.Type type, Request request, Predicate predicate) {
+
+ Set<Resource> resources = new HashSet<Resource>();
+ Set<PropertyId> propertyIds = new HashSet<PropertyId>(request.getPropertyIds());
+ if (predicate != null) {
+ propertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
+ }
+
+ try {
+ Connection connection = connectionFactory.getConnection();
+
+ try {
+
+ for (String table : getTables(propertyIds)) {
+ getImportedKeys(connection, table);
+ }
+ String sql = getSelectSQL(propertyIds, predicate);
+ Statement statement = connection.createStatement();
+
+ ResultSet rs = statement.executeQuery(sql);
+ ResultSetMetaData metaData = rs.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+ while (rs.next()) {
+ final ResourceImpl resource = new ResourceImpl(type);
+ for (int i = 1; i <= columnCount; ++i) {
+ PropertyIdImpl propertyId = new PropertyIdImpl(metaData.getColumnName(i), metaData.getTableName(i), false);
+ if (propertyIds.contains(propertyId)) {
+ resource.setProperty(propertyId, rs.getString(i));
+ }
+ }
+ resources.add(resource);
+ }
+
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+
+ return resources;
+ }
+
+ /**
+ * Update the host resources selected by the given predicate with the properties
+ * from the given request object.
+ *
+ * @param type the resource type
+ * @param request the request object which defines the set of properties
+ * for the resources to be updated
+ * @param predicate the predicate object which can be used to filter which
+ * host resources are updated
+ */
+ private void updateResources(Resource.Type type, Request request, Predicate predicate) {
+ try {
+ Connection connection = connectionFactory.getConnection();
+ try {
+ Set<Map<PropertyId, Object>> propertySet = request.getProperties();
+
+ Map<PropertyId, Object> properties = propertySet.iterator().next();
+
+ String resourceTable = resourceTables.get(type);
+
+ predicate = getPredicate(connection, resourceTable, predicate);
+
+ if (predicate == null) {
+ return;
+ }
+
+ String sql = getUpdateSQL(resourceTable, properties, predicate);
+
+ Statement statement = connection.createStatement();
+
+ statement.execute(sql);
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+ /**
+ * Delete the resources selected by the given predicate.
+ *
+ * @param type the resource type
+ * @param predicate the predicate object which can be used to filter which
+ * resources are deleted
+ */
+ private void deleteResources(Resource.Type type, Predicate predicate) {
+ try {
+ Connection connection = connectionFactory.getConnection();
+ try {
+ String resourceTable = resourceTables.get(type);
+
+ predicate = getPredicate(connection, resourceTable, predicate);
+
+ if (predicate == null) {
+ return;
+ }
+
+ String sql = getDeleteSQL(resourceTable, predicate);
+
+ Statement statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+ /**
+ * Lazily populate the imported key mappings for the given table.
+ *
+ * @param connection the connection to use to obtain the database meta data
+ * @param table the table
+ *
+ * @throws SQLException thrown if the meta data for the given connection cannot be obtained
+ */
+ private void getImportedKeys(Connection connection, String table) throws SQLException {
+ if (!this.importedKeys.containsKey(table)) {
+
+ Map<PropertyId, PropertyId> importedKeys = new HashMap<PropertyId, PropertyId>();
+ this.importedKeys.put(table, importedKeys);
+
+ DatabaseMetaData metaData = connection.getMetaData();
+
+ ResultSet rs = metaData.getImportedKeys(connection.getCatalog(), null, table);
+
+ while (rs.next()) {
+
+ PropertyId pkPropertyId = Properties.getPropertyId(
+ rs.getString("PKCOLUMN_NAME"), rs.getString("PKTABLE_NAME"));
+
+ PropertyId fkPropertyId = Properties.getPropertyId(
+ rs.getString("FKCOLUMN_NAME"), rs.getString("FKTABLE_NAME"));
+
+ importedKeys.put(pkPropertyId, fkPropertyId);
+ }
+ }
+ }
+
+ /**
+ * Lazily populate the primary key mappings for the given table.
+ *
+ * @param connection the connection to use to obtain the database meta data
+ * @param table the table
+ *
+ * @throws SQLException thrown if the meta data for the given connection cannot be obtained
+ */
+ private void getPrimaryKeys(Connection connection, String table) throws SQLException {
+
+ if (!this.primaryKeys.containsKey(table)) {
+
+ Set<PropertyId> primaryKeys = new HashSet<PropertyId>();
+ this.primaryKeys.put(table, primaryKeys);
+
+ DatabaseMetaData metaData = connection.getMetaData();
+
+ ResultSet rs = metaData.getPrimaryKeys(connection.getCatalog(), null, table);
+
+ while (rs.next()) {
+
+ PropertyId pkPropertyId = Properties.getPropertyId(
+ rs.getString("COLUMN_NAME"), rs.getString("TABLE_NAME"));
+
+ primaryKeys.add(pkPropertyId);
+ }
+ }
+ }
+
+ /**
+ * Create a new predicate if the given predicate doesn't work for the given table. Use the
+ * given predicate and join to the given table to get the primary key values to create a new
+ * predicate. (Could probably do this with INNER JOIN???)
+ *
+ * @param connection the JDBC connection
+ * @param table the resource table
+ * @param predicate the predicate
+ *
+ * @return the new predicate
+ *
+ * @throws SQLException thrown if an exception occurred operating on the given connection
+ */
+ private Predicate getPredicate(Connection connection, String table, Predicate predicate) throws SQLException {
+
+ Set<String> predicateTables = getTables(PredicateHelper.getPropertyIds(predicate));
+
+ if (predicateTables.size() > 1 || !predicateTables.contains(table)) {
+ for (String predicateTable : predicateTables){
+ getImportedKeys(connection, predicateTable);
+ }
+
+ getPrimaryKeys(connection, table);
+ getImportedKeys(connection, table);
+
+ Set<PropertyId> pkPropertyIds = primaryKeys.get(table);
+ String sql = getSelectSQL(pkPropertyIds, predicate);
+ Statement statement = connection.createStatement();
+ ResultSet rs = statement.executeQuery(sql);
+ ResultSetMetaData metaData = rs.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+ Set<BasePredicate> predicates = new HashSet<BasePredicate>();
+ while (rs.next()) {
+ for (int i = 1; i <= columnCount; ++i) {
+ PropertyIdImpl propertyId = new PropertyIdImpl(metaData.getColumnName(i), metaData.getTableName(i), false);
+ if (pkPropertyIds.contains(propertyId)) {
+ predicates.add(new EqualsPredicate(propertyId, rs.getString(i)));
+ }
+ }
+ }
+
+ predicate = predicates.size() == 0 ? null : predicates.size() > 1 ?
+ new AndPredicate(predicates.toArray(new BasePredicate[2])) :
+ predicates.iterator().next();
+ }
+ return predicate;
+ }
+
+ /**
+ * Get an insert SQL statement based on the given properties.
+ *
+ * @param table the table
+ * @param properties the properties
+ *
+ * @return the insert SQL
+ */
+ private String getInsertSQL(String table, Map<PropertyId, Object> properties) {
+
+ StringBuilder columns = new StringBuilder();
+ StringBuilder values = new StringBuilder();
+
+ for (Map.Entry<PropertyId, Object> entry : properties.entrySet()) {
+ PropertyId propertyId = entry.getKey();
+ Object propertyValue = entry.getValue();
+
+ if (columns.length() > 0) {
+ columns.append(", ");
+ }
+ columns.append(propertyId.getName());
+
+ if (values.length() > 0) {
+ values.append(", ");
+ }
+
+ if (propertyValue instanceof String) {
+ values.append("'");
+ values.append(propertyValue);
+ values.append("'");
+ } else {
+ values.append(propertyValue);
+ }
+ }
+
+ return "insert into " + table + " (" +
+ columns + ") values (" + values + ")";
+ }
+
+ /**
+ * Get a select SQL statement based on the given property ids and predicate.
+ *
+ * @param propertyIds the property ids
+ * @param predicate the predicate
+ *
+ * @return the select SQL
+ */
+ private String getSelectSQL(Set<PropertyId> propertyIds, Predicate predicate) {
+
+ StringBuilder columns = new StringBuilder();
+ Set<String> tableSet = new HashSet<String>();
+
+ for (PropertyId propertyId : propertyIds) {
+ if (columns.length() > 0) {
+ columns.append(", ");
+ }
+ columns.append(propertyId.getCategory()).append(".").append(propertyId.getName());
+ tableSet.add(propertyId.getCategory());
+ }
+
+ boolean haveWhereClause = false;
+ StringBuilder whereClause = new StringBuilder();
+ if (predicate != null && predicate instanceof PredicateVisitorAcceptor) {
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ PredicateHelper.visit(predicate, visitor);
+ whereClause.append(visitor.getSQL());
+
+ for (PropertyId propertyId : PredicateHelper.getPropertyIds(predicate)) {
+ tableSet.add(propertyId.getCategory());
+ }
+ haveWhereClause = true;
+ }
+
+ StringBuilder joinClause = new StringBuilder();
+
+ if (tableSet.size() > 1) {
+
+ for (String table : tableSet) {
+ Map<PropertyId, PropertyId> joinKeys = importedKeys.get(table);
+ if (joinKeys != null) {
+ for (Map.Entry<PropertyId, PropertyId> entry : joinKeys.entrySet()) {
+ String category1 = entry.getKey().getCategory();
+ String category2 = entry.getValue().getCategory();
+ if (tableSet.contains(category1) && tableSet.contains(category2)) {
+ if (haveWhereClause) {
+ joinClause.append(" AND ");
+ }
+ joinClause.append(category1).append(".").append(entry.getKey().getName());
+ joinClause.append(" = ");
+ joinClause.append(category2).append(".").append(entry.getValue().getName());
+ tableSet.add(category1);
+ tableSet.add(category2);
+
+ haveWhereClause = true;
+ }
+ }
+ }
+ }
+ }
+
+ StringBuilder tables = new StringBuilder();
+
+ for (String table : tableSet) {
+ if (tables.length() > 0) {
+ tables.append(", ");
+ }
+ tables.append(table);
+ }
+
+ String sql = "select " + columns + " from " + tables;
+
+ if (haveWhereClause) {
+ sql = sql + " where " + whereClause + joinClause;
+ }
+ return sql;
+ }
+
+ /**
+ * Get a delete SQL statement based on the given predicate.
+ *
+ * @param table the table
+ * @param predicate the predicate
+ *
+ * @return the delete SQL statement
+ */
+ private String getDeleteSQL(String table, Predicate predicate) {
+
+ StringBuilder whereClause = new StringBuilder();
+ if (predicate instanceof BasePredicate) {
+
+ BasePredicate basePredicate = (BasePredicate) predicate;
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ basePredicate.accept(visitor);
+ whereClause.append(visitor.getSQL());
+
+ return "delete from " + table + " where " + whereClause;
+ }
+ throw new IllegalStateException("Can't generate SQL.");
+ }
+
+ /**
+ * Get an update SQL statement based on the given properties and predicate.
+ *
+ * @param table the table
+ * @param properties the properties
+ * @param predicate the predicate
+ *
+ * @return the update SQL statement
+ */
+ private String getUpdateSQL(String table, Map<PropertyId, Object> properties, Predicate predicate) {
+
+ if (predicate instanceof BasePredicate) {
+
+ StringBuilder whereClause = new StringBuilder();
+
+ BasePredicate basePredicate = (BasePredicate) predicate;
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ basePredicate.accept(visitor);
+ whereClause.append(visitor.getSQL());
+
+ StringBuilder setClause = new StringBuilder();
+ for (Map.Entry<PropertyId, Object> entry : properties.entrySet()) {
+
+ if (setClause.length() > 0) {
+ setClause.append(", ");
+ }
+ setClause.append(entry.getKey().getName());
+ setClause.append(" = ");
+ Object propertyValue = entry.getValue();
+
+ if (propertyValue instanceof String) {
+ setClause.append("'");
+ setClause.append(propertyValue);
+ setClause.append("'");
+ } else {
+ setClause.append(propertyValue);
+ }
+ }
+
+ return "update " + table + " set " + setClause + " where " + whereClause;
+ }
+ throw new IllegalStateException("Can't generate SQL.");
+ }
+
+ /**
+ * Get the set of tables associated with the given property ids.
+ *
+ * @param propertyIds the property ids
+ *
+ * @return the set of tables
+ */
+ private static Set<String> getTables(Set<PropertyId> propertyIds) {
+ Set<String> tables = new HashSet<String>();
+ for (PropertyId propertyId : propertyIds) {
+ tables.add(propertyId.getCategory());
+ }
+ return tables;
}
}
+
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCProviderModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCProviderModule.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCProviderModule.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCProviderModule.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,44 @@
+/**
+ * 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.api.controller.jdbc;
+
+import org.apache.ambari.api.controller.ProviderModule;
+import org.apache.ambari.api.controller.utilities.DBHelper;
+import org.apache.ambari.api.controller.utilities.Properties;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ *
+ */
+public class JDBCProviderModule implements ProviderModule {
+
+ private static final List<PropertyProvider> PROPERTY_PROVIDERS = new LinkedList<PropertyProvider>();
+
+ @Override
+ public ResourceProvider getResourceProvider(Resource.Type type) {
+ return new JDBCResourceProvider(DBHelper.CONNECTION_FACTORY, type,
+ PROPERTY_PROVIDERS, Properties.getPropertyIds(type, "DB"),
+ Properties.getKeyPropertyIds(type));
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCResourceProvider.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCResourceProvider.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/JDBCResourceProvider.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,424 @@
+/**
+ * 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.api.controller.jdbc;
+
+import org.apache.ambari.api.controller.internal.PropertyIdImpl;
+import org.apache.ambari.api.controller.internal.ResourceImpl;
+import org.apache.ambari.api.controller.internal.SchemaImpl;
+import org.apache.ambari.api.controller.utilities.PredicateHelper;
+import org.apache.ambari.api.controller.utilities.Properties;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.PredicateVisitorAcceptor;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.Schema;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Generic JDBC based resource provider.
+ */
+public class JDBCResourceProvider implements ResourceProvider {
+
+ private final Resource.Type type;
+
+ private final Set<PropertyId> propertyIds;
+
+ private final ConnectionFactory connectionFactory;
+
+ /**
+ * The list of property providers for this provider's resource type.
+ */
+ private final List<PropertyProvider> propertyProviders;
+
+ /**
+ * The schema for this provider's resource type.
+ */
+ private final Schema schema;
+
+ /**
+ * Key mappings used for joins.
+ */
+ private final Map<String, Map<PropertyId, PropertyId>> importedKeys = new HashMap<String, Map<PropertyId, PropertyId>>();
+
+ public JDBCResourceProvider(ConnectionFactory connectionFactory,
+ Resource.Type type,
+ List<PropertyProvider> propertyProviders,
+ Set<PropertyId> propertyIds,
+ Map<Resource.Type, PropertyId> keyPropertyIds) {
+ this.connectionFactory = connectionFactory;
+ this.type = type;
+ this.propertyProviders = propertyProviders;
+ this.propertyIds = propertyIds;
+ this.schema = new SchemaImpl(this, keyPropertyIds);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate) {
+
+ Set<Resource> resources = new HashSet<Resource>();
+ Set<PropertyId> propertyIds = new HashSet<PropertyId>(request.getPropertyIds());
+ if (propertyIds.isEmpty()) {
+ propertyIds.addAll(this.propertyIds);
+ } else {
+ if (predicate != null) {
+ propertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
+ }
+ propertyIds.retainAll(this.propertyIds);
+ }
+
+ try {
+ Connection connection = connectionFactory.getConnection();
+
+ try {
+
+ for (String table : getTables(propertyIds)) {
+ getImportedKeys(connection, table);
+ }
+
+ String sql = getSelectSQL(propertyIds, predicate);
+ Statement statement = connection.createStatement();
+
+ ResultSet rs = statement.executeQuery(sql);
+
+ while (rs.next()) {
+ ResultSetMetaData metaData = rs.getMetaData();
+ int columnCount = metaData.getColumnCount();
+
+ final ResourceImpl resource = new ResourceImpl(type);
+ for (int i = 1; i <= columnCount; ++i) {
+ PropertyIdImpl propertyId = new PropertyIdImpl(metaData.getColumnName(i), metaData.getTableName(i), false);
+ if (propertyIds.contains(propertyId)) {
+ resource.setProperty(propertyId, rs.getString(i));
+ }
+ }
+ resources.add(resource);
+ }
+
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+
+ return resources;
+ }
+
+ @Override
+ public void createResources(Request request) {
+ try {
+ Connection connection = connectionFactory.getConnection();
+
+ try {
+
+ Set<Map<PropertyId, Object>> propertySet = request.getProperties();
+
+ for (Map<PropertyId, Object> properties : propertySet) {
+ String sql = getInsertSQL(properties);
+
+ Statement statement = connection.createStatement();
+
+ statement.execute(sql);
+ }
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+ @Override
+ public void updateResources(Request request, Predicate predicate) {
+
+ try {
+ Connection connection = connectionFactory.getConnection();
+ try {
+ Set<Map<PropertyId, Object>> propertySet = request.getProperties();
+
+ Map<PropertyId, Object> properties = propertySet.iterator().next();
+
+ String sql = getUpdateSQL(properties, predicate);
+
+ System.out.println(sql);
+
+ Statement statement = connection.createStatement();
+
+ statement.execute(sql);
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+ @Override
+ public void deleteResources(Predicate predicate) {
+ try {
+ Connection connection = connectionFactory.getConnection();
+ try {
+ String sql = getDeleteSQL(predicate);
+
+ Statement statement = connection.createStatement();
+ statement.execute(sql);
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("DB error : ", e);
+ }
+ }
+
+
+ private String getInsertSQL(Map<PropertyId, Object> properties) {
+
+ StringBuilder columns = new StringBuilder();
+ StringBuilder values = new StringBuilder();
+ String table = null;
+
+
+ for (Map.Entry<PropertyId, Object> entry : properties.entrySet()) {
+ PropertyId propertyId = entry.getKey();
+ String propertyValue = (String) entry.getValue();
+
+ table = propertyId.getCategory();
+
+
+ if (columns.length() > 0) {
+ columns.append(", ");
+ }
+ columns.append(propertyId.getName());
+
+ if (values.length() > 0) {
+ values.append(", ");
+ }
+ values.append("'");
+ values.append(propertyValue);
+ values.append("'");
+ }
+
+ return "insert into " + table + " (" +
+ columns + ") values (" +values + ")";
+ }
+
+ private String getSelectSQL(Set<PropertyId> propertyIds, Predicate predicate) {
+
+ StringBuilder columns = new StringBuilder();
+ Set<String> tableSet = new HashSet<String>();
+
+ for (PropertyId propertyId : propertyIds) {
+ if (columns.length() > 0) {
+ columns.append(", ");
+ }
+ columns.append(propertyId.getCategory()).append(".").append(propertyId.getName());
+ tableSet.add(propertyId.getCategory());
+ }
+
+
+ boolean haveWhereClause = false;
+ StringBuilder whereClause = new StringBuilder();
+ if (predicate != null &&
+ propertyIds.containsAll(PredicateHelper.getPropertyIds(predicate)) &&
+ predicate instanceof PredicateVisitorAcceptor) {
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ ((PredicateVisitorAcceptor) predicate).accept(visitor);
+ whereClause.append(visitor.getSQL());
+ haveWhereClause = true;
+ }
+
+ StringBuilder joinClause = new StringBuilder();
+
+ if (tableSet.size() > 1) {
+
+ for (String table : tableSet) {
+ Map<PropertyId, PropertyId> joinKeys = importedKeys.get(table);
+ if (joinKeys != null) {
+ for (Map.Entry<PropertyId, PropertyId> entry : joinKeys.entrySet()) {
+ String category1 = entry.getKey().getCategory();
+ String category2 = entry.getValue().getCategory();
+ if (tableSet.contains(category1) && tableSet.contains(category2)) {
+ if (haveWhereClause) {
+ joinClause.append(" AND ");
+ }
+ joinClause.append(category1).append(".").append(entry.getKey().getName());
+ joinClause.append(" = ");
+ joinClause.append(category2).append(".").append(entry.getValue().getName());
+ tableSet.add(category1);
+ tableSet.add(category2);
+
+ haveWhereClause = true;
+ }
+ }
+ }
+ }
+ }
+
+ StringBuilder tables = new StringBuilder();
+
+ for (String table : tableSet) {
+ if (tables.length() > 0) {
+ tables.append(", ");
+ }
+ tables.append(table);
+ }
+
+ String sql = "select " + columns + " from " + tables;
+
+ if (haveWhereClause) {
+ sql = sql + " where " + whereClause + joinClause;
+ }
+
+ System.out.println(sql);
+
+ return sql;
+ }
+
+ private String getDeleteSQL(Predicate predicate) {
+
+ StringBuilder whereClause = new StringBuilder();
+ if (predicate instanceof BasePredicate) {
+
+ BasePredicate basePredicate = (BasePredicate) predicate;
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ basePredicate.accept(visitor);
+ whereClause.append(visitor.getSQL());
+
+ String table = basePredicate.getPropertyIds().iterator().next().getCategory();
+
+ return "delete from " + table + " where " + whereClause;
+ }
+ throw new IllegalStateException("Can't generate SQL.");
+ }
+
+ private String getUpdateSQL(Map<PropertyId, Object> properties, Predicate predicate) {
+
+ if (predicate instanceof BasePredicate) {
+
+ StringBuilder whereClause = new StringBuilder();
+
+ BasePredicate basePredicate = (BasePredicate) predicate;
+
+ SQLPredicateVisitor visitor = new SQLPredicateVisitor();
+ basePredicate.accept(visitor);
+ whereClause.append(visitor.getSQL());
+
+ String table = basePredicate.getPropertyIds().iterator().next().getCategory();
+
+
+ StringBuilder setClause = new StringBuilder();
+ for (Map.Entry<PropertyId, Object> entry : properties.entrySet()) {
+
+ if (setClause.length() > 0) {
+ setClause.append(", ");
+ }
+ setClause.append(entry.getKey().getName());
+ setClause.append(" = ");
+ setClause.append("'");
+ setClause.append(entry.getValue());
+ setClause.append("'");
+ }
+
+ return "update " + table + " set " + setClause + " where " + whereClause;
+ }
+ throw new IllegalStateException("Can't generate SQL.");
+ }
+
+ @Override
+ public Set<PropertyId> getPropertyIds() {
+ return propertyIds;
+ }
+
+ @Override
+ public List<PropertyProvider> getPropertyProviders() {
+ return propertyProviders;
+ }
+
+ @Override
+ public Schema getSchema() {
+ return schema;
+ }
+
+ /**
+ * Lazily populate the imported key mappings for the given table.
+ *
+ * @param connection the connection to use to obtain the database meta data
+ * @param table the table
+ *
+ * @throws SQLException thrown if the meta data for the given connection cannot be obtained
+ */
+ private void getImportedKeys(Connection connection, String table) throws SQLException {
+ if (!this.importedKeys.containsKey(table)) {
+
+ Map<PropertyId, PropertyId> importedKeys = new HashMap<PropertyId, PropertyId>();
+ this.importedKeys.put(table, importedKeys);
+
+ DatabaseMetaData metaData = connection.getMetaData();
+
+ ResultSet rs = metaData.getImportedKeys(connection.getCatalog(), null, table);
+
+ while (rs.next()) {
+
+ PropertyId pkPropertyId = Properties.getPropertyId(
+ rs.getString("PKCOLUMN_NAME"), rs.getString("PKTABLE_NAME"));
+
+ PropertyId fkPropertyId = Properties.getPropertyId(
+ rs.getString("FKCOLUMN_NAME"), rs.getString("FKTABLE_NAME"));
+
+ importedKeys.put(pkPropertyId, fkPropertyId);
+ }
+ }
+ }
+
+ /**
+ * Get the set of tables associated with the given property ids.
+ *
+ * @param propertyIds the property ids
+ *
+ * @return the set of tables
+ */
+ private static Set<String> getTables(Set<PropertyId> propertyIds) {
+ Set<String> tables = new HashSet<String>();
+ for (PropertyId propertyId : propertyIds) {
+ tables.add(propertyId.getCategory());
+ }
+ return tables;
+ }
+}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLPredicateVisitor.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLPredicateVisitor.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLPredicateVisitor.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLPredicateVisitor.java Mon Oct 8 01:37:59 2012
@@ -18,20 +18,26 @@
package org.apache.ambari.api.controller.jdbc;
-import org.apache.ambari.api.controller.predicate.ArrayPredicate;
-import org.apache.ambari.api.controller.predicate.BasePredicate;
-import org.apache.ambari.api.controller.predicate.ComparisonPredicate;
-import org.apache.ambari.api.controller.predicate.PredicateVisitor;
-import org.apache.ambari.api.controller.predicate.UnaryPredicate;
-import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.predicate.ArrayPredicate;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.ComparisonPredicate;
+import org.apache.ambari.server.controller.predicate.PredicateVisitor;
+import org.apache.ambari.server.controller.predicate.UnaryPredicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
/**
- *
+ * Predicate visitor used to generate a SQL where clause from a predicate graph.
*/
public class SQLPredicateVisitor implements PredicateVisitor {
+ /**
+ * The string builder.
+ */
private final StringBuilder stringBuilder = new StringBuilder();
+
+ // ----- PredicateVisitor --------------------------------------------------
+
@Override
public void acceptComparisonPredicate(ComparisonPredicate predicate) {
PropertyId propertyId = predicate.getPropertyId();
@@ -71,6 +77,8 @@ public class SQLPredicateVisitor impleme
}
+ // ----- SQLPredicateVisitor -----------------------------------------------
+
public String getSQL() {
return stringBuilder.toString();
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLiteConnectionFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLiteConnectionFactory.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLiteConnectionFactory.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jdbc/SQLiteConnectionFactory.java Mon Oct 8 01:37:59 2012
@@ -23,14 +23,28 @@ import java.sql.DriverManager;
import java.sql.SQLException;
/**
- *
+ * Connection factory implementation for SQLite.
*/
public class SQLiteConnectionFactory implements ConnectionFactory {
- public static final String CONNECTION_URL = "jdbc:sqlite:";
+ /**
+ * The connection URL minus the db file.
+ */
+ private static final String CONNECTION_URL = "jdbc:sqlite:";
+ /**
+ * The filename of the SQLite db file.
+ */
private final String dbFile;
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Create a connection factory.
+ *
+ * @param dbFile the SQLite DB filename
+ */
public SQLiteConnectionFactory(String dbFile) {
this.dbFile = dbFile;
try {
@@ -40,6 +54,9 @@ public class SQLiteConnectionFactory imp
}
}
+
+ // ----- ConnectionFactory -------------------------------------------------
+
@Override
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(CONNECTION_URL + dbFile);
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jmx/JMXPropertyProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jmx/JMXPropertyProvider.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jmx/JMXPropertyProvider.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/jmx/JMXPropertyProvider.java Mon Oct 8 01:37:59 2012
@@ -19,11 +19,11 @@
package org.apache.ambari.api.controller.jmx;
import org.apache.ambari.api.controller.internal.PropertyIdImpl;
-import org.apache.ambari.api.controller.spi.Predicate;
-import org.apache.ambari.api.controller.spi.PropertyId;
-import org.apache.ambari.api.controller.spi.PropertyProvider;
-import org.apache.ambari.api.controller.spi.Request;
-import org.apache.ambari.api.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.api.controller.utilities.PredicateHelper;
import org.apache.ambari.api.controller.utilities.Properties;
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/ClusterControllerHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/ClusterControllerHelper.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/ClusterControllerHelper.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/ClusterControllerHelper.java Mon Oct 8 01:37:59 2012
@@ -18,57 +18,32 @@
package org.apache.ambari.api.controller.utilities;
+import org.apache.ambari.api.controller.ProviderModule;
import org.apache.ambari.api.controller.internal.ClusterControllerImpl;
-import org.apache.ambari.api.controller.internal.PropertyIdImpl;
-import org.apache.ambari.api.controller.internal.ResourceProviderImpl;
-import org.apache.ambari.api.controller.internal.SchemaImpl;
-import org.apache.ambari.api.controller.jdbc.JDBCManagementController;
-import org.apache.ambari.api.controller.spi.ClusterController;
-import org.apache.ambari.api.controller.spi.ManagementController;
-import org.apache.ambari.api.controller.spi.PropertyId;
-import org.apache.ambari.api.controller.spi.PropertyProvider;
-import org.apache.ambari.api.controller.spi.Resource;
-import org.apache.ambari.api.controller.spi.ResourceProvider;
-import org.apache.ambari.api.controller.spi.Schema;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import org.apache.ambari.api.controller.internal.DefaultProviderModule;
+import org.apache.ambari.server.controller.spi.ClusterController;
/**
* Temporary class to bootstrap a cluster controller. TODO : Replace this global state with injection.
*/
public class ClusterControllerHelper {
+
+ private static String PROVIDER_MODULE_CLASS = System.getProperty("provider.module.class",
+ "org.apache.ambari.api.controller.internal.DefaultProviderModule");
+
private static ClusterController controller;
public static synchronized ClusterController getClusterController() {
if (controller == null) {
- controller = new ClusterControllerImpl(getResourceSchemas());
+ try {
+ Class implClass = Class.forName(PROVIDER_MODULE_CLASS);
+ ProviderModule providerModule = (ProviderModule) implClass.newInstance();
+ return new ClusterControllerImpl(providerModule);
+
+ } catch (Exception e) {
+ throw new IllegalStateException("Can't create provider module " + PROVIDER_MODULE_CLASS);
+ }
}
return controller;
}
-
- private static Map<Resource.Type, Schema> getResourceSchemas() {
- Map<Resource.Type, Schema> schemas = new HashMap<Resource.Type, Schema>();
-
- schemas.put(Resource.Type.Cluster, getResourceSchema(Resource.Type.Cluster));
- schemas.put(Resource.Type.Service, getResourceSchema(Resource.Type.Service));
- schemas.put(Resource.Type.Host, getResourceSchema(Resource.Type.Host));
- schemas.put(Resource.Type.Component, getResourceSchema(Resource.Type.Component));
- schemas.put(Resource.Type.HostComponent, getResourceSchema(Resource.Type.HostComponent));
-
- return schemas;
- }
-
- private static Schema getResourceSchema(Resource.Type type) {
-
- ManagementController managementController = new JDBCManagementController(DBHelper.CONNECTION_FACTORY);
-
- ResourceProvider resourceProvider = ResourceProviderImpl.getResourceProvider(type, Properties.getPropertyIds(type, "DB"), managementController);
-
- List<PropertyProvider> propertyProviders = new LinkedList<PropertyProvider>();
-
- return new SchemaImpl(resourceProvider, propertyProviders, Properties.getKeyPropertyIds(type));
- }
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/DBHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/DBHelper.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/DBHelper.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/DBHelper.java Mon Oct 8 01:37:59 2012
@@ -54,7 +54,6 @@ public class DBHelper {
String sql = "select attributes from hosts";
Statement statement = connection.createStatement();
- statement.setQueryTimeout(30); // set timeout to 30 sec.
ResultSet rs = statement.executeQuery(sql);
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateBuilder.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateBuilder.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateBuilder.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateBuilder.java Mon Oct 8 01:37:59 2012
@@ -18,17 +18,17 @@
package org.apache.ambari.api.controller.utilities;
import org.apache.ambari.api.controller.internal.PropertyIdImpl;
-import org.apache.ambari.api.controller.predicate.AndPredicate;
-import org.apache.ambari.api.controller.predicate.BasePredicate;
-import org.apache.ambari.api.controller.predicate.Comparables;
-import org.apache.ambari.api.controller.predicate.EqualsPredicate;
-import org.apache.ambari.api.controller.predicate.GreaterEqualsPredicate;
-import org.apache.ambari.api.controller.predicate.GreaterPredicate;
-import org.apache.ambari.api.controller.predicate.LessEqualsPredicate;
-import org.apache.ambari.api.controller.predicate.LessPredicate;
-import org.apache.ambari.api.controller.predicate.NotPredicate;
-import org.apache.ambari.api.controller.predicate.OrPredicate;
-import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.Comparables;
+import org.apache.ambari.server.controller.predicate.EqualsPredicate;
+import org.apache.ambari.server.controller.predicate.GreaterEqualsPredicate;
+import org.apache.ambari.server.controller.predicate.GreaterPredicate;
+import org.apache.ambari.server.controller.predicate.LessEqualsPredicate;
+import org.apache.ambari.server.controller.predicate.LessPredicate;
+import org.apache.ambari.server.controller.predicate.NotPredicate;
+import org.apache.ambari.server.controller.predicate.OrPredicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
import java.util.LinkedList;
import java.util.List;
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateHelper.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateHelper.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/PredicateHelper.java Mon Oct 8 01:37:59 2012
@@ -17,9 +17,11 @@
*/
package org.apache.ambari.api.controller.utilities;
-import org.apache.ambari.api.controller.predicate.BasePredicate;
-import org.apache.ambari.api.controller.spi.Predicate;
-import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.PredicateVisitor;
+import org.apache.ambari.server.controller.predicate.PredicateVisitorAcceptor;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
import java.util.Collections;
import java.util.Set;
@@ -35,4 +37,10 @@ public class PredicateHelper {
}
return Collections.emptySet();
}
+
+ public static void visit(Predicate predicate, PredicateVisitor visitor) {
+ if (predicate instanceof PredicateVisitorAcceptor) {
+ ((PredicateVisitorAcceptor) predicate).accept(visitor);
+ }
+ }
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/Properties.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/Properties.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/Properties.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/controller/utilities/Properties.java Mon Oct 8 01:37:59 2012
@@ -18,8 +18,8 @@
package org.apache.ambari.api.controller.utilities;
import org.apache.ambari.api.controller.internal.PropertyIdImpl;
-import org.apache.ambari.api.controller.spi.PropertyId;
-import org.apache.ambari.api.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.Resource;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/CreateHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/CreateHandler.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/CreateHandler.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/CreateHandler.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,33 @@
+/**
+ * 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.api.handlers;
+
+import org.apache.ambari.api.services.Request;
+import org.apache.ambari.api.services.Result;
+
+/**
+ * Responsible for create requests.
+ */
+public class CreateHandler implements RequestHandler {
+ @Override
+ public Result handleRequest(Request request) {
+ //TODO: implement
+ return null;
+ }
+}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DelegatingRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DelegatingRequestHandler.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DelegatingRequestHandler.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DelegatingRequestHandler.java Mon Oct 8 01:37:59 2012
@@ -22,14 +22,23 @@ import org.apache.ambari.api.services.Re
import org.apache.ambari.api.services.Result;
/**
- *
+ * Request handler implementation that all requests are funneled through.
+ * Provides common handler functionality and delegates to concrete handler.
*/
public class DelegatingRequestHandler implements RequestHandler {
@Override
public Result handleRequest(Request request) {
- return getRequestHandlerFactory().getRequestHandler(request.getRequestType()).handleRequest(request);
+ Result result = getRequestHandlerFactory().getRequestHandler(request.getRequestType()).handleRequest(request);
+ request.getResultPostProcessor().process(result);
+
+ return result;
}
+ /**
+ * Obtain a factory for the request specific concrete request handlers.
+ *
+ * @return A request handler factory
+ */
RequestHandlerFactory getRequestHandlerFactory() {
return new RequestHandlerFactory();
}
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DeleteHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DeleteHandler.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DeleteHandler.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/DeleteHandler.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,33 @@
+/**
+ * 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.api.handlers;
+
+import org.apache.ambari.api.services.Request;
+import org.apache.ambari.api.services.Result;
+
+/**
+ * Responsible for delete requests.
+ */
+public class DeleteHandler implements RequestHandler {
+ @Override
+ public Result handleRequest(Request request) {
+ //TODO: implement
+ return null;
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/ReadHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/ReadHandler.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/ReadHandler.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/ReadHandler.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,53 @@
+/**
+ * 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.api.handlers;
+
+import org.apache.ambari.api.services.Request;
+import org.apache.ambari.api.services.Result;
+import org.apache.ambari.api.query.Query;
+import org.apache.ambari.server.AmbariException;
+
+/**
+ * Responsible for read requests.
+ */
+public class ReadHandler implements RequestHandler {
+
+ @Override
+ public Result handleRequest(Request request) {
+ Query query = request.getResourceDefinition().getQuery();
+
+ //Partial response
+ //todo: could be encapsulated in request/query
+ for (String s : request.getPartialResponseFields()) {
+ int i = s.lastIndexOf('/');
+ if (i == -1) {
+ query.addProperty(null, s);
+ } else {
+ query.addProperty(s.substring(0, i), s.substring(i + 1));
+ }
+ }
+
+ try {
+ return query.execute();
+ } catch (AmbariException e) {
+ //TODO: exceptions
+ throw new RuntimeException("An exception occurred processing the request: " + e, e);
+ }
+ }
+}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandler.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandler.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandler.java Mon Oct 8 01:37:59 2012
@@ -20,10 +20,17 @@ package org.apache.ambari.api.handlers;
import org.apache.ambari.api.services.Request;
import org.apache.ambari.api.services.Result;
+import org.apache.ambari.server.AmbariException;
/**
- *
+ * Responsible for handling of requests and returning a result.
*/
public interface RequestHandler {
+ /**
+ * Handle the given request and return a result.
+ *
+ * @param request the request to handle
+ * @return the result of the request
+ */
public Result handleRequest(Request request);
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandlerFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandlerFactory.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandlerFactory.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/RequestHandlerFactory.java Mon Oct 8 01:37:59 2012
@@ -21,16 +21,29 @@ package org.apache.ambari.api.handlers;
import org.apache.ambari.api.services.Request;
/**
- *
+ * Factory for {@link RequestHandler}
+ * Returns the appropriate request handler based on the request.
*/
public class RequestHandlerFactory {
- public RequestHandler getRequestHandler(Request.RequestType requestType) {
+ /**
+ * Return an instance of the correct request handler based on the request type.
+ *
+ * @param requestType the request type. Is one of {@link Request.Type}
+ * @return a request handler for the request
+ */
+ public RequestHandler getRequestHandler(Request.Type requestType) {
switch (requestType) {
case GET:
- return new ReadRequestHandler();
+ return new ReadHandler();
+ case PUT:
+ return new CreateHandler();
+ case POST:
+ return new UpdateHandler();
+ case DELETE:
+ return new DeleteHandler();
default:
//todo:
- throw new UnsupportedOperationException("Only GET requests are supported at this time");
+ throw new UnsupportedOperationException("Unsupported Request Type: " + requestType);
}
}
}
Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/UpdateHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/UpdateHandler.java?rev=1395430&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/UpdateHandler.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/handlers/UpdateHandler.java Mon Oct 8 01:37:59 2012
@@ -0,0 +1,33 @@
+/**
+ * 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.api.handlers;
+
+import org.apache.ambari.api.services.Request;
+import org.apache.ambari.api.services.Result;
+
+/**
+ * Responsible for update requests.
+ */
+public class UpdateHandler implements RequestHandler {
+ @Override
+ public Result handleRequest(Request request) {
+ //TODO: implement
+ return null;
+ }
+}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/Query.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/Query.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/Query.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/Query.java Mon Oct 8 01:37:59 2012
@@ -19,25 +19,37 @@
package org.apache.ambari.api.query;
import org.apache.ambari.api.services.Result;
-import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.spi.PropertyId;
-import java.util.Map;
-import java.util.Set;
/**
- *
+ * Responsible for querying the back end for read requests
*/
public interface Query {
- public void addAllProperties(Map<String, Set<String>> setProperties);
-
- public void addProperty(String path, String property);
+ /**
+ * Add a property to the query.
+ * This is the select portion of the query.
+ *
+ * @param group the group name that contains the property
+ * @param property the property name
+ */
+ public void addProperty(String group, String property);
+
+ /**
+ * Add a property to the query.
+ * This is the select portion of the query.
+ *
+ * @param property the property id which contains the group, property name
+ * and whether the property is temporal
+ */
public void addProperty(PropertyId property);
- //todo: signature - need path
- public void retainAllProperties(Set<String> setFields);
-
- public void clearAllProperties();
-
- public Result execute();
+ /**
+ * Execute the query.
+ *
+ * @return the result of the query.
+ */
+ public Result execute() throws AmbariException;
}
Modified: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java?rev=1395430&r1=1395429&r2=1395430&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java Mon Oct 8 01:37:59 2012
@@ -20,107 +20,162 @@ package org.apache.ambari.api.query;
import org.apache.ambari.api.controller.internal.PropertyIdImpl;
import org.apache.ambari.api.controller.internal.RequestImpl;
-import org.apache.ambari.api.controller.predicate.AndPredicate;
-import org.apache.ambari.api.controller.predicate.BasePredicate;
-import org.apache.ambari.api.controller.predicate.EqualsPredicate;
import org.apache.ambari.api.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.EqualsPredicate;
import org.apache.ambari.api.services.Result;
import org.apache.ambari.api.services.ResultImpl;
-import org.apache.ambari.api.controller.spi.*;
+import org.apache.ambari.server.controller.spi.*;
import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.util.TreeNode;
import java.util.*;
/**
- *
+ * Default read query.
*/
public class QueryImpl implements Query {
+ /**
+ * Resource definition of resource being operated on.
+ */
ResourceDefinition m_resourceDefinition;
- Predicate m_predicate;
- private Map<String, Set<String>> m_mapProperties = new HashMap<String, Set<String>>();
- private Map<ResourceDefinition, Query> m_mapSubQueries = new HashMap<ResourceDefinition, Query>();
-
+ /**
+ * Properties of the query which make up the select portion of the query.
+ */
+ private Map<String, Set<String>> m_mapQueryProperties = new HashMap<String, Set<String>>();
+
+ /**
+ * All properties that are available for the resource.
+ */
+ private Map<String, Set<String>> m_mapAllProperties;
+
+ /**
+ * Sub-resources of the resource which is being operated on.
+ */
+ private Map<String, ResourceDefinition> m_mapSubResources = new HashMap<String, ResourceDefinition>();
+
+
+ /**
+ * Constructor.
+ *
+ * @param resourceDefinition the resource definition of the resource being operated on
+ */
public QueryImpl(ResourceDefinition resourceDefinition) {
m_resourceDefinition = resourceDefinition;
+ m_mapAllProperties = Collections.unmodifiableMap(getClusterController().
+ getSchema(resourceDefinition.getType()).getCategories());
}
@Override
- public Result execute() {
- initialize();
-
- Result result = createResult();
- Iterable<Resource> iterResource = getClusterController().getResources(
- m_resourceDefinition.getType(), createRequest(), m_predicate);
-
- List<Resource> listResources = new ArrayList<Resource>();
- for (Resource resource : iterResource) {
- listResources.add(resource);
- }
- //todo: tree?
- result.addResources("/", listResources);
-
- for (Map.Entry<ResourceDefinition, Query> entry : m_mapSubQueries.entrySet()) {
- Query query = entry.getValue();
- ResourceDefinition resDef = entry.getKey();
-
- //todo: this ensures that the sub query is only executed if needed. Refactor.
- if (m_mapProperties.isEmpty() || m_mapProperties.containsKey(resDef.getId() == null ?
- resDef.getPluralName() : resDef.getSingularName())) {
- Map<String, List<Resource>> mapSubResults = query.execute().getResources();
- //todo: only getting sub-resource one level deep at this time
- List<Resource> listSubResources = mapSubResults.get("/");
- String subResourceName = resDef.getId() == null ? resDef.getPluralName() : resDef.getSingularName();
- result.addResources(subResourceName, listSubResources);
+ public void addProperty(String path, String property) {
+ if (m_mapAllProperties.containsKey(path) && m_mapAllProperties.get(path).contains(property)) {
+ // local property
+ Set<String> setProps = m_mapQueryProperties.get(path);
+ if (setProps == null) {
+ setProps = new HashSet<String>();
+ m_mapQueryProperties.put(path, setProps);
}
- }
-
- return result;
- }
-
- //todo: refactor
- public void initialize() {
- m_predicate = createPredicate(m_resourceDefinition);
-
- if (m_resourceDefinition.getId() != null) {
- //sub-resource queries
- for (ResourceDefinition resource : m_resourceDefinition.getChildren()) {
- m_mapSubQueries.put(resource, resource.getQuery());
+ setProps.add(property);
+ } else if (m_mapAllProperties.containsKey(property)) {
+ // no path specified because path is provided as property
+ //local category
+ Set<String> setProps = m_mapQueryProperties.get(property);
+ if (setProps == null) {
+ setProps = new HashSet<String>();
+ m_mapQueryProperties.put(property, setProps);
}
- for (ResourceDefinition resource : m_resourceDefinition.getRelations()) {
- m_mapSubQueries.put(resource, resource.getQuery());
+ // add all props for category
+ setProps.addAll(m_mapAllProperties.get(property));
+ } else {
+ // not a local category/property
+ boolean success = addPropertyToSubResource(path, property);
+ if (!success) {
+ //TODO
+ throw new RuntimeException("Attempted to add invalid property to resource. Resource=" +
+ m_resourceDefinition.getType() + ", Property: Category=" + path + " Field=" + property);
}
}
}
@Override
- public void addAllProperties(Map<String, Set<String>> mapProperties) {
- m_mapProperties.putAll(mapProperties);
+ public void addProperty(PropertyId property) {
+ addProperty(property.getCategory(), property.getName());
}
@Override
- public void addProperty(String path, String property) {
- Set<String> setProps = m_mapProperties.get(path);
- if (setProps == null) {
- setProps = new HashSet<String>();
- m_mapProperties.put(path, setProps);
+ public Result execute() throws AmbariException {
+ Result result = createResult();
+
+ if (m_resourceDefinition.getId() == null) {
+ // collection, add pk only
+ Schema schema = getClusterController().getSchema(m_resourceDefinition.getType());
+ addProperty(schema.getKeyPropertyId(m_resourceDefinition.getType()));
+ result.getResultTree().setProperty("isCollection", "true");
}
- setProps.add(property);
- }
- @Override
- public void addProperty(PropertyId property) {
- addProperty(property.getCategory(), property.getName());
- }
+ if (m_mapQueryProperties.isEmpty() && m_mapSubResources.isEmpty()) {
+ //Add sub resource properties for default case where no fields are specified.
+ m_mapSubResources.putAll(m_resourceDefinition.getSubResources());
+ }
- @Override
- public void retainAllProperties(Set<String> setFields) {
- //todo
+ Predicate predicate = createPredicate(m_resourceDefinition);
+ Iterable<Resource> iterResource = getClusterController().getResources(
+ m_resourceDefinition.getType(), createRequest(), predicate);
+
+ for (Resource resource : iterResource) {
+ TreeNode<Resource> node = result.getResultTree().addChild(resource, null);
+
+ for (Map.Entry<String, ResourceDefinition> entry : m_mapSubResources.entrySet()) {
+ String subResCategory = entry.getKey();
+ ResourceDefinition r = entry.getValue();
+
+ r.setParentId(m_resourceDefinition.getType(), resource.getPropertyValue(
+ getClusterController().getSchema(m_resourceDefinition.getType()).
+ getKeyPropertyId(m_resourceDefinition.getType())));
+
+ TreeNode<Resource> childResult = r.getQuery().execute().getResultTree();
+ childResult.setName(subResCategory);
+ childResult.setProperty("isCollection", "false");
+ node.addChild(childResult);
+ }
+ }
+
+ return result;
}
- @Override
- public void clearAllProperties() {
- m_mapProperties.clear();
+
+ private boolean addPropertyToSubResource(String path, String property) {
+ boolean resourceAdded = false;
+
+ // cases:
+ // path is null, property is path
+ // path is single token and prop in non null
+ // path is multi level and prop is non null
+
+ if (path == null) {
+ path = property;
+ property = null;
+ }
+
+ int i = path.indexOf("/");
+ String p = i == -1 ? path : path.substring(0, i);
+
+ ResourceDefinition subResource = m_resourceDefinition.getSubResources().get(p);
+ if (subResource != null) {
+ m_mapSubResources.put(p, subResource);
+ //todo: handle case of trailing /
+ //todo: for example fields=subResource/
+
+ if (property != null || !path.equals(p)) {
+ //only add if a sub property is set or if a sub category is specified
+ subResource.getQuery().addProperty(i == -1 ? null : path.substring(i + 1), property);
+ }
+ resourceAdded = true;
+ }
+ return resourceAdded;
}
private Predicate createPredicate(ResourceDefinition resourceDefinition) {
@@ -129,31 +184,33 @@ public class QueryImpl implements Query
Map<Resource.Type, String> mapResourceIds = resourceDefinition.getResourceIds();
Schema schema = getClusterController().getSchema(resourceType);
- BasePredicate[] predicates = new BasePredicate[mapResourceIds.size()];
- int count = 0;
+ Set<Predicate> setPredicates = new HashSet<Predicate>();
for (Map.Entry<Resource.Type, String> entry : mapResourceIds.entrySet()) {
- predicates[count++] = new EqualsPredicate(schema.getKeyPropertyId(entry.getKey()), entry.getValue());
+ //todo: this is a hack for host_component and component queries where serviceId is not available for
+ //todo: host_component queries and host is not available for component queries.
+ //todo: this should be rectified when the data model is changed for host_component
+ if (entry.getValue() != null) {
+ setPredicates.add(new EqualsPredicate(schema.getKeyPropertyId(entry.getKey()), entry.getValue()));
+ }
}
- if (predicates.length == 1) {
- return predicates[0];
- } else if (predicates.length > 1) {
- return new AndPredicate(predicates);
+ if (setPredicates.size() == 1) {
+ return setPredicates.iterator().next();
+ } else if (setPredicates.size() > 1) {
+ return new AndPredicate(setPredicates.toArray(new BasePredicate[setPredicates.size()]));
} else {
return null;
}
}
- //todo: how to get Controller?
ClusterController getClusterController() {
return ClusterControllerHelper.getClusterController();
}
- //todo
Request createRequest() {
Set<PropertyId> setProperties = new HashSet<PropertyId>();
- //todo: convert property names to PropertyId's.
- for (Map.Entry<String, Set<String>> entry : m_mapProperties.entrySet()) {
+
+ for (Map.Entry<String, Set<String>> entry : m_mapQueryProperties.entrySet()) {
String group = entry.getKey();
for (String property : entry.getValue()) {
setProperties.add(new PropertyIdImpl(property, group, false));
@@ -162,10 +219,8 @@ public class QueryImpl implements Query
return new RequestImpl(setProperties, null);
}
- //todo
Result createResult() {
return new ResultImpl();
}
-
}