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/09 19:02:02 UTC
svn commit: r1396109 [4/7] - in /incubator/ambari/branches/AMBARI-666: ./
ambari-api/ ambari-project/ ambari-server/
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/
ambari-server/src/main/java/org/apache/ambari/server/api/query/ amba...
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCManagementController.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCManagementController.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCManagementController.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCManagementController.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,673 @@
+/**
+ * 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.server.controller.jdbc;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+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.server.controller.utilities.PredicateHelper;
+
+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 AmbariManagementController {
+ /**
+ * The connection factory.
+ */
+ private final 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 TrackActionResponse createCluster(ClusterRequest request) throws AmbariException {
+// createResources(Resource.Type.Cluster, request);
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse createService(ServiceRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse createComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse createHost(HostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse createHostComponent(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public Set<ClusterResponse> getClusters(ClusterRequest request) throws AmbariException {
+// return getResources(Resource.Type.Cluster, request, predicate);
+ return null;
+ }
+
+ @Override
+ public Set<ServiceResponse> getServices(ServiceRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public Set<ServiceComponentResponse> getComponents(ServiceComponentRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public Set<HostResponse> getHosts(HostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public Set<ServiceComponentHostResponse> getHostComponents(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse updateCluster(ClusterRequest request) throws AmbariException {
+// updateResources(Resource.Type.Cluster, request, predicate);
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse updateService(ServiceRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse updateComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse updateHost(HostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse updateHostComponent(ServiceComponentHostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse deleteCluster(ClusterRequest request) throws AmbariException {
+// deleteResources(Resource.Type.Cluster, predicate);
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse deleteService(ServiceRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse deleteComponent(ServiceComponentRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ public TrackActionResponse deleteHost(HostRequest request) throws AmbariException {
+ return null;
+ }
+
+ @Override
+ 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, String>> propertySet = request.getProperties();
+
+ for (Map<PropertyId, String> 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, String>> propertySet = request.getProperties();
+
+ Map<PropertyId, String> 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 = PropertyHelper.getPropertyId(
+ rs.getString("PKCOLUMN_NAME"), rs.getString("PKTABLE_NAME"));
+
+ PropertyId fkPropertyId = PropertyHelper.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 = PropertyHelper.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, String> properties) {
+
+ StringBuilder columns = new StringBuilder();
+ StringBuilder values = new StringBuilder();
+
+ for (Map.Entry<PropertyId, String> 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, String> 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, String> 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-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCProviderModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCProviderModule.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCProviderModule.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCProviderModule.java Tue Oct 9 17:01:58 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.server.controller.jdbc;
+
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.utilities.DBHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+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, PropertyHelper.getPropertyIds(type, "DB"),
+ PropertyHelper.getKeyPropertyIds(type));
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCResourceProvider.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCResourceProvider.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/JDBCResourceProvider.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,420 @@
+/**
+ * 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.server.controller.jdbc;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.internal.SchemaImpl;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+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, String>> propertySet = request.getProperties();
+
+ for (Map<PropertyId, String> 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, String>> propertySet = request.getProperties();
+
+ Map<PropertyId, String> properties = propertySet.iterator().next();
+
+ String sql = getUpdateSQL(properties, predicate);
+
+ 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, String> properties) {
+
+ StringBuilder columns = new StringBuilder();
+ StringBuilder values = new StringBuilder();
+ String table = null;
+
+
+ for (Map.Entry<PropertyId, String> entry : properties.entrySet()) {
+ PropertyId propertyId = entry.getKey();
+ String propertyValue = 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;
+ }
+
+ 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, String> 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, String> 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 = PropertyHelper.getPropertyId(
+ rs.getString("PKCOLUMN_NAME"), rs.getString("PKTABLE_NAME"));
+
+ PropertyId fkPropertyId = PropertyHelper.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;
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLPredicateVisitor.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLPredicateVisitor.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLPredicateVisitor.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLPredicateVisitor.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,85 @@
+/**
+ * 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.server.controller.jdbc;
+
+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();
+
+ if (propertyId.getCategory() != null) {
+ stringBuilder.append(propertyId.getCategory()).append(".");
+ }
+ stringBuilder.append(propertyId.getName());
+
+ stringBuilder.append(" ").append(predicate.getOperator()).append(" \"");
+ stringBuilder.append(predicate.getValue());
+ stringBuilder.append("\"");
+
+ }
+
+ @Override
+ public void acceptArrayPredicate(ArrayPredicate predicate) {
+ BasePredicate[] predicates = predicate.getPredicates();
+ if (predicates.length > 0) {
+
+ stringBuilder.append("(");
+ for (int i = 0; i < predicates.length; i++) {
+ if (i > 0) {
+ stringBuilder.append(" ").append(predicate.getOperator()).append(" ");
+ }
+ predicates[i].accept(this);
+ }
+ stringBuilder.append(")");
+ }
+ }
+
+ @Override
+ public void acceptUnaryPredicate(UnaryPredicate predicate) {
+ stringBuilder.append(predicate.getOperator()).append("(");
+ predicate.getPredicate().accept(this);
+ stringBuilder.append(")");
+ }
+
+
+ // ----- SQLPredicateVisitor -----------------------------------------------
+
+ public String getSQL() {
+ return stringBuilder.toString();
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLiteConnectionFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLiteConnectionFactory.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLiteConnectionFactory.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/SQLiteConnectionFactory.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,64 @@
+/**
+ * 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.server.controller.jdbc;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+ * Connection factory implementation for SQLite.
+ */
+public class SQLiteConnectionFactory implements ConnectionFactory {
+
+ /**
+ * 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 {
+ Class.forName("org.sqlite.JDBC");
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Can't load SQLite.", e);
+ }
+ }
+
+
+ // ----- ConnectionFactory -------------------------------------------------
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(CONNECTION_URL + dbFile);
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXHelper.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXHelper.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXHelper.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,46 @@
+/**
+ * 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.server.controller.jmx;
+
+import org.codehaus.jackson.map.ObjectMapper;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ *
+ */
+public class JMXHelper {
+
+ public static JMXMetrics getJMXMetrics(String target, String bean) {
+ String s = "http://" + target + "/jmx?qry=" + (bean == null ? "Hadoop:*" : bean);
+ try {
+ URLConnection connection = new URL(s).openConnection();
+
+ connection.setDoOutput(true);
+
+ return new ObjectMapper().readValue(connection.getInputStream(),
+ JMXMetrics.class);
+
+ } catch (IOException e) {
+ throw new IllegalStateException("Can't get metric " + ".", e);
+ }
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetrics.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetrics.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetrics.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetrics.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.jmx;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class JMXMetrics {
+
+ private List<Map<String, String>> beans;
+
+ public List<Map<String, String>> getBeans() {
+ return beans;
+ }
+
+ public void setBeans(List<Map<String, String>> beans) {
+ this.beans = beans;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ for (Map<String, String> map : beans) {
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ stringBuilder.append(" " + entry.toString() + "\n");
+ }
+ }
+ return stringBuilder.toString();
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXPropertyProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXPropertyProvider.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXPropertyProvider.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXPropertyProvider.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,132 @@
+/**
+ * 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.server.controller.jmx;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+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.utilities.PredicateHelper;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Property provider implementation for JMX sources.
+ */
+public class JMXPropertyProvider implements PropertyProvider {
+
+ /**
+ * Map of property ids supported by this provider.
+ */
+ private final Set<PropertyId> propertyIds;
+
+ private final Map<String, String> hosts;
+
+ private static final Map<String, String> JMX_PORTS = new HashMap<String, String>();
+
+ static {
+ JMX_PORTS.put("NAMENODE", "50070");
+ JMX_PORTS.put("HBASE_MASTER", "60010");
+ JMX_PORTS.put("JOBTRACKER", "50030");
+ JMX_PORTS.put("DATANODE", "50075");
+ JMX_PORTS.put("TASKTRACKER", "50060");
+ }
+
+ private JMXPropertyProvider(Resource.Type type, Map<String, String> hosts) {
+ this.hosts = hosts;
+ this.propertyIds = PropertyHelper.getPropertyIds(type, "JMX");
+ }
+
+ @Override
+ public Set<Resource> populateResources(Set<Resource> resources, Request request, Predicate predicate) {
+ Set<Resource> keepers = new HashSet<Resource>();
+ for (Resource resource : resources) {
+ if (populateResource(resource, request, predicate)) {
+ keepers.add(resource);
+ }
+ }
+ return keepers;
+ }
+
+ @Override
+ public Set<PropertyId> getPropertyIds() {
+ return propertyIds;
+ }
+
+
+ private boolean populateResource(Resource resource, Request request, Predicate predicate) {
+
+ if (getPropertyIds().isEmpty()) {
+ return true;
+ }
+
+ Set<PropertyId> ids = new HashSet<PropertyId>(request.getPropertyIds());
+ if (ids == null || ids.isEmpty()) {
+ ids = getPropertyIds();
+ } else {
+ if (predicate != null) {
+ ids.addAll(PredicateHelper.getPropertyIds(predicate));
+ }
+ ids.retainAll(getPropertyIds());
+ }
+
+ String hostName = hosts.get(resource.getPropertyValue(new PropertyIdImpl("host_name", "HostRoles", false)));
+ String port = JMX_PORTS.get(resource.getPropertyValue(new PropertyIdImpl("component_name", "HostRoles", false)));
+
+ String jmxSource = hostName + ":" + port;
+
+ if (hostName == null || port == null || jmxSource == null) {
+ return true;
+ }
+
+ JMXMetrics metrics = JMXHelper.getJMXMetrics(jmxSource, null);
+
+ for (Map<String, String> propertyMap : metrics.getBeans()) {
+ String category = propertyMap.get("tag.context");
+ if (category != null) {
+ for (Map.Entry<String, String> entry : propertyMap.entrySet()) {
+ String name = entry.getKey();
+
+ PropertyIdImpl propertyId = new PropertyIdImpl(name, category, false);
+
+ if (ids.contains(propertyId)) {
+ resource.setProperty(propertyId, entry.getValue());
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Factory method.
+ *
+ * @param type the {@link Resource.Type resource type}
+ * @return a new {@link PropertyProvider} instance
+ */
+ public static PropertyProvider create(Resource.Type type, Map<String, String> hosts) {
+ return new JMXPropertyProvider(type, hosts);
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ProviderModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ProviderModule.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ProviderModule.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ProviderModule.java Tue Oct 9 17:01:58 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.server.controller.spi;
+
+/**
+ * Interface to allow the plugging in of resource adapters.
+ */
+public interface ProviderModule {
+ /**
+ * Get a resource adapter for the given resource type.
+ *
+ * @param type the resource type
+ *
+ * @return the resource adapter
+ */
+ public ResourceProvider getResourceProvider(Resource.Type type);
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,48 @@
+/**
+ * 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.server.controller.utilities;
+
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.internal.ClusterControllerImpl;
+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.server.controller.internal.DefaultProviderModule");
+
+ private static ClusterController controller;
+
+ public static synchronized ClusterController getClusterController() {
+ if (controller == null) {
+ 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;
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DBHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DBHelper.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DBHelper.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DBHelper.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,86 @@
+/**
+ * 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.server.controller.utilities;
+
+import org.apache.ambari.server.controller.jdbc.ConnectionFactory;
+import org.apache.ambari.server.controller.jdbc.SQLiteConnectionFactory;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class DBHelper {
+ private static String DB_FILE_NAME = System.getProperty("ambariapi.dbfile", "src/test/resources/data.db");
+
+ public static final ConnectionFactory CONNECTION_FACTORY = new SQLiteConnectionFactory(DB_FILE_NAME);
+
+ private static final Map<String, String> HOSTS = readHosts();
+
+ public static Map<String, String> getHosts() {
+ return HOSTS;
+ }
+
+ private static Map<String, String> readHosts() {
+ Map<String, String> hosts = new HashMap<String, String>();
+
+ try {
+ Connection connection = CONNECTION_FACTORY.getConnection();
+
+ try {
+ String sql = "select attributes from hosts";
+
+ Statement statement = connection.createStatement();
+
+ ResultSet rs = statement.executeQuery(sql);
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ while (rs.next()) {
+ String attributes = rs.getString(1);
+
+ if (!attributes.startsWith("[]")) {
+ try {
+ Map<String, String> attributeMap = mapper.readValue(attributes, new TypeReference<Map<String, String>>() {
+ });
+ hosts.put(attributeMap.get("privateFQDN"), attributeMap.get("publicFQDN"));
+ } catch (IOException e) {
+ throw new IllegalStateException("Can't read hosts " + attributes, e);
+ }
+ }
+ }
+
+ } finally {
+ connection.close();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("Can't access DB.", e);
+ }
+
+ return hosts;
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,315 @@
+/**
+ * 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.server.controller.utilities;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+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;
+
+/**
+ * Builder for predicates.
+ */
+public class PredicateBuilder {
+
+ private PropertyId propertyId;
+ private List<BasePredicate> predicates = new LinkedList<BasePredicate>();
+ private Operator operator = null;
+ private final PredicateBuilder outer;
+ private boolean done = false;
+ private boolean not = false;
+
+ public PredicateBuilder() {
+ this.outer = null;
+ }
+
+ private PredicateBuilder(PredicateBuilder outer) {
+ this.outer = outer;
+ }
+
+ private enum Operator {
+ And,
+ Or
+ }
+
+
+ public PredicateBuilderWithProperty property(String property, String category, boolean temporal) {
+ return property(new PropertyIdImpl(property, category, temporal));
+ }
+
+ public PredicateBuilderWithProperty property(String property, String category) {
+ return property(property, category, false);
+ }
+
+ public PredicateBuilderWithProperty property(String property) {
+ return property(property, null);
+ }
+
+ public PredicateBuilderWithProperty property(PropertyId id) {
+ checkDone();
+ propertyId = id;
+ return new PredicateBuilderWithProperty();
+ }
+
+ public PredicateBuilder not() {
+ not = true;
+ return this;
+ }
+
+
+ public PredicateBuilder begin() {
+ checkDone();
+ return new PredicateBuilder(this);
+ }
+
+ public BasePredicate toPredicate() {
+ return getPredicate();
+ }
+
+ private void checkDone() {
+ if (done) {
+ throw new IllegalStateException("Can't reuse a predicate builder.");
+ }
+ }
+
+ private PredicateBuilderWithPredicate getPredicateBuilderWithPredicate() {
+ return new PredicateBuilderWithPredicate();
+ }
+
+ private void addPredicate(BasePredicate predicate) {
+ predicates.add(predicate);
+ }
+
+ private void handleComparator() {
+ if (operator == null) {
+ return;
+ }
+
+ if (predicates.size() == 0) {
+ throw new IllegalStateException("No left operand.");
+ }
+ BasePredicate predicate;
+
+ switch (operator) {
+ case And:
+ predicate = new AndPredicate(predicates.toArray(new BasePredicate[predicates.size()]));
+ break;
+ case Or:
+ predicate = new OrPredicate(predicates.toArray(new BasePredicate[predicates.size()]));
+ break;
+ default:
+ throw new IllegalStateException("Unknown operator " + this.operator);
+ }
+ predicates.clear();
+ addPredicate(predicate);
+ }
+
+ private BasePredicate getPredicate() {
+ handleComparator();
+
+ if (predicates.size() == 1) {
+ BasePredicate predicate = predicates.get(0);
+ if (not) {
+ predicate = new NotPredicate(predicate);
+ not = false;
+ }
+ return predicate;
+ }
+ throw new IllegalStateException("Can't return a predicate.");
+ }
+
+ public class PredicateBuilderWithProperty {
+
+ // ----- Equals -----
+ public PredicateBuilderWithPredicate equals(Comparable<String> value) {
+ if (propertyId == null) {
+ throw new IllegalStateException("No property.");
+ }
+ addPredicate(new EqualsPredicate(propertyId, value));
+
+ return new PredicateBuilderWithPredicate();
+ }
+
+ public PredicateBuilderWithPredicate equals(Integer value) {
+ return equals(Comparables.forInteger(value));
+ }
+
+ public PredicateBuilderWithPredicate equals(Float value) {
+ return equals(Comparables.forFloat(value));
+ }
+
+ public PredicateBuilderWithPredicate equals(Double value) {
+ return equals(Comparables.forDouble(value));
+ }
+
+ public PredicateBuilderWithPredicate equals(Long value) {
+ return equals(Comparables.forLong(value));
+ }
+
+ // ----- Greater than -----
+ public PredicateBuilderWithPredicate greaterThan(Comparable<String> value) {
+ if (propertyId == null) {
+ throw new IllegalStateException("No property.");
+ }
+ addPredicate(new GreaterPredicate(propertyId, value));
+
+ return new PredicateBuilderWithPredicate();
+ }
+
+ public PredicateBuilderWithPredicate greaterThan(Integer value) {
+ return greaterThan(Comparables.forInteger(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThan(Float value) {
+ return greaterThan(Comparables.forFloat(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThan(Double value) {
+ return greaterThan(Comparables.forDouble(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThan(Long value) {
+ return greaterThan(Comparables.forLong(value));
+ }
+
+ // ----- Greater than equal to -----
+ public PredicateBuilderWithPredicate greaterThanEqualTo(Comparable<String> value) {
+ if (propertyId == null) {
+ throw new IllegalStateException("No property.");
+ }
+ addPredicate(new GreaterEqualsPredicate(propertyId, value));
+
+ return new PredicateBuilderWithPredicate();
+ }
+
+ public PredicateBuilderWithPredicate greaterThanEqualTo(Integer value) {
+ return greaterThanEqualTo(Comparables.forInteger(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThanEqualTo(Float value) {
+ return greaterThanEqualTo(Comparables.forFloat(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThanEqualTo(Double value) {
+ return greaterThanEqualTo(Comparables.forDouble(value));
+ }
+
+ public PredicateBuilderWithPredicate greaterThanEqualTo(Long value) {
+ return greaterThanEqualTo(Comparables.forLong(value));
+ }
+
+ // ----- Less than -----
+ public PredicateBuilderWithPredicate lessThan(Comparable<String> value) {
+ if (propertyId == null) {
+ throw new IllegalStateException("No property.");
+ }
+ addPredicate(new LessPredicate(propertyId, value));
+
+ return new PredicateBuilderWithPredicate();
+ }
+
+ public PredicateBuilderWithPredicate lessThan(Integer value) {
+ return lessThan(Comparables.forInteger(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThan(Float value) {
+ return lessThan(Comparables.forFloat(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThan(Double value) {
+ return lessThan(Comparables.forDouble(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThan(Long value) {
+ return lessThan(Comparables.forLong(value));
+ }
+
+ // ----- Less than equal to -----
+ public PredicateBuilderWithPredicate lessThanEqualTo(Comparable<String> value) {
+ if (propertyId == null) {
+ throw new IllegalStateException("No property.");
+ }
+ addPredicate(new LessEqualsPredicate(propertyId, value));
+
+ return new PredicateBuilderWithPredicate();
+ }
+
+ public PredicateBuilderWithPredicate lessThanEqualTo(Integer value) {
+ return lessThanEqualTo(Comparables.forInteger(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThanEqualTo(Float value) {
+ return lessThanEqualTo(Comparables.forFloat(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThanEqualTo(Double value) {
+ return lessThanEqualTo(Comparables.forDouble(value));
+ }
+
+ public PredicateBuilderWithPredicate lessThanEqualTo(Long value) {
+ return lessThanEqualTo(Comparables.forLong(value));
+ }
+ }
+
+ public class PredicateBuilderWithPredicate {
+ public PredicateBuilder and() {
+
+ if (operator != Operator.And) {
+ handleComparator();
+ operator = Operator.And;
+ }
+ return PredicateBuilder.this;
+ }
+
+ public PredicateBuilder or() {
+
+ if (operator != Operator.Or) {
+ handleComparator();
+ operator = Operator.Or;
+ }
+ return PredicateBuilder.this;
+ }
+
+ public BasePredicate toPredicate() {
+ if (outer != null) {
+ throw new IllegalStateException("Unbalanced block - missing end.");
+ }
+ done = true;
+ return getPredicate();
+ }
+
+ public PredicateBuilderWithPredicate end() {
+ if (outer == null) {
+ throw new IllegalStateException("Unbalanced block - missing begin.");
+ }
+ outer.addPredicate(getPredicate());
+ return outer.getPredicateBuilderWithPredicate();
+ }
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateHelper.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateHelper.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateHelper.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,46 @@
+/**
+ * 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.server.controller.utilities;
+
+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;
+
+/**
+ *
+ */
+public class PredicateHelper {
+
+ public static Set<PropertyId> getPropertyIds(Predicate predicate) {
+ if (predicate instanceof BasePredicate) {
+ return ((BasePredicate) predicate).getPropertyIds();
+ }
+ return Collections.emptySet();
+ }
+
+ public static void visit(Predicate predicate, PredicateVisitor visitor) {
+ if (predicate instanceof PredicateVisitorAcceptor) {
+ ((PredicateVisitorAcceptor) predicate).accept(visitor);
+ }
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java Tue Oct 9 17:01:58 2012
@@ -0,0 +1,132 @@
+/**
+ * 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.server.controller.utilities;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.internal.RequestImpl;
+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.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public class PropertyHelper {
+
+ private static final String PROPERTIES_FILE = "properties.json";
+ private static final String KEY_PROPERTIES_FILE = "key_properties.json";
+
+ private static final Map<Resource.Type, Map<String, Set<PropertyId>>> PROPERTY_IDS = readPropertyIds(PROPERTIES_FILE);
+ private static final Map<Resource.Type, Map<Resource.Type, PropertyId>> KEY_PROPERTY_IDS = readKeyPropertyIds(KEY_PROPERTIES_FILE);
+
+ public static PropertyId getPropertyId(String name, String category) {
+ return new PropertyIdImpl(name, category, false);
+ }
+
+ public static PropertyId getPropertyId(String name, String category, boolean temporal) {
+ return new PropertyIdImpl(name, category, temporal);
+ }
+
+ public static Set<PropertyId> getPropertyIds(Resource.Type resourceType, String providerKey) {
+
+ Map<String, Set<PropertyId>> propertyIds = PROPERTY_IDS.get(resourceType);
+ if (propertyIds != null) {
+ return propertyIds.get(providerKey);
+ }
+ return Collections.emptySet();
+ }
+
+ public static Map<Resource.Type, PropertyId> getKeyPropertyIds(Resource.Type resourceType) {
+ return KEY_PROPERTY_IDS.get(resourceType);
+ }
+
+ public static Map<PropertyId, String> getProperties(Resource resource) {
+ Map<PropertyId, String> properties = new HashMap<PropertyId, String>();
+
+ Map<String, Map<String, String>> categories = resource.getCategories();
+
+ for (Map.Entry<String, Map<String, String>> categoryEntry : categories.entrySet()) {
+ for (Map.Entry<String, String> propertyEntry : categoryEntry.getValue().entrySet()) {
+
+ properties.put(PropertyHelper.getPropertyId(propertyEntry.getKey(), categoryEntry.getKey()), propertyEntry.getValue());
+ }
+ }
+ return properties;
+ }
+
+ /**
+ * Factory method to create a create request from the given set of property maps.
+ * Each map contains the properties to be used to create a resource. Multiple maps in the
+ * set should result in multiple creates.
+ *
+ * @param properties the properties associated with the request; may be null
+ */
+ public static Request getCreateRequest(Set<Map<PropertyId, String>> properties) {
+ return new RequestImpl(null, properties);
+ }
+
+ /**
+ * Factory method to create a read request from the given set of property ids. The set of
+ * property ids represents the properties of interest for the query.
+ *
+ * @param propertyIds the property ids associated with the request; may be null
+ */
+ public static Request getReadRequest(Set<PropertyId> propertyIds) {
+ return new RequestImpl(propertyIds, null);
+ }
+
+ /**
+ * Factory method to create an update request from the given map of properties.
+ * The properties values in the given map are used to update the resource.
+ *
+ * @param properties the properties associated with the request; may be null
+ */
+ public static Request getUpdateRequest(Map<PropertyId, String> properties) {
+ return new RequestImpl(null, Collections.singleton(properties));
+ }
+
+ private static Map<Resource.Type, Map<String, Set<PropertyId>>> readPropertyIds(String filename) {
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ return mapper.readValue(ClassLoader.getSystemResourceAsStream(filename), new TypeReference<Map<Resource.Type, Map<String, Set<PropertyIdImpl>>>>() {
+ });
+ } catch (IOException e) {
+ throw new IllegalStateException("Can't read properties file " + filename, e);
+ }
+ }
+
+ private static Map<Resource.Type, Map<Resource.Type, PropertyId>> readKeyPropertyIds(String filename) {
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ return mapper.readValue(ClassLoader.getSystemResourceAsStream(filename), new TypeReference<Map<Resource.Type, Map<Resource.Type, PropertyIdImpl>>>() {
+ });
+ } catch (IOException e) {
+ throw new IllegalStateException("Can't read properties file " + filename, e);
+ }
+ }
+}
Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/resources/key_properties.json
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/resources/key_properties.json?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/resources/key_properties.json (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/resources/key_properties.json Tue Oct 9 17:01:58 2012
@@ -0,0 +1,67 @@
+{
+ "Cluster":{
+ "Cluster":{
+ "name":"cluster_name",
+ "category":"Clusters",
+ "temporal":false
+ }
+ },
+ "Service":{
+ "Cluster":{
+ "name":"cluster_name",
+ "category":"ServiceInfo",
+ "temporal":false
+ },
+ "Service":{
+ "name":"service_name",
+ "category":"ServiceInfo",
+ "temporal":false
+ }
+ },
+ "Host":{
+ "Cluster":{
+ "name":"cluster_name",
+ "category":"Hosts",
+ "temporal":false
+ },
+ "Host":{
+ "name":"host_name",
+ "category":"Hosts",
+ "temporal":false
+ }
+ },
+ "Component":{
+ "Cluster":{
+ "name":"cluster_name",
+ "category":"ServiceComponentInfo",
+ "temporal":false
+ },
+ "Service":{
+ "name":"service_name",
+ "category":"ServiceComponentInfo",
+ "temporal":false
+ },
+ "Component":{
+ "name":"component_name",
+ "category":"ServiceComponentInfo",
+ "temporal":false
+ }
+ },
+ "HostComponent":{
+ "Cluster":{
+ "name":"cluster_name",
+ "category":"HostRoles",
+ "temporal":false
+ },
+ "Host":{
+ "name":"host_name",
+ "category":"HostRoles",
+ "temporal":false
+ },
+ "HostComponent":{
+ "name":"component_name",
+ "category":"HostRoles",
+ "temporal":false
+ }
+ }
+}