|
19 | 19 | require 'bigdecimal'
|
20 | 20 | require 'activesupport/json_encoder'
|
21 | 21 | require 'base64'
|
22 |
| -begin |
23 |
| - require 'jar-dependencies' |
24 |
| - require_jar( 'com.amazonaws', 'aws-java-sdk-dynamodb', '1.10.10' ) |
25 |
| - require_jar( 'com.amazonaws', 'dynamodb-import-export-tool', '1.0.0' ) |
26 |
| -end |
| 22 | + |
| 23 | +require "logstash-input-dynamodb_jars" |
27 | 24 | java_import "com.fasterxml.jackson.databind.ObjectMapper"
|
28 | 25 | java_import "com.amazonaws.services.dynamodbv2.model.AttributeValue"
|
29 | 26 | java_import "com.amazonaws.dynamodb.bootstrap.AttributeValueMixIn"
|
30 | 27 |
|
31 |
| -class DynamoDBLogParser |
| 28 | +module Logstash |
| 29 | + module Inputs |
| 30 | + module DynamoDB |
| 31 | + class DynamoDBLogParser |
32 | 32 |
|
33 |
| - MAX_NUMBER_OF_BYTES_FOR_NUMBER = 21; |
| 33 | + MAX_NUMBER_OF_BYTES_FOR_NUMBER = 21; |
34 | 34 |
|
35 |
| - def initialize(view_type, log_format, key_schema, region) |
36 |
| - @view_type = view_type |
37 |
| - @log_format = log_format |
38 |
| - @mapper ||= ObjectMapper.new() |
39 |
| - @mapper.setSerializationInclusion(JsonInclude::Include::NON_NULL) |
40 |
| - @mapper.addMixInAnnotations(AttributeValue, AttributeValueMixIn); |
41 |
| - @key_schema = key_schema |
42 |
| - ActiveSupport.encode_big_decimal_as_string = false |
43 |
| - @hash_template = Hash.new |
44 |
| - @hash_template["eventID"] = "0" |
45 |
| - @hash_template["eventName"] = "INSERT" |
46 |
| - @hash_template["eventVersion"] = "1.0" |
47 |
| - @hash_template["eventSource"] = "aws:dynamodb" |
48 |
| - @hash_template["awsRegion"] = region |
49 |
| - end |
| 35 | + def initialize(view_type, log_format, key_schema, region) |
| 36 | + @view_type = view_type |
| 37 | + @log_format = log_format |
| 38 | + @mapper ||= ObjectMapper.new() |
| 39 | + @mapper.setSerializationInclusion(JsonInclude::Include::NON_NULL) |
| 40 | + @mapper.addMixInAnnotations(AttributeValue, AttributeValueMixIn); |
| 41 | + @key_schema = key_schema |
| 42 | + ActiveSupport.encode_big_decimal_as_string = false |
| 43 | + @hash_template = Hash.new |
| 44 | + @hash_template["eventID"] = "0" |
| 45 | + @hash_template["eventName"] = "INSERT" |
| 46 | + @hash_template["eventVersion"] = "1.0" |
| 47 | + @hash_template["eventSource"] = "aws:dynamodb" |
| 48 | + @hash_template["awsRegion"] = region |
| 49 | + end |
50 | 50 |
|
51 |
| - public |
52 |
| - def parse_scan(log, new_image_size) |
53 |
| - data_hash = JSON.parse(@mapper.writeValueAsString(log)) |
| 51 | + public |
| 52 | + def parse_scan(log, new_image_size) |
| 53 | + data_hash = JSON.parse(@mapper.writeValueAsString(log)) |
54 | 54 |
|
55 |
| - @hash_template["dynamodb"] = Hash.new |
56 |
| - @hash_template["dynamodb"]["keys"] = Hash.new |
57 |
| - size_bytes = calculate_key_size_in_bytes(log) |
58 |
| - @key_schema.each { |x| |
59 |
| - @hash_template["dynamodb"]["keys"][x] = data_hash[x] |
60 |
| - } |
61 |
| - unless @view_type == "keys_only" |
62 |
| - size_bytes += new_image_size |
63 |
| - @hash_template["dynamodb"]["newImage"] = data_hash |
64 |
| - end |
65 |
| - @hash_template["dynamodb"]["sequenceNumber"] = "0" |
66 |
| - @hash_template["dynamodb"]["sizeBytes"] = size_bytes |
67 |
| - @hash_template["dynamodb"]["streamViewType"] = @view_type.upcase |
| 55 | + @hash_template["dynamodb"] = Hash.new |
| 56 | + @hash_template["dynamodb"]["keys"] = Hash.new |
| 57 | + size_bytes = calculate_key_size_in_bytes(log) |
| 58 | + @key_schema.each { |x| |
| 59 | + @hash_template["dynamodb"]["keys"][x] = data_hash[x] |
| 60 | + } |
| 61 | + unless @view_type == "keys_only" |
| 62 | + size_bytes += new_image_size |
| 63 | + @hash_template["dynamodb"]["newImage"] = data_hash |
| 64 | + end |
| 65 | + @hash_template["dynamodb"]["sequenceNumber"] = "0" |
| 66 | + @hash_template["dynamodb"]["sizeBytes"] = size_bytes |
| 67 | + @hash_template["dynamodb"]["streamViewType"] = @view_type.upcase |
68 | 68 |
|
69 |
| - return parse_view_type(@hash_template) |
70 |
| - end |
| 69 | + return parse_view_type(@hash_template) |
| 70 | + end |
71 | 71 |
|
72 |
| - public |
73 |
| - def parse_stream(log) |
74 |
| - return parse_view_type(JSON.parse(@mapper.writeValueAsString(log))["internalObject"]) |
75 |
| - end |
| 72 | + public |
| 73 | + def parse_stream(log) |
| 74 | + return parse_view_type(JSON.parse(@mapper.writeValueAsString(log))["internalObject"]) |
| 75 | + end |
76 | 76 |
|
77 |
| - private |
78 |
| - def calculate_key_size_in_bytes(record) |
79 |
| - key_size = 0 |
80 |
| - @key_schema.each { |x| |
81 |
| - key_size += x.length |
82 |
| - value = record.get(x) |
83 |
| - if not value.getB().nil? |
84 |
| - b = value.getB(); |
85 |
| - key_size += Base64.decode64(b).length |
86 |
| - elsif not value.getS().nil? |
87 |
| - s = value.getS(); |
88 |
| - key_size += s.length; |
89 |
| - elsif not value.getN().nil? |
90 |
| - key_size += MAX_NUMBER_OF_BYTES_FOR_NUMBER; |
91 |
| - end |
92 |
| - } |
93 |
| - return key_size |
94 |
| - end |
| 77 | + private |
| 78 | + def calculate_key_size_in_bytes(record) |
| 79 | + key_size = 0 |
| 80 | + @key_schema.each { |x| |
| 81 | + key_size += x.length |
| 82 | + value = record.get(x) |
| 83 | + if !(value.getB().nil?) |
| 84 | + b = value.getB(); |
| 85 | + key_size += Base64.decode64(b).length |
| 86 | + elsif !(value.getS().nil?) |
| 87 | + s = value.getS(); |
| 88 | + key_size += s.length; |
| 89 | + elsif !(value.getN().nil?) |
| 90 | + key_size += MAX_NUMBER_OF_BYTES_FOR_NUMBER; |
| 91 | + end |
| 92 | + } |
| 93 | + return key_size |
| 94 | + end |
95 | 95 |
|
96 |
| - private |
97 |
| - def parse_view_type(hash) |
98 |
| - if @log_format == LogStash::Inputs::DynamoDB::LF_PLAIN |
99 |
| - return hash.to_json |
100 |
| - end |
101 |
| - case @view_type |
102 |
| - when LogStash::Inputs::DynamoDB::VT_KEYS_ONLY |
103 |
| - return parse_format(hash["dynamodb"]["keys"]) |
104 |
| - when LogStash::Inputs::DynamoDB::VT_OLD_IMAGE |
105 |
| - return parse_format(hash["dynamodb"]["oldImage"]) |
106 |
| - when LogStash::Inputs::DynamoDB::VT_NEW_IMAGE |
107 |
| - return parse_format(hash["dynamodb"]["newImage"]) #check new and old, dynamodb. |
108 |
| - end |
109 |
| - end |
| 96 | + private |
| 97 | + def parse_view_type(hash) |
| 98 | + if @log_format == LogStash::Inputs::DynamoDB::LF_PLAIN |
| 99 | + return hash.to_json |
| 100 | + end |
| 101 | + case @view_type |
| 102 | + when LogStash::Inputs::DynamoDB::VT_KEYS_ONLY |
| 103 | + return parse_format(hash["dynamodb"]["keys"]) |
| 104 | + when LogStash::Inputs::DynamoDB::VT_OLD_IMAGE |
| 105 | + return parse_format(hash["dynamodb"]["oldImage"]) |
| 106 | + when LogStash::Inputs::DynamoDB::VT_NEW_IMAGE |
| 107 | + return parse_format(hash["dynamodb"]["newImage"]) #check new and old, dynamodb. |
| 108 | + end |
| 109 | + end |
110 | 110 |
|
111 |
| - private |
112 |
| - def parse_format(hash) |
113 |
| - if @log_format == LogStash::Inputs::DynamoDB::LF_DYNAMODB |
114 |
| - return hash.to_json |
115 |
| - else |
116 |
| - return dynamodb_to_json(hash) |
117 |
| - end |
118 |
| - end |
| 111 | + private |
| 112 | + def parse_format(hash) |
| 113 | + if @log_format == LogStash::Inputs::DynamoDB::LF_DYNAMODB |
| 114 | + return hash.to_json |
| 115 | + else |
| 116 | + return dynamodb_to_json(hash) |
| 117 | + end |
| 118 | + end |
119 | 119 |
|
120 |
| - private |
121 |
| - def dynamodb_to_json(hash) |
122 |
| - return formatAttributeValueMap(hash).to_json |
123 |
| - end |
| 120 | + private |
| 121 | + def dynamodb_to_json(hash) |
| 122 | + return formatAttributeValueMap(hash).to_json |
| 123 | + end |
124 | 124 |
|
125 |
| - private |
126 |
| - def formatAttributeValueMap(hash) |
127 |
| - keys_to_delete = [] |
128 |
| - hash.each do |k, v| |
129 |
| - dynamodb_key = v.keys.first |
130 |
| - dynamodb_value = v.values.first |
131 |
| - if @log_format == LogStash::Inputs::DynamoDB::LF_JSON_NO_BIN and (dynamodb_key == "BS" or dynamodb_key == "B") |
132 |
| - keys_to_delete.push(k) # remove binary values and binary sets |
133 |
| - next |
134 |
| - end |
135 |
| - hash[k] = formatAttributeValue(v.keys.first, v.values.first) |
136 |
| - end |
137 |
| - keys_to_delete.each {|key| hash.delete(key)} |
138 |
| - return hash |
139 |
| - end |
| 125 | + private |
| 126 | + def formatAttributeValueMap(hash) |
| 127 | + keys_to_delete = [] |
| 128 | + hash.each do |k, v| |
| 129 | + dynamodb_key = v.keys.first |
| 130 | + dynamodb_value = v.values.first |
| 131 | + if @log_format == LogStash::Inputs::DynamoDB::LF_JSON_NO_BIN and (dynamodb_key == "BS" or dynamodb_key == "B") |
| 132 | + keys_to_delete.push(k) # remove binary values and binary sets |
| 133 | + next |
| 134 | + end |
| 135 | + hash[k] = formatAttributeValue(v.keys.first, v.values.first) |
| 136 | + end |
| 137 | + keys_to_delete.each {|key| hash.delete(key)} |
| 138 | + return hash |
| 139 | + end |
| 140 | + |
| 141 | + private |
| 142 | + def formatAttributeValue(key, value) |
| 143 | + case key |
| 144 | + when "M" |
| 145 | + formatAttributeValueMap(value) |
| 146 | + when "L" |
| 147 | + value.map! do |v| |
| 148 | + v = formatAttributeValue(v.keys.first, v.values.first) |
| 149 | + end |
| 150 | + when "NS","SS","BS" |
| 151 | + value.map! do |v| |
| 152 | + v = formatAttributeValue(key[0], v) |
| 153 | + end |
| 154 | + when "N" |
| 155 | + BigDecimal.new(value) |
| 156 | + when "NULL" |
| 157 | + nil |
| 158 | + else |
| 159 | + value |
| 160 | + end |
| 161 | + end |
140 | 162 |
|
141 |
| - private |
142 |
| - def formatAttributeValue(key, value) |
143 |
| - case key |
144 |
| - when "M" |
145 |
| - formatAttributeValueMap(value) |
146 |
| - when "L" |
147 |
| - value.map! do |v| |
148 |
| - v = formatAttributeValue(v.keys.first, v.values.first) |
149 |
| - end |
150 |
| - when "NS","SS","BS" |
151 |
| - value.map! do |v| |
152 |
| - v = formatAttributeValue(key[0], v) |
153 | 163 | end
|
154 |
| - return value |
155 |
| - when "N" |
156 |
| - return BigDecimal.new(value) |
157 |
| - when "NULL" |
158 |
| - return nil |
159 |
| - else |
160 |
| - return value |
161 | 164 | end
|
162 | 165 | end
|
163 |
| - |
164 | 166 | end
|
0 commit comments