Github user cestella commented on the issue: https://github.com/apache/metron/pull/795 TESTING PLAN # Preliminaries Setup some environment variables for convenience: * `export METRON_HOME=/usr/metron/0.4.1` * `export ZOOKEEPER=node1:2181` * `export BROKERLIST=node1:6667` ## Adjust the Profiler Period Duration * Adjust the profiler config by adjusting the "Period Duration" to 1 minute in Ambari Profiler config section. ## Create data generator * Open `~/rand_gen.py` and paste the following: ``` #!/usr/bin/python import random import sys import time def main(): mu = float(sys.argv[1]) sigma = float(sys.argv[2]) freq_s = int(sys.argv[3]) while True: out = '{ "value" : ' + str(random.gauss(mu, sigma)) + ' }' print out sys.stdout.flush() time.sleep(freq_s) if __name__ == '__main__': main() ``` This will generate random JSON maps with a numeric field called `value` ## Create Parser * Create a new parser called `dummy` by editing `$METRON_HOME/config/zookeeper/parsers/dummy.json`: ``` { "parserClassName":"org.apache.metron.parsers.json.JSONMapParser", "sensorTopic":"dummy" } ``` * Create the dummy kafka topic: `/usr/hdp/current/kafka-broker/bin/kafka-topics.sh --zookeeper $ZOOKEEPER --create --topic dummy --partitions 1 --replication-factor 1` # Test Cases ## Base Case First, let's ensure that data flows through with no enrichments or profiler. * Push the configs via `$METRON_HOME/bin/zk_load_configs.sh -m PUSH -i $METRON_HOME/config/zookeeper -z $ZOOKEEPER` * Start the parser via `$METRON_HOME/bin/start_parser_topology.sh -z $ZOOKEEPER -s dummy` * Send some synthetic data through (stop this after a few seconds): `python ~/rand_gen.py 0 1 1 | /usr/hdp/current/kafka-broker/bin/kafka-console-producer.sh --broker-list $BROKERLIST --topic dummy` * Validate data has been written to the index: ``` curl -XPOST 'http://localhost:9200/dummy*/_search?pretty' -d ' { "_source" : [ "source:type", "value" ] } ' ``` ## Modify Parser Now we'll modify the parser and see if our modifications show up. * Delete the dummy indices: `curl -XDELETE "http://localhost:9200/dummy*"` * Modify `$METRON_HOME/config/zookeeper/parsers/dummy.json` like so: ``` { "parserClassName":"org.apache.metron.parsers.json.JSONMapParser", "sensorTopic":"dummy", "fieldTransformations" : [ { "transformation" : "STELLAR" ,"output" : [ "parser_my_name", "parser_value_abs" ] ,"config" : { "parser_my_name" : "TO_UPPER('casey')", "parser_value_abs" : "ABS(value)" } } ] } ``` * Push the configs via `$METRON_HOME/bin/zk_load_configs.sh -m PUSH -i $METRON_HOME/config/zookeeper -z $ZOOKEEPER` * Send some synthetic data through (stop this after a few seconds): `python ~/rand_gen.py 0 1 1 | /usr/hdp/current/kafka-broker/bin/kafka-console-producer.sh --broker-list $BROKERLIST --topic dummy` * Validate data has been written to the index with the new fields, `parser_my_name` and `parser_value_abs`: ``` curl -XPOST 'http://localhost:9200/dummy*/_search?pretty' -d ' { "_source" : [ "source:type", "value", "parser_my_name", "parser_value_abs" ] } ' ``` ## Modify Enrichment * Delete the dummy indices: `curl -XDELETE "http://localhost:9200/dummy*"` * Modify `$METRON_HOME/config/zookeeper/enrichments/dummy.json` like so: ``` { "enrichment" : { "fieldMap": { "stellar" : { "config" : { "enr_my_name" : "TO_UPPER('casey')", "enr_value_abs" : "ABS(value)" } } } } } ``` * Push the configs via `$METRON_HOME/bin/zk_load_configs.sh -m PUSH -i $METRON_HOME/config/zookeeper -z $ZOOKEEPER` * Send some synthetic data through (stop this after a few seconds): `python ~/rand_gen.py 0 1 1 | /usr/hdp/current/kafka-broker/bin/kafka-console-producer.sh --broker-list $BROKERLIST --topic dummy` * Validate data has been written to the index with the new fields, `enr_my_name` and `enr_value_abs`: ``` curl -XPOST 'http://localhost:9200/dummy*/_search?pretty' -d ' { "_source" : [ "source:type", "value", "parser_my_name", "parser_value_abs", "enr_my_name", "enr_value_abs"] } ' ``` ## Modify Indexing We'll change the name of the index now and make sure data is flowing through * Delete the dummy indices: `curl -XDELETE "http://localhost:9200/dummy*"` * Modify `$METRON_HOME/config/zookeeper/indexing/dummy.json` like so: ``` { "hdfs" : { "index": "smarty", "batchSize": 5, "enabled" : true }, "elasticsearch" : { "index": "smarty", "batchSize": 5, "enabled" : true }, "solr" : { "index": "yaf", "batchSize": 5, "enabled" : false } } ``` * Push the configs via `$METRON_HOME/bin/zk_load_configs.sh -m PUSH -i $METRON_HOME/config/zookeeper -z $ZOOKEEPER` * Send some synthetic data through (stop this after a few seconds): `python ~/rand_gen.py 0 1 1 | /usr/hdp/current/kafka-broker/bin/kafka-console-producer.sh --broker-list $BROKERLIST --topic dummy` * Validate data has been written to the new index name: ``` curl -XPOST 'http://localhost:9200/smarty*/_search?pretty' -d ' { "_source" : [ "source:type", "value", "parser_my_name", "parser_value_abs", "enr_my_name", "enr_value_abs"] } ' ``` ## Modify Profiler * Modify `$METRON_HOME/config/zookeeper/profiler.json` like so: ``` { "profiles": [ { "profile": "stat", "foreach": "'global'", "onlyif": "true", "init" : { }, "update": { "s": "STATS_ADD(s, value)" }, "result": "s" } ] } ``` * Push the configs via `$METRON_HOME/bin/zk_load_configs.sh -m PUSH -i $METRON_HOME/config/zookeeper -z $ZOOKEEPER` * Send some synthetic data through (let this go for some time in another window): `python ~/rand_gen.py 0 1 1 | /usr/hdp/current/kafka-broker/bin/kafka-console-producer.sh --broker-list $BROKERLIST --topic dummy` * Execute the following and ensure the number out is neither `null` nor `NaN`: ``` sleep 128 && echo "STATS_MEAN(STATS_MERGE(PROFILE_GET('stat', 'global', PROFILE_WINDOW('from 5 minutes ago'))))" | $METRON_HOME/bin/stellar -z node1:2181 -na ``` # REST Test ## Parser Configurations * Ensure that you can retrieve all the parser configs by running the following and ensuring the default sensors exist: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/parser/config' | python -m json.tool | grep sensorTopic` * You should see the default sensors as well as our sensor, `dummy`: * `jsonMap` * `squid` * `websphere`, * `snort` * `asa` * `bro` * `yaf` * `dummy` * Delete the `websphere` parser sensor via: `curl -u user:password -X DELETE --header 'Accept: */*' 'http://node1:8082/api/v1/sensor/parser/config/websphere'` * Now, list the parser configs and ensure `websphere` is not in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/parser/config' | python -m json.tool | grep sensorTopic` * Add back the websphere parser: ``` curl -u user:password -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "parserClassName":"org.apache.metron.parsers.websphere.GrokWebSphereParser", "sensorTopic":"websphere", "parserConfig": { "grokPath":"/patterns/websphere", "patternLabel":"WEBSPHERE", "timestampField":"timestamp_string", "dateFormat":"yyyy MMM dd HH:mm:ss" } }' 'http://node1:8082/api/v1/sensor/parser/config' ``` * Now, list the parser configs and ensure `websphere` is in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/parser/config' | python -m json.tool | grep sensorTopic` ## Enrichment Configurations * Ensure that you can retrieve all the enrichment configs by running the following and ensuring the default sensors exist: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/enrichment/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'` * You should see the default sensors as well as our sensor, `dummy`: * `asa` * `bro` * `dummy` * `snort` * `websphere` * `yaf` * Delete the `websphere` enrichment via: `curl -u user:password -X DELETE --header 'Accept: */*' 'http://node1:8082/api/v1/sensor/enrichment/config/websphere'` * Now, list the enrichment configs and ensure `websphere` is not in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/enrichment/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'` * Add back the websphere enrichment: ``` curl -u user:password -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "enrichment": { "fieldMap": { "geo": [ "ip_src_addr" ], "host": [ "ip_src_addr" ] }, "fieldToTypeMap": { "ip_src_addr": [ "playful_classification" ] } } }' 'http://node1:8082/api/v1/sensor/enrichment/config/websphere' ``` * Now, list the enrichment configs and ensure `websphere` is in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/enrichment/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'` ## Indexing Configurations * Ensure that you can retrieve all the indexing configs by running the following and ensuring the default sensors exist: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/indexing/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'` * You should see the default sensors as well as our sensor, `dummy`: * `asa` * `bro` * `error` * `dummy` * `snort` * `websphere` * `yaf` * Delete the `websphere` indexing config via: `curl -u user:password -X DELETE --header 'Accept: */*' 'http://node1:8082/api/v1/sensor/indexing/config/websphere'` * Now, list the indexing configs and ensure `websphere` is not in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/indexing/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'` * Add back the websphere indexing config: ``` curl -u user:password -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "hdfs" : { "index": "websphere", "batchSize": 5, "enabled" : true }, "elasticsearch" : { "index": "websphere", "batchSize": 5, "enabled" : true }, "solr" : { "index": "websphere", "batchSize": 5, "enabled" : true } }' 'http://node1:8082/api/v1/sensor/indexing/config/websphere' ``` * Now, list the indexing configs and ensure `websphere` is in the list: `curl -u user:password -X GET --header 'Accept: application/json' 'http://node1:8082/api/v1/sensor/indexing/config' | python -m json.tool | grep "^ \"" | awk -F: '{print $1}' | sed 's/ //g'`
---