Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MetadataStore Models #1068

Merged
merged 16 commits into from
Nov 14, 2019
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata;

import static com.yahoo.elide.datastores.aggregation.AggregationDictionary.isAnalyticView;

import com.yahoo.elide.core.EntityDictionary;
import com.yahoo.elide.core.datastore.inmemory.HashMapDataStore;
import com.yahoo.elide.core.exceptions.DuplicateMappingException;
import com.yahoo.elide.datastores.aggregation.AggregationDataStore;
import com.yahoo.elide.datastores.aggregation.AggregationDictionary;
import com.yahoo.elide.datastores.aggregation.metadata.models.AnalyticView;
import com.yahoo.elide.datastores.aggregation.metadata.models.Column;
import com.yahoo.elide.datastores.aggregation.metadata.models.DataType;
import com.yahoo.elide.datastores.aggregation.metadata.models.FunctionArgument;
import com.yahoo.elide.datastores.aggregation.metadata.models.Metric;
import com.yahoo.elide.datastores.aggregation.metadata.models.MetricFunction;
import com.yahoo.elide.datastores.aggregation.metadata.models.Table;
import com.yahoo.elide.datastores.aggregation.metadata.models.TimeDimension;
import com.yahoo.elide.datastores.aggregation.metadata.models.TimeDimensionGrain;

import java.util.Set;
import java.util.stream.Collectors;

/**
* MetaDataStore is a in-memory data store that manage data models for an {@link AggregationDataStore}.
*/
public class MetaDataStore extends HashMapDataStore {
public static final Package META_DATA_PACKAGE =
Package.getPackage("com.yahoo.elide.datastores.aggregation.metadata.models");

public MetaDataStore() {
super(META_DATA_PACKAGE);
}

public void populateEntityDictionary(EntityDictionary dictionary) {
super.populateEntityDictionary(dictionary);

if (dictionary instanceof AggregationDictionary) {
loadMetaData((AggregationDictionary) dictionary);
}
}

/**
* Load meta data of models from an populated entity dictionary.
*
* @param dictionary entity dictionary used by an aggregation data store.
*/
private void loadMetaData(AggregationDictionary dictionary) {
Set<Class<?>> classes = dictionary.getBindings();

classes.stream()
.filter(cls -> !META_DATA_PACKAGE.equals(cls.getPackage()))
.forEach(cls -> addTable(
isAnalyticView(cls)
? new AnalyticView(cls, dictionary)
: new Table(cls, dictionary)));
}

/**
* Add a table metadata object.
*
* @param table table metadata
*/
private void addTable(Table table) {
addMetaData(table);
table.getColumns().forEach(this::addColumn);
}

/**
* Add a column metadata object.
*
* @param column column metadata
*/
private void addColumn(Column column) {
addMetaData(column);
addDataType(column.getDataType());

if (column instanceof TimeDimension) {
((TimeDimension) column).getSupportedGrains().forEach(this::addTimeDimensionGrain);
} else if (column instanceof Metric) {
addMetricFunction(((Metric) column).getMetricFunction());
}
}

/**
* Add a metric function metadata object.
*
* @param metricFunction metric function metadata
*/
private void addMetricFunction(MetricFunction metricFunction) {
addMetaData(metricFunction);
metricFunction.getArguments().forEach(this::addFunctionArgument);
}

/**
* Add a datatype metadata object.
*
* @param dataType datatype metadata
*/
private void addDataType(DataType dataType) {
addMetaData(dataType);
}

/**
* Add a function argument metadata object.
*
* @param functionArgument function argument metadata
*/
private void addFunctionArgument(FunctionArgument functionArgument) {
addMetaData(functionArgument);
}

/**
* Add a time dimension grain metadata object.
*
* @param timeDimensionGrain time dimension grain metadata
*/
private void addTimeDimensionGrain(TimeDimensionGrain timeDimensionGrain) {
addMetaData(timeDimensionGrain);
}

/**
* Add a meta data object into this data store, check for duplication.
*
* @param object a meta data object
*/
private void addMetaData(Object object) {
Class<?> cls = this.getDictionary().lookupEntityClass(object.getClass());
String id = getDictionary().getId(object);

if (dataStore.get(cls).containsKey(id)) {
if (!dataStore.get(cls).get(id).equals(object)) {
throw new DuplicateMappingException("Duplicated " + cls.getSimpleName() + " metadata " + id);
}
} else {
dataStore.get(cls).put(id, object);
}
}

public <T> Set<T> getMetaData(Class<T> cls) {
return dataStore.get(cls).values().stream().map(cls::cast).collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.enums;

/**
* Aggregation functions
*/
public enum Aggregation {
SUM,
MIN,
MAX;
hellohanchen marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/

package com.yahoo.elide.datastores.aggregation.metadata.enums;

/**
* Format of a value field, e.g. decimal for numbers
*/
public enum Format {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.enums;

/**
* Tag attached to fields
*/
public enum Tag {
DISPLAY
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.enums;

/**
* Actual value type of a data type
*/
public enum ValueType {
DATE,
NUMBER,
TEXT,
COORDINATE,
BOOLEAN,
RELATIONSHIP,
ID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.metric;

import com.yahoo.elide.datastores.aggregation.metadata.models.FunctionArgument;
import com.yahoo.elide.datastores.aggregation.metadata.models.MetricFunction;
import com.yahoo.elide.request.Argument;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Basic implementation for Metric function.
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
public abstract class BasicMetricFunction extends MetricFunction {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to separate this class out from the MetricFunction class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The complicated functions might need to extend from MetricFunction.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss

private String name;

private String longName;

private String description;

private Set<FunctionArgument> arguments;

protected BasicMetricFunction(String name, String longName, String description) {
this(name, longName, description, Collections.emptySet());
}

@Override
public MetricFunctionInvocation invoke(Map<String, Argument> arguments, AggregatedField field, String alias) {
final MetricFunction function = this;
return new MetricFunctionInvocation() {
@Override
public List<Argument> getArguments() {
return new ArrayList<>(arguments.values());
}

@Override
public Argument getArgument(String argumentName) {
return arguments.get(argumentName);
}

@Override
public MetricFunction getFunction() {
return function;
}

@Override
public AggregatedField getAggregatedField() {
return field;
}

@Override
public String getAlias() {
return alias;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.metric;

import com.yahoo.elide.datastores.aggregation.metadata.models.MetricFunction;
import com.yahoo.elide.request.Argument;

import java.util.List;

/**
* An invoked metric function instance applied on an aggregated field with provided arguments to project the result
* as the alias.
*/
public interface MetricFunctionInvocation {
List<Argument> getArguments();

Argument getArgument(String argumentName);

MetricFunction getFunction();

AggregatedField getAggregatedField();

String getAlias();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.metric.functions;

import com.yahoo.elide.datastores.aggregation.metadata.metric.BasicMetricFunction;

/**
* Canned MAX metric function.
*/
public class Max extends BasicMetricFunction {
public Max() {
super("Max", "Max", "Calculate max of a metric column");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.metric.functions;

import com.yahoo.elide.datastores.aggregation.metadata.metric.BasicMetricFunction;

/**
* Canned MIN metric function.
*/
public class Min extends BasicMetricFunction {
public Min() {
super("Min", "Min", "Calculate min of a metric column");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.aggregation.metadata.metric.functions;

import com.yahoo.elide.datastores.aggregation.metadata.metric.BasicMetricFunction;

/**
* Canned SUM metric function.
*/
public class Sum extends BasicMetricFunction {
public Sum() {
super("Sum", "Sum", "Calculate sum of a metric column");
}
}
Loading