/**
* 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.scom;
import org.apache.ambari.server.controller.internal.ResourceImpl;
import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
import org.apache.ambari.server.controller.jdbc.ConnectionFactory;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.TemporalInfo;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
/**
* SQLPropertyProvider Tests
*/
public class SQLPropertyProviderTest {
private static final String PROPERTY_ID_1 = "metrics/rpc/RpcQueueTime_avg_time";
private static final String PROPERTY_ID_2 = "metrics/rpc/RpcSlowResponse_num_ops";
private static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "cluster_name");
private static final String HOST_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "host_name");
private static final String COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "component_name");
private static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("HostRoles", "service_name");
@Test
public void testPopulateResources() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
new TestHostInfoProvider(),
CLUSTER_NAME_PROPERTY_ID,
HOST_NAME_PROPERTY_ID,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(HOST_NAME_PROPERTY_ID, "domU-12-31-39-0E-34-E1.compute-1.internal");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// only ask for one property
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
temporalInfoMap.put(PROPERTY_ID_1, new TemporalInfoImpl(10L, 20L, 1L));
Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID_1), temporalInfoMap);
Assert.assertEquals(1, provider.populateResources(Collections.singleton(resource), request, null).size());
Assert.assertTrue(resource.getPropertyValue(PROPERTY_ID_1) instanceof Number[][]);
Number[][] datapoints = (Number[][]) resource.getPropertyValue(PROPERTY_ID_1);
for (int i = 0; i < datapoints.length; ++i) {
Assert.assertEquals((long) i, datapoints[i][0]);
Assert.assertEquals((999990L + i)/1000, datapoints[i][1]);
}
// verify
verify(connectionFactory, connection, statement, resultSet);
}
@Test
public void testPopulateResources_temporalStartTimeOnly() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
TestHostInfoProvider hostProvider = new TestHostInfoProvider();
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
hostProvider,
CLUSTER_NAME_PROPERTY_ID,
HOST_NAME_PROPERTY_ID,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(HOST_NAME_PROPERTY_ID, "domU-12-31-39-0E-34-E1.compute-1.internal");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// only ask for one property
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
temporalInfoMap.put(PROPERTY_ID_1, new TemporalInfoImpl(10L, -1L, -1L));
Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID_1), temporalInfoMap);
Assert.assertEquals(1, provider.populateResources(Collections.singleton(resource), request, null).size());
Assert.assertTrue(resource.getPropertyValue(PROPERTY_ID_1) instanceof Number[][]);
Number[][] datapoints = (Number[][]) resource.getPropertyValue(PROPERTY_ID_1);
for (int i = 0; i < datapoints.length; ++i) {
Assert.assertEquals((long) i, datapoints[i][0]);
Assert.assertEquals((999990L + i) / 1000, datapoints[i][1]);
}
// verify
verify(connectionFactory, connection, statement, resultSet);
}
@Test
public void testPopulateResources_hostNameProperty() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
TestHostInfoProvider hostProvider = new TestHostInfoProvider();
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
hostProvider,
CLUSTER_NAME_PROPERTY_ID,
HOST_NAME_PROPERTY_ID,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(HOST_NAME_PROPERTY_ID, "domU-12-31-39-0E-34-E1.compute-1.internal");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// only ask for one property
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
temporalInfoMap.put(PROPERTY_ID_1, new TemporalInfoImpl(10L, -1L, -1L));
Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID_1), temporalInfoMap);
provider.populateResources(Collections.singleton(resource), request, null);
Assert.assertEquals("domU-12-31-39-0E-34-E1.compute-1.internal", hostProvider.getHostId());
Assert.assertNull(hostProvider.getClusterName());
Assert.assertNull(hostProvider.getComponentName());
// verify
verify(connectionFactory, connection, statement, resultSet);
}
@Test
public void testPopulateResources_noHostNameProperty() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
TestHostInfoProvider hostProvider = new TestHostInfoProvider();
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
hostProvider,
CLUSTER_NAME_PROPERTY_ID,
null,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// only ask for one property
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
temporalInfoMap.put(PROPERTY_ID_1, new TemporalInfoImpl(10L, -1L, -1L));
Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID_1), temporalInfoMap);
provider.populateResources(Collections.singleton(resource), request, null);
Assert.assertNull(hostProvider.getHostId());
Assert.assertEquals("c1", hostProvider.getClusterName());
Assert.assertEquals("DATANODE", hostProvider.getComponentName());
// verify
verify(connectionFactory, connection, statement, resultSet);
}
@Test
public void testPopulateResources_pointInTime() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
new TestHostInfoProvider(),
CLUSTER_NAME_PROPERTY_ID,
HOST_NAME_PROPERTY_ID,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(HOST_NAME_PROPERTY_ID, "domU-12-31-39-0E-34-E1.compute-1.internal");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// only ask for one property
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID_2), temporalInfoMap);
Assert.assertEquals(1, provider.populateResources(Collections.singleton(resource), request, null).size());
// should be the last value of the time series...
Assert.assertEquals( 3L, resource.getPropertyValue(PROPERTY_ID_2));
// verify
verify(connectionFactory, connection, statement, resultSet);
}
@Test
public void testPopulateResources_multi() throws Exception {
ConnectionFactory connectionFactory = createNiceMock(ConnectionFactory.class);
Connection connection = createNiceMock(Connection.class);
Statement statement = createNiceMock(Statement.class);
ResultSet resultSet = createNiceMock(ResultSet.class);
// set expectations
expect(connectionFactory.getConnection()).andReturn(connection).once();
expect(connection.createStatement()).andReturn(statement).once();
expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet).once();
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcQueueTime_avg_time");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999990L);
expect(resultSet.getNString("MetricValue")).andReturn("0");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcQueueTime_avg_time");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999991L);
expect(resultSet.getNString("MetricValue")).andReturn("1");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999992L);
expect(resultSet.getNString("MetricValue")).andReturn("2");
expect(resultSet.next()).andReturn(true);
expect(resultSet.getString("RecordTypeContext")).andReturn("rpc");
expect(resultSet.getString("RecordTypeName")).andReturn("rpc");
expect(resultSet.getString("TagPairs")).andReturn("");
expect(resultSet.getString("MetricName")).andReturn("RpcSlowResponse_num_ops");
expect(resultSet.getString("ServiceName")).andReturn("datanode");
expect(resultSet.getString("NodeName")).andReturn("host1");
expect(resultSet.getLong("RecordTimeStamp")).andReturn(999993L);
expect(resultSet.getNString("MetricValue")).andReturn("3");
expect(resultSet.next()).andReturn(false);
// replay
replay(connectionFactory, connection, statement, resultSet);
SQLPropertyProvider provider = new SQLPropertyProvider(
PropertyHelper.getGangliaPropertyIds(Resource.Type.HostComponent),
new TestHostInfoProvider(),
CLUSTER_NAME_PROPERTY_ID,
HOST_NAME_PROPERTY_ID,
COMPONENT_NAME_PROPERTY_ID,
SERVICE_NAME_PROPERTY_ID,
connectionFactory);
// namenode
Resource resource = new ResourceImpl(Resource.Type.HostComponent);
resource.setProperty(CLUSTER_NAME_PROPERTY_ID, "c1");
resource.setProperty(HOST_NAME_PROPERTY_ID, "domU-12-31-39-0E-34-E1.compute-1.internal");
resource.setProperty(COMPONENT_NAME_PROPERTY_ID, "DATANODE");
resource.setProperty(SERVICE_NAME_PROPERTY_ID, "HDFS");
// ask for two properties ... on temporal, one point in time
Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>();
temporalInfoMap.put(PROPERTY_ID_1, new TemporalInfoImpl(10L, 20L, 1L));
Set<String> propertyIds = new LinkedHashSet<String>();
propertyIds.add(PROPERTY_ID_1);
propertyIds.add(PROPERTY_ID_2);
Request request = PropertyHelper.getReadRequest(propertyIds, temporalInfoMap);
Assert.assertEquals(1, provider.populateResources(Collections.singleton(resource), request, null).size());
// check the temporal value
Assert.assertTrue(resource.getPropertyValue(PROPERTY_ID_1) instanceof Number[][]);
Number[][] datapoints = (Number[][]) resource.getPropertyValue(PROPERTY_ID_1);
for (int i = 0; i < datapoints.length; ++i) {
Assert.assertEquals((long) i, datapoints[i][0]);
Assert.assertEquals((999990L + i) / 1000, datapoints[i][1]);
}
// check the point in time value ... should be the last value of the time series...
Assert.assertEquals( 3L, resource.getPropertyValue(PROPERTY_ID_2));
// verify
verify(connectionFactory, connection, statement, resultSet);
}
}