You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by ce...@apache.org on 2016/05/10 16:53:56 UTC
[4/5] incubator-metron git commit: METRON-141: The ability to do
threat triage closes apache/incubator-metron#108
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentConfig.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentConfig.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentConfig.java
new file mode 100644
index 0000000..562a928
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentConfig.java
@@ -0,0 +1,108 @@
+/**
+ * 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.metron.common.configuration.enrichment;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.apache.metron.common.configuration.enrichment.threatintel.ThreatIntelConfig;
+import org.apache.metron.common.utils.JSONUtils;
+
+import java.io.IOException;
+
+public class SensorEnrichmentConfig {
+
+ private String index;
+ private int batchSize;
+ private EnrichmentConfig enrichment = new EnrichmentConfig();
+ private ThreatIntelConfig threatIntel = new ThreatIntelConfig();
+
+ public EnrichmentConfig getEnrichment() {
+ return enrichment;
+ }
+
+ public void setEnrichment(EnrichmentConfig enrichment) {
+ this.enrichment = enrichment;
+ }
+
+ public ThreatIntelConfig getThreatIntel() {
+ return threatIntel;
+ }
+
+ public void setThreatIntel(ThreatIntelConfig threatIntel) {
+ this.threatIntel = threatIntel;
+ }
+
+ public String getIndex() {
+ return index;
+ }
+
+ public void setIndex(String index) {
+ this.index = index;
+ }
+
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public void setBatchSize(int batchSize) {
+ this.batchSize = batchSize;
+ }
+
+ @Override
+ public String toString() {
+ return "SensorEnrichmentConfig{" +
+ "index='" + index + '\'' +
+ ", batchSize=" + batchSize +
+ ", enrichment=" + enrichment +
+ ", threatIntel=" + threatIntel +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SensorEnrichmentConfig that = (SensorEnrichmentConfig) o;
+
+ if (getBatchSize() != that.getBatchSize()) return false;
+ if (getIndex() != null ? !getIndex().equals(that.getIndex()) : that.getIndex() != null) return false;
+ if (getEnrichment() != null ? !getEnrichment().equals(that.getEnrichment()) : that.getEnrichment() != null)
+ return false;
+ return getThreatIntel() != null ? getThreatIntel().equals(that.getThreatIntel()) : that.getThreatIntel() == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getIndex() != null ? getIndex().hashCode() : 0;
+ result = 31 * result + getBatchSize();
+ result = 31 * result + (getEnrichment() != null ? getEnrichment().hashCode() : 0);
+ result = 31 * result + (getThreatIntel() != null ? getThreatIntel().hashCode() : 0);
+ return result;
+ }
+
+ public static SensorEnrichmentConfig fromBytes(byte[] config) throws IOException {
+ return JSONUtils.INSTANCE.load(new String(config), SensorEnrichmentConfig.class);
+ }
+
+ public String toJSON() throws JsonProcessingException {
+ return JSONUtils.INSTANCE.toJSON(this, true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentUpdateConfig.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentUpdateConfig.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentUpdateConfig.java
new file mode 100644
index 0000000..99e681a
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/SensorEnrichmentUpdateConfig.java
@@ -0,0 +1,209 @@
+/**
+ * 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.metron.common.configuration.enrichment;
+
+import com.google.common.base.Joiner;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.metron.common.Constants;
+import org.apache.metron.common.configuration.ConfigurationsUtils;
+import org.apache.zookeeper.KeeperException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class SensorEnrichmentUpdateConfig {
+
+ protected static final Logger _LOG = LoggerFactory.getLogger(SensorEnrichmentUpdateConfig.class);
+ public static class FieldList {
+ Type type;
+ Map<String, List<String>> fieldToEnrichmentTypes;
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public Map<String, List<String>> getFieldToEnrichmentTypes() {
+ return fieldToEnrichmentTypes;
+ }
+
+ public void setFieldToEnrichmentTypes(Map<String, List<String>> fieldToEnrichmentTypes) {
+ this.fieldToEnrichmentTypes = fieldToEnrichmentTypes;
+ }
+ }
+ public String zkQuorum;
+ public Map<String, FieldList> sensorToFieldList;
+
+ public String getZkQuorum() {
+ return zkQuorum;
+ }
+
+ public void setZkQuorum(String zkQuorum) {
+ this.zkQuorum = zkQuorum;
+ }
+
+ public Map<String, FieldList> getSensorToFieldList() {
+ return sensorToFieldList;
+ }
+
+ public void setSensorToFieldList(Map<String, FieldList> sensorToFieldList) {
+ this.sensorToFieldList = sensorToFieldList;
+ }
+
+ public void updateSensorConfigs( ) throws Exception {
+ CuratorFramework client = ConfigurationsUtils.getClient(getZkQuorum());
+ try {
+ client.start();
+ updateSensorConfigs(new ZKSourceConfigHandler(client), sensorToFieldList);
+ }
+ finally {
+ client.close();
+ }
+ }
+
+ public static interface SourceConfigHandler {
+ SensorEnrichmentConfig readConfig(String sensor) throws Exception;
+ void persistConfig(String sensor, SensorEnrichmentConfig config) throws Exception;
+ }
+
+ public static class ZKSourceConfigHandler implements SourceConfigHandler {
+ CuratorFramework client;
+ public ZKSourceConfigHandler(CuratorFramework client) {
+ this.client = client;
+ }
+ @Override
+ public SensorEnrichmentConfig readConfig(String sensor) throws Exception {
+ SensorEnrichmentConfig sensorEnrichmentConfig = new SensorEnrichmentConfig();
+ try {
+ sensorEnrichmentConfig = SensorEnrichmentConfig.fromBytes(ConfigurationsUtils.readSensorEnrichmentConfigBytesFromZookeeper(sensor, client));
+ }catch (KeeperException.NoNodeException e) {
+ sensorEnrichmentConfig.setIndex(sensor);
+ sensorEnrichmentConfig.setBatchSize(1);
+ }
+ return sensorEnrichmentConfig;
+ }
+
+ @Override
+ public void persistConfig(String sensor, SensorEnrichmentConfig config) throws Exception {
+ ConfigurationsUtils.writeSensorEnrichmentConfigToZookeeper(sensor, config.toJSON().getBytes(), client);
+ }
+ }
+
+ public static void updateSensorConfigs( SourceConfigHandler scHandler
+ , Map<String, FieldList> sensorToFieldList
+ ) throws Exception
+ {
+ Map<String, SensorEnrichmentConfig> sourceConfigsChanged = new HashMap<>();
+ for (Map.Entry<String, FieldList> kv : sensorToFieldList.entrySet()) {
+ SensorEnrichmentConfig config = sourceConfigsChanged.get(kv.getKey());
+ if(config == null) {
+ config = scHandler.readConfig(kv.getKey());
+ if(_LOG.isDebugEnabled()) {
+ _LOG.debug(config.toJSON());
+ }
+ }
+ Map<String, List<String> > fieldMap = null;
+ Map<String, List<String> > fieldToTypeMap = null;
+ List<String> fieldList = null;
+ if(kv.getValue().type == Type.THREAT_INTEL) {
+ fieldMap = config.getThreatIntel().getFieldMap();
+ if(fieldMap!= null) {
+ fieldList = fieldMap.get(Constants.SIMPLE_HBASE_THREAT_INTEL);
+ } else {
+ fieldMap = new HashMap<>();
+ }
+ if(fieldList == null) {
+ fieldList = new ArrayList<>();
+ fieldMap.put(Constants.SIMPLE_HBASE_THREAT_INTEL, fieldList);
+ }
+ fieldToTypeMap = config.getThreatIntel().getFieldToTypeMap();
+ if(fieldToTypeMap == null) {
+ fieldToTypeMap = new HashMap<>();
+ config.getThreatIntel().setFieldToTypeMap(fieldToTypeMap);
+ }
+ }
+ else if(kv.getValue().type == Type.ENRICHMENT) {
+ fieldMap = config.getEnrichment().getFieldMap();
+ if(fieldMap!= null) {
+ fieldList = fieldMap.get(Constants.SIMPLE_HBASE_ENRICHMENT);
+ } else {
+ fieldMap = new HashMap<>();
+ }
+ if(fieldList == null) {
+ fieldList = new ArrayList<>();
+ fieldMap.put(Constants.SIMPLE_HBASE_ENRICHMENT, fieldList);
+ }
+ fieldToTypeMap = config.getEnrichment().getFieldToTypeMap();
+ if(fieldToTypeMap == null) {
+ fieldToTypeMap = new HashMap<>();
+ config.getEnrichment().setFieldToTypeMap(fieldToTypeMap);
+ }
+ }
+ if(fieldToTypeMap == null || fieldMap == null) {
+ _LOG.debug("fieldToTypeMap is null or fieldMap is null, so skipping");
+ continue;
+ }
+ //Add the additional fields to the field list associated with the hbase adapter
+ {
+ HashSet<String> fieldSet = new HashSet<>(fieldList);
+ List<String> additionalFields = new ArrayList<>();
+ for (String field : kv.getValue().getFieldToEnrichmentTypes().keySet()) {
+ if (!fieldSet.contains(field)) {
+ additionalFields.add(field);
+ }
+ }
+ //adding only the ones that we don't already have to the field list
+ if (additionalFields.size() > 0) {
+ _LOG.debug("Adding additional fields: " + Joiner.on(',').join(additionalFields));
+ fieldList.addAll(additionalFields);
+ sourceConfigsChanged.put(kv.getKey(), config);
+ }
+ }
+ //Add the additional enrichment types to the mapping between the fields
+ {
+ for(Map.Entry<String, List<String>> fieldToType : kv.getValue().getFieldToEnrichmentTypes().entrySet()) {
+ String field = fieldToType.getKey();
+ final HashSet<String> types = new HashSet<>(fieldToType.getValue());
+ int sizeBefore = 0;
+ if(fieldToTypeMap.containsKey(field)) {
+ List<String> typeList = fieldToTypeMap.get(field);
+ sizeBefore = new HashSet<>(typeList).size();
+ types.addAll(typeList);
+ }
+ int sizeAfter = types.size();
+ boolean changed = sizeBefore != sizeAfter;
+ if(changed) {
+ fieldToTypeMap.put(field, new ArrayList<String>() {{
+ addAll(types);
+ }});
+ sourceConfigsChanged.put(kv.getKey(), config);
+ }
+ }
+ }
+ }
+ for(Map.Entry<String, SensorEnrichmentConfig> kv : sourceConfigsChanged.entrySet()) {
+ scHandler.persistConfig(kv.getKey(), kv.getValue());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/Type.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/Type.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/Type.java
new file mode 100644
index 0000000..dc56495
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/Type.java
@@ -0,0 +1,24 @@
+/**
+ * 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.metron.common.configuration.enrichment;
+
+public enum Type {
+ THREAT_INTEL
+ ,ENRICHMENT
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatIntelConfig.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatIntelConfig.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatIntelConfig.java
new file mode 100644
index 0000000..3b34a0a
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatIntelConfig.java
@@ -0,0 +1,59 @@
+/**
+ * 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.metron.common.configuration.enrichment.threatintel;
+
+import org.apache.metron.common.configuration.enrichment.EnrichmentConfig;
+
+public class ThreatIntelConfig extends EnrichmentConfig {
+ private ThreatTriageConfig triageConfig = new ThreatTriageConfig();
+
+ public ThreatTriageConfig getTriageConfig() {
+ return triageConfig;
+ }
+
+ public void setTriageConfig(ThreatTriageConfig triageConfig) {
+ this.triageConfig = triageConfig;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+
+ ThreatIntelConfig that = (ThreatIntelConfig) o;
+
+ return getTriageConfig() != null ? getTriageConfig().equals(that.getTriageConfig()) : that.getTriageConfig() == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (getTriageConfig() != null ? getTriageConfig().hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ThreatIntelConfig{" +
+ "triageConfig=" + triageConfig +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatTriageConfig.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatTriageConfig.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatTriageConfig.java
new file mode 100644
index 0000000..9dea047
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/configuration/enrichment/threatintel/ThreatTriageConfig.java
@@ -0,0 +1,101 @@
+/**
+ * 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.metron.common.configuration.enrichment.threatintel;
+
+import com.google.common.base.Joiner;
+import org.apache.metron.common.aggregator.Aggregator;
+import org.apache.metron.common.aggregator.Aggregators;
+import org.apache.metron.common.query.PredicateProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ThreatTriageConfig {
+ private Map<String, Number> riskLevelRules = new HashMap<>();
+ private Aggregator aggregator = Aggregators.MAX;
+ private Map<String, Object> aggregationConfig = new HashMap<>();
+
+ public Map<String, Number> getRiskLevelRules() {
+ return riskLevelRules;
+ }
+
+ public void setRiskLevelRules(Map<String, Number> riskLevelRules) {
+ this.riskLevelRules = riskLevelRules;
+ PredicateProcessor processor = new PredicateProcessor();
+ for(String rule : riskLevelRules.keySet()) {
+ processor.validate(rule);
+ }
+ }
+
+ public Aggregator getAggregator() {
+ return aggregator;
+ }
+
+ public void setAggregator(String aggregator) {
+ try {
+ this.aggregator = Aggregators.valueOf(aggregator);
+ }
+ catch(IllegalArgumentException iae) {
+ throw new IllegalArgumentException("Unable to load aggregator of " + aggregator
+ + ". Valid aggregators are " + Joiner.on(',').join(Aggregators.values())
+ );
+ }
+ }
+
+ public Map<String, Object> getAggregationConfig() {
+ return aggregationConfig;
+ }
+
+ public void setAggregationConfig(Map<String, Object> aggregationConfig) {
+ this.aggregationConfig = aggregationConfig;
+ }
+
+ @Override
+ public String toString() {
+ return "ThreatTriageConfig{" +
+ "riskLevelRules=" + riskLevelRules +
+ ", aggregator=" + aggregator +
+ ", aggregationConfig=" + aggregationConfig +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ThreatTriageConfig that = (ThreatTriageConfig) o;
+
+ if (getRiskLevelRules() != null ? !getRiskLevelRules().equals(that.getRiskLevelRules()) : that.getRiskLevelRules() != null)
+ return false;
+ if (getAggregator() != null ? !getAggregator().equals(that.getAggregator()) : that.getAggregator() != null)
+ return false;
+ return getAggregationConfig() != null ? getAggregationConfig().equals(that.getAggregationConfig()) : that.getAggregationConfig() == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getRiskLevelRules() != null ? getRiskLevelRules().hashCode() : 0;
+ result = 31 * result + (getAggregator() != null ? getAggregator().hashCode() : 0);
+ result = 31 * result + (getAggregationConfig() != null ? getAggregationConfig().hashCode() : 0);
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/BooleanOp.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/BooleanOp.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/BooleanOp.java
new file mode 100644
index 0000000..cedc9a3
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/BooleanOp.java
@@ -0,0 +1,23 @@
+/**
+ * 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.metron.common.query;
+
+public interface BooleanOp {
+ boolean op(boolean left, boolean right);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ErrorListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ErrorListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ErrorListener.java
new file mode 100644
index 0000000..883dee2
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ErrorListener.java
@@ -0,0 +1,50 @@
+/**
+ * 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.metron.common.query;
+
+import org.antlr.v4.runtime.ANTLRErrorListener;
+import org.antlr.v4.runtime.Parser;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.atn.ATNConfigSet;
+import org.antlr.v4.runtime.dfa.DFA;
+
+import java.util.BitSet;
+
+public class ErrorListener implements ANTLRErrorListener {
+ @Override
+ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
+ throw new ParseException("Syntax error @ " + line + ":" + charPositionInLine+ " " + msg, e);
+ }
+
+
+ @Override
+ public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, ATNConfigSet configs) {
+ }
+
+
+ @Override
+ public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {
+ }
+
+
+ @Override
+ public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/FunctionMarker.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/FunctionMarker.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/FunctionMarker.java
new file mode 100644
index 0000000..aefbbbf
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/FunctionMarker.java
@@ -0,0 +1,21 @@
+/**
+ * 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.metron.common.query;
+
+public class FunctionMarker { }
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/LogicalFunctions.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/LogicalFunctions.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/LogicalFunctions.java
new file mode 100644
index 0000000..77aa173
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/LogicalFunctions.java
@@ -0,0 +1,99 @@
+/**
+ * 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.metron.common.query;
+
+import com.google.common.base.Function;
+import org.apache.commons.net.util.SubnetUtils;
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+public enum LogicalFunctions implements Function<List<String>, Boolean> {
+ IS_EMPTY ( list -> {
+ if(list.size() == 0) {
+ throw new IllegalStateException("IS_EMPTY expects one string arg");
+ }
+ String val = list.get(0);
+ return val == null || val.isEmpty() ? true:false;
+ })
+ ,IN_SUBNET( list -> {
+ if(list.size() < 2) {
+ throw new IllegalStateException("IN_SUBNET expects at least two args: [ip, cidr1, cidr2, ...]"
+ + " where cidr is the subnet mask in cidr form"
+ );
+ }
+ String ip = list.get(0);
+ if(ip == null) {
+ return false;
+ }
+ boolean inSubnet = false;
+ for(int i = 1;i < list.size() && !inSubnet;++i) {
+ String cidr = list.get(1);
+ if(cidr == null) {
+ continue;
+ }
+ inSubnet |= new SubnetUtils(cidr).getInfo().isInRange(ip);
+ }
+
+ return inSubnet;
+ })
+ ,STARTS_WITH( list -> {
+ if(list.size() < 2) {
+ throw new IllegalStateException("STARTS_WITH expects two args: [string, prefix] where prefix is the string fragment that the string should start with");
+ }
+ String prefix = list.get(1);
+ String str = list.get(0);
+ if(str == null || prefix == null) {
+ return false;
+ }
+ return str.startsWith(prefix);
+ })
+ ,ENDS_WITH( list -> {
+ if(list.size() < 2) {
+ throw new IllegalStateException("ENDS_WITH expects two args: [string, suffix] where suffix is the string fragment that the string should end with");
+ }
+ String prefix = list.get(1);
+ String str = list.get(0);
+ if(str == null || prefix == null) {
+ return false;
+ }
+ return str.endsWith(prefix);
+ })
+ ,REGEXP_MATCH( list -> {
+ if(list.size() < 2) {
+ throw new IllegalStateException("REGEXP_MATCH expects two args: [string, pattern] where pattern is a regexp pattern");
+ }
+ String pattern = list.get(1);
+ String str = list.get(0);
+ if(str == null || pattern == null) {
+ return false;
+ }
+ return str.matches(pattern);
+ })
+ ;
+ Function<List<String>, Boolean> func;
+ LogicalFunctions(Function<List<String>, Boolean> func) {
+ this.func = func;
+ }
+ @Nullable
+ @Override
+ public Boolean apply(@Nullable List<String> input) {
+ return func.apply(input);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/MapVariableResolver.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/MapVariableResolver.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/MapVariableResolver.java
new file mode 100644
index 0000000..ad1f810
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/MapVariableResolver.java
@@ -0,0 +1,33 @@
+/**
+ * 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.metron.common.query;
+
+import java.util.Map;
+
+public class MapVariableResolver implements VariableResolver {
+ Map variableMapping;
+ public MapVariableResolver(Map variableMapping) {
+ this.variableMapping = variableMapping;
+ }
+ @Override
+ public String resolve(String variable) {
+ Object o = variableMapping.get(variable);
+ return o == null?null:o.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ParseException.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ParseException.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ParseException.java
new file mode 100644
index 0000000..7d658f0
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/ParseException.java
@@ -0,0 +1,28 @@
+/**
+ * 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.metron.common.query;
+
+public class ParseException extends RuntimeException {
+ public ParseException(String reason) {
+ super(reason);
+ }
+ public ParseException(String reason, Throwable t) {
+ super(reason, t);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateProcessor.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateProcessor.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateProcessor.java
new file mode 100644
index 0000000..6499319
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateProcessor.java
@@ -0,0 +1,59 @@
+/**
+ * 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.metron.common.query;
+
+import org.antlr.v4.runtime.*;
+import org.apache.metron.common.query.generated.*;
+
+
+public class PredicateProcessor {
+ public boolean parse(String rule, VariableResolver resolver) {
+ ANTLRInputStream input = new ANTLRInputStream(rule);
+ PredicateLexer lexer = new PredicateLexer(input);
+ lexer.removeErrorListeners();
+ lexer.addErrorListener(new ErrorListener());
+ TokenStream tokens = new CommonTokenStream(lexer);
+ PredicateParser parser = new PredicateParser(tokens);
+
+ QueryCompiler treeBuilder = new QueryCompiler(resolver);
+ parser.addParseListener(treeBuilder);
+ parser.removeErrorListeners();
+ parser.addErrorListener(new ErrorListener());
+ parser.single_rule();
+ return treeBuilder.getResult();
+ }
+
+ public boolean validate(String rule) throws ParseException {
+ return validate(rule, true);
+ }
+ public boolean validate(String rule, boolean throwException) throws ParseException {
+ try {
+ parse(rule, x -> null);
+ return true;
+ }
+ catch(Throwable t) {
+ if(throwException) {
+ throw new ParseException("Unable to parse " + rule + ": " + t.getMessage(), t);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateToken.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateToken.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateToken.java
new file mode 100644
index 0000000..54ac17d
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/PredicateToken.java
@@ -0,0 +1,58 @@
+/**
+ * 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.metron.common.query;
+
+public class PredicateToken<T> {
+ T value;
+ Class<T> underlyingType;
+ public PredicateToken(T value, Class<T> clazz) {
+ this.value = value;
+ this.underlyingType = clazz;
+ }
+ public T getValue() {
+ return value;
+ }
+ public Class<T> getUnderlyingType() {
+ return underlyingType;
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PredicateToken<?> predicateToken = (PredicateToken<?>) o;
+
+ if (getValue() != null ? !getValue().equals(predicateToken.getValue()) : predicateToken.getValue() != null) return false;
+ return getUnderlyingType() != null ? getUnderlyingType().equals(predicateToken.getUnderlyingType()) : predicateToken.getUnderlyingType() == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = getValue() != null ? getValue().hashCode() : 0;
+ result = 31 * result + (getUnderlyingType() != null ? getUnderlyingType().hashCode() : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/QueryCompiler.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/QueryCompiler.java
new file mode 100644
index 0000000..6351eed
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/QueryCompiler.java
@@ -0,0 +1,288 @@
+/**
+ * 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.metron.common.query;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import org.apache.metron.common.query.generated.PredicateBaseListener;
+import org.apache.metron.common.query.generated.PredicateParser;
+
+import java.util.*;
+
+class QueryCompiler extends PredicateBaseListener {
+ private VariableResolver resolver = null;
+ private Stack<PredicateToken> tokenStack = new Stack<>();
+
+ public QueryCompiler(VariableResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ @Override
+ public void enterSingle_rule(org.apache.metron.common.query.generated.PredicateParser.Single_ruleContext ctx) {
+ tokenStack.clear();
+ }
+
+ @Override
+ public void exitSingle_rule(org.apache.metron.common.query.generated.PredicateParser.Single_ruleContext ctx) {
+ }
+
+ @Override
+ public void exitLogicalExpressionAnd(PredicateParser.LogicalExpressionAndContext ctx) {
+ PredicateToken<?> left = popStack();
+ PredicateToken<?> right = popStack();
+ tokenStack.push(new PredicateToken<>(booleanOp(left, right, (l, r) -> l && r, "&&"), Boolean.class));
+ }
+
+ @Override
+ public void exitLogicalExpressionOr(PredicateParser.LogicalExpressionOrContext ctx) {
+ PredicateToken<?> left = popStack();
+ PredicateToken<?> right = popStack();
+
+ tokenStack.push(new PredicateToken<>(booleanOp(left, right, (l, r) -> l || r, "||"), Boolean.class));
+ }
+
+ private boolean booleanOp(PredicateToken<?> left, PredicateToken<?> right, BooleanOp op, String opName)
+ {
+ if(left.getUnderlyingType().equals(right.getUnderlyingType()) && left.getUnderlyingType().equals(Boolean.class)) {
+ Boolean l = (Boolean) left.getValue();
+ Boolean r = (Boolean) right.getValue();
+ if(l == null || r == null) {
+ throw new ParseException("Unable to operate on " + left.getValue() + " " + opName + " " + right.getValue() + ", null value");
+ }
+ return op.op(l, r);
+ }
+ else {
+ throw new ParseException("Unable to operate on " + left.getValue() + " " + opName + " " + right.getValue() + ", bad types");
+ }
+ }
+
+
+ @Override
+ public void exitLogicalConst(PredicateParser.LogicalConstContext ctx) {
+ Boolean b = null;
+ switch(ctx.getText().toUpperCase()) {
+ case "TRUE":
+ b = true;
+ break;
+ case "FALSE":
+ b = false;
+ break;
+ default:
+ throw new ParseException("Unable to process " + ctx.getText() + " as a boolean constant");
+ }
+ tokenStack.push(new PredicateToken<>(b, Boolean.class));
+ }
+
+ @Override
+ public void exitComparisonExpressionWithOperator(PredicateParser.ComparisonExpressionWithOperatorContext ctx) {
+ boolean isEqualsOp = ctx.getChild(1).getText().equals("==");
+ PredicateToken<?> left = popStack();
+ PredicateToken<?> right = popStack();
+ if(left.getUnderlyingType().equals(right.getUnderlyingType())) {
+ boolean isEquals = left.equals(right);
+ tokenStack.push(new PredicateToken<>(isEqualsOp?isEquals:!isEquals, Boolean.class));
+ }
+ else {
+ throw new ParseException("Unable to compare " + left.getValue() + " " + ctx.getText() + " " + right.getValue());
+ }
+ }
+
+ public PredicateToken<?> popStack() {
+ if(tokenStack.empty()) {
+ throw new ParseException("Unable to pop an empty stack");
+ }
+ return tokenStack.pop();
+ }
+
+ @Override
+ public void exitLogicalVariable(PredicateParser.LogicalVariableContext ctx) {
+ tokenStack.push(new PredicateToken<>(resolver.resolve(ctx.getText()), String.class));
+ }
+
+
+ @Override
+ public void exitStringLiteral(PredicateParser.StringLiteralContext ctx) {
+ String val = ctx.getText();
+ tokenStack.push(new PredicateToken<>(val.substring(1, val.length() - 1), String.class));
+ }
+
+
+ @Override
+ public void enterList_entity(PredicateParser.List_entityContext ctx) {
+ tokenStack.push(new PredicateToken<>(new FunctionMarker(), FunctionMarker.class));
+ }
+
+
+ @Override
+ public void exitList_entity(PredicateParser.List_entityContext ctx) {
+ Set<String> inSet = new HashSet<>();
+ while(true) {
+ PredicateToken<?> token = popStack();
+ if(token.getUnderlyingType().equals(FunctionMarker.class)) {
+ break;
+ }
+ else {
+ inSet.add((String)token.getValue());
+ }
+ }
+ tokenStack.push(new PredicateToken<>(inSet, Set.class));
+ }
+
+
+ @Override
+ public void enterFunc_args(PredicateParser.Func_argsContext ctx) {
+ tokenStack.push(new PredicateToken<>(new FunctionMarker(), FunctionMarker.class));
+ }
+
+
+ @Override
+ public void exitFunc_args(PredicateParser.Func_argsContext ctx) {
+ LinkedList<String> args = new LinkedList<>();
+ while(true) {
+ PredicateToken<?> token = popStack();
+ if(token.getUnderlyingType().equals(FunctionMarker.class)) {
+ break;
+ }
+ else {
+ args.addFirst((String)token.getValue());
+ }
+ }
+ tokenStack.push(new PredicateToken<>(args, List.class));
+ }
+
+ @Override
+ public void exitInExpression(PredicateParser.InExpressionContext ctx) {
+ PredicateToken<?> left = popStack();
+ PredicateToken<?> right = popStack();
+ String key = null;
+ Set<String> set = null;
+ if(left.getUnderlyingType().equals(Set.class)) {
+ set = (Set<String>) left.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + left.getValue() + " is not a set");
+ }
+ if(right.getUnderlyingType().equals(String.class)) {
+ key = (String) right.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + right.getValue() + " is not a string");
+ }
+ tokenStack.push(new PredicateToken<>(set.contains(key), Boolean.class));
+ }
+
+ @Override
+ public void exitNInExpression(PredicateParser.NInExpressionContext ctx) {
+ PredicateToken<?> left = popStack();
+ PredicateToken<?> right = popStack();
+ String key = null;
+ Set<String> set = null;
+ if(left.getUnderlyingType().equals(Set.class)) {
+ set = (Set<String>) left.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + left.getValue() + " is not a set");
+ }
+ if(right.getUnderlyingType().equals(String.class)) {
+ key = (String) right.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + right.getValue() + " is not a string");
+ }
+ tokenStack.push(new PredicateToken<>(!set.contains(key), Boolean.class));
+ }
+
+
+ @Override
+ public void exitLogicalFunc(PredicateParser.LogicalFuncContext ctx) {
+ String funcName = ctx.getChild(0).getText();
+ Function<List<String>, Boolean> func;
+ try {
+ func = LogicalFunctions.valueOf(funcName);
+ }
+ catch(IllegalArgumentException iae) {
+ throw new ParseException("Unable to find logical function " + funcName + ". Valid functions are "
+ + Joiner.on(',').join(LogicalFunctions.values())
+ );
+ }
+ PredicateToken<?> left = popStack();
+ List<String> argList = null;
+ if(left.getUnderlyingType().equals(List.class)) {
+ argList = (List<String>) left.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + left.getValue() + " is not a set");
+ }
+ Boolean result = func.apply(argList);
+ tokenStack.push(new PredicateToken<>(result, Boolean.class));
+ }
+
+ @Override
+ public void exitStringFunc(PredicateParser.StringFuncContext ctx) {
+ String funcName = ctx.getChild(0).getText();
+ Function<List<String>, String> func;
+ try {
+ func = StringFunctions.valueOf(funcName);
+ }
+ catch(IllegalArgumentException iae) {
+ throw new ParseException("Unable to find string function " + funcName + ". Valid functions are "
+ + Joiner.on(',').join(StringFunctions.values())
+ );
+ }
+ PredicateToken<?> left = popStack();
+ List<String> argList = null;
+ if(left.getUnderlyingType().equals(List.class)) {
+ argList = (List<String>) left.getValue();
+ }
+ else {
+ throw new ParseException("Unable to process in clause because " + left.getValue() + " is not a set");
+ }
+ String result = func.apply(argList);
+ tokenStack.push(new PredicateToken<>(result, String.class));
+ }
+
+ @Override
+ public void exitExistsFunc(PredicateParser.ExistsFuncContext ctx) {
+ String variable = ctx.getChild(2).getText();
+ boolean exists = resolver.resolve(variable) != null;
+ tokenStack.push(new PredicateToken<>(exists, Boolean.class));
+ }
+
+ @Override
+ public void exitNotFunc(PredicateParser.NotFuncContext ctx) {
+ PredicateToken<Boolean> arg = (PredicateToken<Boolean>) popStack();
+ tokenStack.push(new PredicateToken<>(!arg.getValue(), Boolean.class));
+ }
+
+ public boolean getResult() throws ParseException {
+ if(tokenStack.empty()) {
+ throw new ParseException("Invalid predicate: Empty stack.");
+ }
+ PredicateToken<?> token = popStack();
+ if(token.getUnderlyingType().equals(Boolean.class) && tokenStack.empty()) {
+ return (Boolean)token.getValue();
+ }
+ if(tokenStack.empty()) {
+ throw new ParseException("Invalid parse, stack not empty: " + Joiner.on(',').join(tokenStack));
+ }
+ else {
+ throw new ParseException("Invalid parse, found " + token + " but expected boolean");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/StringFunctions.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/StringFunctions.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/StringFunctions.java
new file mode 100644
index 0000000..911063e
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/StringFunctions.java
@@ -0,0 +1,42 @@
+/**
+ * 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.metron.common.query;
+
+
+import com.google.common.base.Function;
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+public enum StringFunctions implements Function<List<String>, String> {
+ TO_LOWER(strings -> strings.get(0)==null?null:strings.get(0).toLowerCase())
+ ,TO_UPPER(strings -> strings.get(0) == null?null:strings.get(0).toUpperCase())
+ ,TRIM(strings -> strings.get(0) == null?null:strings.get(0).trim())
+ ;
+ Function<List<String>, String> func;
+ StringFunctions(Function<List<String>, String> func) {
+ this.func = func;
+ }
+
+ @Nullable
+ @Override
+ public String apply(@Nullable List<String> input) {
+ return func.apply(input);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/VariableResolver.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/VariableResolver.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/VariableResolver.java
new file mode 100644
index 0000000..d0a6625
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/VariableResolver.java
@@ -0,0 +1,23 @@
+/**
+ * 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.metron.common.query;
+
+public interface VariableResolver {
+ String resolve(String variable);
+}
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateBaseListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateBaseListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateBaseListener.java
new file mode 100644
index 0000000..ca7ac84
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateBaseListener.java
@@ -0,0 +1,336 @@
+// Generated from org/apache/metron/common/query/generated/Predicate.g4 by ANTLR 4.5
+package org.apache.metron.common.query.generated;
+
+//CHECKSTYLE:OFF
+/**
+ * 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.
+ */
+
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.misc.NotNull;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+/**
+ * This class provides an empty implementation of {@link PredicateListener},
+ * which can be extended to create a listener which only needs to handle a subset
+ * of the available methods.
+ */
+public class PredicateBaseListener implements PredicateListener {
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterSingle_rule(PredicateParser.Single_ruleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitSingle_rule(PredicateParser.Single_ruleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalEntity(PredicateParser.LogicalEntityContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalEntity(PredicateParser.LogicalEntityContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterComparisonExpression(PredicateParser.ComparisonExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitComparisonExpression(PredicateParser.ComparisonExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalExpressionInParen(PredicateParser.LogicalExpressionInParenContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalExpressionInParen(PredicateParser.LogicalExpressionInParenContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterNotFunc(PredicateParser.NotFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitNotFunc(PredicateParser.NotFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalExpressionAnd(PredicateParser.LogicalExpressionAndContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalExpressionAnd(PredicateParser.LogicalExpressionAndContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalExpressionOr(PredicateParser.LogicalExpressionOrContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalExpressionOr(PredicateParser.LogicalExpressionOrContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterComparisonExpressionWithOperator(PredicateParser.ComparisonExpressionWithOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitComparisonExpressionWithOperator(PredicateParser.ComparisonExpressionWithOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterInExpression(PredicateParser.InExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitInExpression(PredicateParser.InExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterNInExpression(PredicateParser.NInExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitNInExpression(PredicateParser.NInExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterComparisonExpressionParens(PredicateParser.ComparisonExpressionParensContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitComparisonExpressionParens(PredicateParser.ComparisonExpressionParensContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalConst(PredicateParser.LogicalConstContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalConst(PredicateParser.LogicalConstContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterExistsFunc(PredicateParser.ExistsFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitExistsFunc(PredicateParser.ExistsFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalFunc(PredicateParser.LogicalFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalFunc(PredicateParser.LogicalFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterList_entity(PredicateParser.List_entityContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitList_entity(PredicateParser.List_entityContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterFunc_args(PredicateParser.Func_argsContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitFunc_args(PredicateParser.Func_argsContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterOp_list(PredicateParser.Op_listContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitOp_list(PredicateParser.Op_listContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterStringLiteral(PredicateParser.StringLiteralContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitStringLiteral(PredicateParser.StringLiteralContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalVariable(PredicateParser.LogicalVariableContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalVariable(PredicateParser.LogicalVariableContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterStringFunc(PredicateParser.StringFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitStringFunc(PredicateParser.StringFuncContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterIdentifierOperand(PredicateParser.IdentifierOperandContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitIdentifierOperand(PredicateParser.IdentifierOperandContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterLogicalConstComparison(PredicateParser.LogicalConstComparisonContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitLogicalConstComparison(PredicateParser.LogicalConstComparisonContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterComparisonOp(PredicateParser.ComparisonOpContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitComparisonOp(PredicateParser.ComparisonOpContext ctx) { }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void visitTerminal(TerminalNode node) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void visitErrorNode(ErrorNode node) { }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateLexer.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateLexer.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateLexer.java
new file mode 100644
index 0000000..ebc0b00
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateLexer.java
@@ -0,0 +1,178 @@
+// Generated from org/apache/metron/common/query/generated/Predicate.g4 by ANTLR 4.5
+package org.apache.metron.common.query.generated;
+
+//CHECKSTYLE:OFF
+/**
+ * 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.
+ */
+
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
+public class PredicateLexer extends Lexer {
+ static { RuntimeMetaData.checkVersion("4.5", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
+ public static final int
+ AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, EQ=6, NEQ=7, COMMA=8, LBRACKET=9,
+ RBRACKET=10, LPAREN=11, RPAREN=12, IN=13, NIN=14, EXISTS=15, IDENTIFIER=16,
+ STRING_LITERAL=17, SEMI=18, COMMENT=19, WS=20;
+ public static String[] modeNames = {
+ "DEFAULT_MODE"
+ };
+
+ public static final String[] ruleNames = {
+ "AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "COMMA", "LBRACKET",
+ "RBRACKET", "LPAREN", "RPAREN", "IN", "NIN", "EXISTS", "IDENTIFIER", "SCHAR",
+ "STRING_LITERAL", "SEMI", "COMMENT", "WS"
+ };
+
+ private static final String[] _LITERAL_NAMES = {
+ null, null, null, null, null, null, "'=='", "'!='", "','", "'['", "']'",
+ "'('", "')'", "'in'", "'not in'", "'exists'", null, null, "';'"
+ };
+ private static final String[] _SYMBOLIC_NAMES = {
+ null, "AND", "OR", "NOT", "TRUE", "FALSE", "EQ", "NEQ", "COMMA", "LBRACKET",
+ "RBRACKET", "LPAREN", "RPAREN", "IN", "NIN", "EXISTS", "IDENTIFIER", "STRING_LITERAL",
+ "SEMI", "COMMENT", "WS"
+ };
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "<INVALID>";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+
+ public PredicateLexer(CharStream input) {
+ super(input);
+ _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+ }
+
+ @Override
+ public String getGrammarFileName() { return "Predicate.g4"; }
+
+ @Override
+ public String[] getRuleNames() { return ruleNames; }
+
+ @Override
+ public String getSerializedATN() { return _serializedATN; }
+
+ @Override
+ public String[] getModeNames() { return modeNames; }
+
+ @Override
+ public ATN getATN() { return _ATN; }
+
+ public static final String _serializedATN =
+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\26\u00af\b\1\4\2"+
+ "\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
+ "\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
+ "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\3\2\3\2\3\2\3\2\3\2\3\2"+
+ "\3\2\3\2\5\2\66\n\2\3\3\3\3\3\3\3\3\3\3\3\3\5\3>\n\3\3\4\3\4\3\4\3\4\3"+
+ "\4\3\4\5\4F\n\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5P\n\5\3\6\3\6\3\6\3"+
+ "\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\\\n\6\3\7\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3"+
+ "\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3"+
+ "\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\7\21\u0081"+
+ "\n\21\f\21\16\21\u0084\13\21\3\22\3\22\3\23\3\23\7\23\u008a\n\23\f\23"+
+ "\16\23\u008d\13\23\3\23\3\23\3\23\7\23\u0092\n\23\f\23\16\23\u0095\13"+
+ "\23\3\23\5\23\u0098\n\23\3\24\3\24\3\25\3\25\3\25\3\25\6\25\u00a0\n\25"+
+ "\r\25\16\25\u00a1\3\25\5\25\u00a5\n\25\3\25\3\25\3\26\6\26\u00aa\n\26"+
+ "\r\26\16\26\u00ab\3\26\3\26\3\u00a1\2\27\3\3\5\4\7\5\t\6\13\7\r\b\17\t"+
+ "\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\2%\23\'\24)\25+\26"+
+ "\3\2\7\5\2C\\aac|\b\2\60\60\62;C\\^^aac|\7\2\f\f\17\17$$))^^\3\3\f\f\5"+
+ "\2\13\f\16\17\"\"\u00ba\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2"+
+ "\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25"+
+ "\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2"+
+ "\2\2\2!\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\3\65\3\2"+
+ "\2\2\5=\3\2\2\2\7E\3\2\2\2\tO\3\2\2\2\13[\3\2\2\2\r]\3\2\2\2\17`\3\2\2"+
+ "\2\21c\3\2\2\2\23e\3\2\2\2\25g\3\2\2\2\27i\3\2\2\2\31k\3\2\2\2\33m\3\2"+
+ "\2\2\35p\3\2\2\2\37w\3\2\2\2!~\3\2\2\2#\u0085\3\2\2\2%\u0097\3\2\2\2\'"+
+ "\u0099\3\2\2\2)\u009b\3\2\2\2+\u00a9\3\2\2\2-.\7c\2\2./\7p\2\2/\66\7f"+
+ "\2\2\60\61\7(\2\2\61\66\7(\2\2\62\63\7C\2\2\63\64\7P\2\2\64\66\7F\2\2"+
+ "\65-\3\2\2\2\65\60\3\2\2\2\65\62\3\2\2\2\66\4\3\2\2\2\678\7q\2\28>\7t"+
+ "\2\29:\7~\2\2:>\7~\2\2;<\7Q\2\2<>\7T\2\2=\67\3\2\2\2=9\3\2\2\2=;\3\2\2"+
+ "\2>\6\3\2\2\2?@\7p\2\2@A\7q\2\2AF\7v\2\2BC\7P\2\2CD\7Q\2\2DF\7V\2\2E?"+
+ "\3\2\2\2EB\3\2\2\2F\b\3\2\2\2GH\7v\2\2HI\7t\2\2IJ\7w\2\2JP\7g\2\2KL\7"+
+ "V\2\2LM\7T\2\2MN\7W\2\2NP\7G\2\2OG\3\2\2\2OK\3\2\2\2P\n\3\2\2\2QR\7h\2"+
+ "\2RS\7c\2\2ST\7n\2\2TU\7u\2\2U\\\7g\2\2VW\7H\2\2WX\7C\2\2XY\7N\2\2YZ\7"+
+ "U\2\2Z\\\7G\2\2[Q\3\2\2\2[V\3\2\2\2\\\f\3\2\2\2]^\7?\2\2^_\7?\2\2_\16"+
+ "\3\2\2\2`a\7#\2\2ab\7?\2\2b\20\3\2\2\2cd\7.\2\2d\22\3\2\2\2ef\7]\2\2f"+
+ "\24\3\2\2\2gh\7_\2\2h\26\3\2\2\2ij\7*\2\2j\30\3\2\2\2kl\7+\2\2l\32\3\2"+
+ "\2\2mn\7k\2\2no\7p\2\2o\34\3\2\2\2pq\7p\2\2qr\7q\2\2rs\7v\2\2st\7\"\2"+
+ "\2tu\7k\2\2uv\7p\2\2v\36\3\2\2\2wx\7g\2\2xy\7z\2\2yz\7k\2\2z{\7u\2\2{"+
+ "|\7v\2\2|}\7u\2\2} \3\2\2\2~\u0082\t\2\2\2\177\u0081\t\3\2\2\u0080\177"+
+ "\3\2\2\2\u0081\u0084\3\2\2\2\u0082\u0080\3\2\2\2\u0082\u0083\3\2\2\2\u0083"+
+ "\"\3\2\2\2\u0084\u0082\3\2\2\2\u0085\u0086\n\4\2\2\u0086$\3\2\2\2\u0087"+
+ "\u008b\7$\2\2\u0088\u008a\5#\22\2\u0089\u0088\3\2\2\2\u008a\u008d\3\2"+
+ "\2\2\u008b\u0089\3\2\2\2\u008b\u008c\3\2\2\2\u008c\u008e\3\2\2\2\u008d"+
+ "\u008b\3\2\2\2\u008e\u0098\7$\2\2\u008f\u0093\7)\2\2\u0090\u0092\5#\22"+
+ "\2\u0091\u0090\3\2\2\2\u0092\u0095\3\2\2\2\u0093\u0091\3\2\2\2\u0093\u0094"+
+ "\3\2\2\2\u0094\u0096\3\2\2\2\u0095\u0093\3\2\2\2\u0096\u0098\7)\2\2\u0097"+
+ "\u0087\3\2\2\2\u0097\u008f\3\2\2\2\u0098&\3\2\2\2\u0099\u009a\7=\2\2\u009a"+
+ "(\3\2\2\2\u009b\u009c\7\61\2\2\u009c\u009d\7\61\2\2\u009d\u009f\3\2\2"+
+ "\2\u009e\u00a0\13\2\2\2\u009f\u009e\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1"+
+ "\u00a2\3\2\2\2\u00a1\u009f\3\2\2\2\u00a2\u00a4\3\2\2\2\u00a3\u00a5\t\5"+
+ "\2\2\u00a4\u00a3\3\2\2\2\u00a5\u00a6\3\2\2\2\u00a6\u00a7\b\25\2\2\u00a7"+
+ "*\3\2\2\2\u00a8\u00aa\t\6\2\2\u00a9\u00a8\3\2\2\2\u00aa\u00ab\3\2\2\2"+
+ "\u00ab\u00a9\3\2\2\2\u00ab\u00ac\3\2\2\2\u00ac\u00ad\3\2\2\2\u00ad\u00ae"+
+ "\b\26\2\2\u00ae,\3\2\2\2\17\2\65=EO[\u0082\u008b\u0093\u0097\u00a1\u00a4"+
+ "\u00ab\3\b\2\2";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/deed21e6/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateListener.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateListener.java b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateListener.java
new file mode 100644
index 0000000..6a8b669
--- /dev/null
+++ b/metron-platform/metron-common/src/main/java/org/apache/metron/common/query/generated/PredicateListener.java
@@ -0,0 +1,299 @@
+// Generated from org/apache/metron/common/query/generated/Predicate.g4 by ANTLR 4.5
+package org.apache.metron.common.query.generated;
+
+//CHECKSTYLE:OFF
+/**
+ * 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.
+ */
+
+import org.antlr.v4.runtime.misc.NotNull;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+
+/**
+ * This interface defines a complete listener for a parse tree produced by
+ * {@link PredicateParser}.
+ */
+public interface PredicateListener extends ParseTreeListener {
+ /**
+ * Enter a parse tree produced by {@link PredicateParser#single_rule}.
+ * @param ctx the parse tree
+ */
+ void enterSingle_rule(PredicateParser.Single_ruleContext ctx);
+ /**
+ * Exit a parse tree produced by {@link PredicateParser#single_rule}.
+ * @param ctx the parse tree
+ */
+ void exitSingle_rule(PredicateParser.Single_ruleContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalEntity}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalEntity(PredicateParser.LogicalEntityContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalEntity}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalEntity(PredicateParser.LogicalEntityContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code ComparisonExpression}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterComparisonExpression(PredicateParser.ComparisonExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code ComparisonExpression}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitComparisonExpression(PredicateParser.ComparisonExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalExpressionInParen}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalExpressionInParen(PredicateParser.LogicalExpressionInParenContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalExpressionInParen}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalExpressionInParen(PredicateParser.LogicalExpressionInParenContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code NotFunc}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterNotFunc(PredicateParser.NotFuncContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code NotFunc}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitNotFunc(PredicateParser.NotFuncContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalExpressionAnd}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalExpressionAnd(PredicateParser.LogicalExpressionAndContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalExpressionAnd}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalExpressionAnd(PredicateParser.LogicalExpressionAndContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalExpressionOr}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalExpressionOr(PredicateParser.LogicalExpressionOrContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalExpressionOr}
+ * labeled alternative in {@link PredicateParser#logical_expr}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalExpressionOr(PredicateParser.LogicalExpressionOrContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code ComparisonExpressionWithOperator}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void enterComparisonExpressionWithOperator(PredicateParser.ComparisonExpressionWithOperatorContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code ComparisonExpressionWithOperator}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void exitComparisonExpressionWithOperator(PredicateParser.ComparisonExpressionWithOperatorContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code InExpression}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void enterInExpression(PredicateParser.InExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code InExpression}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void exitInExpression(PredicateParser.InExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code NInExpression}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void enterNInExpression(PredicateParser.NInExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code NInExpression}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void exitNInExpression(PredicateParser.NInExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code ComparisonExpressionParens}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void enterComparisonExpressionParens(PredicateParser.ComparisonExpressionParensContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code ComparisonExpressionParens}
+ * labeled alternative in {@link PredicateParser#comparison_expr}.
+ * @param ctx the parse tree
+ */
+ void exitComparisonExpressionParens(PredicateParser.ComparisonExpressionParensContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalConst}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalConst(PredicateParser.LogicalConstContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalConst}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalConst(PredicateParser.LogicalConstContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code ExistsFunc}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void enterExistsFunc(PredicateParser.ExistsFuncContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code ExistsFunc}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void exitExistsFunc(PredicateParser.ExistsFuncContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalFunc}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalFunc(PredicateParser.LogicalFuncContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalFunc}
+ * labeled alternative in {@link PredicateParser#logical_entity}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalFunc(PredicateParser.LogicalFuncContext ctx);
+ /**
+ * Enter a parse tree produced by {@link PredicateParser#list_entity}.
+ * @param ctx the parse tree
+ */
+ void enterList_entity(PredicateParser.List_entityContext ctx);
+ /**
+ * Exit a parse tree produced by {@link PredicateParser#list_entity}.
+ * @param ctx the parse tree
+ */
+ void exitList_entity(PredicateParser.List_entityContext ctx);
+ /**
+ * Enter a parse tree produced by {@link PredicateParser#func_args}.
+ * @param ctx the parse tree
+ */
+ void enterFunc_args(PredicateParser.Func_argsContext ctx);
+ /**
+ * Exit a parse tree produced by {@link PredicateParser#func_args}.
+ * @param ctx the parse tree
+ */
+ void exitFunc_args(PredicateParser.Func_argsContext ctx);
+ /**
+ * Enter a parse tree produced by {@link PredicateParser#op_list}.
+ * @param ctx the parse tree
+ */
+ void enterOp_list(PredicateParser.Op_listContext ctx);
+ /**
+ * Exit a parse tree produced by {@link PredicateParser#op_list}.
+ * @param ctx the parse tree
+ */
+ void exitOp_list(PredicateParser.Op_listContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code StringLiteral}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void enterStringLiteral(PredicateParser.StringLiteralContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code StringLiteral}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void exitStringLiteral(PredicateParser.StringLiteralContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalVariable}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalVariable(PredicateParser.LogicalVariableContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalVariable}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalVariable(PredicateParser.LogicalVariableContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code StringFunc}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void enterStringFunc(PredicateParser.StringFuncContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code StringFunc}
+ * labeled alternative in {@link PredicateParser#identifier_operand}.
+ * @param ctx the parse tree
+ */
+ void exitStringFunc(PredicateParser.StringFuncContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code IdentifierOperand}
+ * labeled alternative in {@link PredicateParser#comparison_operand}.
+ * @param ctx the parse tree
+ */
+ void enterIdentifierOperand(PredicateParser.IdentifierOperandContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code IdentifierOperand}
+ * labeled alternative in {@link PredicateParser#comparison_operand}.
+ * @param ctx the parse tree
+ */
+ void exitIdentifierOperand(PredicateParser.IdentifierOperandContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LogicalConstComparison}
+ * labeled alternative in {@link PredicateParser#comparison_operand}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalConstComparison(PredicateParser.LogicalConstComparisonContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LogicalConstComparison}
+ * labeled alternative in {@link PredicateParser#comparison_operand}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalConstComparison(PredicateParser.LogicalConstComparisonContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code ComparisonOp}
+ * labeled alternative in {@link PredicateParser#comp_operator}.
+ * @param ctx the parse tree
+ */
+ void enterComparisonOp(PredicateParser.ComparisonOpContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code ComparisonOp}
+ * labeled alternative in {@link PredicateParser#comp_operator}.
+ * @param ctx the parse tree
+ */
+ void exitComparisonOp(PredicateParser.ComparisonOpContext ctx);
+}
\ No newline at end of file