blob: a4f7014e7822cdb322f81042e01fa5dc740c0100 [file] [log] [blame]
/**
* 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.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.query;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.metrics2.sink.timeline.TopNConfig;
import org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.PhoenixHBaseAccessor;
import org.apache.hadoop.metrics2.sink.timeline.Precision;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class DefaultCondition implements Condition {
List<String> metricNames;
List<String> hostnames;
String appId;
String instanceId;
Long startTime;
Long endTime;
Precision precision;
Integer limit;
boolean grouped;
boolean noLimit = false;
Integer fetchSize;
String statement;
Set<String> orderByColumns = new LinkedHashSet<String>();
boolean metricNamesNotCondition = false;
private static final Log LOG = LogFactory.getLog(DefaultCondition.class);
public DefaultCondition(List<String> metricNames, List<String> hostnames, String appId,
String instanceId, Long startTime, Long endTime, Precision precision,
Integer limit, boolean grouped) {
this.metricNames = metricNames;
this.hostnames = hostnames;
this.appId = appId;
this.instanceId = instanceId;
this.startTime = startTime;
this.endTime = endTime;
this.precision = precision;
this.limit = limit;
this.grouped = grouped;
}
public String getStatement() {
return statement;
}
public void setStatement(String statement) {
this.statement = statement;
}
public List<String> getMetricNames() {
return metricNames == null || metricNames.isEmpty() ? null : metricNames;
}
public StringBuilder getConditionClause() {
StringBuilder sb = new StringBuilder();
boolean appendConjunction = appendMetricNameClause(sb);
appendConjunction = appendHostnameClause(sb, appendConjunction);
appendConjunction = append(sb, appendConjunction, getAppId(), " APP_ID = ?");
appendConjunction = append(sb, appendConjunction, getInstanceId(), " INSTANCE_ID = ?");
appendConjunction = append(sb, appendConjunction, getStartTime(), " SERVER_TIME >= ?");
append(sb, appendConjunction, getEndTime(), " SERVER_TIME < ?");
return sb;
}
protected static boolean append(StringBuilder sb,
boolean appendConjunction,
Object value, String str) {
if (value != null) {
if (appendConjunction) {
sb.append(" AND");
}
sb.append(str);
appendConjunction = true;
}
return appendConjunction;
}
public List<String> getHostnames() {
return hostnames;
}
public Precision getPrecision() {
return precision;
}
public void setPrecision(Precision precision) {
this.precision = precision;
}
public String getAppId() {
if (appId != null && !appId.isEmpty()) {
if (!(appId.equals("HOST") || appId.equals("FLUME_HANDLER"))) {
return appId.toLowerCase();
} else {
return appId;
}
}
return null;
}
public String getInstanceId() {
return instanceId == null || instanceId.isEmpty() ? null : instanceId;
}
/**
* Convert to millis.
*/
public Long getStartTime() {
if (startTime == null) {
return null;
} else if (startTime < 9999999999l) {
return startTime * 1000;
} else {
return startTime;
}
}
public Long getEndTime() {
if (endTime == null) {
return null;
}
if (endTime < 9999999999l) {
return endTime * 1000;
} else {
return endTime;
}
}
public void setNoLimit() {
this.noLimit = true;
}
@Override
public boolean doUpdate() {
return false;
}
public Integer getLimit() {
if (noLimit) {
return null;
}
return limit == null ? PhoenixHBaseAccessor.RESULTSET_LIMIT : limit;
}
public boolean isGrouped() {
return grouped;
}
public boolean isPointInTime() {
return getStartTime() == null && getEndTime() == null;
}
public boolean isEmpty() {
return (metricNames == null || metricNames.isEmpty())
&& (hostnames == null || hostnames.isEmpty())
&& (appId == null || appId.isEmpty())
&& (instanceId == null || instanceId.isEmpty())
&& startTime == null
&& endTime == null;
}
public Integer getFetchSize() {
return fetchSize;
}
public void setFetchSize(Integer fetchSize) {
this.fetchSize = fetchSize;
}
public void addOrderByColumn(String column) {
orderByColumns.add(column);
}
public String getOrderByClause(boolean asc) {
String orderByStr = " ORDER BY ";
if (!orderByColumns.isEmpty()) {
StringBuilder sb = new StringBuilder(orderByStr);
for (String orderByColumn : orderByColumns) {
if (sb.length() != orderByStr.length()) {
sb.append(", ");
}
sb.append(orderByColumn);
if (!asc) {
sb.append(" DESC");
}
}
sb.append(" ");
return sb.toString();
}
return null;
}
protected boolean appendMetricNameClause(StringBuilder sb) {
boolean appendConjunction = false;
List<String> metricsLike = new ArrayList<>();
List<String> metricsIn = new ArrayList<>();
if (getMetricNames() != null) {
for (String name : getMetricNames()) {
if (name.contains("%")) {
metricsLike.add(name);
} else {
metricsIn.add(name);
}
}
// Put a '(' first
sb.append("(");
//IN clause
// METRIC_NAME (NOT) IN (?,?,?,?)
if (CollectionUtils.isNotEmpty(metricsIn)) {
sb.append("METRIC_NAME");
if (metricNamesNotCondition) {
sb.append(" NOT");
}
sb.append(" IN (");
//Append ?,?,?,?
for (int i = 0; i < metricsIn.size(); i++) {
sb.append("?");
if (i < metricsIn.size() - 1) {
sb.append(", ");
}
}
sb.append(")");
appendConjunction = true;
}
//Put an OR/AND if both types are present
if (CollectionUtils.isNotEmpty(metricsIn) &&
CollectionUtils.isNotEmpty(metricsLike)) {
if (metricNamesNotCondition) {
sb.append(" AND ");
} else {
sb.append(" OR ");
}
}
//LIKE clause
// METRIC_NAME (NOT) LIKE ? OR(AND) METRIC_NAME LIKE ?
if (CollectionUtils.isNotEmpty(metricsLike)) {
for (int i = 0; i < metricsLike.size(); i++) {
sb.append("METRIC_NAME");
if (metricNamesNotCondition) {
sb.append(" NOT");
}
sb.append(" LIKE ");
sb.append("?");
if (i < metricsLike.size() - 1) {
if (metricNamesNotCondition) {
sb.append(" AND ");
} else {
sb.append(" OR ");
}
}
}
appendConjunction = true;
}
// Finish with a ')'
if (appendConjunction) {
sb.append(")");
}
metricNames.clear();
if (CollectionUtils.isNotEmpty(metricsIn)) {
metricNames.addAll(metricsIn);
}
if (CollectionUtils.isNotEmpty(metricsLike)) {
metricNames.addAll(metricsLike);
}
}
return appendConjunction;
}
protected boolean appendHostnameClause(StringBuilder sb, boolean appendConjunction) {
boolean hostnameContainsRegex = false;
if (hostnames != null) {
for (String hostname : hostnames) {
if (hostname.contains("%")) {
hostnameContainsRegex = true;
break;
}
}
}
StringBuilder hostnamesCondition = new StringBuilder();
if (hostnameContainsRegex) {
hostnamesCondition.append(" (");
for (String hostname : getHostnames()) {
if (hostnamesCondition.length() > 2) {
hostnamesCondition.append(" OR ");
}
hostnamesCondition.append("HOSTNAME LIKE ?");
}
hostnamesCondition.append(")");
appendConjunction = append(sb, appendConjunction, getHostnames(), hostnamesCondition.toString());
} else if (hostnames != null && getHostnames().size() > 1) {
for (String hostname : getHostnames()) {
if (hostnamesCondition.length() > 0) {
hostnamesCondition.append(" ,");
} else {
hostnamesCondition.append(" HOSTNAME IN (");
}
hostnamesCondition.append('?');
}
hostnamesCondition.append(')');
appendConjunction = append(sb, appendConjunction, getHostnames(), hostnamesCondition.toString());
} else {
appendConjunction = append(sb, appendConjunction, getHostnames(), " HOSTNAME = ?");
}
return appendConjunction;
}
@Override
public String toString() {
return "Condition{" +
"metricNames=" + metricNames +
", hostnames='" + hostnames + '\'' +
", appId='" + appId + '\'' +
", instanceId='" + instanceId + '\'' +
", startTime=" + startTime +
", endTime=" + endTime +
", limit=" + limit +
", grouped=" + grouped +
", orderBy=" + orderByColumns +
", noLimit=" + noLimit +
'}';
}
protected static boolean metricNamesHaveWildcard(List<String> metricNames) {
for (String name : metricNames) {
if (name.contains("%")) {
return true;
}
}
return false;
}
protected static boolean hostNamesHaveWildcard(List<String> hostnames) {
if (hostnames == null)
return false;
for (String name : hostnames) {
if (name.contains("%")) {
return true;
}
}
return false;
}
public void setMetricNamesNotCondition(boolean metricNamesNotCondition) {
this.metricNamesNotCondition = metricNamesNotCondition;
}
}