Finish most codes of analysis.
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
index dd02273..a8dbc1e 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
@@ -55,4 +55,12 @@
void generateRemoteWorker(AnalysisResult result, Writer output) throws IOException, TemplateException {
configuration.getTemplate("RemoteWorkerTemplate.ftl").process(result, output);
}
+
+ void generatePersistentWorker(AnalysisResult result, Writer output) throws IOException, TemplateException {
+ configuration.getTemplate("PersistentWorkerTemplate.ftl").process(result, output);
+ }
+
+ void generateIndicatorImplementor(AnalysisResult result, Writer output) throws IOException, TemplateException {
+ configuration.getTemplate("IndicatorImplementor.ftl").process(result, output);
+ }
}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
index 8c599e1..69ac3c4 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
@@ -18,6 +18,8 @@
package org.apache.skywalking.oal.tool.parser;
+import java.util.LinkedList;
+import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@@ -36,5 +38,69 @@
private String aggregationFunctionName;
+ private String indicatorClassName;
+
private Selector remoteSelector;
+
+ private boolean needMerge;
+
+ private EntryMethod entryMethod;
+
+ private List<DataColumn> persistentFields;
+
+ private List<SourceColumn> fieldsFromSource;
+
+ private PersistenceColumns serializeFields;
+
+ public void addPersistentField(String fieldName, String columnName, Class<?> type) {
+ if (persistentFields == null) {
+ persistentFields = new LinkedList<>();
+ }
+ DataColumn dataColumn = new DataColumn(fieldName, columnName, type);
+ persistentFields.add(dataColumn);
+ }
+
+ public void generateSerializeFields() {
+ serializeFields = new PersistenceColumns();
+ serializeFields.addLongField("timeBucket");
+ for (SourceColumn sourceColumn : fieldsFromSource) {
+ String type = sourceColumn.getType().getSimpleName();
+ switch (type) {
+ case "int":
+ serializeFields.addIntField(sourceColumn.getFieldName());
+ break;
+ case "double":
+ serializeFields.addDoubleField(sourceColumn.getFieldName());
+ break;
+ case "String":
+ serializeFields.addStringField(sourceColumn.getFieldName());
+ break;
+ case "long":
+ serializeFields.addLongField(sourceColumn.getFieldName());
+ break;
+ default:
+ throw new IllegalStateException("Unexpected field type [" + type + "] of source sourceColumn [" + sourceColumn.getFieldName() + "]");
+ }
+ }
+
+ for (DataColumn column : persistentFields) {
+ String type = column.getType().getSimpleName();
+ switch (type) {
+ case "int":
+ serializeFields.addIntField(column.getFieldName());
+ break;
+ case "double":
+ serializeFields.addDoubleField(column.getFieldName());
+ break;
+ case "String":
+ serializeFields.addStringField(column.getFieldName());
+ break;
+ case "long":
+ serializeFields.addLongField(column.getFieldName());
+ break;
+ default:
+ throw new IllegalStateException("Unexpected field type [" + type + "] of persistence column [" + column.getFieldName() + "]");
+ }
+ }
+ }
}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DataColumn.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DataColumn.java
new file mode 100644
index 0000000..5cb2363
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DataColumn.java
@@ -0,0 +1,45 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
+
+@Getter(AccessLevel.PUBLIC)
+@Setter(AccessLevel.PUBLIC)
+public class DataColumn {
+ private String fieldName;
+ private String columnName;
+ private Class<?> type;
+ private String typeName;
+ private String fieldSetter;
+ private String fieldGetter;
+
+ public DataColumn(String fieldName, String columnName, Class<?> type) {
+ this.fieldName = fieldName;
+ this.columnName = columnName;
+ this.type = type;
+ this.typeName = type.getName();
+
+ this.fieldGetter = ClassMethodUtil.toGetMethod(fieldName);
+ this.fieldSetter = ClassMethodUtil.toSetMethod(fieldName);
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java
new file mode 100644
index 0000000..c47ffd2
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java
@@ -0,0 +1,109 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.List;
+import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
+import org.apache.skywalking.oap.server.core.Indicators;
+import org.apache.skywalking.oap.server.core.analysis.indicator.Indicator;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.ConstOne;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Entrance;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.IndicatorType;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.SourceFrom;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+
+public class DeepAnalysis {
+ public AnalysisResult analysis(AnalysisResult result) {
+ // 1. Set sub package name by source.metric
+ result.setPackageName(result.getSourceName().toLowerCase() + "." + result.getMetricName().toLowerCase());
+
+ Class<? extends Indicator> indicatorClass = Indicators.find(result.getAggregationFunctionName());
+
+ // 2. based on class annotation, find selector and merge requirement
+ IndicatorType indicatorClassAnnotation = indicatorClass.getAnnotation(IndicatorType.class);
+ if (indicatorClassAnnotation == null) {
+ throw new IllegalArgumentException("Can't find IndicatorType in class: " + indicatorClass.getName());
+ }
+ result.setIndicatorClassName(indicatorClass.getSimpleName());
+ result.setRemoteSelector(indicatorClassAnnotation.selector());
+ result.setNeedMerge(indicatorClassAnnotation.needMerge());
+
+ // 3. Find Entrance method of this indicator
+ Class c = indicatorClass;
+ Method entranceMethod = null;
+ SearchEntrance:
+ while (!c.equals(Object.class)) {
+ for (Method method : c.getMethods()) {
+ Entrance annotation = method.getAnnotation(Entrance.class);
+ if (annotation != null) {
+ entranceMethod = method;
+ break SearchEntrance;
+ }
+ }
+ c = c.getSuperclass();
+ }
+ if (entranceMethod == null) {
+ throw new IllegalArgumentException("Can't find Entrance method in class: " + indicatorClass.getName());
+ }
+ EntryMethod entryMethod = new EntryMethod();
+ result.setEntryMethod(entryMethod);
+ entryMethod.setMethodName(entranceMethod.getName());
+
+ // 4. Use parameter's annotation of entrance method to generate aggregation entrance.
+ for (Parameter parameter : entranceMethod.getParameters()) {
+ Annotation[] parameterAnnotations = parameter.getAnnotations();
+ if (parameterAnnotations == null || parameterAnnotations.length == 0) {
+ throw new IllegalArgumentException("Entrance method:" + entranceMethod + " doesn't include the annotation.");
+ }
+ Annotation annotation = parameterAnnotations[0];
+ if (annotation instanceof SourceFrom) {
+ entryMethod.addArg("source." + ClassMethodUtil.toGetMethod(result.getSourceAttribute()) + "()");
+ } else if (annotation instanceof ConstOne) {
+ entryMethod.addArg("1");
+ } else {
+ throw new IllegalArgumentException("Entrance method:" + entranceMethod + " doesn't the expected annotation.");
+ }
+ }
+
+ // 5. Get all column declared in Indicator class.
+ c = indicatorClass;
+ while (!c.equals(Object.class)) {
+ for (Field field : c.getDeclaredFields()) {
+ Column column = field.getAnnotation(Column.class);
+ if (column != null) {
+ result.addPersistentField(field.getName(), column.columnName(), field.getType());
+ }
+ }
+ c = c.getSuperclass();
+ }
+
+ // 6. Based on Source, generate default columns
+ List<SourceColumn> columns = SourceColumnsFactory.getColumns(result.getSourceName());
+ result.setFieldsFromSource(columns);
+
+ result.generateSerializeFields();
+
+ return result;
+ }
+
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/EntryMethod.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/EntryMethod.java
new file mode 100644
index 0000000..dc2f6cd
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/EntryMethod.java
@@ -0,0 +1,40 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import java.util.LinkedList;
+import java.util.List;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter(AccessLevel.PUBLIC)
+@Setter(AccessLevel.PUBLIC)
+public class EntryMethod {
+ private String methodName;
+
+ private List<String> argsExpressions;
+
+ public void addArg(String expression) {
+ if (argsExpressions == null) {
+ argsExpressions = new LinkedList<>();
+ }
+ argsExpressions.add(expression);
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
index ca0d715..3d73b3f 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
@@ -38,8 +38,8 @@
@Override
public void exitAggregationStatement(@NotNull OALParser.AggregationStatementContext ctx) {
- current.setPackageName(current.getSourceName().toLowerCase() + "." + current.getMetricName().toLowerCase());
- results.add(current);
+ DeepAnalysis deepAnalysis = new DeepAnalysis();
+ results.add(deepAnalysis.analysis(current));
current = null;
}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java
new file mode 100644
index 0000000..448755d
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java
@@ -0,0 +1,61 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class PersistenceColumns {
+ private List<PersistenceField> stringFields = new LinkedList<>();
+ private List<PersistenceField> longFields = new LinkedList<>();
+ private List<PersistenceField> doubleFields = new LinkedList<>();
+ private List<PersistenceField> intFields = new LinkedList<>();
+
+ public void addStringField(String fieldName) {
+ stringFields.add(new PersistenceField(fieldName));
+ }
+
+ public void addLongField(String fieldName) {
+ longFields.add(new PersistenceField(fieldName));
+ }
+
+ public void addDoubleField(String fieldName) {
+ doubleFields.add(new PersistenceField(fieldName));
+ }
+
+ public void addIntField(String fieldName) {
+ intFields.add(new PersistenceField(fieldName));
+ }
+
+ public List<PersistenceField> getStringFields() {
+ return stringFields;
+ }
+
+ public List<PersistenceField> getLongFields() {
+ return longFields;
+ }
+
+ public List<PersistenceField> getDoubleFields() {
+ return doubleFields;
+ }
+
+ public List<PersistenceField> getIntFields() {
+ return intFields;
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceField.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceField.java
new file mode 100644
index 0000000..c82aca8
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceField.java
@@ -0,0 +1,38 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
+
+@Getter(AccessLevel.PUBLIC)
+@Setter(AccessLevel.PUBLIC)
+public class PersistenceField {
+ private String fieldName;
+ private String setter;
+ private String getter;
+
+ public PersistenceField(String fieldName) {
+ this.fieldName = fieldName;
+ this.setter = ClassMethodUtil.toSetMethod(fieldName);
+ this.getter = ClassMethodUtil.toGetMethod(fieldName);
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumn.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumn.java
new file mode 100644
index 0000000..26b28c7
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumn.java
@@ -0,0 +1,47 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
+
+@Getter(AccessLevel.PUBLIC)
+@Setter(AccessLevel.PUBLIC)
+public class SourceColumn {
+ private String fieldName;
+ private String columnName;
+ private Class<?> type;
+ private String typeName;
+ private boolean isID;
+ private String fieldSetter;
+ private String fieldGetter;
+
+ public SourceColumn(String fieldName, String columnName, Class<?> type, boolean isID) {
+ this.fieldName = fieldName;
+ this.columnName = columnName;
+ this.type = type;
+ this.typeName = type.getSimpleName();
+ this.isID = isID;
+
+ this.fieldGetter = ClassMethodUtil.toGetMethod(fieldName);
+ this.fieldSetter = ClassMethodUtil.toSetMethod(fieldName);
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
new file mode 100644
index 0000000..8b5524e
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
@@ -0,0 +1,47 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class SourceColumnsFactory {
+ public static List<SourceColumn> getColumns(String source) {
+ List<SourceColumn> columnList;
+ SourceColumn idColumn;
+ switch (source) {
+ case "Service":
+ columnList = new LinkedList<>();
+ idColumn = new SourceColumn("id", "id", int.class, true);
+ columnList.add(idColumn);
+ SourceColumn serviceIdColumn = new SourceColumn("serviceId", "serviceId", int.class, false);
+ columnList.add(serviceIdColumn);
+ SourceColumn serviceInstanceIdColumn = new SourceColumn("serviceInstanceId", "serviceInstanceId", int.class, false);
+ columnList.add(serviceInstanceIdColumn);
+ return columnList;
+ case "Endpoint":
+ columnList = new LinkedList<>();
+ idColumn = new SourceColumn("id", "id", int.class, true);
+ columnList.add(idColumn);
+ return columnList;
+ default:
+ throw new IllegalArgumentException("Illegal source :" + source);
+ }
+ }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/util/ClassMethodUtil.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/util/ClassMethodUtil.java
new file mode 100644
index 0000000..081bca5
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/util/ClassMethodUtil.java
@@ -0,0 +1,29 @@
+/*
+ * 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.skywalking.oal.tool.util;
+
+public class ClassMethodUtil {
+ public static String toGetMethod(String attribute) {
+ return "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1);
+ }
+
+ public static String toSetMethod(String attribute) {
+ return "set" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1);
+ }
+}
diff --git a/oal-parser/src/main/resources/code-templates/AggregateWorkerTemplate.ftl b/oal-parser/src/main/resources/code-templates/AggregateWorkerTemplate.ftl
index 253f0fe..b46405e 100644
--- a/oal-parser/src/main/resources/code-templates/AggregateWorkerTemplate.ftl
+++ b/oal-parser/src/main/resources/code-templates/AggregateWorkerTemplate.ftl
@@ -16,7 +16,7 @@
*
*/
-package org.apache.skywalking.oap.server.core.analysis.${packageName};
+package org.apache.skywalking.oap.server.core.analysis.generated.${packageName};
import org.apache.skywalking.oap.server.core.analysis.worker.AbstractAggregatorWorker;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
diff --git a/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl b/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl
new file mode 100644
index 0000000..714efb8
--- /dev/null
+++ b/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl
@@ -0,0 +1,141 @@
+/*
+ * 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.skywalking.oap.server.core.analysis.generated.${packageName};
+
+import java.util.*;
+import lombok.*;
+import org.apache.skywalking.oap.server.core.analysis.indicator.*;
+import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+
+public class ${metricName}Indicator extends ${indicatorClassName} {
+
+<#list fieldsFromSource as sourceField>
+ @Setter @Getter @Column(columnName = "${sourceField.columnName}") private ${sourceField.typeName} ${sourceField.fieldName};
+</#list>
+
+ @Override public String name() {
+ return ${metricName};
+ }
+
+ @Override public String id() {
+ return String.valueOf(id);
+ }
+
+ @Override public int hashCode() {
+ int result = 17;
+<#list fieldsFromSource as sourceField>
+ <#if sourceField.isID()>
+ result = 31 * result + ${sourceField.fieldName};
+ </#if>
+</#list>
+ result = 31 * result + (int)getTimeBucket();
+ return result;
+ }
+
+
+ @Override public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+
+ ${metricName}Indicator indicator = (${metricName}Indicator)obj;
+<#list fieldsFromSource as sourceField>
+ <#if sourceField.isID()>
+ if (${sourceField.fieldName} != indicator.${sourceField.fieldName})
+ </#if>
+</#list>
+ return false;
+ if (getTimeBucket() != indicator.getTimeBucket())
+ return false;
+
+ return true;
+ }
+
+
+ @Override public RemoteData.Builder serialize() {
+ RemoteData.Builder remoteBuilder = RemoteData.newBuilder();
+<#list serializeFields.stringFields as field>
+ remoteBuilder.setDataStrings(${field?index}, ${field.getter}());
+</#list>
+
+<#list serializeFields.longFields as field>
+ remoteBuilder.setDataLongs(${field?index}, ${field.getter}());
+</#list>
+
+<#list serializeFields.doubleFields as field>
+ remoteBuilder.setDataDoubles(${field?index}, ${field.getter}());
+</#list>
+
+<#list serializeFields.intFields as field>
+ remoteBuilder.setDataIntegers(${field?index}, ${field.getter}());
+</#list>
+
+ return remoteBuilder;
+ }
+
+ @Override public void deserialize(RemoteData remoteData) {
+<#list serializeFields.stringFields as field>
+ ${field.setter}(remoteData.getDataStrings(${field?index}));
+</#list>
+
+<#list serializeFields.longFields as field>
+ ${field.setter}(remoteData.getDataLongs(${field?index}));
+</#list>
+
+<#list serializeFields.doubleFields as field>
+ ${field.setter}(remoteData.getDataDoubles(${field?index}));
+</#list>
+
+<#list serializeFields.intFields as field>
+ ${field.setter}(remoteData.getDataIntegers(${field?index}));
+</#list>
+ }
+
+ @Override public Map<String, Object> toMap() {
+ Map<String, Object> map = new HashMap<>();
+<#list fieldsFromSource as field>
+ map.put("${field.columnName}", ${field.fieldGetter}());
+</#list>
+<#list persistentFields as field>
+ map.put("${field.columnName}", ${field.fieldGetter}());
+</#list>
+ return map;
+ }
+
+ @Override public Indicator newOne(Map<String, Object> dbMap) {
+ ${metricName}Indicator indicator = new ${metricName}Indicator();
+<#list fieldsFromSource as field>
+ indicator.${field.fieldSetter}((${field.typeName})dbMap.get("${field.columnName}"));
+</#list>
+<#list persistentFields as field>
+ indicator.${field.fieldSetter}((${field.typeName})dbMap.get("${field.columnName}"));
+</#list>
+ return indicator;
+ }
+}
diff --git a/oal-parser/src/main/resources/code-templates/PersistentWorkerTemplate.ftl b/oal-parser/src/main/resources/code-templates/PersistentWorkerTemplate.ftl
new file mode 100644
index 0000000..4c7848d
--- /dev/null
+++ b/oal-parser/src/main/resources/code-templates/PersistentWorkerTemplate.ftl
@@ -0,0 +1,38 @@
+/*
+ * 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.skywalking.oap.server.core.analysis.generated.${packageName};
+
+import org.apache.skywalking.oap.server.core.analysis.worker.AbstractPersistentWorker;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+public class ${metricName}PersistentWorker extends AbstractPersistentWorker<${metricName}Indicator> {
+
+ public ${metricName}PersistentWorker(ModuleManager moduleManager) {
+ super(moduleManager);
+ }
+
+ @Override protected boolean needMergeDBData() {
+ return ${needMerge?then('true', 'false')};
+ }
+}
diff --git a/oal-parser/src/main/resources/code-templates/RemoteWorkerTemplate.ftl b/oal-parser/src/main/resources/code-templates/RemoteWorkerTemplate.ftl
index 95872da..2156548 100644
--- a/oal-parser/src/main/resources/code-templates/RemoteWorkerTemplate.ftl
+++ b/oal-parser/src/main/resources/code-templates/RemoteWorkerTemplate.ftl
@@ -16,7 +16,7 @@
*
*/
-package org.apache.skywalking.oap.server.core.analysis.${packageName};
+package org.apache.skywalking.oap.server.core.analysis.generated.${packageName};
import org.apache.skywalking.oap.server.core.analysis.worker.AbstractRemoteWorker;
import org.apache.skywalking.oap.server.core.remote.selector.Selector;
diff --git a/oal-parser/src/test/java/org/apache/skywalking/oal/tool/output/FileGeneratorTest.java b/oal-parser/src/test/java/org/apache/skywalking/oal/tool/output/FileGeneratorTest.java
index b6b5b05..3761f7a 100644
--- a/oal-parser/src/test/java/org/apache/skywalking/oal/tool/output/FileGeneratorTest.java
+++ b/oal-parser/src/test/java/org/apache/skywalking/oal/tool/output/FileGeneratorTest.java
@@ -26,6 +26,7 @@
import java.util.LinkedList;
import java.util.List;
import org.apache.skywalking.oal.tool.parser.AnalysisResult;
+import org.apache.skywalking.oal.tool.parser.SourceColumnsFactory;
import org.apache.skywalking.oap.server.core.remote.selector.Selector;
import org.junit.Assert;
import org.junit.Test;
@@ -39,6 +40,13 @@
result.setMetricName("ServiceAvg");
result.setAggregationFunctionName("avg");
result.setRemoteSelector(Selector.HashCode);
+ result.setNeedMerge(true);
+ result.setIndicatorClassName("AvgIndicator");
+ result.addPersistentField("summation", "summation", long.class);
+ result.addPersistentField("count", "count", int.class);
+ result.addPersistentField("value", "value", long.class);
+ result.setFieldsFromSource(SourceColumnsFactory.getColumns("Service"));
+ result.generateSerializeFields();
return result;
}
@@ -73,6 +81,37 @@
//fileGenerator.generateRemoteWorker(result, new OutputStreamWriter(System.out));
}
+ @Test
+ public void testGeneratePersistentWorker() throws IOException, TemplateException {
+ AnalysisResult result = buildResult();
+
+ List<AnalysisResult> results = new LinkedList<>();
+ results.add(result);
+
+ FileGenerator fileGenerator = new FileGenerator(results, ".");
+ StringWriter writer = new StringWriter();
+ fileGenerator.generatePersistentWorker(result, writer);
+
+ Assert.assertEquals(readExpectedFile("PersistentWorkerExpected.java"), writer.toString());
+
+ //fileGenerator.generatePersistentWorker(result, new OutputStreamWriter(System.out));
+ }
+
+ @Test
+ public void testGenerateIndicatorImplementor() throws IOException, TemplateException {
+ AnalysisResult result = buildResult();
+
+ List<AnalysisResult> results = new LinkedList<>();
+ results.add(result);
+
+ FileGenerator fileGenerator = new FileGenerator(results, ".");
+ StringWriter writer = new StringWriter();
+ fileGenerator.generateIndicatorImplementor(result, writer);
+ Assert.assertEquals(readExpectedFile("IndicatorImplementorExpected.java"), writer.toString());
+
+ //fileGenerator.generateIndicatorImplementor(result, new OutputStreamWriter(System.out));
+ }
+
private String readExpectedFile(String filename) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(FileGenerator.class.getResourceAsStream("/expectedFiles/" + filename)));
diff --git a/oal-parser/src/test/java/org/apache/skywalking/oal/tool/parser/DeepAnalysisTest.java b/oal-parser/src/test/java/org/apache/skywalking/oal/tool/parser/DeepAnalysisTest.java
new file mode 100644
index 0000000..1ef392f
--- /dev/null
+++ b/oal-parser/src/test/java/org/apache/skywalking/oal/tool/parser/DeepAnalysisTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.skywalking.oal.tool.parser;
+
+import java.util.List;
+import org.apache.skywalking.oap.server.core.remote.selector.Selector;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DeepAnalysisTest {
+ @Test
+ public void testAnalysis(){
+ AnalysisResult result = new AnalysisResult();
+ result.setSourceName("Service");
+ result.setPackageName("service.serviceavg");
+ result.setSourceAttribute("latency");
+ result.setMetricName("ServiceAvg");
+ result.setAggregationFunctionName("avg");
+
+ DeepAnalysis analysis = new DeepAnalysis();
+ result = analysis.analysis(result);
+
+ Assert.assertEquals(Selector.HashCode, result.getRemoteSelector());
+ Assert.assertEquals(true, result.isNeedMerge());
+ EntryMethod method = result.getEntryMethod();
+ Assert.assertEquals("combine", method.getMethodName());
+ Assert.assertEquals("source.getLatency()", method.getArgsExpressions().get(0));
+ Assert.assertEquals("1", method.getArgsExpressions().get(1));
+
+ List<SourceColumn> source = result.getFieldsFromSource();
+ Assert.assertEquals(3, source.size());
+
+ List<DataColumn> persistentFields = result.getPersistentFields();
+ Assert.assertEquals(4, persistentFields.size());
+ }
+}
diff --git a/oal-parser/src/test/resources/expectedFiles/AggregateWorkerExpected.java b/oal-parser/src/test/resources/expectedFiles/AggregateWorkerExpected.java
index e79290c..320ce9c 100644
--- a/oal-parser/src/test/resources/expectedFiles/AggregateWorkerExpected.java
+++ b/oal-parser/src/test/resources/expectedFiles/AggregateWorkerExpected.java
@@ -16,7 +16,7 @@
*
*/
-package org.apache.skywalking.oap.server.core.analysis.service.serviceavg;
+package org.apache.skywalking.oap.server.core.analysis.generated.service.serviceavg;
import org.apache.skywalking.oap.server.core.analysis.worker.AbstractAggregatorWorker;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
diff --git a/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java b/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java
new file mode 100644
index 0000000..6e80661
--- /dev/null
+++ b/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java
@@ -0,0 +1,123 @@
+/*
+ * 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.skywalking.oap.server.core.analysis.generated.service.serviceavg;
+
+import java.util.*;
+import lombok.*;
+import org.apache.skywalking.oap.server.core.analysis.indicator.*;
+import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+
+public class ServiceAvgIndicator extends AvgIndicator {
+
+ @Setter @Getter @Column(columnName = "id") private int id;
+ @Setter @Getter @Column(columnName = "serviceId") private int serviceId;
+ @Setter @Getter @Column(columnName = "serviceInstanceId") private int serviceInstanceId;
+
+ @Override public String name() {
+ return ServiceAvg;
+ }
+
+ @Override public String id() {
+ return String.valueOf(id);
+ }
+
+ @Override public int hashCode() {
+ int result = 17;
+ result = 31 * result + id;
+ result = 31 * result + (int)getTimeBucket();
+ return result;
+ }
+
+
+ @Override public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+
+ ServiceAvgIndicator indicator = (ServiceAvgIndicator)obj;
+ if (id != indicator.id)
+ return false;
+ if (getTimeBucket() != indicator.getTimeBucket())
+ return false;
+
+ return true;
+ }
+
+
+ @Override public RemoteData.Builder serialize() {
+ RemoteData.Builder remoteBuilder = RemoteData.newBuilder();
+
+ remoteBuilder.setDataLongs(0, getTimeBucket());
+ remoteBuilder.setDataLongs(1, getSummation());
+ remoteBuilder.setDataLongs(2, getValue());
+
+
+ remoteBuilder.setDataIntegers(0, getId());
+ remoteBuilder.setDataIntegers(1, getServiceId());
+ remoteBuilder.setDataIntegers(2, getServiceInstanceId());
+ remoteBuilder.setDataIntegers(3, getCount());
+
+ return remoteBuilder;
+ }
+
+ @Override public void deserialize(RemoteData remoteData) {
+
+ setTimeBucket(remoteData.getDataLongs(0));
+ setSummation(remoteData.getDataLongs(1));
+ setValue(remoteData.getDataLongs(2));
+
+
+ setId(remoteData.getDataIntegers(0));
+ setServiceId(remoteData.getDataIntegers(1));
+ setServiceInstanceId(remoteData.getDataIntegers(2));
+ setCount(remoteData.getDataIntegers(3));
+ }
+
+ @Override public Map<String, Object> toMap() {
+ Map<String, Object> map = new HashMap<>();
+ map.put("id", getId());
+ map.put("serviceId", getServiceId());
+ map.put("serviceInstanceId", getServiceInstanceId());
+ map.put("summation", getSummation());
+ map.put("count", getCount());
+ map.put("value", getValue());
+ return map;
+ }
+
+ @Override public Indicator newOne(Map<String, Object> dbMap) {
+ ServiceAvgIndicator indicator = new ServiceAvgIndicator();
+ indicator.setId((int)dbMap.get("id"));
+ indicator.setServiceId((int)dbMap.get("serviceId"));
+ indicator.setServiceInstanceId((int)dbMap.get("serviceInstanceId"));
+ indicator.setSummation((long)dbMap.get("summation"));
+ indicator.setCount((int)dbMap.get("count"));
+ indicator.setValue((long)dbMap.get("value"));
+ return indicator;
+ }
+}
\ No newline at end of file
diff --git a/oal-parser/src/test/resources/expectedFiles/PersistentWorkerExpected.java b/oal-parser/src/test/resources/expectedFiles/PersistentWorkerExpected.java
new file mode 100644
index 0000000..81950a5
--- /dev/null
+++ b/oal-parser/src/test/resources/expectedFiles/PersistentWorkerExpected.java
@@ -0,0 +1,38 @@
+/*
+ * 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.skywalking.oap.server.core.analysis.generated.service.serviceavg;
+
+import org.apache.skywalking.oap.server.core.analysis.worker.AbstractPersistentWorker;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+public class ServiceAvgPersistentWorker extends AbstractPersistentWorker<ServiceAvgIndicator> {
+
+ public ServiceAvgPersistentWorker(ModuleManager moduleManager) {
+ super(moduleManager);
+ }
+
+ @Override protected boolean needMergeDBData() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/oal-parser/src/test/resources/expectedFiles/RemoteWorkerExpected.java b/oal-parser/src/test/resources/expectedFiles/RemoteWorkerExpected.java
index 45e11c1..3fef183 100644
--- a/oal-parser/src/test/resources/expectedFiles/RemoteWorkerExpected.java
+++ b/oal-parser/src/test/resources/expectedFiles/RemoteWorkerExpected.java
@@ -16,7 +16,7 @@
*
*/
-package org.apache.skywalking.oap.server.core.analysis.service.serviceavg;
+package org.apache.skywalking.oap.server.core.analysis.generated.service.serviceavg;
import org.apache.skywalking.oap.server.core.analysis.worker.AbstractRemoteWorker;
import org.apache.skywalking.oap.server.core.remote.selector.Selector;