Repository: metron Updated Branches: refs/heads/master 9355a0465 -> e206f2508
METRON-984 Create STELLAR Decoding Functions (ottobackwards) closes apache/metron#642 Project: http://git-wip-us.apache.org/repos/asf/metron/repo Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/e206f250 Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/e206f250 Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/e206f250 Branch: refs/heads/master Commit: e206f2508ef7e7d798510df76ccfeb38b9530e89 Parents: 9355a04 Author: ottobackwards <ottobackwa...@gmail.com> Authored: Thu Jul 27 23:37:28 2017 -0400 Committer: otto <o...@apache.org> Committed: Thu Jul 27 23:37:28 2017 -0400 ---------------------------------------------------------------------- metron-stellar/stellar-common/README.md | 52 +++++- metron-stellar/stellar-common/pom.xml | 5 + .../stellar/common/encoding/Encodings.java | 158 +++++++++++++++++++ .../dsl/functions/EncodingFunctions.java | 157 ++++++++++++++++++ .../stellar/common/encoding/EncodingsTest.java | 104 ++++++++++++ .../stellar/dsl/functions/BasicStellarTest.java | 2 - .../dsl/functions/EncodingFunctionsTest.java | 125 +++++++++++++++ 7 files changed, 594 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/README.md ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/README.md b/metron-stellar/stellar-common/README.md index 0ffb096..2b5d4b6 100644 --- a/metron-stellar/stellar-common/README.md +++ b/metron-stellar/stellar-common/README.md @@ -116,15 +116,17 @@ In the core language functions, we support basic functional programming primitiv | [ `DAY_OF_MONTH`](#day_of_month) | | [ `DAY_OF_WEEK`](#day_of_week) | | [ `DAY_OF_YEAR`](#day_of_year) | +| [ `DECODE`](#decode) | | [ `DOMAIN_REMOVE_SUBDOMAINS`](#domain_remove_subdomains) | | [ `DOMAIN_REMOVE_TLD`](#domain_remove_tld) | | [ `DOMAIN_TO_TLD`](#domain_to_tld) | +| [ `ENCODE`](#encode) | | [ `ENDS_WITH`](#ends_with) | | [ `ENRICHMENT_EXISTS`](#enrichment_exists) | | [ `ENRICHMENT_GET`](#enrichment_get) | | [ `FILL_LEFT`](#fill_left) | | [ `FILL_RIGHT`](#fill_right) | -| [ `FILTER`](#filter) | +| [ `FILTER`](#filter) | | [ `FORMAT`](#format) | | [ `HLLP_CARDINALITY`](../../metron-analytics/metron-statistics#hllp_cardinality) | | [ `HLLP_INIT`](../../metron-analytics/metron-statistics#hllp_init) | @@ -134,8 +136,10 @@ In the core language functions, we support basic functional programming primitiv | [ `GET`](#get) | | [ `GET_FIRST`](#get_first) | | [ `GET_LAST`](#get_last) | +| [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings) | | [ `IN_SUBNET`](#in_subnet) | | [ `IS_DATE`](#is_date) | +| [ `IS_ENCODING`](#is_encoding) | | [ `IS_DOMAIN`](#is_domain) | | [ `IS_EMAIL`](#is_email) | | [ `IS_EMPTY`](#is_empty) | @@ -148,10 +152,10 @@ In the core language functions, we support basic functional programming primitiv | [ `KAFKA_PUT`](#kafka_put) | | [ `KAFKA_TAIL`](#kafka_tail) | | [ `LENGTH`](#length) | -| [ `LIST_ADD`](#list_add) | +| [ `LIST_ADD`](#list_add) | | [ `MAAS_GET_ENDPOINT`](#maas_get_endpoint) | | [ `MAAS_MODEL_APPLY`](#maas_model_apply) | -| [ `MAP`](#map) | +| [ `MAP`](#map) | | [ `MAP_EXISTS`](#map_exists) | | [ `MONTH`](#month) | | [ `PREPEND_IF_MISSING`](#prepend_if_missing) | @@ -159,7 +163,7 @@ In the core language functions, we support basic functional programming primitiv | [ `PROFILE_FIXED`](#profile_fixed) | | [ `PROFILE_WINDOW`](#profile_window) | | [ `PROTOCOL_TO_NAME`](#protocol_to_name) | -| [ `REDUCE`](#reduce) | +| [ `REDUCE`](#reduce) | | [ `REGEXP_MATCH`](#regexp_match) | | [ `REGEXP_GROUP_VAL`](#regexp_group_val) | | [ `SPLIT`](#split) | @@ -277,6 +281,19 @@ In the core language functions, we support basic functional programming primitiv * dateTime - The datetime as a long representing the milliseconds since unix epoch * Returns: The day number within the year. +### `DECODE` + * Description: Decodes the passed string with the provided encoding, which + must be one of the encodings returned from [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings) + * Input: + * string - the string to decode + * encoding - the encoding to use, must be one of encodings returned from [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings) + * verify - (optional), true or false to determine if string should be verified as being + encoded with the passed encoding + * Returns: + * The decoded string on success + * The original string the string cannot be decoded + * null on usage error + ### `DOMAIN_REMOVE_SUBDOMAINS` * Description: Removes the subdomains from a domain. * Input: @@ -295,6 +312,16 @@ In the core language functions, we support basic functional programming primitiv * domain - Fully qualified domain name * Returns: The TLD of the domain. (for example, DOMAIN_TO_TLD('mail.yahoo.co.uk') yields 'co.uk') +### `ENCODE` + * Description: Encodes the passed string with the provided encoding, which + must be one of the encodings returned from [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings) + * Input: + * string - the string to encode + * encoding - the encoding to use, must be one of encodings returned from [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings) + * Returns: + * The encoded string on success + * null on error + ### `ENDS_WITH` * Description: Determines whether a string ends with a specified suffix * Input: @@ -405,9 +432,16 @@ In the core language functions, we support basic functional programming primitiv ### `IS_EMPTY` * Description: Returns true if string or collection is empty or null and false if otherwise. * Input: - * input - Object of string or collection type (for example, list) + * Object of string or collection type (for example, list) * Returns: True if the string or collection is empty or null and false if otherwise. +### `IS_ENCODING` + * Description: Returns true if the passed string is encoded in one of the supported encodings and false if otherwise. + * Input: + * string - The string to test + * encoding - The name of the encoding as string. See [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings). + * Returns: True if the passed string is encoded in one of the supported encodings and false if otherwise. + ### `IS_INTEGER` * Description: Determines whether or not an object is an integer. * Input: @@ -477,6 +511,10 @@ In the core language functions, we support basic functional programming primitiv * element - Element to add to list * Returns: Resulting list with the item added at the end. +### `GET_SUPPORTED_ENCODINGS` + * Description: Returns a list of the encodings that are currently supported. + * Returns: A List of String + ### `MAAS_GET_ENDPOINT` * Description: Inspects ZooKeeper and returns a map containing the name, version and url for the model referred to by the input parameters. * Input: @@ -914,8 +952,8 @@ This command lists all functions resolvable in the Stellar environment. Stellar ``` [Stellar]>>> %functions BLOOM_ADD, BLOOM_EXISTS, BLOOM_INIT, BLOOM_MERGE, DAY_OF_MONTH, DAY_OF_WEEK, DAY_OF_YEAR, -DOMAIN_REMOVE_SUBDOMAINS, DOMAIN_REMOVE_TLD, DOMAIN_TO_TLD, ENDS_WITH, GET, GET_FIRST, -GET_LAST, IN_SUBNET, IS_DATE, IS_DOMAIN, IS_EMAIL, IS_EMPTY, IS_INTEGER, IS_IP, IS_URL, +DECODE, DOMAIN_REMOVE_SUBDOMAINS, DOMAIN_REMOVE_TLD, DOMAIN_TO_TLD, ENDS_WITH, GET, GET_FIRST, +GET_LAST, GET_ENCODINGS_LIST, IN_SUBNET, IS_DATE, IS_DOMAIN, IS_EMAIL, IS_EMPTY, IS_ENCODING, IS_INTEGER, IS_IP, IS_URL, JOIN, LENGTH, MAAS_GET_ENDPOINT, MAAS_MODEL_APPLY, MAP_EXISTS, MAP_GET, MONTH, PROTOCOL_TO_NAME, REGEXP_MATCH, SPLIT, STARTS_WITH, STATS_ADD, STATS_COUNT, STATS_GEOMETRIC_MEAN, STATS_INIT, STATS_KURTOSIS, STATS_MAX, STATS_MEAN, STATS_MERGE, STATS_MIN, STATS_PERCENTILE, http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/pom.xml ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/pom.xml b/metron-stellar/stellar-common/pom.xml index 11008b9..2f4cb6e 100644 --- a/metron-stellar/stellar-common/pom.xml +++ b/metron-stellar/stellar-common/pom.xml @@ -92,6 +92,11 @@ <version>4.1</version> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.10</version> + </dependency> + <dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> <version>1.6</version> http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/encoding/Encodings.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/encoding/Encodings.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/encoding/Encodings.java new file mode 100644 index 0000000..aceda1f --- /dev/null +++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/common/encoding/Encodings.java @@ -0,0 +1,158 @@ +/** + * 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.stellar.common.encoding; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.function.Predicate; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base32; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.BinaryCodec; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang.StringUtils; + +/** + * Endodings utility enum for Stellar supported encodings. + */ +public enum Encodings { + BASE32((possible) -> new Base32().isInAlphabet(possible), + (possible) -> new String(new Base32().decode(possible), StandardCharsets.UTF_8), + (possible) -> new String( new Base32().encode(possible.getBytes(StandardCharsets.UTF_8)),StandardCharsets.UTF_8)), + BASE32HEX((possible) -> new Base32(true).isInAlphabet(possible), + (possible) -> new String(new Base32(true).decode(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8), + (possible) -> new String(new Base32(true).encode(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8)), + BASE64((possible) -> Base64.isBase64(possible), + (possible) -> new String(new Base64().decode(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8), + (possible) -> new String(new Base64().encode(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8)), + BINARY((possible) -> { + for (byte b : possible.getBytes(StandardCharsets.UTF_8)) { + if ((b != 48 && b != 49)) { + return false; + } + } + return true; + }, + (possible) -> { + String str = new String(BinaryCodec.fromAscii(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + if (StringUtils.isEmpty(str.trim())) { + return possible; + } + return str; + }, + (possible) -> BinaryCodec.toAsciiString(possible.getBytes(StandardCharsets.UTF_8))), + HEX((possible) -> { + try { + Hex hex = new Hex(StandardCharsets.UTF_8); + hex.decode(possible.getBytes(StandardCharsets.UTF_8)); + return true; + } catch (DecoderException e) { + return false; + } + }, + (possible) -> { + try { + Hex hex = new Hex(StandardCharsets.UTF_8); + return new String(hex.decode(possible.getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + } catch (DecoderException e) { + return possible; + } + }, + (possible) -> new String(new Hex(StandardCharsets.UTF_8).encode(possible.getBytes(StandardCharsets.UTF_8)),StandardCharsets.UTF_8)); + + Predicate<String> is; + Function<String, String> decode; + Function<String, String> encode; + + /** + * Create a specialed Endodings enum member. + * + * @param is function for detecting + * @param decode funtion for decoding + */ + Encodings(Predicate<String> is, Function<String, String> decode, Function<String,String> encode) { + this.is = is; + this.decode = decode; + this.encode = encode; + } + + public static final List<String> SUPPORTED_LIST = new ArrayList<>(Arrays.asList(BASE32.name(), + BASE32HEX.name(), BASE64.name(), BINARY.name() , HEX.name())); + + /** + * Determines if the passed String is encoded in this encoding. + * A given String may be compatible with the encoding, but not actually encoded. + * + * @param possible the String to test + * @return true or false + */ + public boolean is(String possible) { + return is.test(possible); + } + + /** + * Attempts to decode a given String without verification. + * Any failure or compatibility issues will result in the original + * String being returned. + * + * @param encoded the String to decode + * @return The String decoded, or the original String + */ + public String decode(String encoded) { + return decode(encoded, false); + } + + /** + * Attempts to decode a given String, optionally verifying first. + * Any failure or compatibility issues will result in the original + * String being returned. + * + * @param encoded the String to decode + * @param verify flag to perform verification + * @return The String decoded, or the original String + */ + public String decode(String encoded, boolean verify) { + if (verify) { + if (is.test(encoded)) { + return decode.apply(encoded); + } else { + return encoded; + } + } + return decode.apply(encoded); + } + + /** + * Encodes the given String + * @param toEncode + * @return an encoded String + */ + public String encode(String toEncode) { + return encode.apply(toEncode); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/EncodingFunctions.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/EncodingFunctions.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/EncodingFunctions.java new file mode 100644 index 0000000..41783c2 --- /dev/null +++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/EncodingFunctions.java @@ -0,0 +1,157 @@ +/** + * 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.stellar.dsl.functions; + +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.apache.metron.stellar.common.encoding.Encodings; +import org.apache.metron.stellar.dsl.BaseStellarFunction; +import org.apache.metron.stellar.dsl.Stellar; + +/** + * Support for Stellar Functions based on the Apache Commons Codec library + * http://commons.apache.org/proper/commons-codec/index.html + */ +public class EncodingFunctions { + + @Stellar(name = "GET_SUPPORTED_ENCODINGS", + description = "Returns a list of the encodings that are currently supported as a list", + params = {}, + returns = "A list of supported encodings" + ) + public static class GetSupportedEncodings extends BaseStellarFunction { + + @Override + public Object apply(List<Object> list) { + return Encodings.SUPPORTED_LIST; + } + } + + @Stellar(name = "IS_ENCODING", + description = "Returns if the passed string is encoded in one of the supported encodings", + params = {"string - the string to test", + "encoding - the encoding to test, must be one of encodings returned from " + + "LIST_SUPPORTED_ENCODINGS" + }, + returns = "true if it is encoded, false if not" + ) + public static class IsEncoding extends BaseStellarFunction { + + @Override + public Object apply(List<Object> list) { + if (list.size() < 2) { + throw new IllegalStateException( + "IS_ENCODING expects two args: [string, encoding] where encoding is one from " + + "the supported list"); + } + String str = (String) list.get(0); + String encoding = (String) list.get(1); + if (StringUtils.isEmpty(str) || StringUtils.isEmpty(encoding)) { + return false; + } + + Encodings enc = null; + try { + enc = Encodings.valueOf(encoding.toUpperCase()); + } catch (IllegalArgumentException iae) { + throw new IllegalStateException(String.format("Encoding %s not supported", encoding), iae); + } + return enc.is(str); + } + } + + @Stellar(name = "DECODE", + description = "Decodes the passed string with the provided encoding, " + + " must be one of the encodings returned from LIST_SUPPORTED_ENCODINGS", + params = {"string - the string to decode", + "encoding - the encoding to use, must be one of encodings returned from " + + "LIST_SUPPORTED_ENCODINGS", + "verify - (optional), true or false to determine if string should be verified as being " + + "encoded with the passed encoding" + }, + returns = "The decoded string on success\n" + + "The original string the string cannot be decoded\n" + + "null on usage error" + ) + public static class Decode extends BaseStellarFunction { + + @Override + public Object apply(List<Object> list) { + if (list.size() != 2 && list.size() != 3) { + throw new IllegalStateException( + "DECODE expects two or three args: [string, encoding] or " + + "[string, encoding, verify] where encoding is one from " + + "the supported list"); + } + Boolean verify = false; + String str = (String) list.get(0); + String encoding = (String) list.get(1); + + if (list.size() == 3) { + verify = (Boolean)list.get(2); + } + if (StringUtils.isEmpty(str) || StringUtils.isEmpty(encoding)) { + return null; + } + + Encodings enc = null; + try { + enc = Encodings.valueOf(encoding.toUpperCase()); + } catch (IllegalArgumentException iae) { + throw new IllegalStateException(String.format("Encoding %s not supported", encoding), iae); + } + return enc.decode(str, verify); + } + } + + @Stellar(name = "ENCODE", + description = "Encodes the passed string with the provided encoding, " + + " must be one of the encodings returned from LIST_SUPPORTED_ENCODINGS", + params = {"string - the string to encode", + "encoding - the encoding to use, must be one of encodings returned from " + + "LIST_SUPPORTED_ENCODINGS" + }, + returns = "The encoded string or null on error" + ) + public static class Encode extends BaseStellarFunction { + + @Override + public Object apply(List<Object> list) { + if (list.size() != 2 && list.size() != 3) { + throw new IllegalStateException( + "ENCODE expects two or three args: [string, encoding] where encoding is one from " + + "the supported list"); + } + String str = (String) list.get(0); + String encoding = (String) list.get(1); + + if (StringUtils.isEmpty(str) || StringUtils.isEmpty(encoding)) { + return null; + } + + Encodings enc = null; + try { + enc = Encodings.valueOf(encoding.toUpperCase()); + } catch (IllegalArgumentException iae) { + throw new IllegalStateException(String.format("Encoding %s not supported", encoding), iae); + } + return enc.encode(str); + } + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/encoding/EncodingsTest.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/encoding/EncodingsTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/encoding/EncodingsTest.java new file mode 100644 index 0000000..59896cc --- /dev/null +++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/common/encoding/EncodingsTest.java @@ -0,0 +1,104 @@ +/** + * 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.stellar.common.encoding; + +import org.junit.Assert; +import org.junit.Test; + +public class EncodingsTest { + + public static final String STRING_FIXTURE = "Hello World"; + public static final String STRING_FIXTURE_PLUS_NULL = "Hello World\0"; + public static final String BASE32HEX_FIXTURE = "91IMOR3F41BMUSJCCG======"; + public static final String BASE32_FIXTURE = "JBSWY3DPEBLW64TMMQ======"; + public static final String BASE64_FIXTURE = "SGVsbG8gV29ybGQ="; + public static final String BINARY_FIXTURE = "0110010001101100011100100110111101010111001000000110111101101100011011000110010101001000"; + public static final String HEX_FIXTURE = "48656c6c6f20576f726c64"; + + @Test + public void is() throws Exception { + + // base32 + Assert.assertTrue(Encodings.BASE32.is(BASE32_FIXTURE)); + Assert.assertFalse(Encodings.BASE32.is(STRING_FIXTURE)); + + // base32 hex + Assert.assertTrue(Encodings.BASE32HEX.is(BASE32HEX_FIXTURE)); + Assert.assertFalse(Encodings.BASE32HEX.is(STRING_FIXTURE)); + + // base 64 + Assert.assertTrue(Encodings.BASE64.is(BASE64_FIXTURE)); + Assert.assertFalse(Encodings.BASE64.is(STRING_FIXTURE + "\0")); + + // binary + Assert.assertTrue(Encodings.BINARY.is(BINARY_FIXTURE)); + Assert.assertFalse(Encodings.BINARY.is(STRING_FIXTURE)); + + // hex + Assert.assertTrue(Encodings.HEX.is(HEX_FIXTURE)); + Assert.assertFalse(Encodings.HEX.is("AAA")); + } + + @Test + public void decode() throws Exception { + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32.decode(BASE32_FIXTURE)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32HEX.decode(BASE32HEX_FIXTURE)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE64.decode(BASE64_FIXTURE)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BINARY.decode(BINARY_FIXTURE)); + Assert.assertEquals(STRING_FIXTURE,Encodings.HEX.decode(HEX_FIXTURE)); + + // these codecs will just decode away... and return garbage without verification + Assert.assertNotEquals(STRING_FIXTURE,Encodings.BASE32.decode(STRING_FIXTURE)); + Assert.assertNotEquals(STRING_FIXTURE,Encodings.BASE32HEX.decode(STRING_FIXTURE)); + Assert.assertNotEquals(STRING_FIXTURE,Encodings.BASE64.decode(STRING_FIXTURE)); + + // these codecs will fail to decode and return the original string without + // verification + Assert.assertEquals(STRING_FIXTURE,Encodings.BINARY.decode(STRING_FIXTURE)); + Assert.assertEquals(STRING_FIXTURE,Encodings.HEX.decode(STRING_FIXTURE)); + } + + @Test + public void decodeWithVerify() throws Exception { + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32.decode(BASE32_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32HEX.decode(BASE32HEX_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE64.decode(BASE64_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BINARY.decode(BINARY_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.HEX.decode(HEX_FIXTURE,true)); + + // with verification, we will get back the original string + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32.decode(STRING_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BASE32HEX.decode(STRING_FIXTURE,true)); + // if the string IS coincidentally compatable with base64, then it will decode away + Assert.assertNotEquals(STRING_FIXTURE,Encodings.BASE64.decode(STRING_FIXTURE,true)); + // if the string would fail... then we get the original + Assert.assertEquals(STRING_FIXTURE + "\0",Encodings.BASE64.decode(STRING_FIXTURE + "\0",true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.BINARY.decode(STRING_FIXTURE,true)); + Assert.assertEquals(STRING_FIXTURE,Encodings.HEX.decode(STRING_FIXTURE,true)); + } + + @Test + public void testEncode() throws Exception{ + Assert.assertEquals(BASE32_FIXTURE,Encodings.BASE32.encode(STRING_FIXTURE)); + Assert.assertEquals(BASE32HEX_FIXTURE,Encodings.BASE32HEX.encode(STRING_FIXTURE)); + Assert.assertEquals(BASE64_FIXTURE,Encodings.BASE64.encode(STRING_FIXTURE)); + Assert.assertEquals(BINARY_FIXTURE,Encodings.BINARY.encode(STRING_FIXTURE)); + Assert.assertEquals(HEX_FIXTURE,Encodings.HEX.encode(STRING_FIXTURE)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java index 871055a..06edb12 100644 --- a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java +++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/BasicStellarTest.java @@ -104,8 +104,6 @@ public class BasicStellarTest { Stellar annotation = clazz.getAnnotation(Stellar.class); Assert.assertFalse("Must specify a name for " + clazz.getName(),StringUtils.isEmpty(annotation.name())); Assert.assertFalse("Must specify a description annotation for " + clazz.getName(),StringUtils.isEmpty(annotation.description())); - Assert.assertTrue("Must specify a non-empty params for " + clazz.getName(), annotation.params().length > 0); - Assert.assertTrue("Must specify a non-empty params for " + clazz.getName(), StringUtils.isNoneEmpty(annotation.params())); Assert.assertFalse("Must specify a returns annotation for " + clazz.getName(), StringUtils.isEmpty(annotation.returns())); } } http://git-wip-us.apache.org/repos/asf/metron/blob/e206f250/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/EncodingFunctionsTest.java ---------------------------------------------------------------------- diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/EncodingFunctionsTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/EncodingFunctionsTest.java new file mode 100644 index 0000000..ca544aa --- /dev/null +++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/EncodingFunctionsTest.java @@ -0,0 +1,125 @@ +/** + * 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.stellar.dsl.functions; + +import static org.apache.metron.stellar.common.encoding.EncodingsTest.BASE32HEX_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.BASE32_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.BASE64_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.BINARY_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.HEX_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.STRING_FIXTURE; +import static org.apache.metron.stellar.common.encoding.EncodingsTest.STRING_FIXTURE_PLUS_NULL; +import static org.apache.metron.stellar.common.utils.StellarProcessorUtils.run; +import static org.apache.metron.stellar.common.utils.StellarProcessorUtils.runPredicate; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.collections4.ListUtils; +import org.apache.metron.stellar.common.encoding.Encodings; +import org.junit.Assert; +import org.junit.Test; + +public class EncodingFunctionsTest { + + private static final Map<String, Object> variableMap = new HashMap<String, Object>() {{ + put("BASE32HEX_FIXTURE","91IMOR3F41BMUSJCCG======"); + put("BASE32_FIXTURE" , "JBSWY3DPEBLW64TMMQ======\r\n"); + put("BASE64_FIXTURE" , "SGVsbG8gV29ybGQ="); + put("BINARY_FIXTURE" , "0110010001101100011100100110111101010111001000000110111101101100011011000110010101001000"); + put("HEX_FIXTURE" , "48656c6c6f20576f726c64"); + put("STRING_FIXTURE", STRING_FIXTURE); + put("STRING_FIXTURE_PLUS_NULL", STRING_FIXTURE_PLUS_NULL); + + }}; + + @Test + public void testSupportedEncodingsList() throws Exception{ + Object ret = run("GET_SUPPORTED_ENCODINGS()", new HashMap()); + Assert.assertTrue(ret instanceof List ); + List<String> list = (List<String>)ret; + List<String> expected = new ArrayList<>(Arrays.asList("BASE32","BASE32HEX","BASE64","BINARY","HEX")); + Assert.assertTrue(ListUtils.isEqualList(expected,list)); + } + + @Test + public void testEncodingIs() throws Exception{ + Assert.assertTrue(runPredicate("IS_ENCODING(BASE32_FIXTURE,'BASE32')", v -> variableMap.get(v))); + Assert.assertFalse(runPredicate("IS_ENCODING(STRING_FIXTURE,'BASE32')", v -> variableMap.get(v))); + Assert.assertTrue(runPredicate("IS_ENCODING(BASE32HEX_FIXTURE,'BASE32HEX')", v -> variableMap.get(v))); + Assert.assertFalse(runPredicate("IS_ENCODING(STRING_FIXTURE,'BASE32HEX')", v -> variableMap.get(v))); + Assert.assertTrue(runPredicate("IS_ENCODING(BASE64_FIXTURE,'BASE64')", v -> variableMap.get(v))); + Assert.assertFalse(runPredicate("IS_ENCODING(STRING_FIXTURE_PLUS_NULL,'BASE64')", v -> variableMap.get(v))); + Assert.assertTrue(runPredicate("IS_ENCODING(BINARY_FIXTURE,'BINARY')", v -> variableMap.get(v))); + Assert.assertFalse(runPredicate("IS_ENCODING(STRING_FIXTURE,'BINARY')", v -> variableMap.get(v))); + Assert.assertTrue(runPredicate("IS_ENCODING(HEX_FIXTURE,'HEX')", v -> variableMap.get(v))); + Assert.assertFalse(runPredicate("IS_ENCODING(STRING_FIXTURE,'HEX')", v -> variableMap.get(v))); + } + + @Test + public void testDecode() throws Exception { + Assert.assertEquals(STRING_FIXTURE,run("DECODE(BASE32_FIXTURE,'BASE32')",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BASE32HEX_FIXTURE,'BASE32HEX')",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BASE64_FIXTURE,'BASE64')",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BINARY_FIXTURE,'BINARY')",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(HEX_FIXTURE,'HEX')",variableMap)); + + // these codecs will just decode away... and return garbage without verification + Assert.assertNotEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE32')",variableMap)); + Assert.assertNotEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE32HEX')",variableMap)); + Assert.assertNotEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE64')",variableMap)); + + // these codecs will fail to decode and return the original string without + // verification + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BINARY')",variableMap)); + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE, 'HEX')", variableMap)); + } + + @Test + public void testDecodeWithVerify() throws Exception { + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BASE32_FIXTURE,'BASE32',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BASE32HEX_FIXTURE,'BASE32HEX',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BASE64_FIXTURE,'BASE64',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(BINARY_FIXTURE,'BINARY',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE, run("DECODE(HEX_FIXTURE,'HEX',true)",variableMap)); + + + + // with verification, we will get back the original string + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE32',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE32HEX',true)",variableMap)); + // if the string IS coincidentally compatable with base64, then it will decode away + Assert.assertNotEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BASE64',true)",variableMap)); + // if the string would fail... then we get the original + Assert.assertEquals(STRING_FIXTURE_PLUS_NULL,run("DECODE(STRING_FIXTURE_PLUS_NULL,'BASE64',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'BINARY',true)",variableMap)); + Assert.assertEquals(STRING_FIXTURE,run("DECODE(STRING_FIXTURE,'HEX',true)",variableMap)); + } + + @Test + public void testEncode() throws Exception { + Assert.assertEquals(BASE32_FIXTURE,run("ENCODE(STRING_FIXTURE,'BASE32')",variableMap)); + Assert.assertEquals(BASE32HEX_FIXTURE, run("ENCODE(STRING_FIXTURE,'BASE32HEX')",variableMap)); + Assert.assertEquals(BASE64_FIXTURE, run("ENCODE(STRING_FIXTURE,'BASE64')",variableMap)); + Assert.assertEquals(BINARY_FIXTURE, run("ENCODE(STRING_FIXTURE,'BINARY')",variableMap)); + Assert.assertEquals(HEX_FIXTURE, run("ENCODE(STRING_FIXTURE,'HEX')",variableMap)); + } +} \ No newline at end of file