blob: d2d9eef95e64285790adcb9fb289f66221547e7c [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.eagle.log.entity.meta;
import org.apache.eagle.log.base.taggedlog.TaggedLogAPIEntity;
import org.apache.eagle.log.entity.GenericMetricEntity;
import org.apache.eagle.log.entity.GenericMetricShadowEntity;
import org.apache.hadoop.io.Writable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
*
* This object should be regarded as read-only metadata for an entity as it will be shared across all entity object
* with the same entity name, so don't try to set different values for any of the fields,
* otherwise it's not thread safe
*/
public class EntityDefinition implements Writable{
private final static Logger LOG = LoggerFactory.getLogger(EntityDefinition.class);
private Class<? extends TaggedLogAPIEntity> entityClass;
private String table;
private String columnFamily;
// TODO prefix be within search/get condition instead of entity definition. Topology entity should have pre-defined prefix.
private String prefix;
private String service;
private String serviceCreationPath;
private String serviceDeletionPath;
private String[] partitions;
private Map<String, Qualifier> displayNameMap = new HashMap<String, Qualifier>();
private Map<String, Qualifier> qualifierNameMap = new HashMap<String, Qualifier>();
private Map<String, Method> qualifierGetterMap = new HashMap<String, Method>();
private String[] tags;
private boolean isTimeSeries;
private MetricDefinition metricDefinition;
private IndexDefinition[] indexes;
public EntityDefinition(){}
public MetricDefinition getMetricDefinition() {
return metricDefinition;
}
public void setMetricDefinition(MetricDefinition metricDefinition) {
this.metricDefinition = metricDefinition;
}
public boolean isTimeSeries() {
return isTimeSeries;
}
public void setTimeSeries(boolean isTimeSeries) {
this.isTimeSeries = isTimeSeries;
}
public String getColumnFamily() {
return columnFamily;
}
public void setColumnFamily(String columnFamily) {
this.columnFamily = columnFamily;
}
public Class<? extends TaggedLogAPIEntity> getEntityClass() {
return entityClass;
}
public void setEntityClass(Class<? extends TaggedLogAPIEntity> entityClass) {
this.entityClass = entityClass;
}
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public Map<String, Qualifier> getDisplayNameMap() {
return displayNameMap;
}
public void setDisplayNameMap(Map<String, Qualifier> displayNameMap) {
this.displayNameMap = displayNameMap;
}
public Map<String, Qualifier> getQualifierNameMap() {
return qualifierNameMap;
}
public void setQualifierNameMap(Map<String, Qualifier> qualifierNameMap) {
this.qualifierNameMap = qualifierNameMap;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getServiceCreationPath() {
return serviceCreationPath;
}
public void setServiceCreationPath(String serviceCreationPath) {
this.serviceCreationPath = serviceCreationPath;
}
public String getServiceDeletionPath() {
return serviceDeletionPath;
}
public void setServiceDeletionPath(String serviceDeletionPath) {
this.serviceDeletionPath = serviceDeletionPath;
}
public String[] getPartitions() {
return partitions;
}
public void setPartitions(String[] partitions) {
this.partitions = partitions;
}
public IndexDefinition[] getIndexes() {
return indexes;
}
public void setIndexes(IndexDefinition[] indexes) {
this.indexes = indexes;
}
public Map<String, Method> getQualifierGetterMap() {
return qualifierGetterMap;
}
public void setQualifierGetterMap(Map<String, Method> qualifierGetterMap) {
this.qualifierGetterMap = qualifierGetterMap;
}
public String[] getTags(){
return tags;
}
public void setTags(String[] tags){
this.tags = tags;
}
// public Map<String,String> getQualifierDisplayNameMap(){
// Map<String,String> qualifierDisplayNameMap = new HashMap<String, String>();
// for(Map.Entry<String,Qualifier> entry: qualifierNameMap.entrySet()){
// qualifierDisplayNameMap.put(entry.getKey(),entry.getValue().getDisplayName());
// }
// return qualifierDisplayNameMap;
// }
/**
* a filed is a tag when this field is neither in qualifierNameMap nor in displayNameMap
* @param field
* @return
*/
public boolean isTag(String field){
return (qualifierNameMap.get(field) == null && displayNameMap.get(field) == null);
// return (qualifierNameMap.get(field) == null);
}
/**
* Check if the specified field is a partition tag field
*/
public boolean isPartitionTag(String field) {
if (partitions == null || (!isTag(field))) {
return false;
}
for (String partition : partitions) {
if (partition.equals(field)) {
return true;
}
}
return false;
}
public Object getValue(TaggedLogAPIEntity entity, String field) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (!entityClass.equals(entity.getClass())) {
if ((entityClass.equals(GenericMetricEntity.class) && entity.getClass().equals(GenericMetricShadowEntity.class))) {
GenericMetricShadowEntity e = (GenericMetricShadowEntity)entity;
return e.getValue();
} else {
throw new IllegalArgumentException("Invalid entity type: " + entity.getClass().getSimpleName());
}
}
final Method m = qualifierGetterMap.get(field);
if (m == null) {
// The field is a tag
if (entity.getTags() != null) {
return entity.getTags().get(field);
}
}
if (m != null) {
return m.invoke(entity);
}
return null;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(entityClass.getName());
out.writeUTF(table);
out.writeUTF(columnFamily);
out.writeUTF(prefix);
out.writeUTF(service);
int partitionsLen = 0;
if(partitions != null) partitionsLen =partitions.length;
out.writeInt(partitionsLen);
for (int i = 0; i < partitionsLen; i++) {
out.writeUTF(partitions[i]);
}
int displayNameMapSize = displayNameMap.size();
out.writeInt(displayNameMapSize);
for(Map.Entry<String,Qualifier> entry: displayNameMap.entrySet()){
out.writeUTF(entry.getKey());
entry.getValue().write(out);
}
int qualifierNameMapSize = qualifierNameMap.size();
out.writeInt(qualifierNameMapSize);
for(Map.Entry<String,Qualifier> entry: qualifierNameMap.entrySet()){
out.writeUTF(entry.getKey());
entry.getValue().write(out);
}
// TODO: write qualifierGetterMap
out.writeBoolean(isTimeSeries);
boolean hasMetricDefinition = metricDefinition != null;
out.writeBoolean(hasMetricDefinition);
if(hasMetricDefinition) {
// write MetricDefinition
metricDefinition.write(out);
}
// TODO: write indexes
}
public void setEntityDefinition(EntityDefinition ed){
this.entityClass = ed.getEntityClass();
this.table = ed.getTable();
this.columnFamily = ed.getColumnFamily();
this.prefix = ed.getPrefix();
this.service = ed.getService();
this.partitions = ed.getPartitions();
this.displayNameMap = ed.getDisplayNameMap();
this.qualifierGetterMap = ed.getQualifierGetterMap();
this.qualifierNameMap = ed.getQualifierNameMap();
this.isTimeSeries = ed.isTimeSeries();
this.metricDefinition = ed.metricDefinition;
this.indexes = ed.getIndexes();
}
//////////////////////////////////////////////
// TODO: Cache object for reading in region side
//////////////////////////////////////////////
// private final static Map<String,EntityDefinition> _classEntityDefinitionCache = new HashMap<String, EntityDefinition>();
@Override
public void readFields(DataInput in) throws IOException {
String entityClassName = in.readUTF();
// EntityDefinition _cached = _classEntityDefinitionCache.get(entityClassName);
// if(_cached !=null){
// setEntityDefinition(_cached);
// LOG.info("Got cached definition for entity: "+entityClassName);
// return;
// }
if(LOG.isDebugEnabled()) LOG.debug("Reading EntityDefinition entity: "+entityClassName);
try {
entityClass = (Class<? extends TaggedLogAPIEntity>) Class.forName(entityClassName);
} catch (Exception e) {
// ignore
}
table = in.readUTF();
columnFamily = in.readUTF();
prefix = in.readUTF();
service = in.readUTF();
int partitionsLen = in.readInt();
partitions = new String[partitionsLen];
for (int i = 0; i < partitionsLen; i++) {
partitions[i] = in.readUTF();
}
int displayNameMapSize = in.readInt();
for(int i=0;i<displayNameMapSize;i++){
String key = in.readUTF();
Qualifier value = new Qualifier();
value.readFields(in);
displayNameMap.put(key,value);
}
int qualifierNameMapSize = in.readInt();
for(int i=0;i<qualifierNameMapSize;i++){
String key = in.readUTF();
Qualifier value = new Qualifier();
value.readFields(in);
qualifierNameMap.put(key,value);
}
// TODO: readFields qualifierGetterMap
isTimeSeries = in.readBoolean();
// readFields MetricDefinition
boolean hasMetricDefinition = in.readBoolean();
if(hasMetricDefinition) {
if(LOG.isDebugEnabled()) LOG.debug("reading metricDefinition");
metricDefinition = new MetricDefinition();
metricDefinition.readFields(in);
}
// TODO: readFields indexes
// _classEntityDefinitionCache.put(entityClassName,this);
}
}