From c3a360485699c9c0f887d72111dddc773a630b4c Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Tue, 14 Jan 2020 21:18:23 +0100 Subject: [PATCH 01/37] [Filebeat] Fixes for NetFlow v9 devices from various vendors (#15449) - Allow for zero scope fields in options template NetFlow v9 spec allows for options templates that contain no scope fields. The netflow input was treating this case as an error and discarding the template, but that is only applicable to IPFIX. - Use additional fields to populate bytes/pkt counters Some devices out there (Cisco NSEL) use fields 231/232 as bytes counters, when those are supposed to be layer 4 payload counters. This updates the ECS fields populator to use those fields when the expected ones are not found. - Support a classId of 32 bits While the spec mandates a classId of 8 bits, some Cisco ASA devices actually use a 32 bit version of this field. This patches the field to allow up to 32-bit integers and updates the index pattern to use `long` for the `netflow.class_id` field. - Add more fields from v9 Cisco devices Fixes #14212 --- CHANGELOG.next.asciidoc | 3 + filebeat/docs/fields.asciidoc | 2 +- .../filebeat/input/netflow/_meta/fields.yml | 2 +- x-pack/filebeat/input/netflow/convert.go | 32 +- .../input/netflow/decoder/fields/cisco.csv | 14 + .../input/netflow/decoder/fields/doc.go | 1 + .../fields/ipfix-information-elements.csv | 8 +- .../netflow/decoder/fields/zfields_cisco.go | 14 + .../netflow/decoder/fields/zfields_ipfix.go | 2 +- .../input/netflow/decoder/ipfix/decoder.go | 1 + .../netflow/decoder/template/template.go | 5 +- .../netflow/decoder/template/template_test.go | 8 + .../input/netflow/decoder/v9/decoder.go | 3 +- x-pack/filebeat/input/netflow/fields.go | 2 +- .../golden/Netflow-9-Cisco-ASA-2.golden.json | 45 ++ .../Netflow-9-Huawei-Netstream.golden.json | 1 + .../golden/ipfix_cisco.pcap.golden.json | 580 +++++++++++++++++- 17 files changed, 671 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index dbb12aa738b..5346ed8e976 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -230,6 +230,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix SSL config in input.yml for Filebeat httpjson input in the MISP module. {pull}14767[14767] - Check content-type when creating new reader in s3 input. {pull}15252[15252] {issue}15225[15225] - Fix session reset detection and a crash in Netflow input. {pull}14904[14904] +- netflow: Allow for options templates without scope fields. {pull}15449[15449] +- netflow: Fix bytes/packets counters on some devices (NSEL and Netstream). {pull}15449[15449] +- netflow: Fix compatibility with some Cisco devices by changing the field `class_id` from short to long. {pull}15449[15449] *Heartbeat* diff --git a/filebeat/docs/fields.asciidoc b/filebeat/docs/fields.asciidoc index df71321f4f6..98dc6ff13e3 100644 --- a/filebeat/docs/fields.asciidoc +++ b/filebeat/docs/fields.asciidoc @@ -17090,7 +17090,7 @@ type: long *`netflow.class_id`*:: + -- -type: short +type: long -- diff --git a/x-pack/filebeat/input/netflow/_meta/fields.yml b/x-pack/filebeat/input/netflow/_meta/fields.yml index d88ab6d5ab9..f5a4c0823d5 100644 --- a/x-pack/filebeat/input/netflow/_meta/fields.yml +++ b/x-pack/filebeat/input/netflow/_meta/fields.yml @@ -194,7 +194,7 @@ type: long - name: class_id - type: short + type: long - name: minimum_ttl type: short diff --git a/x-pack/filebeat/input/netflow/convert.go b/x-pack/filebeat/input/netflow/convert.go index dbb02c6803a..64d264f57ea 100644 --- a/x-pack/filebeat/input/netflow/convert.go +++ b/x-pack/filebeat/input/netflow/convert.go @@ -245,22 +245,10 @@ func flowToBeatEvent(flow record.Record) (event beat.Event) { ecsNetwork["transport"] = IPProtocol(proto).String() ecsNetwork["iana_number"] = proto } - countBytes, hasBytes := getKeyUint64(flow.Fields, "octetDeltaCount") - if !hasBytes { - countBytes, hasBytes = getKeyUint64(flow.Fields, "octetTotalCount") - } - countPkts, hasPkts := getKeyUint64(flow.Fields, "packetDeltaCount") - if !hasPkts { - countPkts, hasPkts = getKeyUint64(flow.Fields, "packetTotalCount") - } - revBytes, hasRevBytes := getKeyUint64(flow.Fields, "reverseOctetDeltaCount") - if !hasRevBytes { - revBytes, hasRevBytes = getKeyUint64(flow.Fields, "reverseOctetTotalCount") - } - revPkts, hasRevPkts := getKeyUint64(flow.Fields, "reversePacketDeltaCount") - if !hasRevPkts { - revPkts, hasRevPkts = getKeyUint64(flow.Fields, "reversePacketTotalCount") - } + countBytes, hasBytes := getKeyUint64Alternatives(flow.Fields, "octetDeltaCount", "octetTotalCount", "initiatorOctets") + countPkts, hasPkts := getKeyUint64Alternatives(flow.Fields, "packetDeltaCount", "packetTotalCount", "initiatorPackets") + revBytes, hasRevBytes := getKeyUint64Alternatives(flow.Fields, "reverseOctetDeltaCount", "reverseOctetTotalCount", "responderOctets") + revPkts, hasRevPkts := getKeyUint64Alternatives(flow.Fields, "reversePacketDeltaCount", "reversePacketTotalCount", "responderPackets") if hasRevBytes { ecsDest["bytes"] = revBytes @@ -337,6 +325,18 @@ func getKeyUint64(dict record.Map, key string) (value uint64, found bool) { return } +func getKeyUint64Alternatives(dict record.Map, keys ...string) (value uint64, found bool) { + var iface interface{} + for _, key := range keys { + if iface, found = dict[key]; found { + if value, found = iface.(uint64); found { + return + } + } + } + return +} + func getKeyString(dict record.Map, key string) (value string, found bool) { iface, found := dict[key] if !found { diff --git a/x-pack/filebeat/input/netflow/decoder/fields/cisco.csv b/x-pack/filebeat/input/netflow/decoder/fields/cisco.csv index 653a275d06f..65e5f9b5b75 100644 --- a/x-pack/filebeat/input/netflow/decoder/fields/cisco.csv +++ b/x-pack/filebeat/input/netflow/decoder/fields/cisco.csv @@ -270,6 +270,20 @@ netscalerUnknown465,5951,465,unsigned32 ingressAclID,0,33000,aclid egressAclID,0,33001,aclid fwExtEvent,0,33002,unsigned16 +fwEventLevel,0,33003,unsigned32 +fwEventLevelID,0,33004,unsigned32 +fwConfiguredValue,0,33005,unsigned32 +fwCtsSrcSGT,0,34000,unsigned32 +fwExtEventAlt,0,35001,unsigned32 +fwBlackoutSecs,0,35004,unsigned32 +fwHalfOpenHigh,0,35005,unsigned32 +fwHalfOpenRate,0,35006,unsigned32 +fwZonePairID,0,35007,unsigned32 +fwMaxSessions,0,35008,unsigned32 +fwZonePairName,0,35009,unsigned32 +fwExtEventDesc,0,35010,string +fwSummaryPktCount,0,35011,unsigned32 +fwHalfOpenCount,0,35012,unsigned32 username,0,40000,string XlateSourceAddressIPV4,0,40001,ipv4Address XlateDestinationAddressIPV4,0,40002,ipv4Address diff --git a/x-pack/filebeat/input/netflow/decoder/fields/doc.go b/x-pack/filebeat/input/netflow/decoder/fields/doc.go index cf6ddacf37f..d3ae43e4521 100644 --- a/x-pack/filebeat/input/netflow/decoder/fields/doc.go +++ b/x-pack/filebeat/input/netflow/decoder/fields/doc.go @@ -8,3 +8,4 @@ package fields //go:generate go run gen.go -output zfields_cert.go -export CertFields --column-pen=1 --column-id=2 --column-name=3 --column-type=4 cert_pen6871.csv //go:generate go run gen.go -output zfields_cisco.go -export CiscoFields --column-pen=2 --column-id=3 --column-name=1 --column-type=4 cisco.csv //go:generate go run gen.go -output zfields_assorted.go -export AssortedFields --column-pen=1 --column-id=2 --column-name=3 --column-type=4 assorted.csv +//go:generate go fmt diff --git a/x-pack/filebeat/input/netflow/decoder/fields/ipfix-information-elements.csv b/x-pack/filebeat/input/netflow/decoder/fields/ipfix-information-elements.csv index 974d95dbce3..c2c5143f96b 100644 --- a/x-pack/filebeat/input/netflow/decoder/fields/ipfix-information-elements.csv +++ b/x-pack/filebeat/input/netflow/decoder/fields/ipfix-information-elements.csv @@ -1,3 +1,9 @@ +; WARNING: This is an edited version of the original IANA document! +; +; Changes +; ======= +; 2020-01-14 - @adriansr: Change field 51 (classId) from unsigned8 to unsigned32 +; ;ElementID,Name,Abstract Data Type,Data Type Semantics,Status,Description,Units,Range,References,Requester,Revision,Date 0,Reserved,,,,,,,,[RFC5102],,2013-02-18 1,octetDeltaCount,unsigned64,deltaCounter,current,"The number of octets since the previous report (if any) @@ -335,7 +341,7 @@ Sampling. Use with samplerRandomInterval.",,,,[RFC7270],0,2014-04-04 50,samplerRandomInterval,unsigned32,quantity,deprecated,"Deprecated in favor of 305 samplingPacketInterval. Packet interval at which to sample -- in case of random sampling. Used in connection with the samplerMode 0x02 (random sampling) value.",,,,[RFC7270],0,2014-04-04 -51,classId,unsigned8,identifier,deprecated,"Deprecated in favor of 302 selectorId. Characterizes the traffic +51,classId,unsigned32,identifier,deprecated,"Deprecated in favor of 302 selectorId. Characterizes the traffic class, i.e., QoS treatment.",,,,[RFC7270],0,2014-04-04 52,minimumTTL,unsigned8,,current,Minimum TTL value observed for any packet in this Flow.,hops,,"See [RFC791] for the definition of the IPv4 Time to Live field. diff --git a/x-pack/filebeat/input/netflow/decoder/fields/zfields_cisco.go b/x-pack/filebeat/input/netflow/decoder/fields/zfields_cisco.go index ae37275d528..7d1abc1b62c 100644 --- a/x-pack/filebeat/input/netflow/decoder/fields/zfields_cisco.go +++ b/x-pack/filebeat/input/netflow/decoder/fields/zfields_cisco.go @@ -280,6 +280,20 @@ var CiscoFields = FieldDict{ Key{EnterpriseID: 0, FieldID: 33000}: {Name: "ingressAclID", Decoder: ACLID}, Key{EnterpriseID: 0, FieldID: 33001}: {Name: "egressAclID", Decoder: ACLID}, Key{EnterpriseID: 0, FieldID: 33002}: {Name: "fwExtEvent", Decoder: Unsigned16}, + Key{EnterpriseID: 0, FieldID: 33003}: {Name: "fwEventLevel", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 33004}: {Name: "fwEventLevelID", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 33005}: {Name: "fwConfiguredValue", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 34000}: {Name: "fwCtsSrcSGT", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35001}: {Name: "fwExtEventAlt", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35004}: {Name: "fwBlackoutSecs", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35005}: {Name: "fwHalfOpenHigh", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35006}: {Name: "fwHalfOpenRate", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35007}: {Name: "fwZonePairID", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35008}: {Name: "fwMaxSessions", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35009}: {Name: "fwZonePairName", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35010}: {Name: "fwExtEventDesc", Decoder: String}, + Key{EnterpriseID: 0, FieldID: 35011}: {Name: "fwSummaryPktCount", Decoder: Unsigned32}, + Key{EnterpriseID: 0, FieldID: 35012}: {Name: "fwHalfOpenCount", Decoder: Unsigned32}, Key{EnterpriseID: 0, FieldID: 40000}: {Name: "username", Decoder: String}, Key{EnterpriseID: 0, FieldID: 40001}: {Name: "XlateSourceAddressIPV4", Decoder: Ipv4Address}, Key{EnterpriseID: 0, FieldID: 40002}: {Name: "XlateDestinationAddressIPV4", Decoder: Ipv4Address}, diff --git a/x-pack/filebeat/input/netflow/decoder/fields/zfields_ipfix.go b/x-pack/filebeat/input/netflow/decoder/fields/zfields_ipfix.go index 1a47ad39c26..045ec5c3499 100644 --- a/x-pack/filebeat/input/netflow/decoder/fields/zfields_ipfix.go +++ b/x-pack/filebeat/input/netflow/decoder/fields/zfields_ipfix.go @@ -59,7 +59,7 @@ var IpfixFields = FieldDict{ Key{EnterpriseID: 0, FieldID: 48}: {Name: "samplerId", Decoder: Unsigned8}, Key{EnterpriseID: 0, FieldID: 49}: {Name: "samplerMode", Decoder: Unsigned8}, Key{EnterpriseID: 0, FieldID: 50}: {Name: "samplerRandomInterval", Decoder: Unsigned32}, - Key{EnterpriseID: 0, FieldID: 51}: {Name: "classId", Decoder: Unsigned8}, + Key{EnterpriseID: 0, FieldID: 51}: {Name: "classId", Decoder: Unsigned32}, Key{EnterpriseID: 0, FieldID: 52}: {Name: "minimumTTL", Decoder: Unsigned8}, Key{EnterpriseID: 0, FieldID: 53}: {Name: "maximumTTL", Decoder: Unsigned8}, Key{EnterpriseID: 0, FieldID: 54}: {Name: "fragmentIdentification", Decoder: Unsigned32}, diff --git a/x-pack/filebeat/input/netflow/decoder/ipfix/decoder.go b/x-pack/filebeat/input/netflow/decoder/ipfix/decoder.go index 66483775521..9c0252cb9c4 100644 --- a/x-pack/filebeat/input/netflow/decoder/ipfix/decoder.go +++ b/x-pack/filebeat/input/netflow/decoder/ipfix/decoder.go @@ -108,6 +108,7 @@ func (d DecoderIPFIX) ReadOptionsTemplateFlowSet(buf *bytes.Buffer) (templates [ } template.ID = tID template.ScopeFields = scopeCount + template.IsOptions = true templates = append(templates, &template) } return templates, nil diff --git a/x-pack/filebeat/input/netflow/decoder/template/template.go b/x-pack/filebeat/input/netflow/decoder/template/template.go index dc42bcc26f0..e04dc93cfe3 100644 --- a/x-pack/filebeat/input/netflow/decoder/template/template.go +++ b/x-pack/filebeat/input/netflow/decoder/template/template.go @@ -29,6 +29,9 @@ type Template struct { Length int VariableLength bool ScopeFields int + // IsOptions signals that this is an options template. Previously + // ScopeFields>0 was used for this, but that's unreliable under v9. + IsOptions bool } type FieldTemplate struct { @@ -84,7 +87,7 @@ func (t *Template) Apply(data *bytes.Buffer, n int) ([]record.Record, error) { } } makeFn := t.makeFlow - if t.ScopeFields > 0 { + if t.IsOptions { makeFn = t.makeOptions } events := make([]record.Record, 0, alloc) diff --git a/x-pack/filebeat/input/netflow/decoder/template/template_test.go b/x-pack/filebeat/input/netflow/decoder/template/template_test.go index 6ab22766170..882756dc9a2 100644 --- a/x-pack/filebeat/input/netflow/decoder/template/template_test.go +++ b/x-pack/filebeat/input/netflow/decoder/template/template_test.go @@ -313,6 +313,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 7, ScopeFields: 1, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: 2, Info: &fields.Field{Name: "destinationTransportPort", Decoder: fields.Unsigned16}}, @@ -343,6 +344,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 7, ScopeFields: 2, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: 2, Info: &fields.Field{Name: "destinationTransportPort", Decoder: fields.Unsigned16}}, @@ -386,6 +388,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 7, ScopeFields: 3, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: 2, Info: &fields.Field{Name: "destinationTransportPort", Decoder: fields.Unsigned16}}, @@ -415,6 +418,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 7, ScopeFields: 1, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: 2, Info: &fields.Field{Name: "destinationTransportPort", Decoder: fields.Unsigned16}}, @@ -446,6 +450,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 7, ScopeFields: 2, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: 2, Info: &fields.Field{Name: "destinationTransportPort", Decoder: fields.Unsigned16}}, @@ -489,6 +494,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 6, ScopeFields: 1, + IsOptions: true, VariableLength: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, @@ -522,6 +528,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { record: Template{ Length: 6, ScopeFields: 1, + IsOptions: true, VariableLength: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, @@ -571,6 +578,7 @@ func TestOptionsTemplate_Apply(t *testing.T) { Length: 6, VariableLength: true, ScopeFields: 2, + IsOptions: true, Fields: []FieldTemplate{ {Length: 4, Info: &fields.Field{Name: "sourceIPv4Address", Decoder: fields.Ipv4Address}}, {Length: VariableLength, Info: &fields.Field{Name: "vpnIdentifier", Decoder: fields.OctetArray}}, diff --git a/x-pack/filebeat/input/netflow/decoder/v9/decoder.go b/x-pack/filebeat/input/netflow/decoder/v9/decoder.go index f5972684652..6b4fc9be8be 100644 --- a/x-pack/filebeat/input/netflow/decoder/v9/decoder.go +++ b/x-pack/filebeat/input/netflow/decoder/v9/decoder.go @@ -184,7 +184,7 @@ func (d DecoderV9) ReadOptionsTemplateFlowSet(buf *bytes.Buffer) (templates []*t if buf.Len() < int(length) { return nil, io.EOF } - if scopeLen == 0 || scopeLen&3 != 0 || optsLen&3 != 0 { + if (scopeLen+optsLen) == 0 || scopeLen&3 != 0 || optsLen&3 != 0 { return nil, fmt.Errorf("bad length for options template. scope=%d options=%d", scopeLen, optsLen) } template, err := ReadFields(d, buf, (scopeLen+optsLen)/4) @@ -193,6 +193,7 @@ func (d DecoderV9) ReadOptionsTemplateFlowSet(buf *bytes.Buffer) (templates []*t } template.ID = tID template.ScopeFields = scopeLen / 4 + template.IsOptions = true templates = append(templates, &template) } return templates, nil diff --git a/x-pack/filebeat/input/netflow/fields.go b/x-pack/filebeat/input/netflow/fields.go index e5593617924..92226a14406 100644 --- a/x-pack/filebeat/input/netflow/fields.go +++ b/x-pack/filebeat/input/netflow/fields.go @@ -19,5 +19,5 @@ func init() { // AssetNetflow returns asset data. // This is the base64 encoded gzipped contents of input/netflow. func AssetNetflow() string { - return "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" + return "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" } diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA-2.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA-2.golden.json index 05db1239579..dc73be6acf3 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA-2.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Cisco-ASA-2.golden.json @@ -6,6 +6,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 763, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -51,6 +52,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 844, "community_id": "1:XaNCBbXLPvRPq4YmlYj+3C8LbyE=", "direction": "unknown", "iana_number": 6, @@ -60,6 +62,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.2", "locality": "private", "port": 61775 @@ -73,6 +76,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 6207, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -118,6 +122,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 6288, "community_id": "1:ApLoUXZvqTmJTtS6gao5Sqg0kgQ=", "direction": "unknown", "iana_number": 6, @@ -127,6 +132,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.2", "locality": "private", "port": 61776 @@ -140,6 +146,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 6207, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -185,6 +192,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 6288, "community_id": "1:ApLoUXZvqTmJTtS6gao5Sqg0kgQ=", "direction": "unknown", "iana_number": 6, @@ -194,6 +202,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.2", "locality": "private", "port": 61776 @@ -207,6 +216,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 9075, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -252,6 +262,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 9156, "community_id": "1:64faG50xtU56JMAADXSJ0Lro5iE=", "direction": "unknown", "iana_number": 6, @@ -261,6 +272,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.1", "locality": "private", "port": 56635 @@ -274,6 +286,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 9075, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -319,6 +332,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 9156, "community_id": "1:64faG50xtU56JMAADXSJ0Lro5iE=", "direction": "unknown", "iana_number": 6, @@ -328,6 +342,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.1", "locality": "private", "port": 56635 @@ -341,6 +356,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 5536, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -386,6 +402,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 5617, "community_id": "1:8hx//bjfEFu4sYomYN8bh9DeMaQ=", "direction": "unknown", "iana_number": 6, @@ -395,6 +412,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.2", "locality": "private", "port": 61773 @@ -408,6 +426,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 5536, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -453,6 +472,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 5617, "community_id": "1:8hx//bjfEFu4sYomYN8bh9DeMaQ=", "direction": "unknown", "iana_number": 6, @@ -462,6 +482,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 81, "ip": "192.168.0.2", "locality": "private", "port": 61773 @@ -543,6 +564,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14179, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -588,6 +610,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14248, "community_id": "1:IZ8RrSqt8oeb2F2Rp9296zm54bc=", "direction": "unknown", "iana_number": 6, @@ -597,6 +620,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.1", "locality": "private", "port": 56649 @@ -610,6 +634,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14179, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -655,6 +680,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14248, "community_id": "1:IZ8RrSqt8oeb2F2Rp9296zm54bc=", "direction": "unknown", "iana_number": 6, @@ -664,6 +690,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.1", "locality": "private", "port": 56649 @@ -745,6 +772,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14178, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -790,6 +818,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14247, "community_id": "1:E1vNamQGw5X+X+vT1g7ui6Nc3O0=", "direction": "unknown", "iana_number": 6, @@ -799,6 +828,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.2", "locality": "private", "port": 61777 @@ -812,6 +842,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14178, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -857,6 +888,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14247, "community_id": "1:E1vNamQGw5X+X+vT1g7ui6Nc3O0=", "direction": "unknown", "iana_number": 6, @@ -866,6 +898,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.2", "locality": "private", "port": 61777 @@ -947,6 +980,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 881, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -992,6 +1026,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 956, "community_id": "1:pkwcoe/zjCLerUgj+HGAwwt4wV8=", "direction": "unknown", "iana_number": 6, @@ -1001,6 +1036,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 75, "ip": "192.168.0.1", "locality": "private", "port": 56650 @@ -1014,6 +1050,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 881, "ip": "192.168.0.17", "locality": "private", "port": 80 @@ -1059,6 +1096,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 956, "community_id": "1:pkwcoe/zjCLerUgj+HGAwwt4wV8=", "direction": "unknown", "iana_number": 6, @@ -1068,6 +1106,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 75, "ip": "192.168.0.1", "locality": "private", "port": 56650 @@ -1149,6 +1188,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14178, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -1194,6 +1234,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14247, "community_id": "1:35/w0D/WO1QvBp8O+Vd95Nb+tt4=", "direction": "unknown", "iana_number": 6, @@ -1203,6 +1244,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.1", "locality": "private", "port": 56651 @@ -1216,6 +1258,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 14178, "ip": "192.168.0.18", "locality": "private", "port": 80 @@ -1261,6 +1304,7 @@ "type": "netflow_flow" }, "network": { + "bytes": 14247, "community_id": "1:35/w0D/WO1QvBp8O+Vd95Nb+tt4=", "direction": "unknown", "iana_number": 6, @@ -1270,6 +1314,7 @@ "ip": "192.0.2.1" }, "source": { + "bytes": 69, "ip": "192.168.0.1", "locality": "private", "port": 56651 diff --git a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Huawei-Netstream.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Huawei-Netstream.golden.json index 223e3bc161d..99db67a6ed8 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Huawei-Netstream.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/Netflow-9-Huawei-Netstream.golden.json @@ -6,6 +6,7 @@ "Meta": null, "Fields": { "destination": { + "bytes": 0, "ip": "10.111.112.204", "locality": "private", "port": 2598 diff --git a/x-pack/filebeat/input/netflow/testdata/golden/ipfix_cisco.pcap.golden.json b/x-pack/filebeat/input/netflow/testdata/golden/ipfix_cisco.pcap.golden.json index 08f146cddcb..2ff196e7950 100644 --- a/x-pack/filebeat/input/netflow/testdata/golden/ipfix_cisco.pcap.golden.json +++ b/x-pack/filebeat/input/netflow/testdata/golden/ipfix_cisco.pcap.golden.json @@ -5,9 +5,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 719, + "packets": 5 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -56,13 +64,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 719, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 5, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 719, + "packets": 5 } }, "Private": null, @@ -72,9 +90,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1477, + "packets": 6 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -123,13 +149,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 1477, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 6, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 1477, + "packets": 6 } }, "Private": null, @@ -139,9 +175,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1, + "packets": 1 + }, + "destination": { + "bytes": 0, + "packets": 1 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -190,13 +234,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 1, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 2, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 1 + }, + "source": { + "bytes": 1, + "packets": 1 } }, "Private": null, @@ -206,9 +260,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 108580, + "packets": 79 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -257,13 +319,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 108580, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 79, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 108580, + "packets": 79 } }, "Private": null, @@ -273,9 +345,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 342, + "packets": 5 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -324,13 +404,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 342, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 5, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 342, + "packets": 5 } }, "Private": null, @@ -340,9 +430,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1851, + "packets": 17 + }, + "destination": { + "bytes": 9437, + "packets": 18 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -391,13 +489,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 11288, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 35, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 9437, + "packets": 18 + }, + "source": { + "bytes": 1851, + "packets": 17 } }, "Private": null, @@ -407,9 +515,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 51480, + "packets": 39 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -458,13 +574,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 51480, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 39, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 51480, + "packets": 39 } }, "Private": null, @@ -474,9 +600,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 5135, + "packets": 55 + }, + "destination": { + "bytes": 36894, + "packets": 47 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -525,13 +659,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 42029, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 102, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 36894, + "packets": 47 + }, + "source": { + "bytes": 5135, + "packets": 55 } }, "Private": null, @@ -541,9 +685,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 6533, + "packets": 14 + }, + "destination": { + "bytes": 6400, + "packets": 20 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -592,13 +744,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 12933, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 34, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 6400, + "packets": 20 + }, + "source": { + "bytes": 6533, + "packets": 14 } }, "Private": null, @@ -608,9 +770,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 5684, + "packets": 491 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -659,13 +829,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 5684, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 491, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 5684, + "packets": 491 } }, "Private": null, @@ -675,9 +855,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 4965, + "packets": 13 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -726,13 +914,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 4965, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 13, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 4965, + "packets": 13 } }, "Private": null, @@ -742,9 +940,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 138, + "packets": 4 + }, + "destination": { + "bytes": 0, + "packets": 2 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -793,13 +999,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 138, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 6, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 2 + }, + "source": { + "bytes": 138, + "packets": 4 } }, "Private": null, @@ -809,9 +1025,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1, + "packets": 1 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -860,13 +1084,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 1, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 1, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 1, + "packets": 1 } }, "Private": null, @@ -876,9 +1110,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 6079, + "packets": 10 + }, + "destination": { + "bytes": 1571, + "packets": 13 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -927,13 +1169,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 7650, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 23, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 1571, + "packets": 13 + }, + "source": { + "bytes": 6079, + "packets": 10 } }, "Private": null, @@ -943,9 +1195,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 2807, + "packets": 6 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -994,13 +1254,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 2807, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 6, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 2807, + "packets": 6 } }, "Private": null, @@ -1010,9 +1280,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 0, + "packets": 1 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1061,13 +1339,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 0, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 1, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 0, + "packets": 1 } }, "Private": null, @@ -1077,9 +1365,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1877, + "packets": 11 + }, + "destination": { + "bytes": 3409, + "packets": 7 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1128,13 +1424,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 5286, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 18, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 3409, + "packets": 7 + }, + "source": { + "bytes": 1877, + "packets": 11 } }, "Private": null, @@ -1144,9 +1450,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 2255, + "packets": 7 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1195,13 +1509,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 2255, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 7, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 2255, + "packets": 7 } }, "Private": null, @@ -1211,9 +1535,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 538, + "packets": 5 + }, + "destination": { + "bytes": 0, + "packets": 0 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1262,13 +1594,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 538, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 5, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 0 + }, + "source": { + "bytes": 538, + "packets": 5 } }, "Private": null, @@ -1278,9 +1620,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1487, + "packets": 21 + }, + "destination": { + "bytes": 6305, + "packets": 15 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1329,13 +1679,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 7792, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 36, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 6305, + "packets": 15 + }, + "source": { + "bytes": 1487, + "packets": 21 } }, "Private": null, @@ -1345,9 +1705,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 3110, + "packets": 7 + }, + "destination": { + "bytes": 1973, + "packets": 10 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1396,13 +1764,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 5083, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 17, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 1973, + "packets": 10 + }, + "source": { + "bytes": 3110, + "packets": 7 } }, "Private": null, @@ -1412,9 +1790,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 2, + "packets": 4 + }, + "destination": { + "bytes": 2, + "packets": 4 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1463,13 +1849,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 4, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 8, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 2, + "packets": 4 + }, + "source": { + "bytes": 2, + "packets": 4 } }, "Private": null, @@ -1479,9 +1875,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 2, + "packets": 2 + }, + "destination": { + "bytes": 0, + "packets": 2 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1530,13 +1934,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 2, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 4, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 2 + }, + "source": { + "bytes": 2, + "packets": 2 } }, "Private": null, @@ -1546,9 +1960,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 0, + "packets": 4 + }, + "destination": { + "bytes": 0, + "packets": 2 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1597,13 +2019,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 0, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 6, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 2 + }, + "source": { + "bytes": 0, + "packets": 4 } }, "Private": null, @@ -1613,9 +2045,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 1005, + "packets": 4 + }, + "destination": { + "bytes": 174, + "packets": 3 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1664,13 +2104,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 1179, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 7, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 174, + "packets": 3 + }, + "source": { + "bytes": 1005, + "packets": 4 } }, "Private": null, @@ -1680,9 +2130,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 138, + "packets": 4 + }, + "destination": { + "bytes": 0, + "packets": 2 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1731,13 +2189,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 138, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 6, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 2 + }, + "source": { + "bytes": 138, + "packets": 4 } }, "Private": null, @@ -1747,9 +2215,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 31, + "packets": 2 + }, + "destination": { + "bytes": 0, + "packets": 1 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1798,13 +2274,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 31, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 3, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 0, + "packets": 1 + }, + "source": { + "bytes": 31, + "packets": 2 } }, "Private": null, @@ -1814,9 +2300,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 13482, + "packets": 17 + }, + "destination": { + "bytes": 8989, + "packets": 19 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1865,13 +2359,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 22471, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 36, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 8989, + "packets": 19 + }, + "source": { + "bytes": 13482, + "packets": 17 } }, "Private": null, @@ -1881,9 +2385,17 @@ "Timestamp": "2018-07-03T10:47:00Z", "Meta": null, "Fields": { + "client": { + "bytes": 28373, + "packets": 133 + }, + "destination": { + "bytes": 233345, + "packets": 236 + }, "event": { "action": "netflow_flow", - "category": "network_traffic", + "category": "network_session", "created": "2018-07-03T10:47:00Z", "kind": "event" }, @@ -1932,13 +2444,23 @@ "waasoptimization_segment": 16 }, "network": { + "bytes": 261718, "community_id": "1:idwO/QHAjbcGlF1bfQE9dPuu7T0=", "direction": "unknown", "iana_number": 6, + "packets": 369, "transport": "tcp" }, "observer": { "ip": "10.101.255.2" + }, + "server": { + "bytes": 233345, + "packets": 236 + }, + "source": { + "bytes": 28373, + "packets": 133 } }, "Private": null, From bf8cb740c1ece982aeb337e799b987b667181b49 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 14 Jan 2020 13:06:14 -0800 Subject: [PATCH 02/37] update settings for `decode_csv_fields` (#15249) (#15550) Co-authored-by: DeDe Morton Co-authored-by: Sophia Xu --- .../decode_csv_fields/docs/decode_csv_fields.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc b/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc index c402bae48c5..718f9551bd2 100644 --- a/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc +++ b/libbeat/processors/decode_csv_fields/docs/decode_csv_fields.asciidoc @@ -13,7 +13,7 @@ processors: - decode_csv_fields: fields: message: decoded.csv - separator: , + separator: "," ignore_missing: false overwrite_keys: true trim_leading_space: false From 8bf06e309843cb8d4688848be9b96118f704c21d Mon Sep 17 00:00:00 2001 From: Brandon Morelli Date: Tue, 14 Jan 2020 13:21:45 -0800 Subject: [PATCH 03/37] docs: updates to output config (#15272) --- libbeat/outputs/console/docs/console.asciidoc | 22 +++++++++------- libbeat/outputs/fileout/docs/fileout.asciidoc | 9 +++++-- libbeat/outputs/kafka/docs/kafka.asciidoc | 13 ++++++++-- .../outputs/logstash/docs/logstash.asciidoc | 7 +++++- libbeat/outputs/redis/docs/redis.asciidoc | 25 ++++--------------- 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/libbeat/outputs/console/docs/console.asciidoc b/libbeat/outputs/console/docs/console.asciidoc index 102eb13c7c8..71f03f0f740 100644 --- a/libbeat/outputs/console/docs/console.asciidoc +++ b/libbeat/outputs/console/docs/console.asciidoc @@ -7,6 +7,11 @@ The Console output writes events in JSON format to stdout. +To use this output, edit the {beatname_uc} configuration file to disable the {es} +output by commenting it out, and enable the console output by adding `output.console`. + +Example configuration: + [source,yaml] ------------------------------------------------------------------------------ output.console: @@ -15,7 +20,14 @@ output.console: ==== Configuration options -You can specify the following options in the `console` section of the +{beatname_lc}.yml+ config file: +You can specify the following `output.console` options in the +{beatname_lc}.yml+ config file: + +===== `enabled` + +The enabled config is a boolean setting to enable or disable the output. If set +to false, the output is disabled. + +The default value is `true`. ===== `pretty` @@ -27,14 +39,6 @@ Output codec configuration. If the `codec` section is missing, events will be js See <> for more information. - -===== `enabled` - -The enabled config is a boolean setting to enable or disable the output. If set -to false, the output is disabled. - -The default value is true. - ===== `bulk_max_size` The maximum number of events to buffer internally during publishing. The default is 2048. diff --git a/libbeat/outputs/fileout/docs/fileout.asciidoc b/libbeat/outputs/fileout/docs/fileout.asciidoc index aa0af27bb66..6922f8f7142 100644 --- a/libbeat/outputs/fileout/docs/fileout.asciidoc +++ b/libbeat/outputs/fileout/docs/fileout.asciidoc @@ -9,6 +9,11 @@ The File output dumps the transactions into a file where each transaction is in Currently, this output is used for testing, but it can be used as input for Logstash. +To use this output, edit the {beatname_uc} configuration file to disable the {es} +output by commenting it out, and enable the file output by adding `output.file`. + +Example configuration: + ["source","yaml",subs="attributes"] ------------------------------------------------------------------------------ output.file: @@ -21,14 +26,14 @@ output.file: ==== Configuration options -You can specify the following options in the `file` section of the +{beatname_lc}.yml+ config file: +You can specify the following `output.file` options in the +{beatname_lc}.yml+ config file: ===== `enabled` The enabled config is a boolean setting to enable or disable the output. If set to false, the output is disabled. -The default value is true. +The default value is `true`. [[path]] ===== `path` diff --git a/libbeat/outputs/kafka/docs/kafka.asciidoc b/libbeat/outputs/kafka/docs/kafka.asciidoc index ce09e019ad8..48e79a4fd51 100644 --- a/libbeat/outputs/kafka/docs/kafka.asciidoc +++ b/libbeat/outputs/kafka/docs/kafka.asciidoc @@ -5,7 +5,11 @@ Kafka ++++ -The Kafka output sends the events to Apache Kafka. +The Kafka output sends events to Apache Kafka. + +To use this output, edit the {beatname_uc} configuration file to disable the {es} +output by commenting it out, and enable the Kafka output by uncommenting the +Kafka section. Example configuration: @@ -42,7 +46,12 @@ You can specify the following options in the `kafka` section of the +{beatname_l The `enabled` config is a boolean setting to enable or disable the output. If set to false, the output is disabled. -The default value is true. +ifndef::apm-server[] +The default value is `true`. +endif::[] +ifdef::apm-server[] +The default value is `false`. +endif::[] ===== `hosts` diff --git a/libbeat/outputs/logstash/docs/logstash.asciidoc b/libbeat/outputs/logstash/docs/logstash.asciidoc index be90bb4e029..30ed5c2d105 100644 --- a/libbeat/outputs/logstash/docs/logstash.asciidoc +++ b/libbeat/outputs/logstash/docs/logstash.asciidoc @@ -24,7 +24,7 @@ the {stack} getting started tutorial. Also see the documentation for the If you want to use {ls} to perform additional processing on the data collected by {beatname_uc}, you need to configure {beatname_uc} to use {ls}. -To do this, you edit the {beatname_uc} configuration file to disable the {es} +To do this, edit the {beatname_uc} configuration file to disable the {es} output by commenting it out and enable the {ls} output by uncommenting the logstash section: @@ -224,7 +224,12 @@ You can specify the following options in the `logstash` section of the The enabled config is a boolean setting to enable or disable the output. If set to false, the output is disabled. +ifndef::apm-server[] The default value is `true`. +endif::[] +ifdef::apm-server[] +The default value is `false`. +endif::[] [[hosts]] ===== `hosts` diff --git a/libbeat/outputs/redis/docs/redis.asciidoc b/libbeat/outputs/redis/docs/redis.asciidoc index 0d7dde88bfc..e5fdd29eb6b 100644 --- a/libbeat/outputs/redis/docs/redis.asciidoc +++ b/libbeat/outputs/redis/docs/redis.asciidoc @@ -11,6 +11,9 @@ The Redis output inserts the events into a Redis list or a Redis channel. This output plugin is compatible with the https://www.elastic.co/guide/en/logstash/current/plugins-inputs-redis.html[Redis input plugin] for Logstash. +To use this output, edit the {beatname_uc} configuration file to disable the {es} +output by commenting it out, and enable the Redis output by adding `output.redis`. + Example configuration: ["source","yaml",subs="attributes"] @@ -29,14 +32,14 @@ This output works with Redis 3.2.4. ==== Configuration options -You can specify the following options in the `redis` section of the +{beatname_lc}.yml+ config file: +You can specify the following `output.redis` options in the +{beatname_lc}.yml+ config file: ===== `enabled` The enabled config is a boolean setting to enable or disable the output. If set to false, the output is disabled. -The default value is true. +The default value is `true`. ===== `hosts` @@ -143,24 +146,6 @@ Output codec configuration. If the `codec` section is missing, events will be js See <> for more information. -===== `host_topology` - -deprecated:[5.0.0] - -The Redis host to connect to when using topology map support. Topology map support is disabled if this option is not set. - -===== `password_topology` - -deprecated:[5.0.0] - -The password to use for authenticating with the Redis topology server. The default is no authentication. - -===== `db_topology` - -deprecated:[5.0.0] - -The Redis database number where the topology information is stored. The default is 1. - ===== `worker` The number of workers to use for each host configured to publish events to Redis. Use this setting along with the From 2228af4835068db988c9571562f575313db70c80 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Tue, 14 Jan 2020 14:45:52 -0700 Subject: [PATCH 04/37] [Filebeat] Handle error message in handleS3Objects function (#15545) * Handle error message in handleS3Objects function * remove s3Context.Fail and use setError and done instead * Add changelog --- CHANGELOG.next.asciidoc | 1 + x-pack/filebeat/input/s3/input.go | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 5346ed8e976..e29223605c6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -230,6 +230,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix SSL config in input.yml for Filebeat httpjson input in the MISP module. {pull}14767[14767] - Check content-type when creating new reader in s3 input. {pull}15252[15252] {issue}15225[15225] - Fix session reset detection and a crash in Netflow input. {pull}14904[14904] +- Handle errors in handleS3Objects function and add more debug messages for s3 input. {pull}15545[15545] - netflow: Allow for options templates without scope fields. {pull}15449[15449] - netflow: Fix bytes/packets counters on some devices (NSEL and Netstream). {pull}15449[15449] - netflow: Fix compatibility with some Cisco devices by changing the field `class_id` from short to long. {pull}15449[15449] diff --git a/x-pack/filebeat/input/s3/input.go b/x-pack/filebeat/input/s3/input.go index 3ef20ee1041..eef16d918fa 100644 --- a/x-pack/filebeat/input/s3/input.go +++ b/x-pack/filebeat/input/s3/input.go @@ -232,6 +232,7 @@ func (p *s3Input) Wait() { func (p *s3Input) processor(queueURL string, messages []sqs.Message, visibilityTimeout int64, svcS3 s3iface.ClientAPI, svcSQS sqsiface.ClientAPI) { var wg sync.WaitGroup numMessages := len(messages) + p.logger.Debugf("Processing %v messages", numMessages) wg.Add(numMessages * 2) // process messages received from sqs @@ -251,14 +252,16 @@ func (p *s3Input) processMessage(svcS3 s3iface.ClientAPI, message sqs.Message, w p.logger.Error(errors.Wrap(err, "handleSQSMessage failed")) return } + p.logger.Debugf("handleSQSMessage succeed and returned %v sets of S3 log info", len(s3Infos)) // read from s3 object and create event for each log line err = p.handleS3Objects(svcS3, s3Infos, errC) if err != nil { err = errors.Wrap(err, "handleS3Objects failed") p.logger.Error(err) - errC <- err + return } + p.logger.Debugf("handleS3Objects succeed") } func (p *s3Input) processorKeepAlive(svcSQS sqsiface.ClientAPI, message sqs.Message, queueURL string, visibilityTimeout int64, wg *sync.WaitGroup, errC chan error) { @@ -288,13 +291,14 @@ func (p *s3Input) processorKeepAlive(svcSQS sqsiface.ClientAPI, message sqs.Mess } return case <-time.After(time.Duration(visibilityTimeout/2) * time.Second): + p.logger.Warn("Half of the set visibilityTimeout passed, visibility timeout needs to be updated") // If half of the set visibilityTimeout passed and this is // still ongoing, then change visibility timeout. err := p.changeVisibilityTimeout(queueURL, visibilityTimeout, svcSQS, message.ReceiptHandle) if err != nil { p.logger.Error(errors.Wrap(err, "change message visibility failed")) } - p.logger.Infof("Message visibility timeout updated to %v", visibilityTimeout) + p.logger.Infof("Message visibility timeout updated to %v seconds", visibilityTimeout) } } } @@ -370,8 +374,11 @@ func (p *s3Input) handleS3Objects(svc s3iface.ClientAPI, s3Infos []s3Info, errC // read from s3 object reader, err := p.newS3BucketReader(svc, s3Info) if err != nil { - return errors.Wrap(err, "newS3BucketReader failed") + err = errors.Wrap(err, "newS3BucketReader failed") + s3Context.setError(err) + return err } + if reader == nil { continue } @@ -382,7 +389,7 @@ func (p *s3Input) handleS3Objects(svc s3iface.ClientAPI, s3Infos []s3Info, errC err := p.decodeJSONWithKey(decoder, objectHash, s3Info, s3Context) if err != nil { err = errors.Wrapf(err, "decodeJSONWithKey failed for %v", s3Info.key) - s3Context.Fail(err) + s3Context.setError(err) return err } return nil @@ -403,12 +410,14 @@ func (p *s3Input) handleS3Objects(svc s3iface.ClientAPI, s3Infos []s3Info, errC err = p.forwardEvent(event) if err != nil { err = errors.Wrapf(err, "forwardEvent failed for %v", s3Info.key) - s3Context.Fail(err) + s3Context.setError(err) return err } return nil } else if err != nil { - return errors.Wrapf(err, "ReadString failed for %v", s3Info.key) + err = errors.Wrapf(err, "ReadString failed for %v", s3Info.key) + s3Context.setError(err) + return err } // create event per log line @@ -417,7 +426,7 @@ func (p *s3Input) handleS3Objects(svc s3iface.ClientAPI, s3Infos []s3Info, errC err = p.forwardEvent(event) if err != nil { err = errors.Wrapf(err, "forwardEvent failed for %v", s3Info.key) - s3Context.Fail(err) + s3Context.setError(err) return err } } @@ -610,11 +619,6 @@ func s3ObjectHash(s3Info s3Info) string { return prefix[:10] } -func (c *s3Context) Fail(err error) { - c.setError(err) - c.done() -} - func (c *s3Context) setError(err error) { // only care about the last error for now // TODO: add "Typed" error to error for context From 9d70efde031fc964b43b24b12622d3f688acdd54 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Wed, 15 Jan 2020 00:43:32 +0100 Subject: [PATCH 05/37] Fix use of wrong fields in Cisco ASA dashboard (#15553) This dashboard wasn't updated after a couple of fields were renamed. Fixes: #15420 --- CHANGELOG.next.asciidoc | 1 + .../cisco/_meta/kibana/7/dashboard/Filebeat-Cisco-ASA.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e29223605c6..e3e7d99c6e1 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -234,6 +234,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - netflow: Allow for options templates without scope fields. {pull}15449[15449] - netflow: Fix bytes/packets counters on some devices (NSEL and Netstream). {pull}15449[15449] - netflow: Fix compatibility with some Cisco devices by changing the field `class_id` from short to long. {pull}15449[15449] +- Fixed dashboard for Cisco ASA Firewall. {issue}15420[15420] {pull}15553[15553] *Heartbeat* diff --git a/x-pack/filebeat/module/cisco/_meta/kibana/7/dashboard/Filebeat-Cisco-ASA.json b/x-pack/filebeat/module/cisco/_meta/kibana/7/dashboard/Filebeat-Cisco-ASA.json index 5d50368c9f2..7a585fbf501 100644 --- a/x-pack/filebeat/module/cisco/_meta/kibana/7/dashboard/Filebeat-Cisco-ASA.json +++ b/x-pack/filebeat/module/cisco/_meta/kibana/7/dashboard/Filebeat-Cisco-ASA.json @@ -764,7 +764,7 @@ "id": "2", "params": { "customLabel": "ACL ID", - "field": "cisco.asa.list_id", + "field": "cisco.asa.rule_name", "missingBucket": false, "missingBucketLabel": "Missing", "order": "desc", @@ -878,7 +878,7 @@ "params": { "aggregate": "concat", "customLabel": "Sample message", - "field": "log.original", + "field": "event.original", "size": 1, "sortField": "@timestamp", "sortOrder": "desc" From a3b8d3a218a029f4df41e1befa27ae0b1f402575 Mon Sep 17 00:00:00 2001 From: Blake Rouse Date: Tue, 14 Jan 2020 20:58:47 -0500 Subject: [PATCH 06/37] Add test for publisher spool encode and decode. (#15534) * Add test for publisher queue encode and decode. * Run mage fmt. * Fixes from code review. --- libbeat/publisher/queue/spool/codec_test.go | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 libbeat/publisher/queue/spool/codec_test.go diff --git a/libbeat/publisher/queue/spool/codec_test.go b/libbeat/publisher/queue/spool/codec_test.go new file mode 100644 index 00000000000..3588d3e2f21 --- /dev/null +++ b/libbeat/publisher/queue/spool/codec_test.go @@ -0,0 +1,76 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. 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 spool + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/publisher" +) + +func TestEncodeDecode(t *testing.T) { + tests := map[string]codecID{ + "json": codecJSON, + "ubjson": codecUBJSON, + "cborl": codecCBORL, + } + + fieldTimeStr := "2020-01-14T20:33:23.779Z" + fieldTime, _ := time.Parse(time.RFC3339Nano, fieldTimeStr) + event := publisher.Event{ + Content: beat.Event{ + Timestamp: time.Now().Round(0), + Fields: common.MapStr{ + "time": fieldTime, + "commontime": common.Time(fieldTime), + }, + }, + } + expected := publisher.Event{ + Content: beat.Event{ + Timestamp: event.Content.Timestamp, + Fields: common.MapStr{ + "time": fieldTime.Format(time.RFC3339Nano), + "commontime": common.Time(fieldTime).String(), + }, + }, + } + + for name, codec := range tests { + t.Run(name, func(t *testing.T) { + encoder, err := newEncoder(codec) + assert.NoError(t, err) + + encoded, err := encoder.encode(&event) + assert.NoError(t, err) + + decoder := newDecoder() + decoder.buf = encoded + + observed, err := decoder.Decode() + assert.NoError(t, err) + + assert.Equal(t, expected, observed) + }) + } +} From e0071b599f729cdbf92fb8ebc52b2c559aa00a27 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Wed, 15 Jan 2020 10:15:52 +0100 Subject: [PATCH 07/37] Fix convert processor conversion of string with leading zeros to integer (#15557) The conversion failed when for strings with leading zeroes and a decimal digit 8 or 9, as the underlying runtime function would try to parse that as an octal number. This is fixed by only allowing decimal and hex, which in turns makes the processor more aligned to its Elasticsearch counterpart. Fixes #15513 --- CHANGELOG.next.asciidoc | 1 + libbeat/processors/convert/convert.go | 25 ++++++++++++++++++++-- libbeat/processors/convert/convert_test.go | 19 ++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e3e7d99c6e1..574116773c1 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -151,6 +151,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix bug with potential concurrent reads and writes from event.Meta map by Kafka output. {issue}14542[14542] {pull}14568[14568] - Fix spooling to disk blocking infinitely if the lock file can not be acquired. {pull}15338[15338] - Fix `metricbeat test output` with an ipv6 ES host in the output.hosts. {pull}15368[15368] +- Fix `convert` processor conversion of string to integer with leading zeros. {issue}15513[15513] {pull}15557[15557] *Auditbeat* diff --git a/libbeat/processors/convert/convert.go b/libbeat/processors/convert/convert.go index fbc6b5b3014..887fbdd02a9 100644 --- a/libbeat/processors/convert/convert.go +++ b/libbeat/processors/convert/convert.go @@ -205,7 +205,7 @@ func toString(value interface{}) (string, error) { func toLong(value interface{}) (int64, error) { switch v := value.(type) { case string: - return strconv.ParseInt(v, 0, 64) + return strToInt(v, 64) case int: return int64(v), nil case int8: @@ -238,7 +238,7 @@ func toLong(value interface{}) (int64, error) { func toInteger(value interface{}) (int32, error) { switch v := value.(type) { case string: - i, err := strconv.ParseInt(v, 0, 32) + i, err := strToInt(v, 32) return int32(i), err case int: return int32(v), nil @@ -403,3 +403,24 @@ func cloneValue(value interface{}) interface{} { return value } } + +// strToInt is a helper to interpret a string as either base 10 or base 16. +func strToInt(s string, bitSize int) (int64, error) { + base := 10 + if hasHexPrefix(s) { + // strconv.ParseInt will accept the '0x' or '0X` prefix only when base is 0. + base = 0 + } + return strconv.ParseInt(s, base, bitSize) +} + +func hasHexPrefix(s string) bool { + if len(s) < 3 { + return false + } + a, b := s[0], s[1] + if a == '+' || a == '-' { + a, b = b, s[2] + } + return a == '0' && (b == 'x' || b == 'X') +} diff --git a/libbeat/processors/convert/convert_test.go b/libbeat/processors/convert/convert_test.go index 2469fe1848c..141fafc0f8f 100644 --- a/libbeat/processors/convert/convert_test.go +++ b/libbeat/processors/convert/convert_test.go @@ -276,8 +276,16 @@ var testCases = []testCase{ {Long, nil, nil, true}, {Long, "x", nil, true}, + {Long, "0x", nil, true}, + {Long, "0b1", nil, true}, + {Long, "1x2", nil, true}, {Long, true, nil, true}, {Long, "1", int64(1), false}, + {Long, "-1", int64(-1), false}, + {Long, "017", int64(17), false}, + {Long, "08", int64(8), false}, + {Long, "0X0A", int64(10), false}, + {Long, "-0x12", int64(-18), false}, {Long, int(1), int64(1), false}, {Long, int8(1), int64(1), false}, {Long, int16(1), int64(1), false}, @@ -294,6 +302,17 @@ var testCases = []testCase{ {Integer, nil, nil, true}, {Integer, "x", nil, true}, {Integer, true, nil, true}, + {Integer, "x", nil, true}, + {Integer, "0x", nil, true}, + {Integer, "0b1", nil, true}, + {Integer, "1x2", nil, true}, + {Integer, true, nil, true}, + {Integer, "1", int32(1), false}, + {Integer, "-1", int32(-1), false}, + {Integer, "017", int32(17), false}, + {Integer, "08", int32(8), false}, + {Integer, "0X0A", int32(10), false}, + {Integer, "-0x12", int32(-18), false}, {Integer, "1", int32(1), false}, {Integer, int(1), int32(1), false}, {Integer, int8(1), int32(1), false}, From 2916c07b7a07d53b50d5e8c82c8d8df361fe8875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Wed, 15 Jan 2020 18:58:10 +0100 Subject: [PATCH 08/37] New mage target: generate pkg file to test the manager (#15580) This PR adds a new mage target to Functionbeat named `buildPkgForFunction`. It generates the folder `pkg` with the functions to make testing the manager more comfortable during development. --- CHANGELOG-developer.next.asciidoc | 1 + x-pack/functionbeat/magefile.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG-developer.next.asciidoc b/CHANGELOG-developer.next.asciidoc index db5cf33c5d9..feaa59c5dec 100644 --- a/CHANGELOG-developer.next.asciidoc +++ b/CHANGELOG-developer.next.asciidoc @@ -64,3 +64,4 @@ The list below covers the major changes between 7.0.0-rc2 and master only. - Added a `default_field` option to fields in fields.yml to offer a way to exclude fields from the default_field list. {issue}14262[14262] {pull}14341[14341] - `supported-versions.yml` can be used in metricbeat python system tests to obtain the build args for docker compose builds. {pull}14520[14520] - Fix dropped errors in the tests for the metricbeat Azure module. {pull}13773[13773] +- New mage target for Functionbeat: generate pkg folder to make manager easier. {pull}15580[15880] diff --git a/x-pack/functionbeat/magefile.go b/x-pack/functionbeat/magefile.go index 6a10ee93f30..ab3432c720a 100644 --- a/x-pack/functionbeat/magefile.go +++ b/x-pack/functionbeat/magefile.go @@ -8,6 +8,7 @@ package main import ( "fmt" + "os" "path/filepath" "time" @@ -147,6 +148,36 @@ func GoTestUnit() { mg.Deps(unittest.GoUnitTest) } +// BuildPkgForFunctions creates a folder named pkg and adds functions to it. +// This makes testing the manager more comfortable. +func BuildPkgForFunctions() error { + mg.Deps(Update, Build) + + err := os.MkdirAll("pkg", 700) + if err != nil { + return err + } + + filesToCopy := map[string]string{ + filepath.Join("provider", "aws", "functionbeat-aws"): filepath.Join("pkg", "functionbeat-aws"), + filepath.Join("provider", "gcp", "pubsub", "pubsub.go"): filepath.Join("pkg", "pubsub", "pubsub.go"), + filepath.Join("provider", "gcp", "storage", "storage.go"): filepath.Join("pkg", "storage", "storage.go"), + filepath.Join("provider", "gcp", "build", "pubsub", "vendor"): filepath.Join("pkg", "pubsub", "vendor"), + filepath.Join("provider", "gcp", "build", "storage", "vendor"): filepath.Join("pkg", "storage", "vendor"), + } + for src, dest := range filesToCopy { + c := &devtools.CopyTask{ + Source: src, + Dest: dest, + } + err = c.Execute() + if err != nil { + return err + } + } + return nil +} + // BuildSystemTestBinary build a binary for testing that is instrumented for // testing and measuring code coverage. The binary is only instrumented for // coverage when TEST_COVERAGE=true (default is false). From 3ed9a542ae5414c83e4f5f63c1aab037a1938080 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Thu, 16 Jan 2020 00:34:55 +0100 Subject: [PATCH 09/37] Packetbeat TLS: Replace array fields with keyword (#15597) Use of `type: array` in some fields (which was inconsistent) causes those fields to be excluded from the template. This prevents pointing aliases to those fields, which we need in 7.6+. Setting those fields to `keyword` explicitly so that they are included in the template. Fixes #15588 --- packetbeat/docs/fields.asciidoc | 8 ++++---- packetbeat/protos/tls/_meta/fields.yml | 8 ++++---- packetbeat/protos/tls/fields.go | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packetbeat/docs/fields.asciidoc b/packetbeat/docs/fields.asciidoc index b3686647262..ccb26248d48 100644 --- a/packetbeat/docs/fields.asciidoc +++ b/packetbeat/docs/fields.asciidoc @@ -9407,7 +9407,7 @@ type: keyword The list of compression methods the client supports. See https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml -type: array +type: keyword -- @@ -9538,7 +9538,7 @@ The hello extensions provided by the server. -- Negotiated application layer protocol -type: array +type: keyword -- @@ -9658,7 +9658,7 @@ type: keyword -- Subject Alternative Names for this certificate. -type: array +type: keyword -- @@ -9858,7 +9858,7 @@ type: keyword -- Subject Alternative Names for this certificate. -type: array +type: keyword -- diff --git a/packetbeat/protos/tls/_meta/fields.yml b/packetbeat/protos/tls/_meta/fields.yml index 1537beed838..89f0c0c7b6f 100644 --- a/packetbeat/protos/tls/_meta/fields.yml +++ b/packetbeat/protos/tls/_meta/fields.yml @@ -44,7 +44,7 @@ connection with the client. - name: supported_compression_methods - type: array + type: keyword description: > The list of compression methods the client supports. See https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml @@ -123,7 +123,7 @@ description: The hello extensions provided by the server. fields: - name: application_layer_protocol_negotiation - type: array + type: keyword description: Negotiated application layer protocol - name: session_ticket @@ -185,7 +185,7 @@ The algorithm used for the certificate's signature. - name: alternative_names - type: array + type: keyword description: Subject Alternative Names for this certificate. - name: subject @@ -281,7 +281,7 @@ The algorithm used for the certificate's signature. - name: alternative_names - type: array + type: keyword description: Subject Alternative Names for this certificate. - name: subject diff --git a/packetbeat/protos/tls/fields.go b/packetbeat/protos/tls/fields.go index a750dfdaf93..f25aabd7bf5 100644 --- a/packetbeat/protos/tls/fields.go +++ b/packetbeat/protos/tls/fields.go @@ -32,5 +32,5 @@ func init() { // AssetTls returns asset data. // This is the base64 encoded gzipped contents of protos/tls. func AssetTls() string { - return "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" + return "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" } From cddbd85fbcfb5c29108cd376771e7fcf504dd606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Thu, 16 Jan 2020 13:03:19 +0100 Subject: [PATCH 10/37] Add a pull request template providing valuable information when reviewing a PR (#15388) * Add a PR template that provides valuable information when reviewing a PR * Add CLA check * Fix typo * Address comments during review * SF: Fix typo * Add deprecation as PR type * Make it clear how to strike through in markdown * Add default configuration files to the checklist --- .github/PULL_REQUEST_TEMPLATE.md | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..73feceef13e --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,78 @@ + + +## What does this PR do? + + + +## Why is it important? + + + +## Checklist + + + +- [ ] My code follows the style guidelines of this project +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] I have made corresponding change to the default configuration files +- [ ] I have added tests that prove my fix is effective or that my feature works + +## Author's Checklist + + +- [ ] + +## How to test this PR locally + + + +## Related issues + + +- + +## Use cases + + + +## Screenshots + + + +## Logs + + From 2ed633b6d4e03478a21c9501e4617b913a99e601 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 16 Jan 2020 15:41:12 +0100 Subject: [PATCH 11/37] [Metricbeat] Implement IBM MQ module (#15301) * Modify cockroachdb source * Define testdata * Do not publish ports * Update docs * mage fmt update * Describe containerized environment * Update CHANGELOG.next.asciidoc Co-Authored-By: Chris Mark * Update data.json * Rename image * Update source after review * Filter ibmmq_ metrics * mage check * Fix: mage check * Don't expose port * Rename status to qmgr * Add subscriptions overview dashboard for IBM MQ module * Add calls, messages overview dashboard for IBM MQ module * Add screenshots * Fix: mage check * Fix: CHANGELOG * Add explanation * Fix: mage check Co-authored-by: Chris Mark --- CHANGELOG.next.asciidoc | 2 +- metricbeat/docs/fields.asciidoc | 9 + .../docs/images/metricbeat-ibmmq-calls.png | Bin 0 -> 870253 bytes .../docs/images/metricbeat-ibmmq-messages.png | Bin 0 -> 930108 bytes .../images/metricbeat-ibmmq-subscriptions.png | Bin 0 -> 528065 bytes metricbeat/docs/modules/ibmmq.asciidoc | 90 ++ metricbeat/docs/modules/ibmmq/qmgr.asciidoc | 24 + metricbeat/docs/modules_list.asciidoc | 3 + x-pack/metricbeat/include/list.go | 1 + x-pack/metricbeat/metricbeat.reference.yml | 30 + .../metricbeat/module/ibmmq/_meta/Dockerfile | 11 + .../metricbeat/module/ibmmq/_meta/config.yml | 28 + .../module/ibmmq/_meta/docs.asciidoc | 28 + .../metricbeat/module/ibmmq/_meta/fields.yml | 10 + .../Metricbeat-ibmmq-calls-overview.json | 1219 ++++++++++++++++ .../Metricbeat-ibmmq-messages-overview.json | 1250 +++++++++++++++++ ...tricbeat-ibmmq-subscriptions-overview.json | 752 ++++++++++ .../module/ibmmq/docker-compose.yml | 11 + x-pack/metricbeat/module/ibmmq/fields.go | 23 + x-pack/metricbeat/module/ibmmq/module.yml | 3 + .../module/ibmmq/qmgr/_meta/data.json | 114 ++ .../module/ibmmq/qmgr/_meta/docs.asciidoc | 3 + .../module/ibmmq/qmgr/_meta/fields.yml | 1 + .../ibmmq/qmgr/_meta/testdata/config.yml | 4 + .../ibmmq-status.9.1.4.0-r1-amd64.plain | 180 +++ ...tatus.9.1.4.0-r1-amd64.plain-expected.json | 86 ++ .../metricbeat/module/ibmmq/qmgr/manifest.yml | 6 + .../ibmmq/qmgr/qmgr_integration_test.go | 48 + .../metricbeat/module/ibmmq/qmgr/qmgr_test.go | 32 + x-pack/metricbeat/module/ibmmq/test_ibmmq.py | 35 + .../metricbeat/modules.d/ibmmq.yml.disabled | 31 + 31 files changed, 4033 insertions(+), 1 deletion(-) create mode 100644 metricbeat/docs/images/metricbeat-ibmmq-calls.png create mode 100644 metricbeat/docs/images/metricbeat-ibmmq-messages.png create mode 100644 metricbeat/docs/images/metricbeat-ibmmq-subscriptions.png create mode 100644 metricbeat/docs/modules/ibmmq.asciidoc create mode 100644 metricbeat/docs/modules/ibmmq/qmgr.asciidoc create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/Dockerfile create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/config.yml create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-calls-overview.json create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-messages-overview.json create mode 100644 x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-subscriptions-overview.json create mode 100644 x-pack/metricbeat/module/ibmmq/docker-compose.yml create mode 100644 x-pack/metricbeat/module/ibmmq/fields.go create mode 100644 x-pack/metricbeat/module/ibmmq/module.yml create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/data.json create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/config.yml create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain-expected.json create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/manifest.yml create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/qmgr_integration_test.go create mode 100644 x-pack/metricbeat/module/ibmmq/qmgr/qmgr_test.go create mode 100644 x-pack/metricbeat/module/ibmmq/test_ibmmq.py create mode 100644 x-pack/metricbeat/modules.d/ibmmq.yml.disabled diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 574116773c1..647632f6bfb 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -605,9 +605,9 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add DynamoDB AWS Metricbeat light module {pull}15097[15097] - Release elb module as GA. {pull}15485[15485] - Add a `system/network_summary` metricset {pull}15196[15196] +- Add IBM MQ light-weight Metricbeat module {pull}15301[15301] *Packetbeat* - - Update DNS protocol plugin to produce events with ECS fields for DNS. {issue}13320[13320] {pull}13354[13354] *Functionbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index e8ba36e7e76..d16ff59da4a 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -41,6 +41,7 @@ grouped in the following categories: * <> * <> * <> +* <> * <> * <> * <> @@ -15846,6 +15847,14 @@ json metricset server +[[exported-fields-ibmmq]] +== IBM MQ fields + +IBM MQ module + + + + [[exported-fields-jolokia]] == Jolokia fields diff --git a/metricbeat/docs/images/metricbeat-ibmmq-calls.png b/metricbeat/docs/images/metricbeat-ibmmq-calls.png new file mode 100644 index 0000000000000000000000000000000000000000..27e09c4c6ea322c1c1fb934d3fcb57a937966c82 GIT binary patch literal 870253 zcmeEtRZtyUx9$RhOK^9W;O_1&3zq~!aCe8`E`bmrKyX;NyITSQ0>Rzg-MO9p?{lke z)qOa-_IW%{P)PUc*>lYC*@#qAkwrx!L;`_8sPb}B8o(EF5D0k{0S@>{DU@G32t*E& zmlD_VG(KE{)xt4YfjgCjMLvWUM1W}(tTNED9cL=WpRw=PwmlT9T#8y+DxW3M{WcqW zS0OyeX`$jANVR@YJ9FPL!&!TiCES_D?>Lhl9#BRm>i-BLf~6OOLQ)Ha#{LHS7vI7_ zSL2JV`-%S#TnY&v>n$kq2JT;cn*aMeZ?yuUsF#WV-Lw7YYJuuda0#9+|9YkVTulZR zSgeu%nZ?2Z7K<1De;4b&vy1Wncd`Eab^gDL^$!lk|6Qzqv{<)xQ28@%7B;vzOt|O= z;oBD;xOxx;YFJAgQ&9NTp8cROt*sF5ov6~juZ5>JcPxP2a z><9v={1sn*)BaePg~WP{1@)ikLy#0-WQk| zq_AthE{d8i&xA$%XUci6qVc|Q`hA?OUQOzPE6~iBDR)gwx7U^}1s5j}{x7YXtDZEs$6z`3=7kvn5Dmu-tPe}NoSRQO&pYrko0Y=~m-rdo<7|0u^}(m^>IPxh83 zzjGgV>xafa*sK4aevb|V`#c2FX!}Tj9-wxG@5%4Kl*H2R6?r~*Ef4RBH6t((7C#A1 z8IpW^fw#BOvA(sI#5Y&jyY}_NcCH~7BK6WBKf}!&H> zN9@b)e^S#CXS6koE-zqwahr*uQ~I|%%JgHG367Y8P#do4mI@KpVxAu=fk%1o;ECud zrSYPrsJj;07okH=%)YqLhm?J3bHccSe_bpQ`CTShVl_wFP)eJI7OtaK6@C&b;-r3>o;E{y> z{ujH8&16;8>*eKW!Gq7|SO|@nFD4;@&J&yX#;-tZf$wh#rBVZ8+U}a@k?_$G9v*RcgC*YK z(DBq*C`(fPUx@tQ!A<{f5wJ^;7k0jo5fekdG$U7g4aXsPO_iy`8fTGKH8w{7YT7-1 z3?LIz&=uq@dtty>s`x<0+CmC~OF%J6+CAre2zx7w^!OoYr*fH!?-DhMIw~H;{fGaB zwWsI5_)LsJU+$kfi#@qKmL=YpRBLx=#i`7xRVc|bXi-0p{TLUAxKc|f#0N_{UfYsi zlL>vy;I$t%lR_wQ%DZQ8pqzMd12OoQlts+cYQ*?Y=N>@41^qa+LpOS6zo*??r~iiD zMD_^nupCNZmrgC0#YbWHFIZC_LeQ7n=S~DNFOU5=q8SHy8Cc}a(4r!EB;4;7pXXwU z8mmmV2yK^ZH1|(74+GPF(++$`pLnqY{SdGqq$XB}k02Q?i@t6Zke-3*0wt|65gR>s z9z3r*F`%mll{RLtF5H|r4t*tbD<DZJK;JY`$pnd#LEH=7#9V^n?U>RP8<7kn!Pp zlE#z4=V|>|m;3z2D*r2g1av@6S5UC*>7`ZiGDBY^36a~uw8SC)^TR^6?O46668W1q zD6;XHeK!s(Y7i}_zGysFQ>-f9f6P5}mB-q76Lc`?=BL0#JMa}fkC&vez3m(= zWNvRAmOFYMX>3lP7Ce$!^zcK^cj8WoU*ch|Nrl2L@G2CFwvVPz&X^xDFT>-rop#n- z`l4-M2bD@Fm1j$D#12Ir`&MsbiL|?xSx}*2Sl>?VyE$i<>D6}CDi0%&xGdd|@VV{B z2o)-&B^B!zn1*cMl4SOK#S@823)CTy*)7*0IhB_)*Cc~WVbJkC)zeEY$0dq2Tf?Nc zpRnlE^*4WPP^RQ*HU6>~W4D^%$}7TIU_|3E{~ky@m$`a)7@<|7L3kwS--F%ed8V;^ zvNeaKSM#1D<8Z2U248Sgwe;m}cE^WsV&e|qP(=UVr%wmGR%mCnxdAU(7%fH6VRPDs$XjMQx#B|cXfAkcNM!kH&@H`RM#~yNb}32oN#&y z8{zZPxLVR`aulB|HP9p#dAF`56!0u@e|UTx=IfRBvXg-@c{t|-f`3gWsRrEJ9~*i> zis$PRIL=HZI$6+q+UGLzKOC? zY;52v4El^fPIF2C>-!AZArurB@>R`5s-BqNuqiRU{YshEfA}ff@AEcN`TB=y{uC_f z)XwJUY(6(q`(;Fq(pIB=tzwhLC~TQ1`J;!MligXfh&t-(hB&(nSx>JUGNGQ`$l3y@ zDW+8Ea_b6=tc@3^E?|c`o&WUOn;eMUMK&NB*2eU{UuVt|2?*bm$D*`@P$$xI;fT$* zInhky%f|voi0SQjC;h?M8Y>))A|BRTYU6K}hEu3yBEAVbmP-)5rku#{Uy~6^U%`jV zNq(YMiBU@9korLArLM(lYa}~CBpY9s$ z9$0SU&VIL8pl0g)(CBCLe4E|bA+gX19CKwM?p0T}<4X}(bj~=?Bkkd{@&A1W{de0$ zLGDYwd6C}z-m2-b*i_-Y0-j5zpjMx<9R5s#favw{w*_>8eJIj)aHbLAWU)Fd&<#E{ z>;V|^f}daT?RH%xJ8j5i0G^n_WF?X*-jmC-waD)*iObkF6+xz5!Q;iQxH8Ik>Go&c^MRJC{T8HUOxXsLF3>&IGXvI3r{!`=JB(%?A2FNyRFBeqo}xEc*6nv6FOe=~`bntWavqhfS}) zybQ+m%EtB%pc)itmTI;V!lCUxy?CYz(fw0Q5)dNhy2aYl`-RVnP`eBzVVTMA=D6MX zhBo%V?4_Fu!M}|0$kJ)H@6EJ^bFU6Jr$!qKXoz(YUS&~?!6+} zpbfTr1C|ado0eaDn~9=VmPBswH6H`6%E|;u8|)(Oxp+d1ZuB~^0AN3pIAR@sva`Li z-XUj)M}de`XZ<49DaFs*prn&u#&St~iMC9}r2c2?ILD$$1M{(hr;m4vUMA(%IBM-R zcT+6>Tf$?YiOSzkDZtAQX>vBWf?<(u;EKQ!bkA3nA`shOC}P@gof^*=Rs+e0KsDGK zGsC9z*pv$ku21wc=`TGegOYSFms-WqyW=H7>tJl8TS<{k*dCe);<1F4g?(>TnN z;R7B|F@OWE@1yka>7{&eTf0wVoaIDQ(DW4>w%GnkCH($WIl-};pw~W%fct*Q3@ZeR zntcs|gPcI4Sm-#z<}>R1GqX{yG`ku!QEuSzD_@VOyaO#xZ@jNvgyThMy4~ld`ooBT zVY|C#=}J<+%j)5#rK51}knR;B;mr3}3HHlvv4tbTSJTt8OQ?D^#UJ;?#c!&;>!0U8 zGp8|yQ}x1f=1D4{ki(WOgp7A!)oZgd27}A>5v`7n@}uNZD-C;-3Q9MTlyhqlD9Vki zyAGoaKb$@~8TE|~BIB_r9E^UV<24q6P)_!Yp)6b7IYe|n&&V#P9*0|+$k$F4?sDUm=AU54Q=*QU_1(%wY&ffbU zoPC1M#14fI!wXnVn_aw}rS`+9!~!|Ld_ zl*C+(B)(WpS&?&t34xgR#WU8isDES#;yR_xJ+`_)x+)!DA#n;~S%7!&s?6=DJ*9P)UKl5;D24?@ldK8+Kb&~fV$*hn|a|%LN1o5Imf3_ zMW)F6;hN-ehb4iLfguBd4B%Pd`N^_^RBR21ULJ=p+*NE{MgiQwE-2}odg@(%)EQ?l z?mTPdKxHz?nZW1zWcj*LETh+5tf=G+ed{X$A#5l1x7TZVbyI~mowvH>8u`iuVjRR` z8o{Fmb%aG@CC`kVifDAMwhN2j>OFIAyArXQUdZuPC9@^l0yE!OVQ!9Ol7u2}inn<} z7~hA@&s3UVc%CsH!wL5-`Mf^8yTHp=N<>jXOH*%okD+^@RmzSn=6%WcO2=VwV9KWP z?70^{Um*>8G)_;gMprzTwPGdU6d{ieVr*Dx-2BEG?9yLQ%Imnbue{iN0}}0c5!;_+ zP_KJS+O+A6cJqvBBY@?JxWj5JX}Rm-`*e+3qCp#;C;1_nQTzMmUG$IsTP%ywje!wC z&+|)u5#QU8e0j`n3Ip0?Mq>o|Pt?-}y`?%1RrVJwR;@O3rgDjt{Lrk1;;W&hp7_Kc z>#Q{L#FrpdjlZ=Ju?8__G|Mi2{IlH)KL<7+;l&;?Enk_e8zE}gOcWgz1TmCvM8@$RG}7{U8g%}}dkU3s~U z#qmc9R_=Y0ea6iSWdzxwLE}*p)5i#F@)Sex)WG54#5aJFPINk~bVMs>G+No=4GMZ6 zQmcIBgUyg?C^oLgWYmFto0^%P#?7+RC#1&7NgxrtS)WKL)u_*>j>M#}7(M)+wS?&9 z+)D26`!pmU1}*moIaQm{Ic*JreeWL$2qp@o=Qs+~@*~!ERGaZJ+=YBM`BX9mf>&4R zs^akQ<}!&B=;D!`-+Rb>e08S0jMn3@@+{fpx`*^JTPWyOq+0b8919D-dWoqQAV8FI z`_CNvHTm8#j%Id7Fr`-hc#!%cvn1eVYond=M)6fbANvfPZQu#M=-n+{+>yAgbSRr7 z6!o~*@}kxEPYa&lfg)8&^}Nrm;-bJGW6~-`92v}{x5@ZiAIbu^y_$YYA6OUgLUFmj zL3LxdHI5Bbc3RuB%i~UOKt*B81pZ1+v06vW@)w|{U1zq(YY_YVOd)s5SwRKE+QUZE zW%?mX`}=WGLF@d>0jq4JBEBKNc32a*tT6LcZC>llI0Nsaca&K-JSAa&6dq3%cmz_b%5IBN%oE9x|6g}oG!vPk4-b% zAkZz7hFr(%@56uEnzZ!*LY3kOlj#!(#(TVVgpex1UU z5?=h6Z-0z>Kw+ov6THJ*aWQJ-v*kxhs+{+-( z0xOrt+q3bGCDB5A_~U;nNT13gOX)oK;3s+VPS603z*4Ug6KOu^lmETRHr~YE z+rvEcjg)>_Q?oO#gh*e&g$I3^q(#x_=5W6F=Ge~F44FL;o371}-IqsQjp&I}>>wKQ_-3h&)T>wMvGp~w>Pv3D#(U_m9DMUAxO z#u;*jkppODS5nITI}G+5fU)h)=inq!kBg|9gG%(bYCK<#h0#cb?Hp09jx_QN2B#;G z=fmbR8c*1q4_({5ZkAX5F{pRv`myvl3VEAe)>962Ykb?s&rH>Z3$N7L9R17BbShSQ zCiNhACmFnuU^~H^jl1C)eLrv4ds!sh$m_#7WTh_xuPc|^xSQexxEU$=sGagL=l&}T zfK4~{HT624XdJJB2a)Q@b`P!1?S()j)K7f-lHqMemnZqiR~Q+ZK| z{~V4+MD-+S@+@Sj+ldB;LR`V!pmJo5&-blS+XTaMzD8YL{dgyW(_%EoXDrA&#cC2u zfbT0TVU^ zc9KFj-MGhrlXM*V(bLnjI$Z^uC4!j3)2dAmvod}kR0NzNl(h}A@gLP^l(DvVXBq_; z_otFlS)ol~;Ls#j?-XTD1|?uG-t~m2%Y7ja($4+^bH>I(qd%Js{A`wq-%AoK(h6mY z3|cMC5vP>W%`vsRYwfEy<-d(1wmm1n5%qjr2xj$_ZqU^Hhmg;VYOS(nU`nM?>_9~_JhRDXgXfN9}Z-H|9Dk8$!fJOH8G3F zYHSs1ivqUS0N(Zdd7IH8vzL&%swOhX{z zLR}}8K)9)B(j+7w4mE?mQq~sBOe&>lkV189V_}v$1YtGe!w=9zYUPUK)3Ih>90@Xi z?OfW0W%?o3I7lPzFfPK(E>;n*Qtl!hVq9bY^nqWEN&?;MV(W9TG=K!wVUGb?LopCK zL)bhcIY#<2wA6!4j>GtsjI&5N`JM?zZXj+$)B@>zYlOrev^QNYXt^;px2t%!f7h>g z?(*TGd+vw2NIr+_Czkg1AD|TcWOhyOH%44KtU~0+oMY~pP6ykWr?cOPC^2Drd)XIHqcTrm0xP_1xl-L~h$s^>{Ai&(E%22ia8tXpK|9cT zC(g|o2WN{MBdXN6Hi!7lFA}^IP?9stnJu$E-{2}YHrSnz+lu)_GwwGkx!?0SER7=g z^FzAkJGmvV>BASclg|G0S*mb%a(lz01T!sYId#2-EvA`#h+%F)eWN5qi=iN()9(TI zil|`{$sgYbU22L413@DUkBUf)W9J#~0DZ>dd2vrar75QT4Ygs+lEu&m!_!OG7gj7i{Mcx)(+f@(Emew)?J0KBJhGN)nNbaSR7g=z znZvRB6=+;+^f30+i?T*p1M|od&wL&HgOS$RqCA1`i3SNdePts!-FvZ!9+6 z`PBliQg$tnhAZwtR9>>lb3K!o=mZM-Oz)MIkO8m6@z>FFVRFdrPm>z$XQ3(` z_dd%5TA6)P=Fa{Cr8ply9-9r0woh=N!X~(u{)|Xam!5I{{+SsWfWk2hzb!T{ zOI*&aRIV?iBiA7hhg-us=r{M9C7jh}t@{Ge`xL@0Zb{E}pV)%57$ms>wwU+%X33>#CtpL$)yWJD?DhV&Fcb=>BUPvTnI^HuMVD~wwi#!lu6X{2E3-LS@F8nd4MXwY5;jTIzn z`HtcY-<j|4x+3nVzrY`>ViD*dmhL$)P2A4sL6c|J1Rs7HLN6aaZhT1O}rHs8w zF#mAC_501?RM~@SHMj&?6@0{%YX6#8N1OTloMkiWi4$R;*GY|I8G@*GLg1SeOMvz< z8}k`35!X0AD{cNvGjc#3V&uss)V|sWZ#rh%gBYkc8LX$qeLDf~Lca8U@$zOAYS0dA zPiZ;rY@^eY^X!5RJV_p=*n~j_<*yIcMupc5Our-i?XRqJoePk@C-xHPR2UAX*B?|{ zoQQix(M0c9!a`ADiA|s;MVzE>D-%-sxYG&w-XZ`3LIQ-UWFa3h4>0D=995kLM}_hE z?JV7IZA>W5n<_RYkc6}O$h9x+^|%oWa5j0eloT%s$?P0G zWY#+$l~)n--VG8#k9YaxhikoqY~DYq?-pH8WS2lmyYwB=3-xxPwtBVXeAKUiBT*KT z%ur=<0(E)BE0tw40+Ifn%nJ&$!b+IM9u#+V+mnD}X7!aCf#_@&3)nW%D8Mr<+(}cDa_ZNxQ4`tMi+0 z-UhXWsN?mD@XhhJucxnTcq^pRxk`H5S!aX(p)lW-&G<)xF%to3$J)=ii&KJ0 zB5oVY=RnsJk>IMAE{yiK8d6_lVPij6>QX(4pMHcrH{C`Vd2qu>ThQ=(`3_35J8b&G z{|kO}N>O)ct#JepTEtx86EN>b`dU#TYD!7fy{8RTkQQkvA{eA^-^&@{S^hBbWMS_SCp(j^)#t$@FPGH#5pR1>+ z)zC{$I2_?7CXI_o{57d!1|ygru~8qK9}w*qgjcz~dsgcS@KCO+tK1YVv- z7Ass~xR+p3nQJ_8?=uU0MNLE`A4wC&0YjR9InFE?k0C z@qowX+j0o~zIY+D9F=po^ zpr9Xs!v(Vb4O>mO!9s6`FUb!EewWTHs*`Gz%@dW;|Ci|4$YQPf}HsZ?7~M zv~p}SUyedI=(JV>a?jN^!t5O#%H+FcX#(p!ZfH>mIWT3>$Wpf}jfw=|u4Y1*`gkyW zi}l+(e4nIF#kJZoZ(1x{g5m*vsynZ~kTS+znox5_@`nHG%L+=<=EQRvdJ0HGYx;xj zQm*q@HC9nRdRC5w@vB!%I^}e)XUYYz(m+Y}2-|@F>z(og4vmyT*o6OUrdpm1POZe- zAx0?-zt66n$STAOOe@3Dc$HnrR<-6ZOK&wDzhg~S{MKC-9q^!MOlGC>BNeeG=6QZ3 zQGb=OJ(`B()5@ivDj7nv;IYf%fYmL4F@UMe3$R$-2G5Fa$MquBclx3R&qtGJ%=(r9 z`X)LOgn~NI0-sBPo9ausa9aC#%w{wnv(#!;sQ4Y}A@7v&1tltbQqKhqd{>U@%E!$0+sAJ3r2Q##q;z=P!sAIZXZ z!3-MkpFTv1<{Oin>sI&qUqK+s^o7sOnwvP2;};f1HXUy%Rkbv?bYnl zgw|0+Eeau~P%D&nDjUyLF+^6UT$&1#(3;N!z1on?5B zBi7fUQ@Q+YMGXw12PhG~u-1e0)9L7p$NC%oE-tsP@x*}uH&VbJiN}rQW-VpfS#(*Y zpDtTrv4d!rpjhivTAn5hxkaIUMj{@PyN+3XJ&~TjGP*Q4zLd>;j36j5CZ@0ff+v-bYF_At9;KHFn zJ6wqhLF9Uu4EQ@r;2btwvHQn6PDXGEUATlRlTq=^8{^_^z>SkCpd6QSqjIZ91KL=Q zHK*xMKNu9wq+_U?c575J zJU-Va9_qZ%&S3hFy?nm2i$)&mq1kv>1Pjq}m;U@F?XqPbIBn`F%=x5wyRKHdC7ZY{ zDaNQE<$cjaGr3Ut0E*2ucs=4#$&pWs)@F6VgF;k+l&ugHL2{69F$~BuH~ttw+%8P& z?EpW)VVvgitSsRLR2=M-`cRLh{xLcAdL@EY&3LPcHdOm1Eie>z%9Qu@FD=pP4q_1+`{vDuU>W`Yf{ zazT(Wla6m1TP?J`h5Pa??g!CSvS2Whbjf^!F+{-*I187C#9Qcx0uzgs==_(9Gj2)U z%C%&T$2v0?a-?030+Xr_N{IY9ul<-H2H*+^;w)pQ0}M3J&{S436#JT1P4fN?(U%}&DZW%`b7t+nZTljzMt``4sS7Xkw8MMXc>n&30$=@=0a5e~2{>*KPuql|I zXfyS9({#YgRwZ2_N@QSOzKKUBcPr7w891)1xk?;mJ@0hxs5C> z2z)|b_b54ICJHY;&+A}*p-+^0m@%h&6tDT6A5lJ+Es_U}CQ~poerAm{oFlnnL}ZB1 zLm@XG`6><}eqSsc@Qeu~TddHP!f1>>vUu=)32@z0iB)!I8=A)-c79d=)@@L@f;FhM z_L?l#Furd@z=`}7XQ?@G*L81UPA!SW@W3c3)#BIRER5MVek%kJq| zoqn>YYKVf_d2^qVN_nv=!xM;&eF;KcG#CmuYT~Q)KFht1YOU*8?W7CU`tMHWd&UzOQzM+s4 zAj3vBOGT8p>PgQH8XNtp3W7kVbEr{4E}EXp^mALoy1I~^w_;BjOCth*e zb;)m8N|&nFB88!7gwg^JT&lw?wXH-DJMmS}1Ili}Bk_i*b3-*#AQ~-`tMdWBr7_k> zb&HdV7O$Jq%x?FT-MJvYTf}d(rZt`vHm|}!)9cHQsCW!z@7+Zpk2GTnmO&whQtOr7+^$$N1O?;mcP=)r zuNiqRYk;lQc~6qv@pm-nDSy9w?)W3=dw_nll;HJzl%&?oNVzy;cN>zs`>XNE6LggT z36?3wl&KorcUds9D(jC02c9p_!Q%(tfD8$^pH?X|e8J=7AXYw+k^pIII8>t_iNbtn zQ~v>IfSPMLsg=fgFTW5cbTy&!oeQGBB^oH_9d!7-Pz0w=4CxwYsu z7gvA%;KW;&6McvYBC*?TR99Wk z#MpD7B>dy05A(^#HcGGwJUR8Qoh~+#X z0+2s_eysdy7t*&8T50O6+62BBtmUr>7RPo=02N;g4a%#*DiRR(B}1?kKUZL4ur!~X z<+WnasSxj7+?p4=NA|1SANivK&+ zwcTPB^tHRyrY7LzPN4SN&eb86Xci@XGyy}b7;{ia7GF=5>P#b>6VEnEL%dB@exn{A z0c!F+sXCl0#|MRYZYDf=DBL9o^8xf{g*9AFpqD_Dqj7&q#1W5fzj+M=Q6(xxM4VS} zhMy%HZ1w5}{?qN!1fZ%5?H1fkFQ!SFd}MJPd8glCh+(?0>Na8jwkYnAXi*M%WNi7I z@{uWb=yS8O-jPBK#*4VAeS#Ih74Ze_Yh39iyA`%P(zN7lcD(!Q8)PhZIkhTFN(T5W zrr&RlWy_}TT<*D?9?vcG)lKQ z)~l{n>-PP^FNqVQ4R{aKK>nG1FhD$HtiTLj6^Ihh#+RNfOP~o|AN)qOx36dS zSf>1$m4}oXk1vAGkVKcdH2JO!20s3qMP<N6@w> zD3uhEDnionX1ddUo8zyhXf@SRKI?JXBsE`SC5+Ab)nt3A#YL3Ij??f1b43cyL_uxu zQZ`sbs@Srx%U(ZKCM3cAMD%0(L;TuQMk5@n!NK;Gdj4BuuWTT`v^9(!?9;w4<3OOU zZvK6@WWv81t(tVat+mA1vr#bVPukCFcs8fJPz$0Y~or@u_Yu{5d?HfRI4u{1ls`m_weV@PDGR z`A>gKyT8hd-yJ(icS^!HDB^VW4L_R=s7Q6SjL3vXM@h1mKquvZlDyAm92TW6aP78S z2)MrCS})l&7)PxuEHwsDqF2RC zuTjak(TI3$Q>N8wq||Sf&r_c57z3$$O1Bs%6Hx!=s9)TCcEhZtr354fB~blrm>uF2%r z=vQ`#%yyn6xXu#KkyKmeFdmlL1E#mEmyWWSXH7P%0yb+@JrvQZ;DG8rEp%GObfwhc zEM#A~WyR&gk`yQzXNi(f40G_yhNwx!Y+;2EEn_CQSl6IqbZAIw$c+G*Tseya3pm3# zZm>7~jkB1?rxi7iRJ4jQgT%*&p31&V&(~717`0IXa=BYMHltR!WdBoRz{v-tFMOy> zI+JJKWEp3mi42*}!eelBimxjN=Vcz8`50$uITZXqYt0Wp3#+EA28< zwX*2e;5V26Z4BXpahF3b< zRKM}XI7q}Wrxd(VPg5A5A_~jCx!lbwGYI9`>v0swu6^`MV0MAaS4q+E-ZQGpg7GUD zk^_97AsgItYU~+@rT+Q@56880?sBy_K!>JJ;7y%ent;mxcxSk}_wJEYz+(+*`=<#7 zNvmlyX0eIvmGpAn3cc^`r931Fm{ns$wbSqwutgHrPYWN8Dr9y)Ol9`BNzUPzA;Dg5*=rulPO zZS8VN@mrh)rI2FyEaXvbn7~)*#SO);5;}bEq6q5=hj1)_&~BWo)zM#KVvUp~mDluCV0`uF0vmRqlu!`Kow1 z!#ODAkuKL6Z1bz0P9xE{mEODw{rTw%J0>o>33STU@x=*q#IOIA1;{HW zex(I3>Uxp~ES&4iheQ09!N=1xDt*to6o`hNfkBSfZy8Iq&bUhyt@7hS@Rh>XN}D?l zAov2aH&G-B=(lXPxA?a6ZAR(SNl?^R0@9~PJ)y(sE69U!*%SKlyHt>Mt&&6Q!^Gr9 zz&O)BNPqd=LeRG06DFv_YdF~g=5#%sCgXKHML3-8kR29(9Gu$Y44U9ss){|nSp>3k z=%V6}jx(PqrJYMOQY`_U4~XrCgvD~bh|_hre3Z=kX5<4-5gwnM>UG64dlOjad4{Bv z#$&M0l6B@}79Q?Hnk!itL+~fF)9mne71p!QmEP_Fk!KDr*TC(5!=+ENO?Iyvj)chVw6zHdMLrOch6|-MJfQ7`Qp?8} zM14y{AdciQTUYCg!a)Y`YS$&dV!oZq9LI)zGsewlm zh0S)`hA?ydB>Ur_P6{^PgRIx_WDU75-U2l|hJoto>pohH0!aQRjlbOJnF+me28|8v z`=JD5g;&wq1rR0~6cT!}2`!LS-N~zFr1%zy)O!_<7HB!u?66!JX60G?%?R;gLwPJr zjS68tzE>ulexG;%`}Wg`G9ZV(3UEI%jBlF0hguwr4^}TS*7O?6k-X3Gt{9K#TV2hCE{1TTjI!9wsCMSTiGPgZLzIiwD_^k@96G4Nt9Ps zMcv_|{pRI${XsF~r2Ng@5bXD_{GT5A|FWj6u#ejcaq)n6`lYf!*5FTUI$d8Y5pyM& zNgKk5u=i}MP72TrtN*x3SXv@Zwv~o^Kgy6VYCkn~RHW>GPx+!>XB*QWt<}BXU`%>$ z(u0678!>K1E5AU*>-=ekMdW0z9wQPf+=QEx^1#&OpXxpA>VHK_MvdCW=$2El#q(&8 zcP!mX4H^-F?VGrKw!f@=kyXYYhefCSX&G73CKc{rrgZsAix)$w#pwxmAeJEPPx_d1 ziS+<04^ULAH%ter-hDT&j==2-uQVCoJbZU}cRFhO<@uUme1$)L?kTU-?9Xro3OQni zRO}*kuI@_5+CuQ)t@93xNVv#vQ$?;hypxM!$huSm5Hou;pNQ6}Fq>}Ma;C{`C?}!{ z$ok50)mL)ic%hPT>Gc@VQN^ytyfb~|^M&n5v_v)Py*yiw>_x7(<9AKNb|)f$6i6GV z5__kf0uE)%6$yi#D!!-)ZOk$2)4~K0eYdC#5KiQd-k0_>$Fjla^G(v~malsU(?SUz z+5~Lv?tG1Yaz=87-VZ~dB%6NcQxbk%RY`&ma+$O^4Yr2nT0gZ` zXh#;lPnk;HTK7-fd9&6Xgn8gHe+eb#|5~uY03)|v%b}ZZn7~0z-QX}^h3W2IQou5_ zD&BH=t=nuXA{9!t)Zp+!!SHr{H33H@4()q7ckN_*D%84A>dT?0QbD` z6k3kexJ|14eq<{lq=|*INL6g~>)aN9@=e_A%UbY$s~*>x*Y7YOkcO#_N}g8Bv(+5E zFJZUfmNG+^HFsr`3YcrI!CFNshre6>DMJhj4Y|EqX#lUN8PI5Ok5>XB4(Bq}%B^YI zHyDE*2{;RYk(+eJ@IulAEIJh%a3U5sSIUhGLxOX%!G0;STatU~w-PvI0(C56$mWkf zR0!5SQ74tXBgrvPSDJI^?kSi!!3JJf$}y+9mqOilxP)X1fodN0xicUaF!A;8>}xRT z0JPj#cBk0X{?!&ckl(XR`3*inAM5_9ck$N2fzHoldnirv#Din$;EO`8w;kMabDk$mzGU(83n)E10I z``(VunoQ9F)1-><2})jlwT;17r%<;E%2yoTT7)oi_fXX8B^Lej%Fb65YZOC znoeT2$g_1Yt=AC9fa}3!yjH*LTwm%+ab)f3{uGf_Ensq!xwGx({-G^rk0eXEYX0-AS$gCXsLtQ z27W_lJ}UyDfHNc!s;5nK9l-6~teUza@>u0{37YKuGu)+_mpiTNlvVp|5Eq?VIlKVm z1TZgL4>+L#Eh}ZaM5}{((OPF*U>f)(n|03{eoGp6AS&q!47B>*-VzY}rj<0!xK;Pk zsvr1M+q4JcE+8~g0SI@c=bHb>khDf9qZ=oV*gY`+P=CPl*@O*`6>xp{@qr}qr@>BO zFESf6eu5#?nEFO?fX-`g*c|_|82V+SvIVaX`GM*4Q#cU!uqq$X0O~G;kYC~IFp}1I z^kk)|wT%=b%<5oC8tpbB@K+1BqB#~|&+w6{cT1DZW4;SQC2H*Qh{^Uv`P&n^t3|Nj za>zlPodiM*?cVO=-p?#1&0*T*?OW_aNSZ?lAqdYgB%Fo^=?qMT#dN<=$umX#(3VNS zoo^xwiG(Q2d4Athdo|Gfg zf)qnAi;3*@+8i6O5j1$u+9w)U-V*bBODung1iV&|bfZGzZQ4?y9o<|*Vk?pN^{(w` z9{CjkyYm|!+eO+Nyd0(z_ZQ&f@>9#9ldWgr-K&O4-1vLF{tFI#S18I z_YLDPgic37zLKO;NG#yP*;#`su9{i=N=B@b$UHXsKPSPf1k)+U!N%8QSED>CJ+G>2 z6k!hDq@CuO>iN?3r5i zbpF0aNHn?kiNznO^$nSrk{R{zS@<*a@qDGX@`A%vtw#zBpsar8&oz0xByt%aGJ$j1 zzGl`)yz*f&?g;w5!!p!O5?^RfudSQ1{D=b}0tZtABCT>m+`Zp(8>34Pd~Vy&q_Coi z%s^}$9!-Fvw04KJH=tXgB%bd?VM~$RL&bst#p$G*s-!0o!4;^0$MJG|EkJkM9Nh}R zW=L8y{w4X94=3Uqe0+U{G~mOUe%vU6u6EQ56w>*uw5Q(mmh`=x4Lru>e2rOWn~K|? zd~}E3OI&Fq*dIuq?t$kbcWWVs4!{o0Nr=ixol^$tA>DqdBbX;Ev%Uu|h4HiG{pFtH z#J11Cv(e zIZAu$a$mU+S+Y7qx-L@d?wKSB7d#FJ$jQKNT;o!XWrk@Qz|^`3i%EN-13Thd)o%M*8BpF|=iKP9Y`t?q(EKqn^a= zkFkKEU#cbDij-m#%5h3kUb0L({Z0iWe@P@_{nc1Z+7@qzCcS1q@&1u;vJ&R(k+C;e z!R60XjPKBChO@t>&B1&>(MWoW%@Q=Xb?g6O?>)ns+_tt+L=+VP6)Dn@-bJJf0TJm< zdKc;4NC_wB7QBtM-K?bKKKyFyTGg*ziv^A{BR$8iU<5%WA zPj(x^SYDHB=ZKb{Wj$Mq)I&78)7bPAoVE-A&iUi-8jU+IL5|KYE(g>6CSjKu8z?!# z(*&!{!pI*IZ6fY*IMN(C&rQz6C}E{?`2_LCShARH;3kY)n!x3`=0p{c>vn;(m&VVt+#=3ClH3?3!Q! zu8|0m7ZlO&2w`@waKkGA;IxPON+wJnKZ~!86~EvrwYtm)J~(04Z!!;7?8oWH>yoDu?3A$rDW11Dw4SHQ5VVQFEQWjAm# zAIw30cku}u**{mxS-7o#$*D25`t~69(OvLb*gN|>YYi$oIRd(3@(?=N;9c20`?#gP z`9O@br3Kr5b;K&y$<({4f_IMBzZa@u=ke5vaxG?U^lFlL$f*G6d~!epXCC_B4kJDb-_4lRG{3NRg$t8?SyXUt=|9ZcT)cQRzmNi}< zl(N3IKHoQC^d^>`26gMFzg@9P99O_Dr6pVhe}NFlS;_nJ7h za=HAYv1TgE|6IOOaC-TQ)K&7(`%5=vRkgog)$xmFRSpO^GC3V{Vo}L2jIt~aNvIfi znhKF5jOZSHIRbSRwTcOl&Fbun;$m6_7&C33ZTPPMY-)gXG%9g_s69lZMM*4{PgCFF zv^@k6vw?$*T_v@JO8s8C9i8%XIQ2+Tgl~f?XdpNu?ftTo&t9Q?NRNh9?{&FZ>bTu| z>}zL3xRgTU%Z7`jSt4e0b(q&dp7^IDQ;h&Yj-``9%7YqNx84b~AFKNX9hNVD-**h6 zYa)GoaFSJM5l)|>x7Rastg`Dvi>Br`g-WkouT@B$snq%U=^`Vi?2XLAFkDK3cdywW zTp>zwZS*dxa9sZAu_scu@AJFqVa5+R%6hlp?;bvTL%;RVvv)aM^NsI~EPin4%ew%N z?=iC0#E{%Hf_5&Xer(JTC@{8cHVQi)@CR?tgzu5doK7#AZ$-y>lUo5;@O`Xz&En9@ zp0nXpViYvO&N0F@d)v|r4~TC~LGV3R2}s(->RhJ9XP)@yKd<&ZvM*VqUt0)~RtvQb z-z{Vh!QQMEG9S7_P&}Kz@&({oCkflVxJ2&IeO&8o@JyRi>)W15i?t*Lk6|wP{bVGF z+-s-)xla=}uUk>XUGM8*jm}9unw@N9Iti6FkOzTJb2JBQn%}*ZUn<;Nyu=<9AUSUc zfLdm)5kc>D8~tCNJ+A#o9{65DbGCx;z(p3AA*~4tIc{@Lju;XK1GI(;g-w8QkW&w$ zI1w3Me6u-A^nS`O{5X^8OZJ@HRwbqlc!`2Gw?*>+a>`n_T!w?w+w;Z7HENrl zH$Okjd3vs3O*2>JMp)Xy5mCY|$9Ad`jqq&gy1X^WtHtDRUs}Arecn#j@2r0LK0ATRj=ThSBl>xFjCv&&9!xm}G z=<_&-F>_q2tT*<4eW8~iq+spUVO@jM;QW%|n>z^2XJ6M0`xn0tq=RIA2SRbSx3&Eh zwb|^4>dydCtVAdhCD{f=8fGh)n?~&q=iQ3sD=H|Zm^-KuEiXV8m`=p7tLJ=AuJlgz zPJiME%(U*UjScw-$Fb)+)Z2YfnwYdpKMsy$(5y9f_j--OTA}tHgMJk{gBMDxc;U>R zM@&K1gMf--qeOn<|r zbTi|Q1Db{N+jTO-uuF_$Y--^-5_;bnPVX_S!H;CxJ%)t7W(^@HVt*McizX1JNaW{= zx&M#rsEV$eoM<-4^9blRKfx@n3KD=W2IgnSFqNcsCp>bGJmTcJte)NyWqL);(IIqq zb;I1r$|@vB&NgD)Wo~{B8(dylc`qrJGwODZ7e8(2vkT8w2F&J0x6J8vX^5?Xx-i(2zspQtT|g)iWMV=`)m>AQ_qa z!tkKXd{JrXb62&m%e{J&!QrE&t88F(og>R+hfIl@&hG11MLBtznKdhHdMzJ| ztpGq`EczsxPI#)?j!rhnG4Xub8d?coh5;tZN<6fOoM!jlTQkUGlS13dd`ib@ z78^7PH@cx{q3GR09ci|UENaP8%*%bsQa{Rk zYvRGnhOPDWEEK$k*A-vnn@raZmcbFbw5t8H!)>mn*6hVB-@r&S7{kW26Lm_T2VTJ^ z@f*|c1Bon9%}1*?kZTVW1Dw0zvi8SHQi4(`w|U1(4U$boMg!yRr>&iOcukvGT9%{X z2b&1~S>c-U@(f`e2NO1ftaez(Ho0BuV&j}=LW7~mm|sA*vqHDc{oC>H0|LHHl{oC8 zW{XVI-HE9l=oYe_$zuttwp<-@<5TqH65EWv(m;6zpWwn3Mrl91|M20CF=KifPW_%j zy5xRn1!iI8d-P-+DZ{9Ht)hN`?*&e;<$cfrhPf;)wJ#ZOXpGLgGaQaHaYGq_37?A< z>2+Eboj*pJEO>LWPjBz_tiE$M5@B%$;}a>n9qji^eUw|h_5kzUc^_-SbQJK7Yfj2 z@}LaIlUei67b2D6^dippKD`zb#Cp982wWA;wkoSomz>C;n@jS|6leL*8~#HmN%t8M zX*l@7?7@7sOL|ODRJ6&!YgS+cl(a*r4eiA8E|@ z=%Fb=lz6Qzxd;Z6S25e#r1N^Eat}El$}dT#Udn|{o~*)pdnB}2SSCzuW<+nC#Ox=n z;a`z1^xaG9X%pzDbGnva_V#@ax5d~D>tKUL@zC7A5Z?!Psg;!u;TGueF(En)Hh$wdFq*oDPs(ydas z^yg70-@ADO{=vO z?;gDcB6gS*{|EVQMpt_2#@)l1g{qa*=I#bh0H5q2-mwu`6PseYX*#*%H<1bLda#k# z*qQtfy^$yNfNa=bM_kmt`F)?z)dH#szDzU2Jyq?T=$-{|ySlc?<2H>&e4CuI%F7v% zQ2Qu6|32j}&q#CI3rCB%>2|+w)P?{BbDzV#2g?7^A^+U%okrPZntHpk?n1Dn7%t$>PA$1xjzm1ovueTvyPq>e#?s#-%g{!|zITytT zI>H>jGlMmBE22NnB!bto^^(>XXLGHJsM-edGOc8sJr->Xi5`W@qe65#SS!j^k!)3c z59DXZi^Dwv&k1aNwx}AMVRO0@2hX}}n)UbM+)s;_{&K;@a{CW10NKqiN4Ob2w|>Bc zRgXtIi01RhO<%CGvZ@wte~IvEe@zcfsvfB92b@@RJ27~ngS^+m4yjuqC2wBTh+oIU z8Pe}C-a$_%-ifu4(ivZ?;X-Ji)KG`r`}KACN$23F;RZHBUWuH^F5r&u$}@wpN%0sW z7H`@d&|d*f!V=gvMOMoT`25mUy@g5>_hpJ52XE@uIlhW%7^@ksMTTZVH8oS3IzHEX z9`?JJm=*+lCXLGLsyMXW`XP#Y zD|h{X;dhSKt+k!4bgNKTuB|ot2n478H~Es_BW73myYgTVv zWN_E7lQN8ry|adr@77NmY7=(V3;Nqp=1&1!nb3Z_0|aF5r_|DhW)H8~H1FTTK(_*B zxbC<2896bqlTc4BF4(RSeVOJ5(Lnmrllxt*LMbX*<;>>@UPXV=?9H6FHPeob*gQ0a z&Ig$s*o_F;+2bChhIL;2=R^L+8GZW4(t_mQF>q%};k+~1Gis6`?}3hU8nt8(VHdQe zUb@y%QB#s48U}-36X71D$CCW2KcD_S*^l4X#^bCzc~wO8B|Il|zD+Q%bK>02e7Fwx zV;!)f8tW7}MLWrcczdg)ch}(A^IasVO+wwCPnQrZF~b-CL#FX>wrtDx4<%n>Tp9z} zoXMtDmvCu3I1?+PY|i-W?vtT(W&pRczj#Hur=$(<8jhCeTiUN{eX-3C@1gU!!l@ka z6)>(m89skAmHKIeQ8;{jg$5I5Kv!rY#;t)0Kh$ri{DkNNLDW+uzh6733%~L2 zX8?bS?}(q#FLqk!+W!jWC;R+gq5K=0{$HW|uTXySkv}8Izkc}tsij;pg+p`|or5zV z|HcshRSN&+n{6FwJWeyc&iY?JfPb7+i~iE@hL(zy#wf`<8u#QXU?!TyW^Gb0LzPA3 zxD;_Z(I;i=I_SBe@lJUEGqD@^e@|Wix=;q9>({ljIdCfh3M3TwCw&3~&kX|iy4p?_ z%2nG>-UKMVSI=?lmT(#*5JbKV&GdwVualGKfwQ8c=Q;S0+1ZN=w;mdB6)@UCV)R1p zM3cq*`Z@a}sp&s=Nmz}Jl^N|>m04M>`4ITwr-6!>3o>qnU#_v$qzdFE%Ca&KwH+;# zyAHsawb}LAEX4HW5N-B+x65y0ZBt#QTbYvy(nQ(QtmOJuAo$JxJ`RQ;c; z{;o)_u=60USqUPkgfD+Cab3f%VxEJC!q(kn2VCF5>Dr z#Y2uuO0r5tJ&8%6zpV!I6`i)Hqpn8adRkSDzIvnTRUksj%r@J#l^`J7BD}=_^@(I^V%JyXDX`< zJ*GqQYEr+o*E9IZWp9IuHLl%L!o^xfN<|RIS%oQ`RXV3x?qPCGnv3{Gj!c%NQ8saR zmOUNU`50ld+swa_{hV(8bIQ3M4~fF35sDM}Zpm40Hd)!e2B`r;4&y*B9ZpjqZfr@I zz3h8Ck>+_aElrJyZ=BQ~UKA?}vD#cdlKLwl_uE3I8oa{a2Azasdghj#~KD-*b9fQy^9E zbCB%&oeJ@^Fw;Fp5LMYzAn==F>{FJ;EAT4GoBXMK_}e%iAhM5zK)s?XCiLL<`rEltRt?D?0n9rG9QEAc#sD_f8`I&Gi>wy1-}^r)BY*&Xbe? zSkI23dKJ@;^(VKym8eRPKZq#F(#so5#u}^qnpUJ;uK>o8k`<$^mRYS;NuFzIK2N<{c#|I;i}10of4dnGeq>DHl)HD3SO^s8aRCa&EH^E zow?8K%igN;drI4I}x5D^@mqx;bS7@n#^)$VvMtQ-9i8{)5P^YRo zDdzjcMi#_|DabgLw`iQa1815@L)s=FB89QFQZX&R9dxjE#pm)W1#{gu+9uLfif2Bx zWludtr1s5KQYu)`9?mogbWJ9uxmzKt2l5BabguEGrF*{eE~ApI;?|*t3H;oLQ`H^d zVKS{DP#WxW)C5=~L4_s(>+leRSsk*7Ol`GUZ!(D#uPgi2)NJz9jY@6$jU=$~dJD^X z*5lr^$E4qABaQ3TOM3P6zN6)(Ubx~8)C?`R4-N*NUjlN%%ndQp+|6_``$xvu9J;EZ z^an|0(wd5jnEkJ$^O$2qiAOYIrUZ_eZ@)VDMz#0SQlU6ya+yA?f4z-=AVP4{li3>R zLT}*VJTWi0WO>XEHxBEMXU_=~YbAT`uoEt=+)p0Nuf@P4N9s+N@_ahe&dyKqZ))54 z2b-l+rk^Y*+qDq3)%eg>L(5cXmb#w2d;JdFu{Et{i(4Y4%!8w5T6G*}^JG(xb^ZU( zOzW?`#lI0iK1OGG${b=zfhp56t!f7Y{SD9HU3&(RlxA1mWfs3!@=kSM=Ato*4u~_9 z*Ev;G!~#6>*}1|Ap*EOV&d4@kLXS&pW_0Bd8`u4a?>gY@PH&?_p2RdGv6Nr!>dj4OCLal3Da@;g_^YDnR+Qc z?d9U6m5q2qqX+5{p$y*qPOj^TSr#K>vs~2(bTQ!&D8165tr&Yy)K8}IYkPjnt^%9` ziM*aicta`NBq1m|BcVy)KKG=sMgz!hUS4je9i%O;A3QKex6m0Q-$`;-Lhtp?@s4gg zKv9pZRIm}dU&2SpQ_EtoE2d^h2)e@VY%f}BbC=tjDW)) zdiSu$fiyBc@Z9PEfSyT!qrZGi)4LmIkdUlC!K5~2qY-!38;Xt=MWeS8x2sA;IlMh) z%9DX>CWcF`S_z^GlWTyFX=L8N7K@`UoUU&tgXv5*yhT)SE~(+Jc#YFl8-`Z*oZF`c zRzuoKDc5n;qITmdA<1SU=lE+0Mqa}T;WQ{jrdhzk4hS804C^>lAX;LU$8)Qqmy}%D z<5~g#oZnL1Sy%;PQ}sFSEVn~%Rg5dSPOCjXKT*7jD(J)2V2=FY|Cfy1sPOW0RoL<1b$T@CI{XM;iYLb!7lG!&&n*Bl4QzOCi3#O%rZb&r} zO0@vekBvVXRg`#;SDPaNbMoceUz=ewMLz;JAAWuRS`=zm?J|5b=m2@WYeS0hyqgOE zl6N;^R&pk{#)_>3_OjwMwI5!?Hdd<+V4unFMtH=ffN08k{hXaF)~AW)E9#c>HXO&x zEK;BoW8@wLT<|nCtgW0la0j*f%hdDkzzawA`<@p)ZFwNHhf5Bgi`?0Si|~5vf0F?( zQF5bfwGFVAbOX%?8@r!tPTe~_e;6Xnl6fxOi7JjnV0CND|z_R6dJ}Uaj zWD5{DNta8)0=dUK_puUPC)0aj>KhXhh0|wNfuPp~E$dUwOHU!{R)Y;w7QZy=R8vMA zZ;>%%sz0IJ7Ui>TF(v+C_D3$ztzO(#rzE+Q~uSIbYBJ-~b zLb;vhYxyI?fcq`mhAg@pVYs=vBI5)WJTSr_OGFIbQ`Xzo)~bxz-y#)Rg}?Xm=~6Rt zQ#>wNy{p>)!7Sz0O|4cw3RM%2PvjOBnC2zBI#;;&6F21N#!e=H0Ltfqky&-tZQ6Ha z;P-{&R8o_q5~82XSBx4jV5e)t2>Yq&J{&`)ENPd@cFbVr!4pe`Hr#X$^SEH#H0ybf zGGCEWv}v2r`^5}tVSEK3#ppU$*LGDzH6K&;?UUx&g)bXE9RhF|YwFi$h$%^usa8Gf z+Bj_8Vna94f*-O=hcmi(C)SKM>8yaswSQ)Te|;MMFp@*dA7RSf+4)SiUM^3F=D1XX zLCzx64s+cmxsxG9rzF{mbpVq{dbw;$^+3j@qQtudxDJ}mE-1rhR1EE1Uxo2+qiRb%-Q3& zWfEBGx3=ZEhrzzqMX13Fr(Vx(Y#{j*9i)G*qBlP0O@c2p)pz*$VVBX)@K=*+L_E0L zrncmEz0N3Y4_TYq?#$fY#a zm4Ua;8}mni=OqI}vP<%A4wR8*<&eM()gyPsdrDSc8?qe{5jp-Tm9weQJG_sLADac#v`1o{-%qZ(?Fb)~46cjRTs}uay;PqRo2E0ybXDjhszN zcwk3w7pohL*yB+VvBi_$m`sM#kAcKgj}~}M>5y&mFJ)41*$sbW6>wJ~M(h`q;#O5& zZg!Ddmm>4RHzLi-Q^5IRZGyW*NTUiTS<6`RpY-Pibuuw~+l-avUIcPTRx5s5K~X;RC*i>g)!u6R zr>GR%fyn%rh|;rNh`QDvT!71nDX6qDWGHA){XKgY9PP%2aoy9L&OTFD%CNZ{^E`;J zbtgQ`p|W@ImBc~cWrqcKF?-v(`ZXen&M~NxtXfA0tERsG6-E7pnQ1obDaHN|%2HJ( z)KXlM>Y)pT$824Z>4%J1R~@F;Nq3Xh4y!i#UYvzXNNto>YCM8=YUYh z`=pkv>T&USa*O%)%Ezh9`NP>PhW2v@2|>Eiv;8PZ2W>ZJJ@k#JX5j3KnJt&9lgE8> zwqKYty3T%LesB4%=YDa^>Eu~9ZZZP;ANfHz~+@@cAV5o4SFOBRRc{{pB0t@C7#@E%?( z{5Dj2=ZWTIkwr2EcyN%$W3j+F?^PvQkg_y_DFO8AWUG)lxWgdWDb=pg_gj`P701O( z)sidks%H|j&UcQQO;wDoF}EIgHu|VsyXUn$1QjU|0Z&CA?o1R^AZjHSKGS*UHJz}O zt+4Tjoh@ZZI7xX9LW#R-2c|xYK8TssBEfVBCYn53HU=xWZR%620j7GmA@E^g+-0BC+(lfs94<}{DweY}H&*4RE# zsa&LKy*k??-7%YM-_d9W)0fk8DG9B6$pem*d31MK1hcotkN6{J*jjxibdxV1@LS|{ z6ySUXp|}C|^($t4b;E|TWr(1uI}fmxcn^p61CL2cYePw#4BG?K=W^fIxW64p?_S5$ zf^U@-S5&z0zjy}Mqt;e7#a9Tgh@ScdwjO}aM4159#Jcx#a}7WnOgdi$reb9{tB?i9 zXtOcyE_WPvmbcP5B}34da&lE!C{+-mxD%-vg*0&b48EWFmamtR25yivzdEc z@6xv4J&%OJ6ar1OdZ?8=*s0wn7giZW=45OZ`g`zMK8V+Zh`^s}EPsE^-I?3Oz`Ci9 z+44_*ZrO7wo>WGq(XDNw5VEQ!4p;%@Mx7Pro9hSe)D^F~7W(n<JF8M?z9At5Z~m*rAMxle6Mo%#^5@8%jq=-_A(VmvgDpj<-J*FqDLugJ4`x93dfb z!IcLN-}a2mVmgcUr2Mp#VeuwVeQQV-Cs0HSgE(u@LoepQy&{mJ>JSzxkHyh}4vXQ0 z?5=ZB_RJ-he=Xge0iZ2_7lLd_00Q`%_%U8(NKe7KP_fN%{f>l>HOZ0%UV*PP^Nnxk zEY5eW98g`6xV#oSc`m=Qfo`jJD0mv#w4m<9llFR7lh$J))b0R;9nl5vmST&lTTcc_ z=W{O#4lnG$Jro*g`YT6~nO!*US^t$CAfacV)$;P>5KCK+-RXnJq250{F~iS+phzKQOc%4G;vsroeaVY&pB@88``>b0{j^+5S&-b~zE}d0yEfr;HggELTnMT>%1YN(bQ9V5( zvrGP;k_M@Ayd=vI)7A#RjGB~^)HOD~<^-DKTs}>;*Z4Q|kpicMctrj3(I-BIC2lqe zM_=z182IqxTrz?D1K-W9*UgTqjK$f29d0|3IZRvT&OG1Qk4UZkc5Mkl zRG`fKM{QEAbd=HSWJZ4@9Z|J?WyGDdjbUZ>z}e6S$e-fs6z@q}AWW}70F=Pl%Smnd zbH}mEjRb}|rnfqy4fPeSM}9^Cj8bRA9|~80O^!UvwpXv7p+%U zrD8H=7gibBA_j^$#6GWHoo=girLB{1I}gzstoz#tNFs?UPq~=J%mw}V5~4z-c@Q2B1Tq;FiEe$*W!B`QhpwYf~Jl)61%09 zC!nr@m;6|4%`PyRl=_;S?Qawr|Ex%&$bev*QZ8be*T?G@tH5hkB?ZGB27`C1hKDr< zJIh%7p7e4y0a=f@B}t7G(tmfw(&o*y8X~LzOU*^LneE-`Po?+WSHE;`hP`YFc8>(I z!ElpO?^-^c;YvMv0iJ%T<~xUbihxwRl-~0p4v|Ga0H6(4Jt)^yjq|IMlyJNuv-CuY zycwNFJQd?Aku|=e%c;sV@oWer%BjK@t}LbkfoJbdMitn z)^H#Y6VxLRt?!_E?!57nbb`h5fvGcG$nPsSC_A6e?z7#`*~$l@CEf`z-H~PSGA_T^ zaAe&((eTgGviJ({8xp)~SesR$on4?#+8vuMqWvlf9LXVdml%cKU$c+?rJP7Q>$G;e zsz;ek#t&l68=8>E7XqX)FOtm?P0n~PtCO5oCwZIU zCtF&prHX<K$3$P5~EjP%jT(6n|N+6T$VDb1sI!oUUt+Kvnd~qIKld( zZcZ>-GG=JOL%QePJ>)N{f)41`tzC%U?4Y?OEq;`HaVru)owSU-HonH4Cq&VT2(~_* zZm(9+0_ga)={2_QDezRrI%N&`qjlx(7413k+2`W6Z+ zSF!1$B+E4pwQf2bdnao@?Q7`Vho1lDHYd9}z)rGBUYAzule)$pm~4c%Itig{AKr{D zUAZc;7m`W{DH&TFv&ricLHRQCx^9Yignxjn#hlE1#v5{>_XhR1;byB#K)$g1Db1S{ z$zjYFa~+{uS#}e-t!J{yN*NdcpgUvAp|qb}E`r-DyTKAiCI0Qo9DJDBzY4{ zy!R%=b>UmGnHtWs-}Ko$rP&0NU}#}!$M*PPF*nJ}G`eYRu^kiGp=EP}tau&qN8;@4#sBMjEe^!fj<aiE_(dEgxh2l z$>0S_OVOtGJlg1%kWc5!VG5ceAk!`5j@W3`Yn)cD93G0H+@NtXBG;W7z?StZLQE#z zdrMbQ@>XTrZ_4WUCi!bo!*7PrWhw^Oswm4|wgkCHI@2jZKuV^k;Zc-sXGL$Q0SZ1g z-AZuLVdxQG?Ys!?${zYW6N9)x?n8=9J5}bxBjmTNbcSoG({ZTRS|>t4B{P9tTN$b& zp_>sxNkGcP%X&8%(yt+o)K~d#;SPJ$wi+bQYd4;_#utaMv-d@|)S^sR-8JlTXj=^C zSZ};frrf0Yfc7YUdgm0Twt?;4yDQ{sXK1}JkoFJVk_S7JQ~G)*D;;}2nV&iQ)b%yj z1wdv?CG7H48m5d_bk0RZKcM!;F589_Zqxz*xFv6s@%JZFuu8$vdgc9I-`x03x49u9 zf$ztWHgkn8cm=}gSC4ERRer78C@c>gCVk-1!W*uqvDNpflJ9Za(5-fx+BJIk(U|jT zb82^hmG$cQ-CJUOKzl}IGn`JEi-A_uT0ioz>xR$$(8>~JDf$jXS|U9TqPI#S3daqp zfid|*cwPU9cz0jjK)Tv&k~fhS)F<~p2k@Y|Hg7537=jmR*g06@z5|(x!rGq*h?DQ8 z9}@sL)y-P2)_2g^PQwh}s^T zCWk#9Dz*Zn&CEhqtofBAS<@wO7*syc{A;AJ;Wwpw)@!n0(Iz4Oz-hGP-YiSK5IRrY zrZknke?oA7GFLuV1#o(x0YuyaOZGIdA2k6qrbxJgfj-7~U_MosS=!VYwbmE~4r~CT z%l^b*mX>-$-Q=voX_*dS&TK8#J@B+K`+!ToNXO7PQMs-6gha!5_qX3d46fu>09W8bsFcpT_mpDiU(g-53uDDQvJI3MRv{Ga zdkfZwI=TE^F*{St*M`-^hM6bp-$j@F zcm=IaP2>{01!hf^Y#tFqne86K*mHxBSP@d7_?~oO&WsA=TYTrmtLD<9-P)~G*=e5&sV%Frq{FuTSNE5CKJ|31v~C@XGtYoT`aYF&DTO)d<` zBU#Cs&?hft>IPiK1tTU3TrO{nGU=8WF}MsE(vvnziI9C%Tyv!Dv9rZn1^VBQ>&)U& z&auVacE`jK(4f5+0RaI(r$rHSG-;RkS!J?u+=eha8@1rl7x}>@N#pBXx*DAW;8J|K z=G*RyGsoNO^#|C%)vZNz^5KWGT(hq@)1~5~Q=h0coBQ59G`F+m^4b7pxcYiqrhl8x zG5KU%ecLp-mgQticNL}6?Qp-&V=K~SBmUxeT#MOkjs6L>x+9;MBhoFQ+!DZ37hfJD z!bK=cl#!P?FH_O7XV0Af1j^l>j)-9cA49smaBy-t{nMn&6AQ>TEd5k=N# zgd7IfCbolV-luol%!8ZuLnVVeLKoWv>h22i?syrDc>)%7TBjQCsjNCffxpR<-w)k) zGVBEV>=uEWFa0YI<1fF_00G8@Zdh_E0gNkJ5xWnRe<`?DtyN4k;gAa!T?+ob*_qcx zBjFdjTLBi$;ySdKf*stJx3M0dijD!c1?XZ;t0S1v9(FNe zGqh(Fhj(VLB06}3-G5g61BO@LU-{j&wlr2Tj@~YO%#sdYqMC~&|_YlHz4r==loia8x;euwjui0X``DVKo1{$RPiB8zDrnOaeHW%H|Zvzl$g7YC&*w# zQMr-QWaVitkNNU?MgU&Ll4;EcvFEifS~+mVDh8O@ z(A{D=alySig}yI!B>_l-W58+c2Lf`jOA>T(bjm6ah8dw&ueb3P!xSdM0#3kI>~39* zpE;Z$+zOSS8(5Fk85^tvP>BRO!MhPnt#>@ffD~ZT9de4~0+@*7?Q}tT;xHG6+jnZ$ zX3eY6?Mj!^;V$Mg0B}>k7v7MZGEV3+%)F1Nwehvvl+igaZ|}-`adR zg6u4LOlqX|kM?%#wz||1g8Q?j@!R@Oz;FJze0Ca++X?h3Wxa1=hh5*&?dXB~Id-eb}1Xe9>hdQ!;Md zGWGE?cwMbQ>cdJkAOTb>+gcoLv9Mz(>Dh3MA0^?o`?S}@skCh%Z1JwgcDV4?c@LL_ zJqM8^U!Y;{P932-HWT_w6(gR1=T#srrqwI?wJzbG1-vcAsfRtjp&IaO&;0|TlU_J2 zStE*ce|>D}#{=&W0TI`_A`GZ*e`^65V1O4#-KA6XYnkSsrAJaA&?>Lee-QJhM1JkV zXHh_Y;R}U2zsZX1y9e~$40y5>|MFb=ze6&%w1E6N!J}M%DCF0q=x@yg&>DH-2U-4< z$gh3469LF?q2503*Pi>wYNe}Ad4LqXw%2}Bf7J4T{J_RFzcD#_y3q`SQ}YeAx^wY2 z^%u?z$WOG?koEtrqQ5ez&pfBJ&W_tj1b;~6*W~!W?*ISY{fDeu!>Visrasv`I{Z&o z$cQ6A?;#NxG7aenMya^}SJ2Cd$0r70)cDzv#tCk%_;!;8o6g}F%612ak{3c9tTm-Y zjA!tP$!xXsuQ2;~yuboE`oaP2l_tl@9CKo4ZKG3quqxs;KTqc$PKlpwj4e0`AczOcVCME_+@4Ue|EH>6J*(%ZaJ7*Lxo z^hnFtpBC-N6;*;TtFrPL3MZS7P~52+P4NIY=+SROKKOK$I zocHe}`#7ei0EFne2dYDrfNY;P^rs#MRQ6kP{dL4;h^@= zp4ReDSZZxyd^3&Zl}0M^zjk{2YahqX8lzUmSyCCgW)TCC?zb-er0O-kQxPNQTsx=} zW{#{e+mm+0P7k2?1k?s!FaV!3J?&PeObZa+Uhp5pLCq77h4LKylm18aLW(P0 z;Ddu53%anM(i4F6Yl%D8$lHpd54d4E#TQ~n>CmWTmH*nrN~MnAc9 zVc8pRf+WL7qe8)Q=5O#GYBjB>!U5|_&dI-Z<-clOcHxJM(qu%% z^~+iSe}#(o(xtW0D!Qn(j(AWUuwRgaCXD63YGFgvig*S2`J&=!?0(v2vU?Zq)V$p; z0+I6?0(M>FGq<}!)Z1+E^3vI@|7Q4*kBw!)#kQm8GrxJxG4I*kqr)e7%2b8_IjU?5Sbx&mzj3TPInuTCU!H>6IQ2?Spbc$i za0#KG&XA8K(zP&n$pDYiS%r>@QefMu{C?UDvhEia?>(C2Ck@x-y_A)~c$9}?2JQ)J zGB6$e9%yCCD{p=4zbf=fx+tLcVUb7TZ+zNWe+VK)?+04Z^W0;V{r=w+GZEuxmkJ&J z5hE~{MOqZ~K>%>o;KNb34Wb^5F=f`xzf7s5Rq-di{d%#Or0kuA`r~6Dygc}+hLE29 z5tCA(vG%fDhySL#SK&Q`ei~tlA_dBtqw-5)w9oi?Twj=}j{i3;47kAq z{klMwkpW2Fw#~_(ik>&qU%t|oR0@?zOh-P}{^_jwH-~h-BBRl1;$ar!2BU?*L7=gB z96$M5e$x*p@&QHz_5`$orKNxjf9V6);*-ljcw~YJnH&e)290;*|MXw}JlFsEK_ljW zJe6$~BZ@kK!HS=0{uiY8PgN2^YJSc5C&y2_KpA5bmsqG zj#9O3Xrpng3!Y<=wMaLgwFphy0Itev58lyh_X0T53(I^irNeWME5Q4YKYTv$zi}#K{M$O ze>nyGg^c_3$fZ7popch7oQ~wwjR8~_`|;A+B`HpJzvJWd*f?SJe}?lu^&d%(d~P<& zMJDnt01N!)b^@FYkE_ad)(w1eTqjn>2Sj>|Jys{BPP{tPMr&JI>sgk04al^X%fdha z7dGv6Yqnzw0RD}+ncj+SsNZ}hrz)Q22=Ty)Kq8%v(X=f<)lw+tXJDx)2i2zktxRP zeI2Zn`^q+|SIYa6WaX}Yy7f+BzdQ)U;_aJ~ez*jUSqL~r^c8K5+S~$sR@32uJM}S9 zFBw31MZs)jc3q}#=bCzbV|xlZI+z9@EimM6s^hj~2J4hN{2mHsmJVzC${4Wo1^#r9 z{?m{DJVT;He(Y5MwKAYz&c)ZZvf=48HstC4uBSL@V-3F%G3P8Cxd43 zF$(f7_XX>b#u8s%4!`Qvp6kUXdfL%tMApVaM0YwVuHGt) zcBV$Dz+J9mtI7uvGO0Y4ZH0!|Q6fMd)2cm`ak1^Ln>=AYrb*;30|xXi{U-DPh5NR_h?CEv6EM>ukrl(wZNo ztE*h#OgK28ac2@zVBqKKqk4_ao_N zk)shxfVq4m{NXI=4UVWY*(ToAkvPa=Il#AkYp9Cr2Mf+q9;laIxo^LQHx#*kF#`2DyTOp+z8sQ5`#t3yRk|C5qLy=8JkXuZMX0Y^@pgl}QDnB;4ynpRTmpjb^v$ zB6zWz4zAu88J!xF04V+FM%o5HPp>PFafLA27^9CKV?B1dkpPDsvKfA8JMe6-b5o_Q z(WyH;0ES~+`__p;lx7<7v9ay5I4_Pg-{nAi_R797+4+$&DAQCe))J-b-ofwkLdm=oxwwADi{vIxrfCw}8fxLw@mpUe zvn)JuYUDj_LaqiW-n~TvFx0j^Ys7S|JZ71jIZHjEXVYNJ!#KPn6^PH3P!KK_)OrmL zg{q+`UzqN6(1~2UP$N~eE0ey+Pg;V~(P?1$;)Vj5M#9xiub9nNxL~$oO{haf%clA| zu-In&TU7W4*A?E&L$EstyU<`dm;&Z|WoVHjHcrnp)FmD49M?rEcIa2XUKyIHQ#91( z-^y3E>3e{=^LeDiXuKZR3LniWtR%Rw81i;|sdph$8TQ(=SEohoWG!Jn8G&h2pl>bh zMaH+yQHacXx*9H(O5mu^5|ZRAyITQ16s7kAk&ud+N;#`w#xN;TitSNLoQ*(Hi!jrt zh>Dn|R@@=GrG&3^Op1Jkdg+Gg0*K{$*`<_sQ@);B$j40(JsD+bp<9C?`So@>_Q)`c zgNg5mn$rP9DR^(up23{q=nXi^6rd~T$jpgY^MupEg==;9g!AqJR#6&{H?-__Uhnpp zBi!7eHFVJ>ZVEXybgQ@Tl$A{FrpvPT)~FjgFn zbU{0)B-R2q7^X=!$+t#TJBF~a9xJRCO%q;pqrnmQVXY_Ej*$5RGIh6j29Rz z9rvdCiz#(!6oEa>E--r9xIRdF`z-V%Ww7En%9;H9Nqh3nf)+3$^?mMz^Ty-66FLik z81-7z#|xcc6c2D(X4p_C`}E1rUq>(0(CJxpTOrSsIwA%T=uG+H*+{ASbw4EtyFJif z+fuowAPe8MTtAKLZH~CkoBc%|$>$W=zJy<0o;Sp?d&1KoyhY4F!okKb#Cjn zC=wt+gL`lZ?(XjHuE8a^OK^7x!QI{6ZD7G20>RyV!2RdiYggU#a^`u4f@0A7Crx_8 zZ*^8s9Gl8`*nIugP|NCkAZWg7OCaDPcE;QZF*{Q*GSjl9)MQsa|5dqMjQR2Lac6Lh z_4tHB7Gr34%oLTk*$!m|$l5D_9=FdI>z%$J+Zl?&r!XB#7B=Ye3_92M`g^Zmq+-$O zais(VS(3}9s%;XLylbnrC?Fvc^7Iz#n?j6HGH?__z!2yORb15EpMH}=BEF+Z`NFD$ z9pBM8J`N}P)^4J-Fq$0lkqoIkix9=YPprp|bDlC52%DBa9t)X3$nsz+pm!4i`eE%ej zKn|4M7fFBUx|*CI(LdOho`&==@hpSx17MT{-7+2#UK^9Y?sMgRlS8-)3Oj;p-az89 z8*A9A$O(EXr?0>$3d&QS*9@F*GYwHN=47!`(mrb}#7j0o#}eHej)MGq#d+3ZZI zIhaf#%;J4j4C;!})@KU9Xo$tOkcIr0hrU01LM?vqP5sgu#gI{5p0vEx6g<=PmvN;)7M9`?7oK^YS$UrFby{2MOAuskm4o}KeMh)TAZN0R)eUr z|1Mr)NO#g-9__+^AVD#I#r0oc4GJ+UG-6YHmVuxxu-yF$= zp;ao85Lc_Y&SKB-LAOh#*Np()w;%Jx6ds%@2qXEvBX-=q)$I$n;eS-(r(nC<3Tri6 z*t{AFNnTO591n#N4hf~>>)&LdX=(!GtO@8W)|IYrDC5@{O}z2mpSHKhkio`(TbPW< zZmJ*Sj+6_KeK`B}@ZB+F;?RH|L4_g`Mibj&J!`!Mya(~xHfAK(?bkI0s*yZ#*jHI$E&R7kYM~x_{h3WhzM*;0g z#YTVKA+e{!ZX(KQdHZ=g?K;70^_nHY29GcFtM&m)qw#CF^^-~&c=S)IAw+YwcVy0@ zfkwI2cTGYa%o56MnZhoKoxTv3C&XCOc)a zR;B5*5P!j9?2@z&J4rV=KI`xdNqzJ+Tx{uKdta8me_9Fw~!+KQunSSx;9FHv-|QCN4%w+~kob#nO+Z z%CWo4zY8!nee1hH@l{jmvsA;I!h7?R@W@+nQH+A2YcU_S=`RX{D+dz`myip}CGwBs zJ&5JX#bk=eoyQkOE`FPAe+^>B=A4R(O-ae8*rxX<@D9+(#x_sV&x$JWdQ-ce?&$JK zU|07slPBD=yt$8>{?me>xOYOz)_9SYNS!nHxCQx)-+g~GGCe-EJ#8~BuRx`l$hEvw zL&ujG+EYVi-z8RtI}-i;5nrfWmkY_slbo&N#6+NIglM>FDV3H-ns?Z+3e(Bg_bJbbLq>K^3yHdc$sdl+6lK8HQ0(PCmZ}u{TU3E50&^4vbCc` zIDs@IUeMnl`KzwF!h{|~nfHT$wUpJyD&}ZBN!J)5F25U^+xart68%p>=nw?#Mz62| z*m#3Zj|c?p&Rzd}9o1tXD}i2;W4=rk{c0!JpKJ#Rx2v<5_S5V3!Hmo1OL<5vym6E~ znx#W#}`RwBbfxh!~X zRtu4hcJ>5vX|xJ(KL-YEhuc}uL)Dtc?IH7Lg6QP0s<~oiXw-(yY&(OWz`X18#3nC< z9rruOdlep}h<}I0^F&~js$|5qnNpzwc=7!0~S=XJ?J~z|f?;Uv>(;F8ojwcGK5G z+{OFZlnO4VU9K+zKEW2#gZv&52^6y5)M|8a(^<@GA2VFeR$Wgwy&+I81cQ5e1fBLk z5uHyrxj>eg$J2F6Uw5Rbsde1}msTbYz7jF)N2UNXu&~ZjG4ZcdxiEbLfzqbKMs@rz zN7{Hr4O9p%XV2&;Gd`||1G<&R%OHvS5AhOepnQQt@!-MC4%+w4d3xNPj_u=Cn(&7r z`1o^Icc=HgqcGBD)&6eL#%wV3f(XFWliy2RZPko>t=9na)~Zd_<7WruSm zGHYBRG%8Q=a-|j*t(s(VbgBqm-?SOa9*gs?nDLrqjJ?@n&xJd277B^C+X!}78i8kG zhR$2j&{q4$gETZ$WRi$WWpEqS_jgkWc*>|SRWe#jo~=?KD?Z|ZfJvgtn$2@UC@GKB z#{F`m)Rni0ZLRkfiS6254Np#O)}WKC_?AJ|p9Bf% z`r}l2T{q)*VG8cm0$JS&-9}I@3M#`d9{bNGLn{5Usr%{F!ago1uLUz)&ya-z{JbWh z3318;8W9!27Ke~iZTb?IswQ*Ze;EmdAmOX& z-@q#k*hYVg>A%HbG5#WhHfd(S=Ku%6+@$?vm-@x_2@A{vcQh9kN^m>U>U_Y!U9aqZ9opsrc_P=H6D3aa!I0 zY_9zo9_3QR)?MA-l2T)7-R72Nc-0^Y`adT(h%g9yBLGBJCK_I=mNvz|H~n`cCg9+g ztHevK&kEG;RF-NpYG6rVkc7~O7CCxMn$)D6ux7Okba1%Rb|bFy_uKGmAt+VZaSi#I z0&k0klM?xi7$p36<~D;@eU%aoq}#(4!|EIXJ3dhISM%Q-q$7RDoJja8y@4<|LiOi= zLQY*a|5pnTek^Grp_v#H70Vak%ozP{XIWlS&?Qr##&HA08EPH1Y{P$fgwf(e#n)W{ zQe^YWSh$n9qXOhQH+hjH_*Y8UA}x?MN?6?ujDa2d@#dQKLvXN=8sh45)d!~&^(XDx z1CDmE?}Fw1voF|t50_>V#Wz02&lC)i2-Fe%vXTSw)3yh^G1CrW&3X^6>)k9pdJ%;I zywEp%@KeV$Fd8FOa@~An6o4bKqQj=MN+F7g3VXv>GlRZXV4@qWZrzc<+?{YoyrYQdNyx#M${~#rb=zq>^_khJvTAVgV&VIJ1yoMh zkr)$U8uWO?%^7De75@-u@e$0uZY=P4{i=lg)&3brjWKLx zn-zJPY|U%%d&t8ejf5hIy=6P=z;Bd!KUZ&q#X+X>x$Wm_G9>w&bvs02S4u>sFN(Me zfx%Xb#;-H#OIP?{Y@v4lcgSBYmbC7jsw2&oOVu&j!2tn6KAOU9M_YRA6wdf3{k$e! zk~;2uezzY;ZIfBOIXXQbkg*x{R5&qD-XDG2o`v)_;FX8|jx=X2{E1!{ut3JW=l=eh z-0nMuCeG}7{Gqk2t-QtxXcmx&;LGHXN8wEUze&L63utw>XM*#8_Wfrh)KE~ji8i_; zpK7l37%r;n+)x*)V3EF9{pNG%=5ticg2!gmPrdmZb?7}5DK7PE`7&@J-&(pOr@iz{ zY|VD1f!Oc$vDI-?)}HpBQF?ap8Ydl|7|3VB<@ZKWdJt`7RAb7iTz48fsmCk+EL^(R z1E#rnkBC4Jl?s)#JD%6J&b8kOPAJv7;w>29aeXGRU9Z*d7Wj7RsI5G{DlYg+R!$cI zvfSxP5j3>#UBNZLX2gHpOs`nvu-L45G@bNv)j~y+$>zg7-)y(}{4;~!roQrLagQbN zCtvvM*Gjz#MCJ_TBi!nD`-sCrx<)N8u@uSnvZvxB6Y}Ms+w{Eg&$K3>p*4N`^zoz6 zNREHsoy{h!ZyJq00nujHNJNsw{F3+UEH1q+2m7(chm!qiUE52qF_j^6_ODlM#8_7= zx%dM>-U3j0eu2&K;knu&prsZG^H5V*P3IpxKc_E5R%S%lRoNmDgBcBJJlwukBa`-v z58cvS&5tHy@V=xeFA?4NMX)r85D66s@}hRns{5n$Wg>#z|ISG6=_T0LaRxLljbktP zA%QtvwNj>?t;-J5416yo-xA=Whq2b8EAt67H)f5GwCQ+DUcn@(8DuoXHr9IvcXKU< z`K_A+ZZ3B43GR5WxdO))!Ts{V11) z79!~19_L>Pd~S!&Wu%l*1<*b#6AHEO`{LhVSE(Cf3DmB_oW{(GZ zwfC0B!Az5>O;Z-vOoR0#r5^ACwcU`P%Nd4OzYI`X7ME)DVbp0;RC6|of9Ty{RVVk6 z*RfUVBB|4)Hi6<}{vWDD(uaOnUwCt=Xgt=~F*xN&alT3?pE*89CzdYF9qIOn=d)B= zUJSR9ez&|7{L1gt-222+0uQ1Q^Pe2eEInP(VdLda#MyAnCYe#~8gasap=9A3FT9U0 z6cDvNmDv$+zVSSo^@XpH=y<6LlR+p22qBEQGN$#{Qkg>`j%bF4yOjVxyZ$+?d<~)e z!3~B*RCTZ?VryjtA|tEZXlc$}4u8w*Z&i6yHQH`|U|?XVpUmKN07eZAf;YuB?FNOj z<9bj+wNrR1B>6_6*TWG*5Tpq*fTdkud}H2>!e&%zF<@P(6zcQ&$z)%MD0G+_gU@Mt z+{k@Ba)G}f`u^5McQtl5oz0)NVD7SAlEd31S|D+^@De@<=0>NQR-)|*ho?)S)l_=H zI_Yq`h#F6;9$h+Ks-S?j05Gpq!6>5yruB{sL)VO2Nb+qipIxrgt&$I^6&hvXkkDQv z#{I$97N{z^drxqw4B90AQ;A>6u;{Z*)e=DEgl+*6h$JCjf`Kh2Py2>w9{c&>BoL3i zd<-JX!@hFg$Bm<2p`p?>*zI<_tRGrCc)j$zAeFH=fG06w*!m&6 zVhPktI>Bwf{t@>UuA8yQ1Oq4FbZoKfQ|_xAl~(t$X8Y{RkMRg4kH#%4Zwgg)VL3eW()E#E6? z31KfYMr&O!Q;E$L3PUFCBfV^iCbVe#-Q72Wp+()A`TI2ZH;L8Bg;UZF#z5+YkxMyBT4CXp)cQPN0?;MP4jpt3;p{j6-ucpKx&5qwAW z2m^~BQ$Qr-b^XlB7fJ(TAV=>mp)OLK4Cz%!k~~t<(9@(-zI}ZT>zG{{kI^= zI;$urCqsYf1X5i1-N}f4m>UvR*txw}@fTT5d!w0acBeTx+}SaZa63BHGkEf62crA= zSN|usi&rwIZ{u|DbmjOF@KQilbV!&aUgMKWm6ZRQ`^Bc|=%Lkhk;)LlctDc<3<|Ni zTn?76w+oZ@?7|7imCoQTY+dej?Gkchfswwwdr(gzIx8q3m{pM#y^e>xCY4URpJP+h=_kJWTpMIiyq4NMc5N^{)SZ(Kk zM!bJ&&dfLb|JI!Q)0H?>vXSwuY!+7nP#QfUgHQ$$?@sZ9owl*X4douCyA2i?LM1H6 zuUAnJY}vRnmQ*s+uq5>4HTP|+K(WT&Is-_8HCnk|04}Z7O=7>jh~VmQ!+D}OcNjV-M;+Q(Mw^Oo5m6L1BSh)Ryo)RDH=E;bBrax7*S0Pbw|dgfs1~ z2sUmrBx_8;7+zX~SJ;@Xx3mEv{FeFoi??Oy@t|Rl=JPfYs-qs0L-9ogHy!Iu}hU$li|69|iA{h+PHYfAS>SVW*MZ(kdE^OervBBW)1@Qu1S6va$ z3lVM?&ud1p^uOLqVRI&Y{f_*R!=He)tdR>D`AN7}TDeyO5;ndP8eKTqWo$>}gU3|Y zWrIB#oFyhlfZ2GmoBplvq<9GuhbLI zoHHjmC$REopNKd7&%>h0P<|5LIL4`1+xMyH&WzQ6d-~liBC)bn6y}iNzhm5VA<8e4 z*J%K2^6chtyXH24C2S)Mt@- z6wF}aDec-~x4o0$S=}WyMOGQdga`+U=i+8;7hsY(hO#sjYwn|OHp-2oS_=nf#XU0shiiwv|&Xm+a9=YBC1E~+W zh?I$yS`814=0|#Liz9hpBMLTv9szv=nos|4KM*?dU_OzM^-}StNDMZ8b(@uP!S8SR z*DlF9{?;KrZO%Ul?#nKm`R+U^Wq0<*Qjn^vWy)*-0H8FlEB;k>OdG5)7?GO|Jv^G$ zui;hS7^kQBZ)=56;7`(AqFZKm;0fQo_;FFs-#KM_J77*~9(hm4y;CplnI;{q3^(w> z-a+l_t7_Y1SUUUXadA(b|GBg9u-ZIQID z^+msPh4l-es3-x-^6K?;j#NVbW#4!{*>@D#w(AA+9CMkp-rFPeg*SXoJNgQu zh)9AAj%sBhFMKzsXG{g1Cfi6uKV=af;AR8q;kM1?aa{JIVP79wf0oahu>T@Nx zqK)=+P7XthGT%M?wA>}j{f$1}~C$ z6pdm(N(Vr@qPd>1r!YndfsRvTPnYq}I8YaI7(DbtK1!}M=yiLkc7@5>8rEo-|HHfS z>x+Xp{Bi`0??7AMk0(5VJql-Md8u3((;Sq{f^)Ia;m+lBTIf?{c9s8`1Xnk;MA5hQ z`N4I$)wp40Qp~(?waJE5A#=Ie1qpnqxO}YtOn7(9`jIM@HU%N}wMEib>VC5ej>%_` z>*-mM&`&JvK5yaIZ3}h|%o(rC5U@#H?-8zX5=)~E36DdloN&tHBS{2^C{&cj8z#{(|KGC8l(AHV|P&UMDTStwu*)eLv-_0-TsOhT1 zX(!;}&%q_q+60?PN;l?<}t(jYeC9(JTIv)q;y17%U}9pb&}}BHDE-BdZ~YacNK~GEszY zbTvfclqR3~-flWV>mOGn_Y2xR<-4>~ZPvV(X+az{WHihmgD&OlZ;Le+hv?G%_V}N1 z0#PGPcpJYWpB4q82q@XiH&=rSl|6LAW{?ld@oPL6cGg!#ov zCEcgvaQ~}J(^PhTvQd*c@P)~Ao>{XLikYom<0LbfqS~8AbGqgth<|I<0b~eT@Wd%n zSr8r1sS-c9Km%|63;@?&s_0Cp$xjQr$PT^~a)xCu`7+cE=dgRM*kIGYH!jbFNSuzv zij6qiRlNrCZ&r~9EiSpP*#OI}@AY#xnLoUvy+g#(>Pkn#3zmE8CIEUgz>KXU~ra%@On;{yU=h=kJZ&CO$g7(_#@&AS+8|B;H`7HIF=~GP=LSUHE+Oha?ZWG zMU1}bc2s!;+!h|m{8p$KS_~7jVYgrQ6YzTte*=f@Ola@*?LEuRQ6iaR(&^(!_3Wg# z!3*#2dtPk%Hd>YitGYyexW@gE>(hT*nPG;n9K>x4?zGm>%hi`BAvzYxLW_p8i>Yqu6wKL zS-9KcEDu|4svxtNA~+W9YVw-q^M8X<%;pan<2oH1H4u5EJl#f!$kNqo=(Km|fsGP#qUx zB3;%nP}Q^Lf~^6q$7imRW>+Ihoej@>NNovRSZh+UfLkXS_H@Zw3seDyjTU^{_IytO zp3#SG*yy@K=#52Cyqa5;y+lCdur47I`qezSW>zcPf(k8lPrz=Ez6YfPoRMtr9}+!T zahI>0&Gf-u;_GDVaqNUz&WS8M{gNitFKv+q=+dC>&CFddl*UHL)NeWvi za_>0uC@D03W229(c=TzFHBheEH-NnYa~HLCQS)oG9zK&;Vs_U-kHaBXPN zLoDzOAf$U%CrcB8lnW#l98vxk_BI}%PmQf&2r&EFIhX$w*ZS}$Px$@eLQv=i%Wm(p ze1>nFKv%mqyJTGB`Eu>1YI6(-A`$0ex`)GfKiX5`X5yznRwbQElQqTeMEV9=#@Jnp z{YKx^hWGc!t@px|Hi}c`^8X?IqD91uo0kX=Y9R~%nI-@HSdMEt(Fo;zk3cWk&Y|Zu z%kbx@5e2~U(^W%yj>u>Tl@1PhrNZ31_o-PELAkp+*B6FpB2MvYv>rnW8LWYAQOUhJ ztf-IBNcb!ebtY}bv&reL9@~jN;NQY0qQ*OcGlXmI>d>~X)|w-|fxd`PmcY(0nd2Aq zeeR|Cv`2WL9fythR(Lt}erxqI&d*U&Fo4bLl>Br(Pfc^V`Hm6LOU<9g1MKKf>5NQB z6SHYpflf-~_4MMD@WV?UkrT!mz;1ui=Xpr>MIz*YaJ8Wo7Em3p;B@$%C(3zuW7s2~ zUSFhCHtSxhSJ#PGTfbY<^EOv9T@Tuv+IVq%TNl6UGAc&_F!$0aPEU~BikzUDnKiGk zD7aaN08aNl#qR5$(to!57?Q+g=cGz`jz-s@!yLOkPoT3Q-n^p=N z3zU>Y$&!!=D@uPIn`FW?i~3%TQ z70r{mS=8NUYSiB}0c_p}^0#Z%$OjLdDCUxBRv##a^cfl*=p`7^h3?r^&f;I|{_(O~N8|B$!@cYpDW>LZ% zKcrY~Y5y)+>#Iy#nYr{_r={-ZBapT>jI2*xEEVa&#hm|RLB&1iiR5KDsNQ#SLb|rd z-O5!L0J~VN_0vb!`ywm9d-!f08=`O&22eu1JP-~3Ha0agY%j;(k+?cyJpe^w6l0;v z0D~w`hrP(s9X2q#0#MCk-Pv^g5hH(lu6opOxP#CvMJcI|pk#F@8Gu3>DEw4VAG2c5mW;vo{?z5EeUn=XtZ&H#_9K(A@qISVW^@0+R3r%|_!l zkHPcpd0cNOU-&~jP}Uk=-ET1zGLe1bTRnPR5=3T*1khegK98>SAYJVYCM?*8A`=Bw zXjW&eZvarV(X$Ihfa#>u?cw*^Gfp**DuV)ei5MK)`pA_q6u-wjJ1Tay28)MpcPW8=rDLy@PEEkMq&ik$6G-|I`xFrjt7X)I2@{u zrT=uIO0R)hR6xcU07-s={5v)$Do^5V{?Td-_w{}+kap3|s$0EA<%qe!74r1@TDVHQ zglsiy>})_ohy_y!4gXjZ3GMyESMGho%xkdGd`anYp?7a|>Av&Zn@z=m?@c<9!eb|= zB@r%Uq2%B4UNS2J?kQjfW%dobdkV!Sdab*OeewkXIFt^SY}E0S3W@)-m{e+S?QEjI z5)<0(dIUt5{|Iw{*(;VY#MrSR{)laLBCX z!+{dwXzpA-ej%UQ2t$#LYt@iwDS~NwnY#Y$!rN0Nwb(7MBi!|OoB(($bkhOGp#*CC z`N?r*XsLelkOSCE?hA?-9`{G0>wT4MM;6Cr@^C7taK_Lszo)TsQ)&=q6mf!9wO&U= zh-?Z~TR4Sks0+0Qx!^w%o%ydx6??9(DIupw#7EQ4*R8@Dld3&H&*ez^4*f6elTcud z+CK=-%lmbK_L$3YHt=L0tau5bx<3|Y3dWS#D-#G=cG_f5oM`2IC)a88EJ0~QLX8`* z^&ai@HE7oc`eawAIQeQfXDP=cTBFA>-alJ|m)C1?qS$@}BJqe*&kQE0KNc(f@8$EG z=Cg7ChLaSe;&ju`9-|0E^t1K4nOv{%)^zWkLR{Ds8nF(Fr~_iz)Cttp93XIp(V$ao z!%N=$J*7ge_py#_BG&b0->&f~uRw3B(u(Z%d}HI-Q=B|t_v8f;39mWcG~#mLFhO)8 z7N3CNNBv%Md~)e)z1JSvlZ6em)HCOw=^Rc%@kk7nk$N|xeueY9lcmdcA4~&-v^s~a z9#~98zt=oW9{1++>|8(u^t(-#vB?{-7^_K*C6M8-Z_E+fueUm7RY$5V1B~mPTA8ZJ zO>xsVq#!`NS?%N6CSVI8jV*_EA+PL9*=gPzV9fQJqvC1wP~DTjWPI2oS?TweOK5;> zMA7ujPC3_i`K40t(|u{SL&;S!>2M9q&&)0sNcqvrvmx`C;Lf#sfEn0eVk~ zoermDw~uF`3m$^DW^8Mn_KSr-?|PsB1t{C#y44Cd9rugY2B2Lv6@ZOz^n#O6 z6$FOK+mfE6TT?dOqRhjMxi&7EeP%jo@4XpbjLg>@J;54bhF3ib6RIzbxpRWjWm|?W z!Eu9+%D6)99#43k3||%Fsg)~<>n$cR7>>?;!)nb({8owq;+I-mj@y&j55&iJ=gaWU zXLIe?+SAt63rUYs1YU^w_Gbu(yq44ocU9Mtf?T7Y}lco#@g z?gM3T0(Ib%lSi=|P~$R?Y4KJ6tp)lFL8bl>7)RM0n8vS`3bc(d`8)c@NeXN0@~BpK zN}%t7Ho4^1o%%F3{BX(7!sK1GV{<(kTG{rLgzpW5x`lVH1`*y&s!~Sx zm!=sJ+J7ac(I#JG>mws|z2yu`rB+!mZYVN-KzoyoR+sl;sJjbE z`nso+$&(5NG4T(KEp??~5Wu7O88)n+0*D%)c+&8D(uuf`1&F+8C)w|=__Dkw`U~$T zUiZ_4HA_sP*__Iccm!OIQdI;dUl9v?&K!EGhIc4vcV&H_-+mOw;Nx+Jzf~+*QU}=r z%!BU>%FqlM$X9F|hD}VVd~TZGtOMwqV8?-bJAC4DhICy#Hfu=391Ewr88UBqjfuKv zBn){ZLVh1Jq^P*K8pNJ1A26P$^MM#ZybynJv>RvnhZWjz7P9|eF6DIpzk{S}(Hpea z_DkqpB_0SEJKG=<-|mwrV&1$^?MZ)&6C7bz58e08yU9UUbVDu5iv4!V6Hu~5gbq5@d z{D2??%RBHw_6CNyiHOJ#)Xx~v!Qf>7Ij-YGfo%M9d1aAlamg>eZP0YFm@Yfr6bUbBhWeEVaP1%ebsuGY zQ)<0oNMsSP?|KX8gzTeS6PJLn+J5l-{Upn=?QF!f{&F!~!HCk#%pP(2$&?I-r1frU zYnMQE?4rWm0s4B+c)`EpE8X0{}9iBCK(k0T57lwAYni?-t(^Icb{aL zof9kx>R(dVBXr4VNrN`S5%hgYuk3obMU&X&0}UklI=(0<`74R5v-4xh*Q?tLrSD!!;g{k7arrWxlez z(@Cmtp5ymj%Uy<_QrWGv5HLY0Y%4?KX*J)^cg%OkvY^k)MB~7xPd(fFS>8?=5vH)j z!hCyU=Fj7kYY$A`eGb<}X3}V;x3!zc$NwWt+mj|2eRgL()a{A0<9#qaFxX@4ya1(& z%}Id9ZfeJe{oQsz>P4ppX$p4nujA4mVdE#dSRZ-*4ddx;p)~q>NM=uY+)CHjuMA8c zb@`^sT>foeMLi;zl&|W-9BU&LB1k5`d^ol01eH;Npu(Mz6c~HM{n)e8St;`Xe1>u)o7qNS@x4vC8lSHe z<#?&4pn0xlv%z=G5Rf7_3lotZsx@ekHNmHJL6R$99qtT`e-5nw2k^+WIH>M&-0n=% zdzjvLl}ewzG@dW!z~k|W*1>B+0-O3L3c~&*(^KsQK$PTuPg<-KOAL1AMnM9fo3OS+OzH_0*yhp4-6sCTmF3&k;bV{-zhD`8NDmoR_!srGmleJR*#;#DGc` z5N4=KoZ0M#(mtO3aC&dEkBEjy{D`sfvrr8eb9^f5KRQ>y1L8O{d8Hmt97_vqnIq-z z=LHW~MWtb-_Ko$b%;d7Ud{QH7#Ij3A<6jrzZ^xnCkq!L=FZQX0z3KqntlTt2;#iC6 zgr_p#0y3HAr9m&iHqronC%1fJ|4xgOfLjHQJqEqk)#H+3Fs+ zWS(0fMBUBW_v*C*NNY&J>#r5;VH!W$`5 zh~0~exGUBDzk4T~*LPk`6}et}*Voe-E$73V{&66|hr`*$Qna}a_X}p%MUzgi8;xc_ z3UhlpBpaPxI-yFZ&)XynC`XX?J@1C;>9jg^x+xWe;U+rxIfnwaZYe0OJjjw*b!@{&)RmQR-;l%ilfZ!gY+ylNyq@33#XPJ{6~=i zZK~RfK&LEae{R8Cy6a+Dv&&!XH<5C7|8rUW%rq%y(1UEMB>yUjMDjdLuUm(9hn4cL?e1XhE;v~=L_8MTXq_3+TVvpq zYYs`@qAsd*-fssH=``6hRzQD+4DX3Phhg12JZi(b!KO>7NTtt;1JtUxY~DBf^j`O0 z0#25ay+`|DUJoPm-hB(a4i_r$*Vor~r%BB?>{jV)*SdAjIBg-umL72N z*lhEv4O@*U;W259nBpv^vkSz>-K^tnrcTSK4LYTwpYMzxM=u=-`Mn5yUy#)O-%}ZN z1K6xo@CjAHZYF!NXZVPIa0A}xVr&8A<(c5$&FJ=CTd4ys&u#px;8HcwIr<%guIi1K zKRY3^*F`z2Ey7{QGVEk^hj5RB7Ng}UQHcG*VQ~Zl0dE8I_rOqh3+?p}Or6O+7b5`u zKhB!umn#6Rb>NsN?eX6c=!eHlfeTCfstZ3?63a=t)$WTu9G8*bT}>o}#&{e@E09yH zfNP`l>G*Wz=1|b6_4$Rq836qOSk`1d42DV;lJ!59EI6)Wn0PVFLRnK95@Q0+=v5CG z)BCMDiore0{t_SVSFQ?5y}NAtJua3R-lS3i;WqmLtXFrs+h9MPhk0rhYR1_@X_%`x zFko-_^BO{H?I?A47#8NDV=-;m?~v_Z=8@m8be^egE;aVDNSG<$j4Ci~FnUMY%jTyh z*fg6^>PKEq96^y>q#39H12wj4F~?xGvRgh+IvDEIb5n{5izP{TEUumdwcR_rYt|614#T?NKjW zdx{X?b3<}7+a0#~dFgOC$-9C!G>k$qOKKYVc=N3) zXpX@5R!gg-VdnC73{>;~mVp0yy$HzYTVnq4dQD~dD)*wo(80tHW*$s|F>T(oY82jI zhLMy?g#^OGW+Tgq(-`#=PIl#=D$ z4*2L6tJVUv8?Z+O29aJTb=f2mL|{nlCj_1M3Ea-sqr6d)OIBNKXFl+Ixzr6(EuCm$ zp@KPVR;6Hv#4rbGm+b#sAie(qoUiS9T0n^yw2Aw|FEOIfQ;MlDXhUj7e$L(QCGN@6 z#q>GK5y0iqYKR2=;JaQBRo0qqwsg|rG6AZdBbDw+UMI51CJotguDD43<$yW{M}S2D z4Um}~&RGyEWFmH9D|EU$A56xON1$y#-5hY;ZZW@l|A}v}s~Qo=2kyY-T!}zE)X(Z4 zais)mU0#?^+4pyMLp0M()_csTztdT)qJ>k)0n2BeykyW;fd+jBsRkYAdb=xJ*gI?G z#6P8RomZ>E&GfFJ*g7S$R4I?3-fS!wP`LlS9h-v{?zPi>7pXUs1{?u1HCUQ;v+ng< z1S|D_wg*PIe4ptS-|t$41%c(pWbZ$en`)T{MJj+a^l$JZW%GHKzu8;JluYXdMox)N7P~S{s zv$ldKM01k;`5g(N>I?N3nxsO1%Rjo&Yjlb-1v2wMaoLHzfb)4I2<|*WBURR;V5`;z zP_HN-bQFAf-g+o0Qo4Qqy7FfueCApJEISvx8A#&HNnn-tDU`#IM8b}^+u7zEdpYCy zh?8}s2`kPL_SQwY*`R3P-wz;g2~4rHk!A|{p><+JInY4~?OO~%xqw|__(B6vmVlAm ze!J=9)V>}P1&e``QGR_Xnl<*Sc$M%raC0mFe>+uWG@tgr1%a?jNWdL^{H`F!gZ~&%R*bdqm`-6~ZuTVB7Gt)L z%gJ4b`XLgBM8{$OwFGR12Q)#F_to8QbsW}Tl_y_?|BXZ!?GgPoScg=YO3)frosrCu ziiN7g!3$ON^M3>D1}i zPbR-#h{iwR0o|x>%X#nPr@4M#{P0W39>2T?l9lJ|h}ipnkIV3{*9J6oK#ukYarnKc z*fOs5pOBD&KLwl_INrM!cGg3YkHXqrQ~Y1FIxJCz&`cwM=t(<&WOuErZUZiV%AMgD zoB8wgHiW~~s<@Ris%WAJZD*`e;#gp%nDJb;R^EptVD=%lUMRPxC#%+L3pMn*<$QXn zIuVGx!ODky_Ue0(vw-aUG>7)MU}yI7-%Kp~4Y0`LR7&j64B?9~gr6QLN6N|06E zJ*y4g%*+Ag_o|wGQm>v%;zWomjxYxX)On81vcNLURO2d~JXNi>cl6g2wINopHf*xk z4v=I=OrhLShg^H1#H6?1g(`;>0EgN1+sSMFXmHV9^93A6h6hf~Yf$tr2@MEoL^T0B z($hm-yereNO=x@jYSMQlI}j>?=k-*s^f6a;D_1_03Pr4`6{mSfq0U^~cJQ=!P&2^t z%mFC%)!FVcQlo&e=R-PCeH=fvyO%+b-ea50H|T)e_|Jn!ZK~aiMOr!&PkptORi-xL z8>jg^0flP~HwKz@RyPVkGLr4C0DB--=L%*KnQSsw`( zDpWD^K`P7QnS3jqb|}aMJk=V+vrS_u{0OU!w!vepekm#Oql6>e=iew zi2WOAjq-nk;2sd%MSv4Ke4pjL5Gk2o_wfrRy#~%kyNlQ_w&90jt%fii;J0#-ez`tBEO)Pw=0ARztW{>Nrz?*KFa zTUrq*|JN%jzJX}6#fW2hc5AgE#j{l$HN(1L<#o7SU_PeRsAgV$$78R^*NkI0Tx^O% zL`g>=j`$wDk?s4w14wlrFVFeWC}hG3+MIH2j}oO4NV(sZ%6(gbqdfu$g3QEez~!>- z4^gFfbM@w`84uHVL8JC$PBFpuA7+^|@{@j5E2t`~L7#Z!SGu?+O2v zxKqvzILo820`^D{X>fz>iVOk2+pHzZFAl44x3ksJX?EwRkIeGv9BY4^mDC`QH=EGQ z)hnW5V|2v00?3E&uiK+BX@L}F)ejinw}+7g-1RH3sn{t~60zBqO#T}e`@N7|<_nFG z(2}Em@-Xo((2?afFYo+xv?W6^g!t!H{PBVg_Q}-Bh+)WteZ9gmM8!~20Ck$-o{6v2 z8~6dx?_3y#f1W+0Yy;Ya%8}%U1UJ3gKI02)YaHp|SomVu;C+g@JPAm^90s(h+@<5F z1cN837EQov=|mnGQ-NMyx}E=!1C>x)^S!iF<$3VuA|E5Xg^ab5v=rxk*mR(l=b?a? zU3VzNca_mWr^~d&M+Qy!wr?XaMDqqdt7aWNfFVC9|BF*rsel?FSE@kHEDdhVRri~x zi^r>Gn37og025|(07Gutc{B_VGRWVP&`@P{-oZCvWwVrK7oMD6 zJ(dIBDZT)URSt*SEx&=&^`%CJfYhS7@jFeTF462yd6@WBtJ~DpxAr>ht!-QbW74k{ zFS&@sEB5gdM-r0QyC z!R8U}1F>@d2dQ*E+?_#YpUCvGx4};z0sWE3&I`fS-yw0HIJR*7B`2@>)V8D5$hzzv zpAgNO%~AAEfDTD~RqK8tZteeWRr<%v^hX!tGfIok+aeL;<_lSK1}jT(IGm;hl@Bta zL{R!j-9;b%SpB{~%uHjU6MAF;oz6yY(cRr^X}KJR`d_ZqtNTmG%7?syN5?N1;qZ{C zxoyrDU;aP#-ZHGpZfhGB1Qn$uMY^RGl`f^byHr5ByFrldSc?u>bV+w8x#;ea6mWrb z!*?z3`~HsS#%Di!zwGyUf9*dW9>?Okt}*8rgGlQIkPQM9 z3`j#016?s9SncT{;;}=(&H}G%Sbr)%r9l@?0P*y013R1jWv2C;H)KE=5_vn;(Llh4 zJp9~8HiM6OYXfIEDSzY_FC-K!GQ})Zpo*kiBTuQ2wuSl={m5?SgC2+cnecs7;C*0o zELs^xL6f2)P-;-|sMe(HK1#sRVfT1(+Fa;@Q{N&TgkU82c(35M*(+cY4=W z#@ByFF&p%ak_i;*Y58S@u1sI`+sC-p(*TmYOsm~|PcTRSXvQ)3tO7C0LRYxjKx2u= zNP{(5xvuH5Rd9dW3K`=ZvA~2>@o{G8X3%bYG)1`RYpPJv2XlO+R+rxhiCm1dS}AG| zp>1s_70+pfb;5^8c&gm{fn)SFA3{W?p2y-dh$hpWY7KyGpw1tqmRtm} zYlq0nJ5CM_LX!TWDxGVwIEVN{5;#<9Ds-m zQi;E-MeMma!x*R+*34C^kPr?b<~}FHTPjjqn8t>4k*Z5_j$SPhtlh zx1jkj{_~9wqK8Db7JK%<(e8bFBGI}dc#|3jSzp4(_kJQ#&tv{mjtBpPcUfNWJ{<16 zy7;KIyq_qBs8uZjhFqMF7b#0aPVfm9Yrm~R@-!T`BQADM8wE-5WP*V9E8h??Ncmp( z&)wcR9>i9kG&-MnC^A|&*W?*a(r{;CBX-lq()DOP?7j5kwx7If`*Z>brpSLad0D+U zJ#0RjA7{@yF9+HZggoNZseBka?qD|WrB?Dzof~Odej)LXtf88&mrmaPA{ z<@_QrQyjL3A8J#`+boydzciFq!?fSx}W9b_7YX$L6XMzit7 zMph|l=RxQ+jvxP7!VZ{+<1C~<={C?dMBdT(d+1E0vmE+`!u`xr>d+o?qAW|DdB-@x zFM+_M=*Bm%^`}15pLj&XYr`|c%b=deA%adyB`Bu#M8Mlpa$y-d{C(0itu2}4xyut^ z9W^T#n#ePBqSn4-SF5F3cAW+nrt!6&SYpmHLqTuE6S;g9G@!ACd>Ak(BFI3Qw^!5E zToADB^zCrgRpAv9mhBo8I7|;TbbxIDT{SM)^IB%JybR!MS%U;xjSSTMFUcLoCZ=%Q{zXa89S<=5yq;iFqTIFH*I`*v^s2<=dK=&+EGS08^0qvZC245`tKYt-B$F*wx zt>EvE{e!9(H7q!S>GW4o!5(coyU#xhyKVUDZ%f+*bK2;U>a-}(`H1AXg&?pI2Jg8Q z_WDJiH!WkvL;j?6=MO{A!XFq4|Lw8syy=-!L;qj30DsPWa}<1u*l}s3HttaC-#iPm zCgOPTH#wUfenpz_P5Hw(z;if00G<rKH*Q zEPYk~=dFDJAwE;3jiPDQr&x+lJsSh?UytZ+--o{;?&m+T8Yl+jeLv%e7)I87D~gin zqfydrSv3(#4-UaSq)a^${61iD{JUfQciIISY5f8QH_4%}l9cfy;w26%yuUr?1^dMX z-1YB7{CKv+hGT^U99<&%_C#oj$muKVt)&cG`((itc}SwIu4vW~L{kLT_B zQ~$4TDE@brlgX!EO2)enlRQ=pW!V8>zzKNm{f=(wTXSLysTF~0CLFkTR%f3$k z3i|#ZtGo2=E#u=;hB*7hNZwg1!uxV$_mN#jWACzu}*&+2f51I?fd8$S?fX=yn)C;6(QJq6?fV2Rcb zL?14oNQ!b|`Ry(I?+Dd}_llhS-u?T2o&vZ0EUW!avQs9eajP%bsm77{?FZ|2${zpI;s`_Jb^splp-)sk{ z$7a&R-xmQZo?nY&ogsx64iQlZyp72@k(Ueu%e(GE_Ctpb7(lqiuyVjJpW$7p-LlrJ z`_kKs+t&w}4_3vJV?OuW_2cI&s6YtyFRh)=M4M-4DPKpg9Gu_VvDUl(%x49%PxHEk zMD0210jOjjoB5yIOTD=Lb7$BvWZvdMa6f-pm869z!hIvgfm}HW)Iu<>^-`gN` zl|@8DLt2g!#HjY6XAo|HG?Cv88ixD^jelRL|5(+$A5mit!uc7$2(g6>=51^_%e{N3t=atu$H$YThTDzp=*9RP2S0f&>UTQU7BF4?7aVZXyh0I6 zl9MAStr>A-!M7@QX+yFg+2-BdwPa;j`--~Lf#++VJZla@txdlp69=n ziio&k`s&peRtVK4wj`3Jd3dK%4HI&s20}KAYt{q2nt(km=DvWX)gZN!8BAIbP;{WR zV%pc&XBF5i&O&?TMRrNj@v|!GSO7#$MZkCem7Lg9vfE-_ib&XERU|xMF7@H;fNv5> zeAi|A?{o#28JQAUD-@+~QPhyOnuD_iD(o8>Ll)H_>y5Ta7(c$}%y``x7p5@-f`Ep; z5*uHIy}!Uc@3p`i%=6ob2EtU@x9HSnrb!T;ExGZ5SKA;hb29IICZ;v~4xGeXlxJjD zt*)tUZfip>S|sOr2<&zH!;4hV-zXjCxmgL)2-<(6q;`b(Mo^T_)E-G$q`cJY3b1Q2 zzb?W*;*#jpWR^W%)jO|Qe5owIdSxL%I%`w5<>Hc1uTO?hf`F16prB>6*J58jZOF?R z9gE>iU>?t&XFq0NoJi|xCgdk?Gz5IZ?J%aS z@h~Q=9sG`)$_ma4rH{qJnr{t_@8OM5zZM>)q&>jqdPh2nO6JbH4K$6u{;B^W*nj!& z_Xkg^-urSObPYo)^4)O8I9ZF<_S6)vsiC=w0@Hq8my&|M@r?ecgdv?$UQG~9ik=7f4D z;@!_LOC$fP75^g{yzT%|rLouXOUEyO>~3~7mjCE4{|7+(+Zxea3WRQ;(8hHUt_TM}uFT{HU9ET|s;2KW^no{*3lay&MJGb|2szpd=h1~2!wu~K{+KMX zn82q5{{tQNq6=76&F7LSXtgB`?6d?)@7x)d+|rF@KS&zX@nCD&Y3bN9XMY zx6!mZa69=;%^a?!2p+&!qSiVlZ{#R{=^3dU&>F&Q!wdAA`0QVk;Ju6z;T6Nf-zRb- z*Z=c1WNE-0-~YaqY5i{viAomm+vO8$wwr4k&~d!^s}zg4RIc(L6~rvw;Wn5G&DF!-_sD*R6>t^uN>kY zlZ5w!(^)v{YA0MpXxpz1vglJY%glWEKB;~W<^ii0S=loc7u@1IOl_p^m!4*hd{%{; zz2$WFuuz7Sk&`N8oMy~cd0RuFxaVT39|eWtqH&6$YH=~sW8H1{yyYX{4_z-tmWl7E%+N<>!XJ{kj=Bp#CxQ!Mi05;o-YC;v+G3gJ{NDMO5; zhiAuxC^UD-@~lrXIG($l!ULu(_!#8c3|nMwn~NMEXQc`2$htKX3jX;e zfB8o*N4GO_nL!lKGlOM=+YCf}2k->O8gh?*lqQ_D|)Vp2Z*XYHd zh@2}^g&ffMm(hpk)drEQMs4!2HG6jw&=mEa5kGCL*9+TT{@o1>|8l(}j6B-R*FFu4 zBIGwkLC9S|S3`mnRjUWZKaraP_($C0^`KW-0mwqj{EAquSYm$wey;J|aOl zO=TtesqdE4dz`&9FxJjUGq&&7ZD8Uo)sI*(3ltaMc!j925h7Uh;bu@1!3SS$MK4Gm zK2v=!+*4J~@uI-X_v1&CD;20Ha3NF-buj)EHSIcW4pl}ajH|1{biAC3>L4H}2=qP2 z7Q~uN{WO!(q?qmC6jo<5?=@e}n(FklN~mKFbQ^3b<|L*v`TX1(8bkhMa(wS264j=5 z&>?yOgTYs=`Po1uh&~3w{hPvdb2@-)>-tte12@sr!}aa*iXtkE^*S<62BW?o>sTZ@ z6v>@gZqGgE2&m21w#JxWWSBdjY`2>ed}dTQJIb4@fat`ZY3H>zDqcZlxigk0PBv}U zPtEC6pMrT*Xi{Gk#p!BE1GQ^5ig=d1l>VRI30)95=(6SN(x>t$@=96Egn{8cRg3Bh z=*!01F-z8ilcH(~OMfk}yL5lT0Cv8m+yYr}pR7pD$M0q8&7-2}f*UMoOI*sy6$V|5 zV&^D3EXzQGd?b{CmUtF(Gip{eI0W)Ic#K=L0U~`eID#_REH2su^>$@3438-6zizYh z>fok1yiaI6tyWPvn?lZ%OED|mDh@8)SZK2OX%-TL@&MG&RVo-K=@aX7!)3!w0$^~d z8(}fIAyYLurd2vqGQzWU4Nqok?FX50h>4jDKlMQm;?z*k9@ujlKVjXq3=9hb5s`mU zcmkM?9}SKFcW%bq^iG^otyhl z-NGKl7D9=hUJg2TlfuJoRa3mEer`@#lNx7QojY!2x>=U|dK$%W^ub;siBKtXG%miH z%J+N0c;q!(GRBQF*_h+-{_%YJC#6gMhQlas6fxoX3+=wS5L+X*&mQswbCm^$r;zz@ z@g`k#Q-0CLt2i7eSnzC89#LVFg-tUmp@$iBu{QqFcV^H`k^tWPdlaa*2MH5qM;mb`jQ&S2q`5jMi;kvd-FvDKux zyKpzZVs|PQN~?QNlzTC=KO9=RG2%JZkI(O{@VbObm0KYe@$&`tsD)fHdM_ zu*7Cz7Y&xHapGgJd7=h0EJK12eP5} z%b<(umW`w(aX@l~)?LcfOzRVuu2^ydg-y3Lw$hud7?@_A%r!rwULyM-@#Q=9v4k8+=8xQQt}FY1-irrYG-B zWQ)v_Cakl&G<83PZfUz3?B~2yD89@9?o{l*o2iee;4`>spr;hluGcUedC(_j;-9ju zQ*0n%q6|>4*RU|nqj6#9cN;3*dzC0+q!&(Ve5Xrsho{^JL7f2(D?hrbaa=`T z`xlh+Y=@(W=@xL%-v$Yrn17aL9wKyrsU(e@8WkEiW|%G|imiqOLbWQn$;^qg`lBGg zRRD>#H)UNw1mYF$9S~5%%J8nSl5#L9U>ytVT~mIDOqzq_;}`llKc;Frlrl{!x^{Ou z--?3PXG!?rUOnUZugh}GN=zwxV+quQ9qJK2X?{<|jzGW{D_?vW8>LuNA~>h>G_F#Am;ssoLW zN2;bM>?U_J1xa7V{J3hOj4*$j;lag7S|lN*wA+CMsihn@t|R^EuOHh$%F9gP^FgX% zwTPRJ7msv6hx-MjF{U%Mx+T&cap)&)aCdXImKH62NLnZ8IL4ip6>QT<0CUoI^|MdkXgCjIEj3ql!+>3tnUlsuN?jcaDF#dI7>#| z65KsA`5aLO=-76(yb#|?9JnvKTw@9%{@};PNJG6#7+v3mj~*F>vFb3rxRi>~JrEm+ z!Yk>j1Qx;FCG1iwg@x3Aep7rnV<-y-ji)eLIJvKQ?+ux?qr+-gQka<<%yp{xCR~n4 zH<2LS;v;LsKPA#r_FVqoe4>dMbzmVceh_-Fsi*;t1ry?orj*JEoaX5n7^~)|aSK~B-ZTQ>V-P@$>URir zWXPg@gnajI_YCLok0_u04zD++vzwH1HNcIb!p68Nu>;b(b()rpn8RH;FKjj~nY~iIx_%G> zX<_ZtX`}=04iI#moyUqOm|jOejm!GByQ&ySLq%3Y*->&sce^Xskb}j$hE*QbS6n>1X)U|&3r|E{uB^mdXI<_>%2X{R2Gaw@g;`V|MAK>K zaWLx5=Uzchvk5E4FPIRZwaM-#_@Ks6$!h&n22mPlG-a>@BZ?Svq&4QvjKPcaeuUSu zfAXqvtZ3+C21#(?Q)vN{nPq|+2Uvn6iWuA-=2g!7<RFj62 zXBP#UK=*9YxO=c$!E*6EZ0%JzZtPq0Eo$0Hyov36cUI$WW0)}jA&HKQ)Z^0(7l>rY7$O%RkAFR{XIl^N9fA^>YaCZGS|9~BMXkZQhnFfIt zmd+<_!+`ipC?zsfqSFg6Gf4wg-A=B(h(Dcpue*CR)4J_^s-N9rK6d7|$FPSAR9y4U zI2f^}Y%13Na)XKP{L-X*Zwy6j1B$L#1zl`nHYzUO(3aeYt(h+h@kNSk*JJNYH7qhI zKCwX@8uPG+NIX2FDq$Y3>K?y)HM-$xW#tag{_NbdBG1d{90qoXjFS#D`nmNH24yweUsP075?oX)W@c8~`Z+*x0y-Qjs~x#YHURZ$Gnqs8*aW8B2{g+%nvYn3aAuExGLusUxN zz~)U1Q#l**B-_)-x;IVMNbP%ilI1~b0Q^xrBtD7Z9e~JPbiu023nF8B!iw3IQ&UuBVIm+Fg zjuzsS!tD=`sE8Ez%0gf86J~PqFQv9eI)MRkz(N!c^U&8`NP9)vIb}~sU9W@^kNs@6 zH{o>c+nkgDm-CKa3{j(qj}sN6&=_h#B9(-j+Xtod1&qLunoMF>ixF%PQhFKKQeqI} z>T}FsPN(}&mPXtNV~VJZZY{a(SZWL@CClTYw~1aj_^D*F;qz4aG8fszs(i8z>uP0b zJSuEWt#d)qxUT)s<4{^OgJTWEp-Bez%phiVJzXVP+3Y5=FLYMP_Pu1a#) z$c$=fT-R27ZEILTB#Ia%DR|@L!MPk9yMDZI%&WJ6-67y`%26s*QKyl9v^JD02`-KR zx}6!-(d7CAJxW23K+5>grTFnj{l(x| z)Q-6tLYC*3$D&yUCmp5vF&+Y6%;J|r@3cXt^@OP$(e*wNpom%6v){d8m~tEmH@^|} z6qO3?Y4oWuA#9qk=nZ8CSB((KHP|0{FqS`)c3iVe&`deN3P&5Dv%pLgVFhskKylB1xYV1Z~8^`UWJ$}Q;M zuJ>dTe(L$~L5SoYbaCG))tC(ThG-NL0GPWbjRD)?TeC1mden7OP1#wU?8E=ekZEu&ja0%}molxU+WYd^d z7xz@#{v5M`w*29SWcJr%I{3g?HzAGM3-H8?5){ipTm+yj+0^8m)5zkoZ-73-QBo-! za|3d*Np{QM=YO~@PtVH2Zb+5jk5vH~Y@0;Jr?P5)ZXvvGx!)Nj{6Ly;veI1?9;Ii9 zqD8wLkfKT5)A)F^H2JU1oHy_dZiKfFjm9f|;E3+yj~cNmo%l!}#H>r6Arcn*8S%sb z*u0SYcQ!J`XaNt&j1F_ijCYBOoI<8!WE`=QP*N(dJd0GfiDEFYMZFnO`ZaJbPdLR+ zy#P^EgaLl>XGUMDyFdPUHlupI9MDKkarqP{=--&71y^7ICpxKel>deuBOtknz_ZZn z_vvrAvGK?Do7Xn5UB2w<{yOyEFfb&{p9BDla?4`K`8Vns0D&55foO000OjTDn~}Lc zwn~}}frQ;|d{G+3zvHL(j^X>ljpMW<_imcj_@&>}hk(Bu)_w@OA*K4`vHuv&Kh))a zjOHJK(SMBQKSuM9Y~vqRU;M{t{$n)%F&bdW|G&#=0>@2aBGT{;PQI8LDE^-Rg@}5S z6%M`%yb>S1YaOPvvik126+&)%mj~N^uWscY`tmd*@VB4y1iIR}fsM-1KB>uI>N{Ct zY!d1Q5~A0Ml(&#~8jiFOMc)^W-&nZ!2)5WHhyNVjTCvJTGhC5uEwFJ8Ft!nHWYOFY_UhBqXukc$MQvtH=DmFI#Qu-RSV-cDc#fs zsEOAx^mgSV;%KR;`5y*y__KuH+wi+))?QclA;L+5;}mn>nwI<$e*1JcqVYpuyil;H z5SD!znnEsBMk2eVWKTt+&BZElU~nCS44cUA5=hbhHzF_gz&njBQYxNRBFrqFn#zz3 z3StWG?GsC(C4aak7EH2|@SFa0y<J8R8`1;bkYE|V` z{vNof%kvp~gB+Lef5R=sA1tFoX-@W5v2dGfkF5An0y#v7#)y6|_oic5DCF?hkz6FE zo7Rm9yEaL;5XB!janAuoR70zLj=r$_ob*QatLL6J7wzVSMJKz54}ebHx`P9T8xAEPJJ>czp&D#mT4_ ziE1%+!UP`El_Ou*@zp~ysFS|}pd8Qk4=RdfWTQ2b&um_p2WIXEI4~g>g$=pPsaGo)?bivRscFz3CQ0IsBOg>nWdh+$+2u zlQhpG)e~$FOv@lfrG_GIGSw;%Y_u0n+i;x*jRh@YtWchG_Mb*?Trc7T3h?RG?0+mH z7ovO=+>QqNMX14iarDa=qTD3|ZI5lY6&sQH!Vyx#FTbUJLE-T@0TP-Xur)FS;UN!e+2@N zhkHR0lD|w9An}^Zc{OS#u&#Sc)MF%E3HQG$)7JHc&0new!D;=3xM?TmVs?p&KFpCJNOrQIO%Hu(5I3k?K9tvE&TFT0d9Hs2fo{P# zNw9-#?qNjB2a)UWwlIze4RuswPXUs?1oy|L?ebHXs9!BEEv+2q25UT^_w_#!m&~EL z{?dC$3C)+CPYT7UN$Pc}1n)q}#<+n_Yb=WN;q!-thCGT4g zt=Rk0*%O^ay-;r@Tn9LTTleAL&IGVR_KrVE&QR44pmNiCXUAr-$Dj}yNX3YYDo9@+ z5Tac3qn!IgQ4v@lK2Wt>RgKCcV!=O;`rGFb`0;;z9_&o)F}I^c`d_UZZqc{!e!iG{ zEBP8g2~@020p)tYBLr#*Nm*#c0d^+J9DF3exU z7DS99MFsgHDT~9dgpdnHnzm_LCEc{@lL9CZpcu6g^uL+k0Nnh<)JUKaP-pm@dy(A# z{X|F;z7;K?a*&h%ydyW-^$J& zBl9Wf`U@a>2!Q_ELjt+Ua+4@|cLIPyAs!ARuItY4L9-x}Bxw0~kL$c3I+ywS&+Agn z(N6vZ4*^(vYIRTPre7plcS;+uyZ+<3Kyxwxn?%4+21=A3UN=}f z#$Q7Th7UyuDepWjI)~yn8PuAS1#qpy?0Dq<8~Mq8$&bE+&i`F4FW}m8CBTLElWOj5 zyD;1`C`7&UxE+^Pltuto#QoZGo<{wfKnO^P@_&3yfC!=dH}7wL2seeQ1SipjeSW6j zkP-8jDR9C~A;U)?medaGcOxKvP>r2K(H9wZ_rCOX!rY93G!tn1y_bCM+g)Nw-0O#D z#5xdDTDg0w0ciDkC6v~M!4*hP5z&W?$9S&Mml8UJL$AWfBAsgT4wKXFJIiE^X_b&@ zYP1$PxdP<7;Ly*VJ5h9sG*v6iI`ve;S)O!fholks+>K};elRwKr z+SSNPs;5k+V=zdKekR}05t__hb@jq40S*hfRG%$o?@X3E2Rl?~)x2Jg)!{`|JzTA) z!evi*?wG=;eVG5kV&AuZ=7JiU#A!=kF~SX&KN{QF3ABDaEehPHP9^AvI#&}B4qDtU zkt8+9)X>4Kc0B?Lzuxj$K9yYUS*KuzA&Ue7AgzDT32Xal9T9L4=)3O-*UJh-W!u$0 zu(D^tvlsdOrVW`Yy^m!Q^Y|9}<8a?{tj6Q@W@^{5WvwM&9qFob4iXQ#r?`AVR!So*Gv z@UfD!X19}FgY~nqY4mQ@=&N9!{WKgF6)BAumNZ|!aBAmCnvm?TP1&jGvJoc{fia!?SHn~Zpi#EMcay+2 z=95d&lb!5Trg6DI3XJh01IOO!Doe@1MFYluPY%0){U3wcXH~Uyo`wr=PF53z9o8<0 zotszY?Kh+S(Mair4SPy?D(v^T=(MUMlDHjZ<~$rfubgZs=XWMr?u*M)#uf||b})cU zees@<>G2b+>?hzeYsE+?nrN#Wa+L+@nMzL8F)X?=55gvCE;Gl@n)0G2U9G-+KwgQK zC*_3Qera)f;Hk>2Rcpj4gWQ@Wo$}_?Q7Bcd>iZd~kh=Oc z4So_HTE2WyF_n~3yd;j=OsG@T?ptX&PsgM=TW6?Vxi6ZlP!pwsjLY(UZcll#Mh~1W z0hCzAkb>McpoPtQ3hy*VTXD?^$Uoir8W~V&h${ zF`R}PE_H~R%(2uBNEMTOdbh8fH&z*Q@@_3md@hkz8DYA*?MM7DuZG)`+)c>JX63f# z*mlkPrMB846Zx!CgDxX+&kEDYjyvWTBQ?>Dk5ZSHhgq6JA}R>k9;wZ(UxAeDN*82J z+DLdW+y)`)l9N@AO~$I0T37yuI^BO1aC^t#{lbrrPX0?eJHSe!nUFnykz-@Vf3@#Y zQ#Vq07GV5QweVDMwMX}jGpxqJJX1LMy~DiqXz^LjzEe%2F+sLWD(K5LT1CA|iJP;t zp#cA|9<6LV4W(#kNxj2vDrKpAN1xJ3(Zq1S>3cLzPoV#}#(6`5dYw$-T^wv|%2)=~ zC==y;u@#9}h(|*$b8o}R=Ff*GhttA9eUJsG$2n<@^IjGXgNl>{_&)g1d^)ZVLE)g} zqF~GTO3kxKbzV5^#L2g%?JcK|Ns=qviJo8TslfLxw#ZcV8~Kh!!+VFpLyof%L=sX=B(ySiw~p7edb^CWYb{uCvj>5SEzkc;^m;q?n!tiy)o)K z^39t5i^!^!HaA=5aUNu;-IIL7 z^Hi_BTwKFy^svNWlg)T`m9u-e>Eg7^;NvWvVs>{xWa>n+VwsBl$^6lwxOfq!{l<*6 zN^v8Y@#H|&cBSO>VEJdHm~;KNhGcNU3uCG>!+2V(Y8ztJFnNUjMe1&KbY+!y+5JjmANHE*_(y*D)x~~U5|@3uLc`W< zZFNkD>RRL-o5ibW^HJ#8p&9sWyPpAYM)_&wuf-BmB|6C5ne$hLn~UFhCr-Eh)Mu;A zr^)-vEi8|Q(r?%Opjk}fv6pb!cj^5mgxe6|0MqFHE>B9}KumZ!_#~dqJ&P_i!7a<; z(D~1J(+eQTaMF3`2b?X6p~q!5RVlV|&H?y~eC@$^g8=Hds2b<;zcgGUl86RL)V`s>(tOv7I&s5{^$+=IS@5xFssj8Qp)0%&E)R;-l zvQnhe5lY-&wg6Dh3P3p;sU*e>eu8Xmg*Hs|t!eYgwo#W4e)h?y4Wp`aTUS}4qjor{ z)_7I>-(NE)K`z61&)jIcBeiSoBv>B~$09*S>UAB`mzrf|)%Sy-QM3-Z;y%T7qbdFC26)95a0nio`D|MR>| zoNfBhz5A4R+^n91{`1?GJFL!&hJJB=g{fSQ%K;cGnMKLOW1GNLS_%~+=5__q#41dbVULTjiXQV# zj_kT!oZ7D>7O%#mPapO>#-MFtKmrBM`tlzDg;1k{I*ja0x0UkJ|MS9Y3?7*cR=R!WTzV5 zgS;TD5PatIb^`)YZnV~R9qfZI8uPrAxrn1+FWWUYV-$hvJ#R4 z7MpMLuH3CTw;N);^y?4>i&JKK=hThAw$iblM$1+>15Ba;U@+&L z2;$-WcChnLc==+zX9lW0qt7zPo^;%$@}rR8=Ia2domz7---*%MbdDYW(&g91a|qllSAWhFc^1)b-2 z9j{IcPlXLuVgRQolnCa6cxjIIgf}buq24}sE8b7G8v<#1lbGFKalKd7ukdjk;3*@r z7WINGOf_(_($nZ#5hklPK9h_@6^m46vclT(&M}Ws6+1%dwX@UueNeaO?vCj0Vlc7d zdEMf&hfdky2LGEhw~GTu=8FwZjSw}?aEYfVN2220%Iq1Lr>tlWg?;Uu3qf;Ym8s`sfy)0Figt;22mL%iqLS4Mm=hBi3N2il z&RXT+&`kxGpN7BO?aFs&6ddF_1kwT7P3cMgw-C2}#bOMpNK}p^!`~;$(Us7g&ZM0; zrI%!gxIRuT+IEc)IIsd|<4n3o_}pPtF#u9$;V>x(p-aFOwQf(N=vE+W$VV6zO*@{c!0ADtYG&!cfm z<*XGpmCI(leNzpb)@U4fkgIuDw{g&N>{INIx#a4PPScfz`iuBW6{*St1p_|RsB+NR zbrBXRQ>q4CnR>ws|FU^uJS0WYlbY2^hk z6$0I4Qy$K*4S&pqKeGU4NiCyDkPOi)&?(yE$xx{S=Te1__ic9fjVH^k%Vsw#AGF88 zC_Z&LeR_L45-Ac0gi8_yK5cK99-hci3vsvr)sn$e!cbL`A70B0ypdc7KUa_-adD66 zv@1)I-_2xaFxA!Mj52Fh)>b8&#?r^?PqG|2aL9zEsJpf60w>3|qwS;ND{loUPcqL! zj$1{u+T}S$++28_2JHn0R>U0Gc@IxxVr1h0w+lRa+2A;jpkA`*$UVfbQXDaqiN%i} zM-9|;<9k-gkvO-yWm`@QTkJn@O7L0^oye%-)8#k?#togFmkRrp(D|tZPkDKuEfUX# zIzCagbU#}9UZ+|SEfb8_i`vo(c%l8fDlk`fKseuvm~SSCL#d|Y&F|Nyq!W-7;V^`%#G<(-#s=D1`oZ1jY44*|Oip!q#xf_e|#ccj05&h=b zZP_aa=RF>*i2B@hQiGG-ddQ$2A8?W-%P4}L+^D~=P@_~wqEAvG_?D=Mh=h|rq0yd6~<|bk6o(W)m zO;xN2o(r@U9wbaFQFuC0{RB89l93|Pk!7DI;chiwV;-&F6$2$p`@kEUKgv35(9DG( z?#`*3Ya-oZZ9*Z@3Lb`tMY>K?6#vQYIEr5RobHZ(-~?@M%{7Q7R2Z4(_@7d2@9pR@ z>PF=y23t01npN$lW^oeI&&##_{cCDhmJZHjmtLY zkBQ!0=@tj>DIx+{pBz`=rwGXJDHIm;Kgi==81VDB5PS>aLI)tR8V}42fXX+#|Ji^bM*>2R^;X@BS2E^ zQI`T~+=%bpi*%I?`7h5e(l;v3$LFcY`E*?AMf-^0SvrRU`6cl}GwY3g<3OM+wA4Vt zv{9V;nbQ#M#^RMuH5riUiYhbADEE-l%mFiKwr?GMsr=L>GOB2Pw|GM<(}p@%DL2Xh zj3zp;F=0OK(7DCynyEHOq0r#+66L{zQHT8rAR1YD;m)H8&Oog)pC^xu6kQq0lvJp- zqs!H(2wL`BK*+vuIoi^epLWgP$!^cdGmU4>Y>SN*0cMC|gjRH)DNdQ+n~ZQq*<>l`>uiY_YAgs}a1Zga%s zz4Pw!;3bVl@rZ#dv8toM#$Z_@>e&Ks_d5O4u~KDC$xmr6>5AF-`aRzxr=Eo&u0!3g z*w1*a95R5TTkl=x_6eRFO#GD3YEl8tb-nL!|9MHaKDuYnE%A1|Sa*D?&S?k3Z@0&R z3jmt+R92lo_7<9D{>W92gxkiUsZYD!JNP&V9?tI6JJ?i5S3N4{b!m97_Cka>yKzDJ zsB>dy?u_*D7Vd~ip=9G(mlaedxemH9dbAb0zkJV-Tij`BTuM4m{%BlYelUvNk|bBH z`i}4D#np3=NgQBv85N4N!TvzqK80|QSnuOeCT^Tf1CHA4 zFVcT$5)NkIfTt-x0Q~_z((_xV?PN8Q`OL0X|&!N zqM*?~TRG1{Gld9vpHE%5Ee~d}9uBu^cZ>+aXf7neTZQ;zN76jl3(oj!b_f9K!UH43 z1j{7TH+VDK9hM81bXG}1|4#9!r*VF2|yZmGorlaN0ZE5-RKwfrdeZ-TM=5=_a z3J)TAcRO3ew-8}@f#wF`q*tPcu=(OP{O1NeRMah!M#1>F%vzmRIYF9vP2k&e1ZK`U z2kSZEe#Tct%K3iF{i*YI=hbDm6bY;TPX0CrV~+e` zG!1!={HKt=p6;aroec6)bUj~=W6D~;M1Z>J1RWIh1F?x@>Uhs8LM|k&=ArK6Rqves z!v4kq=+D{j;9*+Hy;bQ7UE(s}rbWlRXBnd6eMy0~G9yH30ETrByro2KTG>W(R@H&c zO1kz_Xj=g>%LZhXsbO@RSTLF0@>Fqm#xa#gqba?zEa=kd z;y_jZr@&H)_=Wf$6|={$3uVnV zx=FT>b!=lqk*pE2XWuf)zRgT3`@Zix%~;1W3^Qit{px<6-{<$f@4x==;rd?JaUSP! z9OrdaJ$(x7Gl(lB;X}$SbRHJ2Dh?EoC0<5GR zCw^CkGyxZp%=uLeZY-{IbDLoV?Yp?2-Z%W;EWoG1yYpJvmc>Nf)(0S)V}tanXH_qK zv_+W^XmoKyv}iC9ho(C3{<*l??Lw`|EcCY$= zsy$z?5Nr)}hNWN1fEy+H>hwDMWolh_i~O~LnztVrVs}OLhvi=z2cdU1p)Nq+e7E+7 zYLfF*52#27a7HebdsmlzROnEk>3k(PgKVnPMg*snz(XLtkcNBT#OF7wT*dfg~Fk2aEzW{bm*Y`f&g{yRfX?r)0 zPld$lPFC@jdmBHC^wV$f#awrVDkW9#+y8!51Pr_Cp1950e78K-y!Mg}I}FNYafSpm z6lJcJAp@P4y-yri?;J>4(&z{#6mP7@xmu37z@8Ak3v-WB=3~cVpY7o;9QV<6+l3{Y8(?CZs*P7c@Z^ z-k2fhVYsg7oc*nc>7K5tr$cjw3LH{u95}I-jn30N>@FF0SlJCH%n3I_H-IbH$`h0E zKb#C{IH2%xSK1cmuM$V=T;@%_$eg)#9J$V>|Gr+Wcl$%o$n35Q3H2h1_=l?kScOd} z!${n|6mSSs?AN_HB==am1#TZ=!7xk`BwvSO@p$5DyDBbEPU3rM^g~9*fn+{8EEgpV%U#b$)o&el zZTJ$P>(bZY#GsQRUrF5q3yaoM^v|CHdmsIC?D@#H$Jj=zGl}F6lf2*_OU<_p$vTYD zsSezJ*Owg0O8h*^uJv^JAw1t3I6T`avm7AZ6p3*bH6A5n+er}B(zZ@DF7N2^v`jgp zM~09dXXmClfo;Wb+(TB`j;rn&ai6f~Sz)%dy=J1;yF#DMWy(A@y&4-C9Lu>87Jeyd zwcG6TUa`iraFoh#mN-38Hz%ZT~U9a$m=lwpmA8G4<*Y(Y zZ+$Ace`mFrbW{WXDwU~jdr0URo`_DPlg1)*!rz5|?dFsA{Ole4JKz4D9-Q{WVQq83`Y>0S!~YU^^$#i|=dS!3xDZ^Aw1)+SU@lpibY9 zHZaM!{B2x$;#DIT2*lzbW)fuN3EbDY56K&E&6Jlz{FWRA`ugjQ2SK+El<#6Q>lh{P z!w7`@rG<5*MQeF188#DZ(3*+qN&9!=-sf zWqu9(-i+Qly^?;Jms>l30aoz%X$UPK3Z4IJ2bhGN%fE`{c4uE>cvGsmG4@eo{*IJX zxp|an`0UlMHr4v7hGGH5NlJK4Low)t{>3q~RufEF=BKY_G^t>cuG0vX-pKRd!I*-1 ziB-eBsdLxOOvh^|Ly&6-7B6LvgQp4BE={n4NqW&7wQ^!^1@ApLMa>^NK+;ZDa$0g2 zDm=J9<&g#K91{&*cx9y1UhF}urQ+=4myh*k3fczM%Q*)cHjqC)s!I3 z8f1yi8hsL=gVz?IYjQ+q3U|qqMaa!W;QUC~HZdemzOz|7sBEUr@vHA_)XkgejHd)B zlowg>IJ7iRhM!5e$ka?s^QhzBP#adwQwCEH_Ut`r255rSYT~8nSha28uv9U5EG*W$pl9i zkAC_e89U^E4T8MYcbM!^ej~BIf2Up68Omhm8|z9-DFqpMyX3X{entl4YS(EUpZtvZS}Z=SVgm8MWhI2EV4%9!DI@gp8x|Mr&7SLYYyFC~j4 zh2$q-OHI*r9iL0blY3pn6Sp%2`5A)MasY7gUKYKtr zFv3Yly!_v-nSQ!|)eODAYKGr_6Q4sO#Dr?zue~ckqn-3Gj~HMtbsp~L96)!qN5|Qf zD<=DB4FUS>N1c<%8$(B}Q-XKmbCQcHUv!J+X)=xfF`sB_;}(z4)0ZJ}H*fbRO>w`^ z2lR>>cm~Y9bp1Kf&e0Gk_I}dtYmtw7Gbm1JJd)Oy#qFaJ!rwV+z?xNm$`hL3`rOPA z27u~KVsiPEe1>kJnQCv@kx?+d+mv=sUw~w}<$MK_viQ9RSu$T1tv3Y#GZAmIs0vk&MM&vzcMbI^4r|04;(& zhj(m$&G?@ExCBTcdbY_z#b@R>{c?e8`fqe*Ev~n32~r9XO*P%>DOZ`19_;smo-}f* zdrP?i>$>s^<*Ea#m2}ZG%%%@=g0RqQX$MO!o;i0}i-yKviRa}g5OY7T&_1nEX!51B z?-p}+VNAMs@1Xn4D64aNSDS&LzLhC+l5v&m22(e>oHgE}4%T;f&2BMta?dZUo%`OT zzVlO#Wp@JH2xz8nX?)WKd!&dp0TXv=v-+n5Fvw&Z(V@jKlnR+D#h~yS7)9<&ZknP{r5kyr$ z;c?rFnq8T}PQUCZQz+qy`>CdGf3PkcE^1McysVvF{IjReX!XxU`j33UN1d;c|EkX? z@+z^I`T837r%9J~6I4zd@4Af~(TiWvQ|bvV>O$yeMrf3?xYkaE2CKt>EQ|Q}9|6$I z(uJ0_j)<5W8(yRPT;t^*7Zx&dO{YtaUt2d_(;9WYFY7jU_e6PvQASs_6tZzemqRJg zJCQj8Rm7w0F=Tv<`AvUJ+`wIeh(0giHIQ}^xY0swpG*A#lXj)TXRoSpxGkk&L_}_| zrzSjkD4Kiq>5C3U=8yha8lsUMkFRp5e=uxJ#q2JXzP>_$|01Ku)}W|az%xO@uWOx-!Qlp*U3b*Gf+Y|D!?r92A{OWz#vo zhAAnxB3Y#HtHH*ao;0N<(;+i!L4FNf`?wXX0k8a85^TNO=rdjJMY)FLqhpP?IPLR`pOwJGbIG%PM-~HTlvnH}YYXjG^4qJ}H?mDwKXT zFc&xZpN*2bm*WgBZp9W7vcZq$k{PO__sT|a@R_)mc-d#P)|j5ubg|Mq z-sAVF|4@9_lx%yY$1e#Q9@A?L7okO!0(dgY%ukv>@X?d`%xL*!A zbB_Pao0D^Q)UGLL&aQKNfOQ{t6ID8{g@#Axg{0t|qDYk>MPI?5yibttDH< zWvf@K?P~N|2!*I9z3K{&1MjCH6(~wk^F5yc$IZs!u4K#F14{DS3-ND-R%i!8GF)r7 z;+G|zS6<_04d(;#Fv_nuWhSTSQtQq7VJ66NUL2>u{-0i1^gP>Mfg0zRGS?;FfI$K( z$<(4GSq6KoPepmIwf?#|Czf00W8*QYF;wT?8(3h9C?nXj!;jl%WbJ2^mhIc3$JGh< zM)$@nT=YPZtMztt<3POmVhc6q_EoJvrTxDJ2a0(cOqzV}5qf1^*5X^v*I9kWP8f$Z z<159yei>8eiY(a;648V?k{U6J&+3bhGI52~e}Mw%4S0eB8pb|vM8`d5BQxoj_l){| zGbCTz)YZa$d+l3kx(em@?bihUTEtVX@H_p)fqxyx3{+TxunhVR5Gzu0y-V!GEYNE4I@`UnuI=yTe4ZMHl z$T z19Uj#TI>B4a4rMqJQQbLxf}}~(NXoRF~A?+CyE;_8)u~*eRd!jvc!9Hzhhhar>*Xj zr>@uN%K*L^P<2x^N`13-Lt<~RJ-Z`}S((Loiu!UrAw*nE@1Dv5rOXnze>4YB(RiVHJ@WWA7;Ig#G10=BrcieBAJOW^w2KK^zfBn z6EB9Pu%wIxr@O9;OMpbCSJEGzt`2#u{`bNs&Xnqv1l=)<9XSOGyeD-L7S&M{hS|to zH}mj#o(J}Cqi&86AZ zT50-s%q=|+K!-@$!>e-u>pgVN3Ljgq91lGI)jiU3kib&v4Sn09IlkH9iC=i&**EFn zcPo1PpInalc1C#-S>p4vhWM5jT?~o#d5p3>y3Qvs<_>M)>?|;R-~nC7s2N1a22PH7 zH54WDps(SO8ociT`5bAP`(*P3=eP6bYAzmn6iTd-ZdxY?;?Mdi<|Hovp z3MxO{x`53m#NsOvw=I9C(_@fuo=>kuvbdJ}keJ_6hAE%mY8 z0Qf`kgH2G7dx4XEUQ-sfPp&1Ym^{j%Og&+kbc^5wJ2%BC24%mR4(6(09vl@ta34IE zkCkqVyJD2a(FR$Jfixf_I znEUgOmx00Fk)q7v?f}vvOg2`@Z5Q@1jvs6WAKXwR0LN5|`pauv$#Y=w9=^HCiyC_| zK0u8%L|=Z*Z_+kuta5>b^P-73W{J1L1X!IN+V58uNqhwca7}(0a&#!;bS`9Vc(2b;y+VgIh$duerohU=5es zV*0NURK7h7!!q#=*vtixG6!HIRO{%zFd#ah89pBbdyqdk-)dHbzU@-p@Djm9uhpuU zu>U`G;x0|plXrbj>l8Fa=(V0&V?K0)l2I@=(Df@&?9z4c_KXNrlo-s;C>Prljxyl6 zf7CG$o5B|JsKWftXF)e;q(gSr?R3}LlJNpd_a^IbYdZ}rV8_z=fAKp9>g0JuqrN<+Doa|t%3(1A-)C9n1+H*Obxe33pOjTm zO=TYvw{~TP!NL2{M#vXjN=v4R2;fWVAVE#Us94#?p@YxhM_QO!m+k(7_51J6c3K^z z7Q5vTM}INTY&iWcjbTz;|NJDhc>VLZl~03%rkRkLjTf>f6>P@VW5cgPKB=04<7O+T zoZGsd!3#=gX)>wu671T|Ed^RQKd_`9b4@^G}dA zRM<3UjCuE?V-0C#n?RFZp9m%%FNGY+Hgviu%F4$lhRIe>we-{Bvo#FEs@hq@8*wY# zKqaU7XGD-Ds&A1%i_EJG&=f?IAEJ*PxjTRl1v0bpckPR*o%QAN-=PFH|EAvWQ+t@G`0fky5Ayo+1}Ub?`xf}) zgLfF=?l!K~INA^C6%vxF>iTl>pYATVs~C4F4`K}TM7i!CA_mlMQ*L$@2=P0eIX(n$ z8@hNH*)O$6e+p3X8hq*fh9yRR@Vu7PoPAQVxc%nmrwzE)2xjg(2FmjC8$VW_1(Bw7o@kCm({JFFdV$JY1ONHt3O(c~OYJ;kR58uo;LFRwV%i zZR`ywl@y>Fln$HRl+cC=V;Nc|G?dKlNR%iq?rz`OZ8>M|WWF~Zub0$}982hn~?Gn@Y;{((3 zx-K7eKK<-WMah&;dBWc5oy;mn9b$Q%qIQqs;@e`l#@8E_dz|@-^s*&{GwP4Ris46K z)&>E74YRy~{I}|)gQW60H{lILmD}y>$jb(^_x!8IEW=sy4kzrO@;f2CbBMbXx;dK+eQUFqb9WR z;%u2+BQ- z2H5N`iROoHNY@t##D@o5ZpMlD{r(CH2a6J!nPi|BY;l1**cbuvuDg8jtJk8AaZ)}l z9`oTt2an=h5%kenR%2ZAR89a9S?zHpHiWG=bf_C+Rw?1zK zNX6$M0J@@KtaqE?Lf3H_n9j`KP`{CL{ZV>#-+|=kkd<{%z;{~^(St@}*e3O+O9j$Y z+z0~**QpzvTGy|I5~f_3IebVvR!s^OvUAmX#eD9)nSx^F)w!R32`GFsJTco4NDax~ zB5aInN}zUv%xxnDn{PZkHd!aAxW%?3vDw}y9ytQD`+Z7Au?n7Fth}}kau!lCS*ZdJ znfIk+Xhb-JN+L_gAx2*4m<`?6bh1iRVzikW`d9+p4flGJoVNi5Da~m%|;cx#Gc?0 zN%a?laCU#{7>`6BnDBK%#JX!Ac|aa9F^b%HKEtF%%d{bEeK@6VQ8U%Ua1;l&0-B{7 zklt0#?~xM8!_;qSv)`m9y5~*I+Y4|VO}IhnBFiJ?)K7m|`?T!!plfwpufCtlms1gG zr|vt2AZpFsCRg))(p$lINfGFycq-2En=#OvnXJPmM{T^DTSMt|MjbAmPiR=bKX~R{ z6iC5_30!T{=LUN0|CESVxWI~Y0u7A=F;2azJ%3XkS@ms#Tblr}D{ z)!OvO$9hl(s_fSaQY7SQoVxZCU0^OF=b!b-9lV%yB}m8{#0c@PfyUe z)^TQ!fAvuH7?x>#qAMb)+Mez0>?mub^5^EfEzO{NOY0^pjKZz7Zt8?Q{!{5vq@?zp zl~^8p^#0@C@8u|V#!1eA?kS?9i{8OW0rkJ-Mxj;-ZKCxk^(GWu)0mjB zM5jqn*+VNs?|;8~K<95XZ5!_MuCb&Tn|b(aPZSOWRRZg^URRiLJp%w&g*nIOk5uqw z`;P{6=;sryp40E2HY`D-QF@2i=D_WF&OE60^SUiw5>A+CgRe8kE#gqp!tBsIc5Edf zI42MZ-}3zYu-)VX)j89a(^h%D1cO#{bhf^Elo@g9j>>j zDVD8qo5-au){A9QppCoE&%jO*<#KEGe_x62EjSOuM_AhURn%|V;#kliqIIEux&*Vz zo}-rHz!^$AFG>a1y%PmO-l5}}Q5k1sJgUe3OdGuxbzl%CDYdIp*K)G5Y_QJ;0v?Y` zyTju8F!BB2R&Aa4bWvFfzX|p|LX`DR8S?~bbJj%asEI5i-9m!^5ml&rQLmai*&2kr zTP>}nizgPH6CIJZTUh^V2{Lmp@}8*ZmOu~9i#jDW`2+`Df97dRG%^eorbi?K?R-AA zTlc#!bkbh90kbWcTNbtsr+EC_ZSQg_8r!rjgvVWQf5;ji3UWys*`N3&EjH;$HiY1% zkDO1ANcMYG{hcZlNm<`fKBOri*CAwFN1ct#;lE68QizTJn!gizHnt%!6z%n#z)ROA#IJ#AaAT$n zkO?c&MTlnZ3}K6%GLZ5`GUa24@hh3vyuhgiq>sx&&##mY$gi7XZUcPdgILAK4Fp=m z;rFn<(o=moN`12%kKXftP!12poGKG8q@wYAVmYng&{ba8O0dEG_qwV>(8!?n0k6IU z->ur7KnRouwHR*ciE&47y6M79sT%8$uW{gH zzDasUtpA>NdlZFTQAb;~G@ptYK4X25Nyi z4I6OXt4C2x-=6KLmJlDKR4YC4sg5C`5(1TLh0>fRGZWICe+Vj+*JCD0krx(YIAKMP z;jZD$!0^}&YZa{UL1svPWFn9(n6qC?cSj{@3M)$7cj&p;+iw{$&p&%OIZd+sG(TvX{Z2|<_F>VYKwN`-=QVJN`{88NU1saP| z`VGv`8U~x(rUkT$GiQAs{K)k>+RB3(o8rC&lLkX(YR2esKlbOqUd@?r0A%%UNpO7L zG-b$+t|x5=dbyc6(h2ARpCeg6(3`Q<-?6y^3wHKZ`~d8P>~B zghT}g!mw`wUo>q|+|pt>1FKse)n5NHM@L9ZfuyCmv>TxMQ$k+U7y!*zR-pIcl7B3h zA*(@-2hE22H;CH23yGO1mHuG6*k(XgY1RWc zDSl9suUo%qD3*AAoZKRomr2YX<$_kNbtCSJHF+P4wZpf$?Fw4|G zz<4evv@(F7_NJI23*$fNocoo#mEw|VRbK3 z?VW>uIwTm-#T|kg{|Qho9Grh?{f&A!?TpfJL}IPvS67x-^I79SViKLL@EUzdM#*_O zT|L#xw&}6aD!m!Gp{pqXu&xb${0Wq^cmLF5c|7zILyT{PjjY-yTrHKEZ%(S7e%WMo zHw=+`yitMfq~i<1GMb0Ib$ARnhXlGlngc+m_7|lqg2?hkY?#=7VWR@X_39g{F3JAx zld1VG!|w9hwtyQW1}X>jj(p2ZfbH@Nz);^CMBThcl|A?LPGyhiSx(D$ISacuIMq_d z^%|3-h`{F=rEQ4(7QV_W<-P8o_ZxW#p;EExb7mSME4r(|LnA)zbJ7x@6xqg;mHBO; zy(T&AwT|*zgaHPLi}dau;|j}oqZb_>nt?@DHh7hz9ra0jpz}_NW4QO;WqMR-Frc8v z)%st%gHbbvgQ`yf6rD$d)^gsM{DX03Qh>KGuL_L_(bnXvHC%8e(LhOk8%dy8?Uq$E zK4w~nsTK!#pZ^5tHr^5W!vv+wTMoI<7}?bta1J?Cb-5!dfRF#x5^ z+?Y}|{wEgkB-cI`OcC(M=4g768+OB8noV@9QtOEozF!cm@k?*lvFr6y%#3?ZQ`JtJ zOj=1t}m@gU#Im__y!^&ONo#YM6cC&;Qd-qKC{A|Y?pkeVI?6K zb4)K@sFFvIbJiX<-`(A*c$g!IMQo# z*7J`!W|hJ{t084UK{T~>t~q3-le}^;aWUN^8wv4LmuPS%|?j73UHZT z?t#uOy|vWCExr+~PD#<<_8t$b{UjrnL+=D0eD{<$*s=KpHhq{QaTRbOs{aQVfqc=8 zt1F{(NpbwSV;F!r$Vw9vY&7*_qbF6@Q(3ik&vd=*{cbw|JD;c+im&l8?#l7Z`M5 z2P)8Bqoo=~iO{+60T8(y(RFEmjiZOnY%v>=+aa89b3AApub1$0qHn>EqpIhc zlj>X^;(2nOT#A>-x)N;`PXi;@%XMk+sU-wOJvRW z*?4`^G~<4Q^ZkJGbT`y!VD_EW+rl*3!249usgRiz^e;23^v2hHv(VUNpE2{M=P6(R zFMx9l3fmxg$$Mxc6lRavt&B~r5)?FFFRs*UXhpROj+$9zmFe{>l8r^$W!?$J{|9eY zcCWqfv@Ru7KelRq${i7;;8#NbxMq7dPUVIsBX0u9%gU+`xr|FmG?2e#_UB6&Q+!!P zbC0}4=P0~}wpHqP5X#8;tl^BB-@7H(jrB<(H*Tj7x;JS`J_)mS0R<*WXdxH+```^w zjw}nA5GnajMr&QuEx-lmBCt{7!-abNz>V#UhJ*P9Yeq$W4_YvcJf~BoyAmZdSJF6m zXSB7b+rk#VkppxpoR0=IS?_okaL%q3k1Qm!8Yt*(H&I(=>>0{0oDesvkXsGpU(_A; z%|zv^>#+<0QWm!KPPH?hEVG5C{Z5zr`@lZ&dNPyG+<1f26$zUR4c(v8L-N^)>t*l& zF)&t_x@qq9u&ySS*UZZIBYrFJ^;7rY{ocBjcOsz99`mYZfohvz$g{FOhJJ(O7}=?B zre}vDg}H@`vOH}OLHN8n^e`|}9Q6X&iG4{?)4rD7*mXI|;8*kesY-#diF&!U#(dLa zdpU9n9b1$+h^d8B!4s8(2bQdZ7kRk8qO(#|*=H4|45D{7+R8sI_D6-0ctwp0n?Jey zDdegUuMZpD>y{s1& zt!cg5IcMF;SHpVtR0z^b+2k)mT2?#Wa6#}u1UE+4KwTCth*U19cT!HHzG@l}6?Yt+ z|AGu!RA{WyeQoav=%~H`u}tAy$Q}Q{dd>>dDD>&!y9F#+V> zK`o66R7_7muVsyp%~?Y!5yK4||5m{v%);E>F~+82JJ6T0{2xkZQFi!Q-z8rO0h*G} znx6k}Mp@VmNY+a<(HA5}3i_^8KeKw$_laF7kfH7&Gt87qVgh%|+Q8Gnt8__Nx`JDD z^$+f!mIArR?+ z7>H(KE*@sWJX$CvGJkM92P6gfqBM*|q=Feysmf$&|FzYUJ>u8N93FLY0P!(-+tRD~ zN0wuD7z5SOfAps@>pnBpeA0yE3GmLjlA;X$4MdaM1G9;y4ahx*zL|Jl<5GlC?1js) z>~fHv*1r!AGV5oTqJS=Zin@QERKI?Ip0d#tf1zM%?<>c!8tU?_PXSQcx?naE?Ka*6 z|Mlp5Nn)DWk?U-Oq;7VbU=E8-&GtNS%9@gVG1cPFfLmtMTQ*rkDi)A@s@+C)((X(? zWa4`LqR*`K290)&-|AJxljpWCy;+ND+V6gTH-w!C%kI6(8HR&hrjM{yhn9Tz>ufdy?Ax5Z=Gq z9Zi$tzTL8sk`R)=>R!Lg*08x(W@{}8s7BGu6ZR>YD_KqK?L9}DD1bEvK%#`QUAWtO z%!;}Ub;V7h9?Wb%7>4+_=sxUdPY05l|q}9ptVv?L-~%}Pf89&fIJ(+ zi_J<)Omn2Pha_t|H&hLqo{z$P{ob~olbL8NoG!O`#c9SbGPLfVnd>7G@|bOrr`>1K zVpcvdF-A7I!5zh6G4N&PoB+?;U{dDZlI~s?ethL%+@V!M$5M-qG4$JSISuK^##r4U zo-XU9RG>=2nCJYKV>0HmyCZcyN7uIN?OvICXqN^eYWg0@LwBH8nTeX;>+^{py2Uhc zr>N`33DnqC%2<8d0`}R5Rzas!PuBQc^6%ma0X=ehG zgYRy~BOY6k%}9{P>OC0nDH)UAZ~eddq+!AQQavvqcwRhh%(oi>b4(4qcu$+b#Dnhw zOdy!$Va~by^9-nzG1pqArz0=EM1?aRP-^EXbbc)~9_@wct~dLYltiG;d&B*2l{wex zRes1lgCB0nzQDODsig#Mex!Q=_z9w-ijIQUs(fdh>YjMUUQo#JQ_~X)+*wMqs-}cX zgC$D_b^+mW)%VJWraAU(*lmYQFNh=i4QmgRM0NZCdmj@xoV0M-qQR-;v*z_XX6E&; zbJ(qxao_UZOk$Xuo(UNQ3(4lIiScbblm3BCv0>}_X#-C}19r7j!(LZz%U0D(@`o?L>t~!WbtW19J*#x%t7cx{N7jHO?BVI<7VrftEBjWu z0N`MTu9VtI`n?jjWNwRl=Zox8qUWnb=YPcPwOj6~Pb>kMb+0;;(*NuV*5G7F=0HZ&t zo{%EGp@wf%9EM&$Ssv=H_{8PTokfBIO}fZ1kAio!9yhl?>GfLWI4>mE4#g91Mb@CZ z4jWVnQiV6{P`8%@P$Os9#nTNgzfRq7oqqLHjHYvbty}hS&H|H}5Q0($16s6R|7B^M zvc={pqre?ZZ(U}3y$e0;P6;vI1~LwQ0BE~RVv#cy@ZXCOUEdhkD*CcPG}`^v-n;gm z-8)wrULK$%gJ+)M2sax!eXHG}a~@5bD3V)_3edsy+>&Sh+frWshxOY(CRpx+3a{VC zE>ez`*?H~Jyf?%xYkRJZGZ$f)c!ccQV;QV}!oy9F|Cak)1kHT8miM5Y0)`i`#upmE zO#<+x=1&Uj+O1c%zvp?u;*{BOV@_rbETarZu5CBMN@?M2NJ+@fB zmSS@UM&iE8nTWVU#AH(wSJPz))v2q=mSfY}g2i;BDW}qD{@qZ%3K%?=sQdk#z&K$# zh~DqiGj!djQs$`)lg8~uX}QjKDTDSnvKrA7_+UvS)aE(}P~>)gY~6C(4Q)HgGlmsD zkvD@0t?R0XbBjA<`060s2VaaVY^z8-rW{njJ7s_oCuLrB$pnO3OG-;#0`g zkz59)id0& zlzPQ2BbHhbe8x%|a75f=TrS1N7Cf^`NEVT$5t%}tdeIm7q;E&u3*g&@7v-UQEf&dy zKLHE_q;@t-H&$Y1zz)Tul6*KF`PZ?c{O4E!Qr{_8-kTIsNS1091cWlIM4LR2WI+6t z17J63N)UI9TQ-Emjn|%dx29mSE40}L(LP&^MRj%`dEc?b|%7-6a0c z?q&0sY}n8=eTRzFdo|h{a~UMl_uqn_A_d}Wza2CqlSAn& z_A8>%VdaJ0uH)3jg^@aSL3+K`8?l3RoxGXQl=}R;Wb8C-9`*vr`mBykKMH@vc7o;7 z+Z*tLMmP3ONB)__K;qwo#WKZgWy)gw$R6J#A-93;f9oRxF=U@jRs&t4Ammc4eBaG@ z50^Kf9OL`^Fb%;2LO9nxXuI%v?4_Np%9>p_>* zQ_>w^{Lh#S-cFSo3|oodgMVT*P_`~K2$XKWbN$QW&y_u0(8cmKj1TaC%vA7>*Fb|3oQ5GuU|b^@pD|Wp!`HBxz~FK|;_61=vQUgYCeybETwC8N zq#)Ee^{KUN3c`*x*Un(3=(%Y)jaSvhvzb^l=6W?Yx1CBUZ2Lp0H=OwhEC+ z2M2AJt*&cq?E$*B&c;}JAX%*X*7vegmJZZ|tBi_W>|c#<)09ZyQvrp?S=Ma&9IX&u zVcL}nZ8%)-wr{;=8ZQZ*;~A1Z2>L(uUWAg;!`KwA=MI*9`5F(Nlyltz`a{5Eg6x1Uu4Y)+@tb|FQH zusDSF(9V{H^Vx*txHkKv@qd&F|GD|-KMlgyZ!M+tv*%m7_Pcn{|7q;lL6J7a#Vrw= zlR~BUvDaUsWK2wLVAAgOoLmF0Xxt=EMhN7~-M-mD2S4)k*VJK8 zNyTF~4~ePA-h`rm*)ukr>;r;Mc7-dK`!dyf8-Q5Ft52w=p6oh)D6(mrTd--XR?bv} zC@y!@tE>PS|3Bflxv;=Zbaws!_;zBl657j|5=|%0{Yu7Mc)ONRis2oa64cUOwSo48 z&^%I&y8T~G(Y@3+Y9*eq85@b^IOKyb5;)!Br$ z@b$ANoKP<^qinb9tw--3?~TovR}Sfjefa+bBF6lt8-r>iV+H>P<*qeGd7Qd-Vt>;R zHd?BsVhkobjida=t;qK?f&G~cU*dqZ<2-}x4_0zHUw-vxKFy>i)5Qw!1l;-h0iRGX zzheWI87fjZ6j3;Nzi51FQScd*SXQAOm$jJmY~MQYNPN5-K%I~EKfwyK(>sZJ(E{9X}RK}=B%W*Ze;6rHChYj@h$#AKUU*Jpo86Y#*T%HU#P4Np?e#&l(`DnT)wI!z z5a!?s%3fJT{)Y0b`lV03jT;EdZbBH19w@-oGCNr%Wl?8lfCp+%EpK3M%6oYr{g(K_G zhEtagwozVJu%AV`s-6h8;iK1@hY>QXT?vFI*?^VxOnz%5u^D|$M^&`lhH~6rp{5=0ypN!u(2A?(gFI`wbimH{W3fNYB>`wG z{a?y>!fQzx&%Rgg=@a|i?vYNBJ`Yl;Po5CO0c)Q~ur?3V64LjR`y}V?PdMaCJ6Smg z`uMwa@Z3D(zK?=Li;&GEM+NGR%h&G#<(PrSfWIkXB46DS!kL}Rz4~LbvWw~58G`KG z=Udi8Z^0E2E0{46LKKE$b!~M&7Q^HgZkfH&8JvTl>P6D=htV zKfMB7ZsOLrX{O#pbAjO*kPh;g5R+)qA|6^dd)WX6lM*}o#PRmD`wBipYavuk*pxbKM|iF~F>W zAk+&4_?;H9fw7d{Q?Vm2>K=9;APgb0%#Qs` zk1S}}SFSIm-o(+3&WBFiOb6Hnha!MkdfEkVXEu#}u%VZ54w}4X*2yS)2QpyJTyrpz zl0{%UKXgmtfyn&NiU&*phRu-5g#5^OT=q)M_{*`Mn?SeC{$aa52R=NJWS=HeK5F_} z_^X^{({DM!D}PIWTsg0+orM7bwZTQ942zAYg5Z`JV13!l1J;+QlrPolE|Aa4 zb`2$K|Cb~9yIJ4pu)ZDyFA;%<(hJ0m=*G(~gIy->TX5BpSdoL2kw=0dLCVgsw4M79r^egsl4X)NhY2e##&o*`#(a-BR?B! zd`Yg(%JF5zWBwILyRAIt6_>B50LM{26+r7h0Jc)s0~o2hhokD^p=^CZ44d)OGR=xG z=W?MHn}-@j3+(}bU)I>QqidA)kx}Lu+H|@Vf?xJM-UH>H&G;Z3tY!%yRe-fwx_*FX zCAZ|=IriM>^;eX~t|d?Y1_;8IMGkXS4iO%nZK;?)r8BQ*O@^u*^j^OJ+E_zOQi9fafQppfi@w03>7c=u}X-A9tt~^#9%Jiyeq7)9eaURcD&NsL>Z#%n3 z#9*($V#TC1LM`5yuluSa>(tvsIb zxQ20?Kp!{gw&6U(lJ{v!fH?LxwB>Or583W8dSZbLl+L6>sv4L-$u4~#RIl}DMp2{TMdW>AFxY?S?FV4aAl@1eWL&R|_J+1`Nqg3B);K(4hyLq1 zBvRCUw9EXPs4-n@`PRGN@$Ar6U0gCCk{Oq|?GSDRR3-p{;PP64o(JNPARh4O9Sc?~ zd27Gc-&V2%mg9f30F2!H7-l8mu~-5A-KGEdy7raR7!}_j*x9m- z8+psG#t^md>`yigY{yQ&NYr!owHrdG0MHRtw_Uxlo#Rdhyi%BrNR|eC%I>^%lQMn;#{>t-Mp5z~&lbIr4qvT)yoo zm}%1y0iUK|I#@~F?hw#D`*9Yx>%&THMBF?$W;J|)11;7uRN9NJ+mQ%__NU)2#3j1- z!NkU20^pODG1_FHlB%>36KXfmdh5|8v^Iq}p0t&q#*ZFI=JZR0q;%s|>kg zbkrgtm0O&j_l9(h)QhF~Z2=!C=WSSLB5%J^heiVhKWqT`_B#_AQzoe9sH%fT!Cnk} z`Q;_{{^$VHn+WOz(BnPP^R#LcQX^ zpcu2Yb6d~&>P*frH4wfrZ9_zu2gDbQ|7hhu>eH|X$XZfz`EWD}(jZR*>%{XrpG$B!6QTghtrMMPnR&>@y zuHsp{`84>h_C2&~&Ojh-$u7jGkEM%i;ne138-!cZ{gg#CW7rOZU} zOW9(z>9-_)Our4kW%aC3yENy?7vWqn|MO;^WBZL=y9;(e`!!KZmhmLHN|y;=1AJix z1SJ<#yzVe~ZRmiI+nJyn&Jw>@u4=TYT!1O}A~ypc?g8}FdV|1W$&PoEv%O0|NB<9d z-vQKQw!bZ+Vnb9`Q4p{p3IY}&0s?jv1QZ3N1yPY6KuYMr1}cITqO>TzgS5~iq9DD7 z7DA|@h898#Nxt&}ZgcP6-T!z0_xqgLo!J@2A>=*hJ-_}u&v6~8)$tQ>yEW|o>EUA^ z)~ZnzS)9U5N7224jlt>sj_qQTu6@b&dizgQB_~tOeWVkOgB&S&1_6?58Wjh-r%BeL zIT~t`mn(TrPC8$2i7GF%t5#dfSf#}Myd5^IiE7Q9>16r+Xcm|gLK*$ z0l~F$z=C0gwUQ9V96HmQX~lh`W5P`kbi?8i}TR3`J((`Z@x36JT5(#aTR&2 zE_U9(UU6>b)yv7Z8upSPyTywsxUs}!P|atLAlhbvaSp>-K09hGPy?CO?H_Otwf6BI zx#>K59Jzl_?{J#hGg?Idjo{POaw-rsr_iLZ|DnCoYkuUwYuBoVvj!u) zN6Xf&YERd!v}ALOMsWZ61Ji;C5tK7OnTONr~tlcw}Grxw~?%h(>GSR`H``BPEY z2LX33h4YTh9&!T?*D-CqRH2SJCT=@0zmns@rz3$=|B^ShQ~N zsfUUF&ES`hR8k90({H91aG>=TyUkTX;s*lX!K?%Djw?F_Go@90i(N<0Y_~Hu^4?|oOtFNP_Yy0ITTuWsj z+G4u_zfwtk#0730lMsg|YgYumes}ZQOp&7Qm(lhY&p@wWR?iFSDh&2f3_B%(fSz| z&`6&mph^vSrCx5))<3B`PfMCer9K*qeWfhpo%ATy z&A|bH*bI|-WuzH%L)OQQ!hg~$rh)l(#7X$+YWZ@}oHN}*w*c<$powWz4)E~O zL5ipX;eA6JuG`*-jostCHn+-wbw|WAc7Lqh&i(6u8VvHkkj;!Ie5^J+WTDm?z$rmH7Lx>6~GODAN>l6vax<8HFG9ppX^F;rxMRN8j$(U#C zi{RU3cbyh9Y8QtMEFD(vDER`lH>e!qsi}x%yl$b;LJXz6i&YMG=HJ{$ONbYI*H;-N ztjMGbL(|N>p6KgGJnXOc0_NDsY;zG?is^GdkAyiImUN5g(CDYy@GL&M8dp}FI^&1p z2Tl|Ob1_`#l(y9j76-%^4TavbHDv5dzg{?9m!n!))e0jzB@UC^4dd5&l{H~m7Trmi zwOs9iPGKia9+K^M?F8tmU8ns5+*uL_&b^uf&A*IPCtVTH2S_%OG{}j?nx~8U+;A7u z#?%tSBrj+>lxd7gY3-X!>@1hSO-y!iHX2qZI1J?jNl=fed#9E08a}q&Zk%^Js9!|l z(KD{qxa=66+ zku@^t_2}_o0Q%58^YQHHqalSg=QVFNxEYwmoYE{9ACzuOBfWVgmrqrb(|Xwda=G?< zpN%ng%SAR=W#b*Q9VZem>h$qnuw@7DxZ~1V%6|W@UG)yDuky2Pi5GD0IXsJE@l=Fe z2!l8-fVKD-Gy=aiGhcdMb+{dIda?atywKd@kX7=}mLT3eF}V7S_EWc;jrP`eH~Q7B zfxz}s>nQs*UDmyRux!PXO*Nk-LVTDX2KMo}%E?h0vsDs981qK}+A_S%d7<2lSs0CC zAGhCazg)q(mz$83->7@Uz4i4C&CT+dQD?DQwc2AVc0OOTywKp<-1Mj@8h-pBcXv|H z&iiZ5*AA(njFn4EkN6LBH{ClCu)4=b#fAK~FM?&ne)IBk&(}g+MhP3w`+54bZ)(y5 z0zzpTOU=Ju(% zF08ud`RZ#AMC|>%ZaEh(XIs7ZLB;wdLkB1!chc zZBmAn(v}*QoL-)1V@~y%9=dI^bK#j)u9GWt?$k!2zf7T?5#>s2??1apY3@I^qE4*? zs@tm-SjQc=!AMRa37M^=I)yWHi}~k)o!4t+<~!dZBR;0sZ(8(z&o?cfLoiBBFvWh3 zJ&!t5@Az!pzN_%iu1f|hZdbS&i02QNHLFqbu5ie7&UDAc7fk|GsHqLaDL=LvXp(=F z+8C#CeQ(ZUs+LUl=JF_5b?c7o{G4f|yE7n;JQd>(~DH!vLwXfd}ZQ z+w6W2_tUn=;tLEXNG4(-se=CEkwqNvt>(+yWPknd3%>&7p+F;2amS?JPul|i_`|?J zi_R|BSR1_hy~xUQVLsnK<@!aa#&*Y_yf*y&wcnlq2)h7^D;G!po|RsafB0c2L9hXX zz~#cHVwCT`=->VQQx+{YqrLbazCR5?#eTCujfKpy=;Y}6yG8?l_+jWZ=tHmJ@jtKO zpVt7P;{UORf2`pjr}R&3C|U^7|HOuWLi9hG(utk_SOZ8d|4CREGwgrrhJRwiKi05_ zCist5(Q$Xq&2>Lhyv3ZK1?qj=I%bjnB1og872lQ43%vpVb0IguBzJ-_P2x!(TPvEd z6SP~eTD}E$v6O*(0)$;c{I%ga>BEN13G}_DE1Uo%xUwBp87M^^?9KJ?GI;g}6|;yM z)XwpZzC1ccXZB%GE_3&bHDXrPrW&j0+$k0Ex#LhP_XPg>*M+u%Md^)iSb%T!cf*>6 z8TB48qkilx;#w=YPSaoLG7}%A79s+~*!+0X>+@ZwCnUaZ`PK~hRpGwT=Mq?2H)yxM z7RI=xzKaAh{Rf8<($r#}?%N?xA5IIS-7f*%a!~+Lz(N$74^8v))N132p3;meaD}Q` zX1j~Uaezqt)!$tB@viJ%sDFcqxI9`@fEp|0I0CMb)s=*`+~OXnd4FHhydkDhMms-z zgKBZ)g4W`18w&eRK`qJLy--gjBYmwV{=pPL`Mm^}Ka`aSqJ|xORz#Smg8LPI(}Do1 zoas;##H>N4-F@1?dA1h~u(?sGWg_vP1LLg-neA%}nePjaaSN+WIx5tKylDa?d~1&I zY6bd5`-j&VLE?U4xw}?AQ&*V%tfE^Ne%5CzP$G*5B2e?sRc^GpQ7et<6s&q~c@65@ zf&6((PvAF0O`@H3F+kQWG3QadK%5?=1UP{QBSpDg1Mk-*_TLjNEYci}(Y;xJ`1{YF zTj<1@g3HtH7DZf+iQAWubIR5}(rEMZxYARTD}TSkb!vcD9(lR%&EcC~6>pC!NtVXA z)2D>qmaFU5oe2lRblQNFDwGTm!*s*9hm7vIu^7{-?Jh$XqSZp~G|{QmipFhOwi5(v zTxl_%^+AA9wHwj5Iok!#cX2*>a>sY?6LkJUA-J%fdQkf~j>S+fe!6{6;HC6>HMz$l zPJm|RIXPCu<;ofcH$JP?*PwENW+rx{Hq=V|r3tq1<40xa)mq$Nu~&3y)}(C-q8vkO6@biFkbghd?>`*z7IYVt!>h*I?5dq}MUee9Cjn?M?d3%W z0NgAEk7eCrTf%Q#uL|SD*Yf)cICZd%TD#9pz5r0MMmmW(qLfqrl9_)w{M>sN4@KP! zb0N9ml+za&?>7Gan*jDwdimCnBHW$U$qkC7G0s$ST`qD|*AwpCyTutCgM5QG4zSxS z&^EK2JOFiFe|vyEPZ(@mK*WK&0S&H2e`>lIbV;+bQ+x6bP^8Q_KK_{-Eb+An&;8$R z(A|Wk6AXIjo4|#!p~KmIp{YPLb&J&Wy_M^F-g^s7lz}_1)dS!z1G*0OLPnfZwP$v# z?yu_xG`9e7ln;)osQ}rfhsS9RSKuut@2}cI;aK_mmjE6%g&R7s`1&a1Jb?3tu6hsj z4NlulIssV+=sxCDyq2CbYoId@*(`Q~^Sk9OTOp#lFg0KYkg3dz{Q44Br!@I@#xx57 zb(L+(;(y>rH!YgxNLKd-opjR|_9JaN_S3r=)^CjiUH~gG&@yn)1Pss%U-{Ov z)Wcp=cV^I^ZRiC8;zK6KHRtOR-_|2a>5xM#u@^upO^IvvmMR_VmfU-~2W(%Z?Mv-p6HK^4ALK2A(Au68zYeJOiw(=R=7A_2u){3=3gB z>--EP(-+qM912ahgRJ%ee&-`v1X$~}P}dO|iO1((J!XPie7DQoiO`0T~DOOhUL!6K%HFVQ%iW}Upd-K2bTBqM-K7ZRseH+E!^1YzHe~4?zDl9MdnYM?) zZSLziuV^#ZrZW;->3!$&Cw0M?xD5}GtRc=fgzCkw3at{4S_s6v4o&C;)`@GSpUTgz zhmWOhvJv&gfIqYjF1hZgzI3VLD&|<+|ED!%Fn)U579Q; zxICa;tzC3LmS^{j?R=fu)eu|lWSt36GOhS> zosUnJ*B@GQ9)J5q&VYI&YG=aLPUAhRB%E4SXZaUbTefwql;C62Gn-%9EbXE$e+O6H z2XW~GI|3)EkbDuiH+(lxeAEyt0X$1<<4+IP)TNtUk?DDUI*-bma@1qqX%tmLxjG5u zA0yd)0ubjMOMfwPFT#5yFd}{p2lDJ%>HcKN9hUL0-@Z;q?IU^|cp4YGKF_kz6YYyO z&)FRjw7bAr@7>> z2I$|pFpA1MKNvX08r7XJzZGLfF{t>Cjq-x*x>HhSi;coR4K*O$O1akQ31h?9_lVjWr*| z@X_ilvVp#qHt^l{8Y(M+8Z;YG2J~jBR&usWpzV59p9)qAx~>F1L7I1(M)B_0j6n!P!@$)u3d# zcLyD?VqbyEqm@3bCP(R^fU@QC9*MiAU7sI^iLS>Yh`Iofn_F|sspBpOV03znIqD78 zMf&i}Q0b$%@^rKM9uPUHW#?YKdQuq`!8kfFL!@SS=B>>zk7Up@m0rDR_Zk0fo_pAZwpN*ItTW;3#VLy#XnH-c+kam`~75 zNnCu=pb)!N&Ons&`^vXRO9Js~MO&7|L6@ zlz>{0A{MMMY}%feJqcE)br__LhI$w1dUX_@w3GjrQFP&WZQxUz^Lk}ZcX*VkCeA6r zr?p_NU~fR!|H8Et_LuB+AqO#_Ff}QRwAxH`CaCM1WS~@PcD4_bZ}8k+DO`h#INJ}U zmB0ZeHHdU!Gb)ah_o!-#^xjzXUY}wD%RZLh<^ zH!A~S&A9uEYYv}8R$=0CkYB_zm|7HuT{zrD4AO5I1i59^@eeO`w#02_7pS+Xg9S$r zlK1JouH$j?KNTCb{#&jEp0JB!=?Ou|{Mm6OIkMuWm@TFR6+HkO+8{@|W3gZ)hT^!n zBrXX)+rPWEaAdQLb~!_Oh&f^|la>AA{M{J0t9e940`z1mpXdXmqDM$G`yK zH`I5sm0Ec;ScpA{bNRwgxVEqy_4ehN0v~^s1N~|6+9K;+IW2lw){J#AhoO8Zq1xhO z`8ht|4c%fMLMKy<9O=tL-TeC;FmB3OXXzwBWoxb6aBzIDN00*wnX#j-?JEcu2#~{d zS}(;D;55*_+8M`TIW*Z>5LbdYI~osV8xxa2Y8NaFuEmp99L(5yN;AL9&+6a+pIRM7 z*qTj`>znyPi}{sL{${m#e!0f#~_e95r4yl#l2V;wCm%?0mICx2Wc2FL#RNuF zhVpB*R>fBc+~)N|RNk@FS}(LOkD&QNw*4!I@$1(T=ML9$Wm%?EB0{(J55jxm-kU;jW0k@D=K66QYcu6xk>n5Md zf`2I0``F0-%{M@P^OuAT3gt_SS;}q!+$?3*Lr7T|iXDb)ylBqA-c5^u2jt3FFzzpT z>Ek!x-@O*Rf<$~iO1gEb4(jvBx_F1!WwcqRjf^G*03(;lDy#(GD>nb_V1aBbbv!Ph z?;I8`Y`6|(m&Vq{yAPW{zyl{iU9tIj8(As8@l;HlcH0MEA@`ySIgB2$>qBhc?E9C{ z4rRnYoA)ny$$PtIH{9mPg?cD?MbTW|syxf|PT*X;b^p2_=g%*y%GMph>P#cG%fSM6 zv@Kcnx8esB1uagR<#yqE$*+;t9a3o=HizH zoqLHM6I)Yg%b@aNY3Dn%commIGN^UFEoLzmL&Ct81%{977TmA)JtKEGJ6yUIs_IUQ z{od#P>a}QPRF{J+&o?ta9TY3ce(gqm`eM_B1bS|KFId2aKg<&2db4X2n@XELk=iVm zVZBPlh8#i1yzBVg6??I>myElg2JW|QEvf*kGpt-tq6|GG9+8cnfF3ZPpxGKly)z%6lnt2~zu7F4xK!|@Ys z{f$FC7M<1zX-~bPo&bm39FXXSo>=~pFdx&TyIPa>L@x8gLY9HaTWKlpxm0CBi}};S z3Pg*bQSC7MI_6t@y8rcSm?lsJNrRkf=F+;q9t!^n7ypEdg$B?+;o_fg@lUw;!#>~t zr{RLdYRTnt$}JONu|)mtSI0isduHQmp~>BvhqgzYiMzVxEWgR52_OGZf5joc@Tana zG2!)}mp}5{eV&``?%tidG$J1GuD<)c{cHX%220kPReEVkbqZ-r$`8$*?kj*FU8`fE zSnZxnv#d4{riad~HI@6gPD1sBPZVyfZiQRz}jNR+Y^H#wFrQv}*)(u^~+%>7k(1ARCn=&q zG*lZ8((BV{rp8sZIkMCZL>Yg&6_HNVlWB9ilhsM)9y6}B&YE4}rZX8t_Ck~W%ZAR8 zlDgCSVTPPG@lkrjp~1JvTMo;)cFtBQ#pkPg>>i`lPn37*o5O=u^4yl|Y7O=sp)t%_UDA*AnHq#RdyfQ{F)~LOBZ)f@3Nmdr z)HO4y{jfH-3NfmqyhK7<0B;Z_Ft)=1~biJV&O(9FTPN^SPG zxB;!{92YXbPRK|0^99t)=3DQ_X=ESe@hRv$lPqY+X2s#OcsQVwA`z%i-}b9@hy^m^ z0qe^|T3bo5u7ux2neHzp*{okD)|GDgo?x?^_ zfy4?KU2T*0_j1v9aEY!sS5faE^$km#&I!YKO89tyZ>`JIa3=N>9Ne}t$nk6lynVc@ zfjreOL9K&rFKKqal+Q`c*tWMmXGu0;P0x}&GuiXNAqR&8oRp6|su(lGuhs!hyk>d) z2<_@B%?g?Hc8T4xIf~&;5}#5kEIK01x+9&(&xt`>>th$|Y%Bh|)1%DLk19}9)qAEz z-jNu8bhIYqN;au6pOo)kR4MGew9#Hc>L1Z(ao}6c;IVm#Ns6q3j|UaM3~Qc)&rb?< zR?-q4TlR9)?RDUncX3xoD!znSAFCZI(LO<7gM&j34g@$I9X?UjlCWRa0aTbN-x}txPE4eS_!SZ+Dp5()&aV;w7TI4F z+h#q~KH6T^Nq$wdw9#M*9pzyp@U4=`SK+WZM}Ev%+^o5$o)mEqu3eqCC!X7BSt(LM zx$?#(O%WvdMlCG3pVlqwee;K8r!3sJ1zN;fxhf$<;uMM@d zb7`ZOJPi2OKy8s^KKER|>M)X<)W^g?ghO(?N&5@@n&X~5a)Ob!566i3%h`SC=Tn=U z8{bmn==qBaoCzB^TFLp#I)Jr;HVZyKwCvpz8Sh5=*)vMhCX;h#w*@$J=1E%RNlLWG zeEF?0{_4cUV#*t)qs@kD%Ywrl9LW4Rb|TY+oatQbovhg&o289j@-X0AD@FaAdpy{;MMf z)~GO>)KZ|j?+s*G_kK9bLL1mVRo#B4#6sG>vGrN&hZ0mZwsZwl5nP6%<2&P8lOH6O ztCUl?VD4>6{WSTZ%-Z2Ad&IFY^wl#1GBPOlHJE2-( z2UHH3>VT^8$0*+F?zj$CYd2%J7EHt{k>qkJU8V;62-m})+U*cjlGdd5AN@hHuE^f0 zW`<(gsJOGW-4&8Y`R<{5)FbQrk0DR}=|}U_0far%Otd@di=h;Z=F4tE@T3&aNxw0L zob&o0%sHE7%R5aYDM}QKC1TKUUqyOhQ3?HrT}$Pg2?sh!%Fq-sh;hUi6`d38|6vWr zv6=$3?;2S*?XIA3_XUDjx%NlPLUj@K2u7H}4MPjWpwCU~%)`0Nhd-|I z^TSYO;-ljfa+HGHAZ#j1UTxg!P%RW;w*7DsCYR>*tXY#VpOPJm+wS<5l3AVo;~p}Y z;q=MeoKcoEj5c1#LlEG|tNw9Qm|_dk&88__M0V`6_48aoHebEn`7TOA_1dZ*tX@lR z^PmT%4SU_y1~2A)0V$Qi#d`hYn!mM&dmsZr04+w^-FDUu4u0B7(kkvs(5-t|2sI%C z&SHL$mZ_K+HaB;~$y!iKhMT)t#2?p{nV`(0m+g*aX4ZJ(!ig-msRG-tKYBy|Njp6K$|HU zx6Q12J%-fQptn`Pd{n;g*?%e6Xa?FH)X%Dswrswh??OwZU`YiNEXS6hrQc-`Ja$$X9z>Q^h^K@cjjlIHr^fbGPXIhfQWg98*~+5b+pj*XwbniMH(@Ms zWx?GKdEhDFVv>TEuX~jI(qE}7$fU)hB@7Ww2FQ?%jEsD8b;;B1Hvvfz+-vfhCUvuT zJz!SS+sBlwQFMY;bco~24VNG+hJ=yO#;0hl6@PIvjKOByISddqTk|~*Kj}4G3B$-B z%(C5kCn#1UDUp?`6h+iM_x?P^?|WP~k|@+qoY+Kw^ojOBskoyQX!AM%=+KCFUUmTI zd~NUjxI=TQ>y-W`K11`3U4kCA3eu0(`*7oI+6y_CWwGP2N`Rx8k!X;cIr~_tyVy4k zAFoXS$_7EKr11;qUkR&chRVAZkWT6vKcxKPGcLU`>s@D zdI9*!AcW)jM3DE{BQa~kN$EC!bI`B(P^JVh*(?C(n-#Thq@OK950U-lc4Z*m%`;|v z%>|$^f*>E%N&TFZO%5cVKCi^@@R|Z>(m_cX_5&KZ6J?@7EVqioCCvzM=h{FuqygYM zKVFh(O)8j5Lgts}AV))ocAkas582N*ul=MV3Q%F%qP(z0z{JmprX|eEB22~3Ppdcn z&}dCgR#tz%hYuWgtn^OugP>|YYHFNyYaj9zjp-Gy;~m3HT3j?41frCW!BN^?S$JcKJ3ve>{gQMnI zvkA6f&NP}dXri(z*&Ja$KM!jWt_te?F6_jY0k`xZ0DzC+lR?$-@mYAraVG%q;xA-B zuZL7qF1>w8b1n5Y&*Q&|@XDD8z6nfiDu^^+3`m5g9Q^jr!OANTdE>g65wr&P61$&npB$*C z0QPkXpnF2fAm~3hV>!x*@}`OmmD|in`MiEFG8Pub8gcwMhHNdBW2JEk?}=B2KYVXV zKIJs~+IA72_MO2RI0MgSJ-+DK#>0B`H^DGRAiQwbht( zxYfX5pH+ir{&2as!f;XP*SMG3M*D-ZH^LQ++ZGXLi}27TL}*oQoSSwi(v+y@w&?Qm zOl7n`SN1&xE)SEPgH7C#4!{v1eWTYgGS*4oxx8eNstk7sLb(7k6Qz0l$D)IQLse~K z<86=#n5EeQ_H++9S^)4eql-A613xD1Iv5*0{B_T>bouGFqiLPi*}YqXq$~pX-6w0M z0aslw)AFr>?UyZ$@!Ar(9rxB9u?sk;b3@y}0e|}@9J39=)>$BfW=!+ac{?JVGs5C~ zrigUmmYXVwjOmftE3V}m`Uri|eyP3jhUwLUZpjqM{dBfVnu*Hr!Re95CFS9_z5bPb z#{v7clM|NBA%!)K?!Z^!L=Xx$+v@JnCo}RB@>x0LsA92g2#g%E;J>?@w$w@(0Z^(f zT!%k+^E)(Lu3XjL#(q9g9R{fXFDZG{s<)hqR;`k*Juj4oKeBUKG7Y=A{gZM>a>&95 zL)@oY-pWuY6vt8_v?OboU2w*e)?a(m$2%5}(OW+p;pt4}kxo8-=W~jh?t5MI7nOKn zD2M<9he^zYG0a-jDHJ*PDleLAn!ypOL=XvFkUjr^HquVwn9NBKao(~#^`TEk@0DVJ z#r*}>sabC^{N{2iOzQ=NKAsE69n9PF@a5TRd{~qE`&FUx9pua1JX|vkvelGVP17lO zcWFti)a}lV^e!2nJiUuYp4knGuKRiJXnwYP2~+rQ;Jts{%)iJebr*&gv!C}>-zN(c zzbu2SGR>sN$O0$KkDqUFdIyo!Gt0$uZ%NNL#9pD)DhXx)<&Nel5(*Ur*vC==`n-~+ z&qM60WZue%YA2TdwB9PtNYLFTq@sbnOO>WS^2YRNG#$uk(X7?991+lpd}px@jH_m7T#xG zJA@3i?1OKIVI&~e*;Oo%88t1+wUd%!BS)v(1$;lm{oQ72GT|j;S%{?#Q$%3vPE=w zqFlnd*rWfnU|9tuZ^W2u!eth?(_3BJsiFED2OtP=^~2YfHo|oeFK(ip>x}`yVMUf( zPDZlc?GnG)2O%?25-pza)9%N%>u6F%)<@l6*V)VcyW_ZkEQV?eWQMbMzwd%+hFH*lngpOO@(EvQy1B4ePUf)eq+Mg}Pdfbrd>I)+)hJ+!JG+ML~y;-mXZYkK|VGyZGk1 zH^1Yx+eL;Bc+JdPrJLn|JeJjDe{Cj$C`%uIhH85%&zh$us$&$azXr*>W->;QIEy4Z z;C{)n=NIt!;t>z-jnzH5yAY1T2qaZL6BT%8r)VO}l{WU}4UTAfm z-(;1G(0BlD7a`%v{JJHMh=m|T%FYQvI<&cELe*NQp5g4R+~TI1NCri8RR8;8{C_Pg zY7Oo#6HQK!R6&yw&5go5QVNWi@dLorMO>zHNkq3}19-z^W_mcV-soA+E8RnViY#Yp zeSj|J$>iKaJxoHw%;$)67ekXF$iL#V%gTqH%XqCd$V%|UdzDF<7OF8ai(Tv>#IUR#~59yXJx;Ap~9<>SpuNM@98 zr~E;-bG&Kl0)Y7hk-?}uFXxFKvHCuQpWXzVj6+|wx!miJ8oE6pqp2^8r<-H>W1cux}PB8vSsaLj!$QA{g>ZHmVal;16lcPnaxb{ zv(qpu)0&BP$J&AT@0-Ay&PkM40Br=T1oKB{hb`C~3tn+Hm`R!j2NieAnZJe2gwb|Sk0|g=|d@M~uoo|nv{t3!}`n;6) zZj?ye2vGV4y_`F%k+f0*N9!O>lrk@mvh=3d-0j=UPp&cHg+jT1b)@=k!>#TC)sLBV z!EiyqyYK*HW{7I>C(V}b%sVZ1Q*RY1>1LMXm0aVXszHYsuP{h?v(0By$z~$iZ zXgjlir5d=;G-?Zwk6U0zTR+@X7|A|UGTkF%7le{_tcW?4tcUlp6?galS7!Pzx_RB1 zGha9;D$hnt&IZEf3ly7L%B@w&(H zJaZ)Y^~=h4aX*nO#W(-WS`Y7B_2Evh@(@@*_0{tU4=I7`=GNBOyX+jg(<4M`RQ^73 zXgiSaSMKYK>;x1f2Y;An!>BpY3qSQiandX*q+kd(EK$r%ba@=nSM<>1sF40syMfdH zD)(rD3SJgpcsO0mg^@_}DJ!WIeg;ks^)|_hN5LVB2CpYJPPSi{Z?aDt4M{2dej_x& zMy!+v8&S!-{d=lgLelY=)}`+3H&4FQp|zt+F>k2p=@GVe^P$*Gnp2E|x_D)L+bZ3q zx~R-AAq$a1@8F3WY))n?3zwLDk`f-*ix;^x%KmM z%&R`;6w{!?pA@(0F`BH2$H*DNv7eY^KdT^8`+;0Hyr1CoStwRczAaw(1-pSOUomGf zz1S|4gjBq?65uEC17bf!Nm^*<1tJp+aRsxFD|~U?AApPx?tL~|+`t@2I1Qu>xK0h5 zf$l}A`~EO!GeM_tWfxg=HDVx3p4E^zg>QM4P#rfib%&%aaD1-wv+wsY^$lh=&!)&~ zXoXu#EQthGq%MyN072EkLEuE0wZPUEO%Ba+v;=kt6jGdA8-2GQE#9XZ*sw#(YQSP{ za$pK7v<@UVC$1CEx_(7JG!F&wj^4o4-6XZKvcAvN>Vfq`;qi?oqD|td)ort7 z5;3v^swnGM$O4-oPdM5@D*2S{5hz95_AgR2!${|nr6R_Pxw#pr&r&!m-GO8&47J8e z$?!f0S0?DL9i4vv2x@KFofg{qC@6VnR%G|oa0RLLtetwMhn0LHQ~?(QqM0@(&e&GX zeG6pofKA9)_U9oWx9eRT=neb6uLshPK^P|>YIRI6-zB3mR6cihlo#_r(s|;R#XLEv z(p?_%cp^ZH_~obnlq(Cfe$k#3xX;*Ti~Ag-i59;mxV{) zCnqzTB_bhUWpa5evNDB!#iEU!)?Q-5Ucztb+mUl#cl$yDtc!1+K#aAf*2eDv)kWN# zU0*6*qM0Yk58>fzEjaBg=YURzq5@!CsDZv=T&N1>6!YNRL7e8E&49$Z$Xxv`_fXrY z{lkqfYjc5yDFvurB0Ti?V}mC05bUh@|V3Ni%GzZ>1-u`4TIcjIZc~CTaHXsV(DnIo0c6ZJBBx(IIn;Kj?rN z*j}Oya(JpK%-$Lz<|6B@OJ52(f(s=jy)S=jHS6`Z&OC_Bw(Dzsu!b9c^rJbWID}j6 zSRpSaD?P(-A^E{JCJ(#iN!l)P9>FW;P+TOCZvL6LoZjC+7hNLl#tc5O+hDLa@##XQ zmuPP340Ez->BnyZ*@`A3+padwWVjqjX`7$g=gW8<@?i+;c8LF0?P9W`36hmvD3Giy zx{)Pf?Qdz4xpR5lKz=!0#*Un~N_2=VqL@T8J?_~s<3gghV+Tg>^_Q{Go1m?=_BFUA zj!?s>LMNfR9T+3Un0Q^6A9UOb^DK zRgTsW45WP_qm~|P>l!^4n6V^XTqj(YQiNFWN8@!x%QHM4^hen>0V)by`0Y$m1mf(Zo?sjK}04DT~@ZUC@--a+|M- zW*G7llop`k*;ERa!Fi7@QD6a|_`cvGpZM|5Ja%3CL5BY#Z+rVyhYWDN=?nNdsB?>f zpOwb#0lpkiwKZvdRXkeE7UpcII|ywrnF_GYv+tpbTFQiKpI}J+bGhH zsqiR?pM|>uc(m%3PVSwWKBGuh)y<=F-N6br)5u{(0;@PvuRxW`79o`nYu282`I;%1 zjU0yQbqt1dYIRJ#%>M~dP}i|QDF64)!RnF&n6Wg2u9hjs4jWH?po#nzk?8I1r^s~T zlXFb4q<>l`(F|^OB~`dGq6MLmZxYaECu2ff24km&)2gLWSJb;tMuS@MgUsro_Wa!R z+t7f_eU0ed>v`$B|3=sgvg_v^FkTFMnzyKOpH$+vf#g#YH4>cP1*gyDdrRW-vBP6< z*U?bL@k0CO0FM|9xf6M`!ozu;Nga>)b9;dr!lDGiZ%ORQb$K`KxOU2ewu&Q|ErR^0 z+Y(G{Gk6T$YI$)F9DBaLs8m-^jnaJd4GYi;+SIqkpxKz=DwVx#FvDHIHCq+GPA0ID zX75>H6P{&E8{D+WY`M-eqCoU|rqKKyM~X)=n*Qh61%8z#mgpEH5A?$ZXZFyF$a$HJke@~%@A`G|#) zc9w@z4Pu?9w+634AvJ?XA z%cELgEc;tjf}GRm>?vlx1oeNkOe~H;X#_v$t1RRg zKQ|!%6aHDDU{ac1<<1Q}2eU{W%cVNw|2O?Js6T^TmkoflG!#uzMN8Xnya#c2nrRT zR$m3goN0lI*6Z^C&>J)=R&D6t{ z+e3vRtNyXL;KO>Z1wlT*qtX zkv#e~g?!9{b4vaTi8O74>K=BOAwQJZ`2{H&qo-#wISuMatymo^3ZtpTm2Y z$2o85t*dna*-iJN*vj|N1j*6nI`;EHLsJ+a6Ip=c{AHbn$U{&?r!91|G7G->%o?hnqQ6HI#vZaKxCf!Fdfz!r zC2^8cKXg}*TOBD(sIpNRBOG*7$(lV64fdhQ);BF7ykqyMgXJvvKZ$)wkz~*ubvPPy z;(XOl0@-Y9>Xj$D>R&Qyv=Xiv0W5+uRj^v7ZwH^G=_T=MFzu*902SZc!(`B|w`CMt zHw=J&9_O}09h^-CEGC`O?mC(Qr19~7Aeg&ZRKF!W^~vdMaQ_$-e?A$YU%0<15d8{d zwkX>2i`WV7O+6U5=tf6vUyx~u*75g4K3qJvam+Ru_jV!2@jatv99VdIQ_ z*c$GA%?k8kDsMLwr$<4=Bja4FUEAyD?IZmP0zh|58}4jOea0s^kPj*v9h?Wlk~WB! zhKBoKZWoAh1Ooo8pnYJ6KLWLwJiblv{?yBaxS&8~1&JfA(loHGdhZkAzX_TmL~Htr zjjl=-!}F)ys9XqGCV~Tzz5I z0tO2~`Vs{*U8*Q%A(w|uy)cheTUMrUcvd?>1X3dCW9#mgg2)l%GrX0|T+R!Riof}O$+BtG)UZBZ1M%K9HAiLv8I1rHXTL;%f6+?q^q<4+^_Z@#Y>rP%xWiseVoKgbRZ zobhWM2^~R}lk>Y8+vAA=mbkL2Q6{+asX6(3xsI+r`+w8^8+;dc*a_UOkZTDb!a)KD z&5y5^^q8L^-#-ITXYS^8pxC-yvcs+-N-^}Pi5k@?s<$E8&ek5Ah2O^9QwnYHN%mjnG5!1M|OOfPA^-0N>L zXqIVT2v~wMAG6VK&d2%>w*B9AUE>eM=w{!E1mKbI*$d}`=;m(98r|L5KJ#Gv@$Kyh zc8(2gld;N!v~Wn{EFNAv4t(=BB|^~mA1nIPzQ0I?jQ#uO#jVsbG~}14TxvhH&r~Q9 zGSUh_cQ2E8`?WjcE6?BbAVadF*D}og6Af{2kN$qV=3}TQ{p(b^&QQSWinrQ_5Hgpw zf@iwv`Jj-Dshf_&A1^_zh}YU={16Gd|EkITCO*vwp|hxkwMcp zTj!OKepCzfbzjH~=KCDszbMV8N%L)u$IJy2kJAlk$!T2r#30 zo33+zuXO%SYY)`KN@$81m){$++$ugRihS$vLn9T+%$8`vfoMkAcOA9=qJm&@T)|~J z^{rq^E}7}XT|7<7EOxOU>IG0eFb7ipi*umgYfysTxMG$i%+=}ht4#X5ZDuNAt*g<@ z=AiV+y>i_lO|$>6PqTzakGwP}e}WDb*i|SKqLfgAYUhA}+GWrS(WL3m{WM`xYciY2 z`vSCG{||Ft9uMW-zkf<76)hxt<&+{+vWKLo6m9k`WHyF!TG|a+cq7&UwB)Pv?1h{`0zDue@^KpU-=_-q&@#zsaYy#hN%{Adb=J zjLDo^z_q#kG`_muf4cLyhpthybM_B)G*g1dFPCtL)y-&F4W9_GWJh=?_29@lps=IzE))!Ky2A zXk#yz;Klw2(9{jgNmagO>h_Q3q@Y%})D)^U40LKAnp^9MfDHDtm^{3|m+$_-d~20ET^&}oV~j{n8YXq-U!FQUjCp!Z!$%be z02({94|gk4H%ie;PoXtD3|N()9vSJSEUpb)AzT{0>FjQ!%jaqRbJ^#*@9U9M>P zAx!ZC!Cdm;;^NZ+hd$4ZDX&r7A93RUqEo7hQg8CcNC4;b_;9O`?)ruXdmh^w{`=!I z*>3f|t99o&j3Z9_i(%c=yAb|P_XR>;i5ULq4?oUV2<)a!>92}+4dQ9xA7$w}JHGok zlji)Sg*62E)dW!Qd34-lAcNVOV(MoKLw|J%MJCPTN48uC_IDtzCTrd*P{hOb|_1D z*B~b%S7LNpkHfX&?hmh`caxDx4Q7!haF;zf;T~SDx?mmDE5XbdF5%=3U6G@Kd5R@wK|j0*@xNQ$+0x#G$wNDS7&g<+37&EEnid?| z@%^P&y&xJk{4jSp%-b?ElqIaQoHOQwa07=4LIQu~hsQFbw|nwK%?@=xlN>akt841k z!Q19ei%;GA{y)3T(zOeWGpA;~eK7Kq;hi#^9NE!_XtSFT*&n~T0-L$6?e+^7;6Gqc zzS&;96VJ<5nhe9t0(j4JnQO|+mE1zhY8?iYlfa4jB;e+xxbVSgR&a)}kbG537&l~ido|YfwTmIoi$~qk!HvJ?VR=w@uly@jy z7p3b4mX>MN;`_gRXJ8LZ3m@nJTrA8h3$HAHeCh)mDuYdPG^&mK0T%ji7As7aZIXFI z$}A-tmwT(C)HsTBH3V#dOmDg%ob&*X8}yiZdYi*adpgi$F+vt1##R+9PM@3xrCTc9 zUr<{9toP`}1NG93p{3TMkgLhYu_DU~1Z-tsn?t`E{}1gg+aoO7v`H&+)1}@enFgsk zAKcMYnBsDU+y%l)rlpsjGT`q;Q?Z$6t6EMo9t2+U^g?66V^N z`VkNEdMTk>!HaetcFyR_>!s;sUkp(r*a8hplBVu{KkSH!D1ukxghmdEW_%bvvu3_E zC75_`JC3>1@hPq;M;&m|wiaUie{6+6LN4X7>50(gxpx$47^>`izUT+A$?$G;Ir#yG zcT!(RTtD=Ozo3_lq*gxHsSH@z=TFNaa1XOUMVZ3ERgTWN!D8d2sd=T|6SjuHV?xiv zb#&ikPdp-!&FP^;u6auI@`(QwGFmcnfkuNizA4XqabhPxY8u7Di?!^cq07YZt(WOM zRyj@cKBCa*vAvF^!(!I8JkxTTBBM?_mYleJExT^hADTbKCIh>x!*Hg(Xv^o*pFQZr zml_zmqMOJ*5?L!JT$|X*WR61=A!}AQ{RpfxY+;+HFZ z2w5>^g1H**9hRl2mwlhk^ZB&K>#WGwv9G%V1Y49}dtO{~=C$m9y|(G_3pt-}?K zR_3+Fdcj%fvkv7*nUJjr7DBNdw^#(MJR%E*2$0ErZY$0$#45DGr{ybVWE3Oct566* zgzdZjf(!o#43ybocT7nKseex9Jz-+TVWl>|Yc0?WR{L4}HF>?~UqM+?vmTjbo zPbIk;F~qQGsr5a?&yQ2xA`fP3o4Zz!#)Dlku{cii#g7})&6UDkm@2ojM(nisK&TjP z(pOlxQ8K)^Cjm%WOauYj=-b-SCm5{JOio6AVtFIq za`uNFmTZ8u3=eW-V-V!xn}@}^B(w0AaPUfET*oDe-HQ}33@-jPpfJx4OiqtAbL81N zlIiBIv-z}coe_k5uSE;so98fpdy<+i;IhcdXb>%3%OiY{QDHMHTU3YNewMy`@zk-Kr)d02JrB5+J~s{^-PF_5 zyP@~`t;zb0^9`?FC1>j5JEar2pVFVYvqRUo_3+vr1H%<5!U}f(Y+2NjO;eB2j26Lp ze)!;*ZsHOl9e$1w-DPXZbf#UIbzD8unPw(h{6K-4oHOIIkxQp1tx4*Mb-v+%$q*-NlpSAXo$Nzf?+wi-XvrX<48sxD=5|4RpQz8UbL50` zzJmhRe5it#6&uEXIG9+QeleRZ;xN+nu}WK;^1<6LsMhT}51lv1mMI(8Xx2ui9UVAf zA+$Y8UUbmOdw5b-qkTpTJf$88i^ASPXM{P+z5jV^`}1kHpW70pl`a9gNc|E;^%7}D z{G-wl?SabueQmYjPS!ijO@{*pPyFtINbY>7Ch86vQ6GEVmX?n=cdMu|X>wz*^h}7^ zQ${%rl!&&pNBpwXZvIm2^U=?uuKV1DjPue&T9!;!i&ikG=9;>R5v_}UQ&O>g2Q)i~ zOg4!!b)f>ZiQpA@N`~i|mf`O-BH4WztK~=Upv-rOsB|_NbWRQ$FPIuO?$^>4LGu>j(MS49w@k z=MBxCB7GwRe;U2hD59;qTG*_d>k6JuK0+Sn%D;zCHNfrX*;V-PfjGx5dy`wCx3Fi0 zZ8ttzqf3aiRt!&}cLDzNGstZBOI6+OEHiftPx|Y`AU{H?#$Jr z(LUr3!tw8aDbp|L$d9NUaF3^8dz(G*r?hXkMk-!XDu*M9D-1P_(}q0fAMgz~eA#Dx zP?%*~V`7vws%+jqKFyQ>J*BXgSFm`8Q>jC7Dj%@h_Q^r=z(h+d_Zy_X#mL&DK^G4K zTOap6{<(pjR;I)9D3R?#xi(eS2Y>eF|CAW$B&PIK$^NzPZCy37+&Z-A5<+aNEcEHiy-z_B3SoH9G(b%;`3%F1* z25`=?8j0-M zX$7w4AVXLN3rwlV5jguy8LqbQEgV( z+<+71MqszA6#F9vjkm{=thv^8JDD}C6DH&1=A4}77>qk|f*rS+C^zemMF`MHiRd0H zXn8YS%j9zhx_1b94Z(iLQ%0J>75;;Xwx__(`zW5N(Q{Kv);Z3C0;5mU)19fCL{B$i z?ll$V+71|Ua#{5E3Axtd=dQMAe72F-Urc46VOWxGC44Bd-a8{QB13N{*8IN_QOJ^F zyAYO<-cwH~k;I{6&`a?OB$w;Ur%U@7ZlHEwkgp`ow|cy7J8-f?NhXXc}vZ}|469Pkq#F-+$WNhdh=ZcE=jcYr_WrzGX#3V+V~ zcX^Chg@5C&nz*r(fGQVY*P_rzCI1|`xxP&r4l#**vts-14q z;q*mi+1*%iJ%12p1z{T{XWhriGNV(EaK{svSV;cyS&9{kRPd|mcE$xZRd48_cr@Cg zd~-#smZ^gioVjsLzi<#3X@~`TT;Z%R?S^{MxKuM-sV!~Yf>8T{#dH+1tHxJD1bH)Z z;*=)}5{%ql-ON>=++UI8lFNHN^DsEyyf)BT; znxm=f2+T|ADFRRFDtJW;5?yq77lKr;eWv^wvwAgI-YeztKu|%%Bz4f_Mvvpe)Qc!^ zX}}$U5>96uxO_K%_W-0Mo&u*t7pVwoV0ogsJov^TTCsyz?WKFHV;_G|9#m+n{H$r2R(vqy{W@h~?u9Ope4M9ypM|&YEnzG4R2`nZGaMju z3d&neiD|EAi(U$(%YkdyQb5lS5-7v6Ez|OvNH^+rgzaUO4wTm@YuG3(WwfVT)H*xl zV7`@=>q4$&U;ByRH#gOUT!ao!F$m`O-!nHWrtYmH3A^kq#QksFp0HD*$;sVQFx%dz zX~t0@FrH^tH&yM$waM%GW4MWXcIIE`UVOp%CP zwU?Py=yQ8}duNWx3j$)KA(E4ypAMJ{r7Y|N9xUt5376ttU$=~ORp67(e&U?BeOE^vk7YR~mHaeDG$~#t z+x?a53fBYS(;s`dJm#+5m~*16Xu` z=?fz+?|!&+26(M2C7=*kVY^9#=ccRH(z3N*sw9m z_lo}^XAj&P8S0^-p(A%>hF*jp%K!>gHmxFuCHPZKsA4ac_P%^lTay!%lnhGLrD-m` z+HQFClU<hcTKV1N&@-tH>DbWr-VVj#4i9k}PbIh=;-|Lehj~A#PegSwAF}}U?8kza0zoRzY+)M5 zm+HXNwc{3_KJm5_O(PsDu6yzw>1vd_q{V#iIK5+igQk>~CLUi*p-H)UuRs?ED)*0X zl^eG%+SdnADgX69xhG{}FlsO@A9qPt_h_O0+W4IE`-~G(9lqw)uNipMBudC+p6t0S83dyqLjvOBRyU)8nZxh1|sh< zpu?K(1-`+Qbz!_R%F2g;n4KmeF>zJwD%44O=sdgh^8x;JrmyF|FR#dj+QPlW875sK zW_`3_b) zkyb4)5Gdl8_kZ&_w*==rvoz)FId9o(VQ-zCxp~e9BKlv2h*N0!Ei@mG&roU8b9>nG zMcn!m4nNQ)K-T@ohCOBH8MR-y0HC6YGQ)7c(}9|I{=c(%4>h+98W_++0mpA#WkL;Q z;@D)gBd!#<3O8ryNbO<2u)^~w*e&kP(2LMx8IT42GM>Y2RvJ&1TBsLjes?!1W5uv3 zCUA9OG+sWO@34eRPKMVI)btW4PhCDXH}D$ty&1`3J1sOEGOA&%;%$c(2e-9a+tu;& zt9EmzVU|9})tyONVOne|*$InWE{jYhKYR^WS|PqGdKU5}d4|&Mq-Wo-KE{P-KflIg zMc`MkYOC|!f@MaZI!JbnuxZ8x-Jum=ie7XsM#*ZnKb(kU56l zwWZ0qwaE-lVPQrf`+oEn?>jM+XKpg0$8`5v>8^v#0;3-lZL*bIojOXS3VvFU*C~6r zF5mptL=lBv3r_CNXCVZ3`c*MeyPHPalaDy5nZ2Wv1XankzpP4LnBYniS8KjjC7fJi zhLqOX){Ia%AA3i7^+JkHjxk@RI$#hL7d8_a7>9)&E?VG@5?ns}C;ifpCPw+%h7EvV z+2qtAsa`YrWe>HfuP)c;p6T)T=PTSP zDk^%Gf}>s2=F{;QM-Zu0U-&DQw3VW^P}nHW?$tF(eBS|9o!m)O0Zyv;{K5R!$Szf=ZrN~k{rC-uCtQ$o~V?kkpOMDB&sz?ecq>;!R7N%Hn4VEE0StX~d z*N^VhLbG|W7PIp*=ZZg1G(&&iSCBYE0?6+N`W}C=I4wiEjO1ZK4t*J%VN~YQg($~T z`MgW;LP;mQij#Xa$L;2vTHEv8p+VUMI7NKZs@_}H3=n8IPyJTi+~b9Qz7KH9zq7O< zM(MB4596-9VH0^n8qzb;vGJCKzWjF@(;U1(Fdbd0S<|jF5D$zi3-TCg4H*ux{?!tBq zHrYYPl*Mw+@6@(FbvnWSX?WV%fi38H3ki7cuaZJ|0orhJo!(J4P0ztpVAc=%|8T%h;05=WV+nnBIs_L(?XV-R1H7++(MP?MNYGYO)9@c1bno^pTw z;-~N5pVkCE%*C{K&LfH|wmtRplSeCI=!YmjxXkmO($-Y0{94(=ZdTq1&~dbeN$b;) z0*ZO{bl&DDv0;{s`$aoHn6U?0T8q9m%Bif@Ao-o#y4eOL2XDrd@X-k@Y6k55S00jzmsffZ!&ffW#``oY4K1=2cb4X((_Ql)?{0qmA>^>6_8hVfv5 zh0a`>S~eAEeud^27OZj3qoCd|d^oiGuJPry(wpfFzg&l^Yjs`GkqeJWaxpHP5 zZ?`O4&UsJ15sbf`<(iqV(i(7~zGwb0cS@a=*66hwv$ln+Vd+a$r96Dz-gf)vvIJ%S zF-_06P$no}Ra9J%gd?RXVx@=3eRX79$>b*?kV)VVOgn4^JBS=i5{?$2IEAt{ap48q zoLZ#)m=bocGm}oeg;a+6LqW>K!`cos=}0@jv|EUDsX)u%P)e3FIX$_cD8H#i_^CTA z_hSZs&wwqZ$GPDKjwCOozy3V+P4=vO+rD=Imttuf60%L78Id+ z<1L9}9T^muJ@>N}Pi}na8=oY5rMU|A8F@)w0w{dN zb)T?*_ANH&L7PAh1^_wcA51%(ZP6Yd?7TFzu;%8Qx5Ls+!%h3vV_aoVNMtj>Q|;R? zz2`ew^{nM6axE(Y3RXDy2F59K&V%lj2du6D*;l3lPw!KFi&`DD`*0l#2Bi;ePZ@zi zTOIoOBbZz~f1!~=Xg`O48oER4VpeqUjP+R@iope-D}Sml>;p?&SjDpzx~e8U0;xd>2~5tz?P4k#0KmN_Gh4%UnikK z3(=f#?S;Bd#ll2th701^d8@vQi}>D>W&B8Ev_J4nbV692cbHPe=bx6-38}lKcwz1_ zAsCpi@O9_GCMS;+K$B*;G)>4=6w>gQE-h*xX%6%VX1m2oFdSzK7ZhQX2hw$#rk=Fa zhKl445}JRGXE3yIIvnYkQJF?z6bk_Fzu}9l*hzjF3XM~|t(em|)yJTuntM2vMo76;`#24I_BoVgv2YwqFr5u8O{!sApZ-t0p zjkmS50;}0w_kev5S3o#I)m;L9R?FKp)z$p~LUcuiZ}dFw8c?5V-%v)1ab8)Dt*J*I?%kc1crBr3) z%78zd;~13KODu04-S5ZPu@hjySK6hmh*pE~PIjM!!Iw#zWIJqoZ{5Rbq|ajz(KPnB zq3Da=y=sm)YgwUV_U7HW%u-WQOg$R#rGsOqD?IxQ-o+O?0kr7UU!z5T)kPCG?xtl* zmatYca`-4SO{3zz%xHOr!i4T$oSQ>hVBIv{JWfSg9hyK|i1`cu5bBb{>fsYkSwat(1?4 zXF-zkREk-5&MAi(tXirlu;8->TejSW&%9U7+zw2f(l-`1;2~&EggZd?CW-sLUI{N6 z-&-i8>@Qa$XNg?3l1R?Tixntb-!sYv4^O*Tw)Db;va>j8ht8xM5A$2W(y2Hul;Y*W zcfA@S=}S!CekBG$kb+r#4N_JQytLG?=5A1sa$m5Mryqu0DH*^SM>JRQn8Mrdyg#Yx z<6eojDo0)cS3;$KKHsXNJNrU4oh{-rVX%6?g~y%$D=qvjOqERp8gT(CTj?1X+O<#m zX;PVXq_Y9MS(W(iDm9lYCJ**X5-tYX3>BhENS)07rc%bRWx}CDhx8hwM4xKv`4x-V zjXeaG)tutukzyA&aXA|0ofQL>g3@62e%pQ@P{VJq#AuPcx;+)}cDwm5j3`17Kkr?e zTeowWj2sH~j_+mGQTmk3(@L!+z41gLHlmZe3 zgpS_Y>#k&-efAJY%taerBPUJJ6dV4;W8$2>Jf`~XHm7+`UdG4GtjsXfnR_2dA4Xj8 zCSET=+Aa1>dAuRSvh4hCo%hf^wn3nuaN1_^<$VPHNJm@Sed6-8aZAFkI7IAFHS6kP z0!Y^9Epe=%KX5;-(~N{7{LRm-uPgk$__u%|e0l*jzx(pR2j`6+r@)KO#+5r-sRa|E zFppQX@I(uSilo-@Kl^fo!d5<}yeeAW3XT}HzC`l=<}>|57hn}4?qARJ`qdK-#{u*V zy6)$E7e9^vLsl+p9QaUP<@-bHI{9~bF28-?i3wPo_I>`)I2@a zBFp|-eX$uezAO&9+)1}WoD}<>g9T5VtaG6DXGqvoM{89cRj@{9 z91{^d?J9o;*}#B&+i@^&JG{_zS!u8cZxAc(bv~+RSS7|xdYnf!Utcm^a%TS?6XHz- z51aPeDC@(Uzo{Tc>5dfOgLH8HE6j?G#YEZ8Ff=t+7_F?bdY;NXlXm9Qe5#M){W1O3 zgI_Q-$2A4GHns;3Dm0x(8>RT_>@mv*}~2mU}Ec&`qJV{C68g0zjifGq2gr z{f+}7L%#S|$dDG!#}6_zq*&egbj>&lSI=YGipy2)G-L|mKJ`(Nk3WmyI`Tw`{lS=q zb)QkBF(L4<{j$`brThOj_w5MazSU<%&XNi}jz~=&et9qbA_8kW8$GC#%`n!gq?Su5 z^}2;7!Xyx?XeBxZZd&Rs<#i!*s(a67l@r|3?VKWPs&pYL&oe;fxwc^iSYL>Lh4r-@ zzl$lkKBemOb6w+CF~bbGCU~*a=GpYo*KMpZ!--G@i#eEHTBk-{VAbbIuTmS8ypG(s z7Aou!MXT)l9r(&XrMDHqo2ry(&zb{WJZiRu>L@O8}nP? z$_}xOPFuJ-iBB08?Yld8^&rT~{(r-fbDxzJTRxvs`pJM3rKl8y%DV@vSof?nR_UfG zDSVGrKH2ZGH0(cTxG*YFt%l(*>s%NhpK7UPX@0hm@LT))BW`L)rHZaY^TDwwiJfM7 z@W&RsidDQ6Z@ZzJiZbJMmyAD{bxyqxG_|hj29dqxMjCJXC*^v51&XjEwu$9+F9m4h zA@0nD@Vx62K7d)g_OmuCf3*Bu79hasN`>oY1jjd|Mu^JU**AzgHR?L!-n!t@q5(vC#avoDNrL!Xpr!Pm|>_TolPlFEJLK7nJS{iPVHOZ3QYd8Pv zi~l1Bj(i%m1Jo8W`C;XAU18&6&m|5^v7N6|j#X4K8NR;mVkmsRp}w?+R@gZm&^GU{ zju5OBI>gV6BxB%z!$pnu-TNV9+Znyqljko|WF${38LS}hOWFtvR^s`(ba`G{NvziI zywS8Vz?dJf?Mqjn-jHdIr-Jex#AKZG3Q@hdf&e=;Bv4102@=uC35)8+*lC#dX z*vRH}#ULX-_8J`kJKsUCD;G1`-`KU$9Cuq|kEJ7eR6TczA|t3(yvGv+win+U)EXr6 zC5rL}s0GxIrBR6(EQB*Y<4(!H??7VB!FKO-)cQ~d1vM)-oq8VCF;S}UJs$$1~mj^K}eymz63{}rH)+b}y;aXd-O16g!wHBW7&Bv|26sw^7-CG#(I zOu(`;omwLSEOZl@K>CkRo?c<#N*<9nqjHpL2 zIBxdjl^NB0AIfYOd1eAxs^Hd4r(*br8)WbP2Frc-VG}KR-Si6=;CHay?@_vca`0sN zwqN1fv6uU>Pq1G#XOZr<8OeegD7p=m-5naZJCxP>EU$M_(;FjI1u8g^f{ne0I~H^# zRm4y?LWsqo7N}`i>qVwsP)T?~naJe>)Ib6;NoNWe7#qvj zcoZ(hYndF*TBzH7Rf)KK-(}_=Uav)`iH5Yj1&^=@Tyh>}f0kYevz|om6%z5WK4mHN zgR8c1fuORtTB+9R)sb_!?h+>ri8H1M=#8x=^7r>5G#?7x46X!hjSDKbE0b1`D{2r` zrgvr`>TgI3O9-@2Zw8ZhRj7%`y8-aZh|F#GuQ$40O{JRQV4J$Yd8vQdC^9}_iI(o_ zXv>B5sjLGmQRT>&!Yp@wgHnG)Z`Eo7%Y-TJSHLgoqg0$YOm792APRRgnFN|&S+jza zR&>0DtkbWTt9Gq2x&%G<8(v9XIkngz!6?j5P6<|;2s>$HFVL+6k&})9y7%+7exOQ| z{B~6u)>b2X%6{FtN3RLh1;*F+ZR_|YMGLh|c-AMf z_$BxL{aN8(&jh%0$Eg{VBCTb^5xRH!;mIjofkavJD}w>%8X=OJ92RbSg85dd#LkPe z1Et!i=ye_yJpwh1;IH#(Oz;NSc}j*1G;?tD@D zuFVNO9g02bk`!1yhV7dl@Ob1-Um zno!orvKsYfkc=i7)JA$J>#p@4-;{^4bWm)LZvF!l@V}Ib0{p1z+FsOfHLHCQVb|57 zl>C06Dll$G#zSun$Wp3X>xzB&y1bfGm(*hP>t^g>ufkjLT?Qsy+(153-NBv%E|*w`)k=nT^bss?q3EQZO}C3Jo(3VkdCh$*cJ zt3^Njyy37ZrptYAKLrBVo6X36^*ES4h;ygZ&P5)r3+Wv?4Bgg)yYZE~c`T$m4#`-V zHySr(+BeDG&>}Duwj`x zbvBuk`7dlI>4jN5tZkbhfoTx6gF8o;21}er`y<9@Z-o($Q=Sm5RC*1JBRYD(MO9g3 zEVw*$ll$E4s4Zd5ZY}(jB}vVD+#}q4Q&Fi&x5>@&htQ->&Dy__+V_|0O5g^q)sC4f zCuE1L5Df$Q0S!2hPR_$Hk-|!=#d@Y;(L6kFX`4M= zEIhk-W!QJO+xt8Dmqk+}n@KbfR&LJ+Q)=UYu=4BQjFpeXV6fwaKB*!P&oB+%)a{SL9=;X1&#-CIs`iU z^W%@ipPUY?`!YAe5FU341*k)>|B*WMRlp@Gm$UHN(aPw)$0oV4SD`WOF4la#5_GI; zcrq0^wU{C;??L~{gf2Dx;+AaH9lmInGi}q?+r=F`-F>H!H6PwWF|M@tR&-|5L5VXH z{^X!h(AGE8|A)u$ewY;>4A@gZJvI8QI3QpTSbR~~Xuo+n zb+}@m?W*uMd-{uPnw1}|dk9k4L4s!1ZNI28d?a+X@J4AR?nY6kxH&zh60f;t+|cdL%#= z1WFXlLCLZ@q0F^8>$WRa&`nD-59mQQ2NV;U-6_dZ(10TJuLcx=^9&I$va-(MjRb9M zY-o3#na@7_RUcMFuw@J(CnP1ce%zelp8xRda7DwHogk9JCdBjm-YvR@XyEA41o&C` zr^SXw=wQDSO1}^kV3liDX==-2B;*Y11EmCg$3fG!gl&WvRnPZ^&XQQtaVU=yc{Uk{ zn|jI?q8$sr^}&2jz!UY^SUt47X5O|@bQ(x1Qzy4S_ZVq>`RRP}Jcae-m$X-BbhiVt zf%8KY;Bkt8B~0j};k_O5{OBPqJ+ZdbEsn>eX5*$mg#C7!h>IxXlV1!GK(o&xwFv-& z8R4(45hC`T3k+Y?kWBXyyQ934m^^$ohi;_HURt+NBE`_iX97O@gw21pNDclOr7Njm z;=w7&%^du^mSJUP?%-!}#{j4VFbenJc+o*(L#rdaK^Y)X9Wz0L(r}`CEm&VJ!4%0D;d1wnj9C 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%0A=jSP04qMGn@LL>tINNscd?`nS-hnS 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 z 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

(CbvxK^N#oDM5qK+KrFZ4v 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

  • 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�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

    C(R>SmnWzgU=P$@f4Wp;f$*3s=f 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

      SytzV47NprR4aom+B$f7WNZq~(x0xs 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

      {*rJ%NW?=3H=hFI+fSs*bKj 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 z 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

      6V~rew^~2XrNden0EE`H+Vw96d8?J`RJ3H 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

      x*lF!~>|Rq*0Ftt1tm{4Utja4p~Gh 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. Here is an example configuration: + +[source,yaml] +---- +metricbeat.modules: +- module: ibmmq + metricsets: ['qmgr'] + period: 10s + hosts: ['localhost:9157'] + + # This module uses the Prometheus collector metricset, all + # the options for this metricset are also available here. + metrics_path: /metrics + + # The custom processor is responsible for filtering Prometheus metrics + # not stricly related to the IBM MQ domain, e.g. system load, process, + # metrics HTTP server. + processors: + - script: + lang: javascript + source: > + function process(event) { + var metrics = event.Get("prometheus.metrics"); + Object.keys(metrics).forEach(function(key) { + if (!(key.match(/^ibmmq_.*$/))) { + event.Delete("prometheus.metrics." + key); + } + }); + metrics = event.Get("prometheus.metrics"); + if (Object.keys(metrics).length == 0) { + event.Cancel(); + } + } +---- + +It also supports the options described in <>. + +[float] +=== Metricsets + +The following metricsets are available: + +* <> + +include::ibmmq/qmgr.asciidoc[] + diff --git a/metricbeat/docs/modules/ibmmq/qmgr.asciidoc b/metricbeat/docs/modules/ibmmq/qmgr.asciidoc new file mode 100644 index 00000000000..7617b660ad6 --- /dev/null +++ b/metricbeat/docs/modules/ibmmq/qmgr.asciidoc @@ -0,0 +1,24 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-ibmmq-qmgr]] +=== IBM MQ qmgr metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/ibmmq/qmgr/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/ibmmq/qmgr/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index e3ba332daa0..886add0578c 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -100,6 +100,8 @@ This file is generated! See scripts/mage/docs_collector.go |<> |image:./images/icon-no.png[No prebuilt dashboards] | .2+| .2+| |<> |<> +|<> beta[] |image:./images/icon-yes.png[Prebuilt dashboards are available] | +.1+| .1+| |<> beta[] |<> |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | @@ -255,6 +257,7 @@ include::modules/googlecloud.asciidoc[] include::modules/graphite.asciidoc[] include::modules/haproxy.asciidoc[] include::modules/http.asciidoc[] +include::modules/ibmmq.asciidoc[] include::modules/jolokia.asciidoc[] include::modules/kafka.asciidoc[] include::modules/kibana.asciidoc[] diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index 0625c8daf96..f1d2485b128 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -28,6 +28,7 @@ import ( _ "github.com/elastic/beats/x-pack/metricbeat/module/coredns/stats" _ "github.com/elastic/beats/x-pack/metricbeat/module/googlecloud" _ "github.com/elastic/beats/x-pack/metricbeat/module/googlecloud/stackdriver" + _ "github.com/elastic/beats/x-pack/metricbeat/module/ibmmq" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql/performance" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql/transaction_log" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index d9f5c41f435..bf24255b4e3 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -503,6 +503,36 @@ metricbeat.modules: # fields: # added to the the response in root. overwrites existing fields # key: "value" +#-------------------------------- IBM MQ Module -------------------------------- +- module: ibmmq + metricsets: ['qmgr'] + period: 10s + hosts: ['localhost:9157'] + + # This module uses the Prometheus collector metricset, all + # the options for this metricset are also available here. + metrics_path: /metrics + + # The custom processor is responsible for filtering Prometheus metrics + # not stricly related to the IBM MQ domain, e.g. system load, process, + # metrics HTTP server. + processors: + - script: + lang: javascript + source: > + function process(event) { + var metrics = event.Get("prometheus.metrics"); + Object.keys(metrics).forEach(function(key) { + if (!(key.match(/^ibmmq_.*$/))) { + event.Delete("prometheus.metrics." + key); + } + }); + metrics = event.Get("prometheus.metrics"); + if (Object.keys(metrics).length == 0) { + event.Cancel(); + } + } + #------------------------------- Jolokia Module ------------------------------- - module: jolokia #metricsets: ["jmx"] diff --git a/x-pack/metricbeat/module/ibmmq/_meta/Dockerfile b/x-pack/metricbeat/module/ibmmq/_meta/Dockerfile new file mode 100644 index 00000000000..f95d8e8c0d8 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/Dockerfile @@ -0,0 +1,11 @@ +ARG IBMMQ_VERSION + +FROM ibmcom/mq:${IBMMQ_VERSION} + +ENV IBMMQ_METRICS_REST_PORT=9157 + +ENV LICENSE=accept +ENV MQ_QMGR_NAME=QM1 +ENV MQ_ENABLE_METRICS=true + +HEALTHCHECK --interval=1s --retries=90 CMD curl -s --fail http://127.0.0.1:${IBMMQ_METRICS_REST_PORT}/metrics | grep -q "ibmmq_qmgr_commit_total" diff --git a/x-pack/metricbeat/module/ibmmq/_meta/config.yml b/x-pack/metricbeat/module/ibmmq/_meta/config.yml new file mode 100644 index 00000000000..2f8973d9730 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/config.yml @@ -0,0 +1,28 @@ +- module: ibmmq + metricsets: ['qmgr'] + period: 10s + hosts: ['localhost:9157'] + + # This module uses the Prometheus collector metricset, all + # the options for this metricset are also available here. + metrics_path: /metrics + + # The custom processor is responsible for filtering Prometheus metrics + # not stricly related to the IBM MQ domain, e.g. system load, process, + # metrics HTTP server. + processors: + - script: + lang: javascript + source: > + function process(event) { + var metrics = event.Get("prometheus.metrics"); + Object.keys(metrics).forEach(function(key) { + if (!(key.match(/^ibmmq_.*$/))) { + event.Delete("prometheus.metrics." + key); + } + }); + metrics = event.Get("prometheus.metrics"); + if (Object.keys(metrics).length == 0) { + event.Cancel(); + } + } diff --git a/x-pack/metricbeat/module/ibmmq/_meta/docs.asciidoc b/x-pack/metricbeat/module/ibmmq/_meta/docs.asciidoc new file mode 100644 index 00000000000..a031924fbaf --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/docs.asciidoc @@ -0,0 +1,28 @@ +This module periodically fetches metrics from a containerized distribution of IBM MQ. + +[float] +=== Compatibility + +The ibmmq `qmgr` metricset is compatible with a containerized distribution of IBM MQ (since version 9.1.0). +The Docker image starts the `runmqserver` process, which spawns the HTTP server exposing metrics in Prometheus +format ([source code](https://github.com/ibm-messaging/mq-container/blob/9.1.0/internal/metrics/metrics.go)). + +The Docker container lifecycle, including metrics collection, has been described in the [Internals](https://github.com/ibm-messaging/mq-container/blob/9.1.0/docs/internals.md) +document. + +The image provides an option to easily enable metrics exporter using an environment +variable: + +`MQ_ENABLE_METRICS` - Set this to `true` to generate Prometheus metrics for the Queue Manager. + +[float] +=== Dashboard + +The ibmmq module includes predefined dashboards with overview information +of the monitored Queue Manager, including subscriptions, calls and messages. + +image::./images/metricbeat-ibmmq-calls.png[] + +image::./images/metricbeat-ibmmq-messages.png[] + +image::./images/metricbeat-ibmmq-subscriptions.png[] diff --git a/x-pack/metricbeat/module/ibmmq/_meta/fields.yml b/x-pack/metricbeat/module/ibmmq/_meta/fields.yml new file mode 100644 index 00000000000..c19c63bcdb0 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/fields.yml @@ -0,0 +1,10 @@ +- key: ibmmq + title: 'IBM MQ' + release: beta + description: > + IBM MQ module + settings: ["http"] + fields: + - name: ibmmq + type: group + fields: diff --git a/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-calls-overview.json b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-calls-overview.json new file mode 100644 index 00000000000..68dc16e3062 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-calls-overview.json @@ -0,0 +1,1219 @@ +{ + "objects": [ + { + "attributes": { + "description": "The dashboard presents metric data describing IBM MQ calls, collected by a queue manager.", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "68140594-23bf-4e1e-a062-19b21e557e1a", + "w": 16, + "x": 0, + "y": 0 + }, + "panelIndex": "68140594-23bf-4e1e-a062-19b21e557e1a", + "panelRefName": "panel_0", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "2bb94f86-2fa8-4e3e-b91d-9838a29b9674", + "w": 16, + "x": 16, + "y": 0 + }, + "panelIndex": "2bb94f86-2fa8-4e3e-b91d-9838a29b9674", + "panelRefName": "panel_1", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "0b68733f-6f86-4686-9580-1354f5d6bc4d", + "w": 16, + "x": 32, + "y": 0 + }, + "panelIndex": "0b68733f-6f86-4686-9580-1354f5d6bc4d", + "panelRefName": "panel_2", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "0423a3f2-8f1f-4402-842b-9423008ac5c1", + "w": 16, + "x": 0, + "y": 12 + }, + "panelIndex": "0423a3f2-8f1f-4402-842b-9423008ac5c1", + "panelRefName": "panel_3", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "6936c053-8168-4eb9-9964-fc0e892b9130", + "w": 16, + "x": 16, + "y": 12 + }, + "panelIndex": "6936c053-8168-4eb9-9964-fc0e892b9130", + "panelRefName": "panel_4", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "084602cd-6b17-4f8f-97a8-c33ac2bafb14", + "w": 16, + "x": 32, + "y": 12 + }, + "panelIndex": "084602cd-6b17-4f8f-97a8-c33ac2bafb14", + "panelRefName": "panel_5", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "50a75e9d-e345-45c7-93fb-54e29d0863f2", + "w": 16, + "x": 0, + "y": 24 + }, + "panelIndex": "50a75e9d-e345-45c7-93fb-54e29d0863f2", + "panelRefName": "panel_6", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "9cae147d-66d9-4bff-b916-f3b82adc07be", + "w": 16, + "x": 16, + "y": 24 + }, + "panelIndex": "9cae147d-66d9-4bff-b916-f3b82adc07be", + "panelRefName": "panel_7", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "fc84cd97-80a9-406d-ab2b-c1d9ce5dca72", + "w": 16, + "x": 32, + "y": 24 + }, + "panelIndex": "fc84cd97-80a9-406d-ab2b-c1d9ce5dca72", + "panelRefName": "panel_8", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "d8c19a6d-a25b-4950-9ef4-6a15a894f725", + "w": 16, + "x": 0, + "y": 36 + }, + "panelIndex": "d8c19a6d-a25b-4950-9ef4-6a15a894f725", + "panelRefName": "panel_9", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "d76eb9f9-2198-475b-a058-7204244d5597", + "w": 16, + "x": 16, + "y": 36 + }, + "panelIndex": "d76eb9f9-2198-475b-a058-7204244d5597", + "panelRefName": "panel_10", + "version": "7.4.0" + } + ], + "timeRestore": false, + "title": "[Metricbeat IBM MQ] Calls Overview", + "version": 1 + }, + "id": "fc5512c0-36d1-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "07262080-36d3-11ea-9f7a-097fe7ab3ddd", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "1dba2700-36de-11ea-9f7a-097fe7ab3ddd", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "2fcbdab0-36de-11ea-9f7a-097fe7ab3ddd", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "d781db00-36df-11ea-9f7a-097fe7ab3ddd", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "fd0e16a0-36de-11ea-9f7a-097fe7ab3ddd", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "aa90ec20-36e0-11ea-9f7a-097fe7ab3ddd", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "fd0e16a0-36de-11ea-9f7a-097fe7ab3ddd", + "name": "panel_6", + "type": "visualization" + }, + { + "id": "56b63f60-36e0-11ea-9f7a-097fe7ab3ddd", + "name": "panel_7", + "type": "visualization" + }, + { + "id": "74874de0-36e0-11ea-9f7a-097fe7ab3ddd", + "name": "panel_8", + "type": "visualization" + }, + { + "id": "92bf3480-36e0-11ea-9f7a-097fe7ab3ddd", + "name": "panel_9", + "type": "visualization" + }, + { + "id": "c4be1ff0-36e0-11ea-9f7a-097fe7ab3ddd", + "name": "panel_10", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-01-14T18:46:51.094Z", + "version": "WzYyLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQCB calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqcb_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqcb_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQCB calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "07262080-36d3-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T13:37:37.416Z", + "version": "WzI1LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQCLOSE calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqclose_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqclose_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQCLOSE calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "1dba2700-36de-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T14:56:59.760Z", + "version": "WzI2LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQCONN/MQCONNX calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqconn_mqconnx_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqconn_mqconnx_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQCONN/MQCONNX calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "2fcbdab0-36de-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T14:57:30.075Z", + "version": "WzI3LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQDISC calls succeeded [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqdisc_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQDISC calls succeeded [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "d781db00-36df-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:09:20.944Z", + "version": "WzI5LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQCTL calls succeeded [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqctl_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQCTL calls succeeded [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "fd0e16a0-36de-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:03:14.442Z", + "version": "WzI4LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQSTAT calls succeeded [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqstat_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQSTAT calls succeeded [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "aa90ec20-36e0-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T18:46:20.735Z", + "version": "WzYxLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQOPEN calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqopen_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqopen_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQOPEN calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "56b63f60-36e0-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:13:24.521Z", + "version": "WzMxLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQINQ calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqinq_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqinq_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQINQ calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "74874de0-36e0-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:14:01.330Z", + "version": "WzMzLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQSET calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqset_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqset_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQSET calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "92bf3480-36e0-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:14:35.080Z", + "version": "WzM0LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "MQSUBRQ calls succeeded/failed [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_mqsubrq_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "92c00030-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + }, + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "a8f2add0-36d2-11ea-8b7d-bfeb3bd2cf33", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_mqsubrq_total", + "id": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "max" + }, + { + "field": "a8f2add1-36d2-11ea-8b7d-bfeb3bd2cf33", + "id": "bb30c8b0-36d2-11ea-8b7d-bfeb3bd2cf33", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "MQSUBRQ calls succeeded/failed [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "c4be1ff0-36e0-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T15:15:58.959Z", + "version": "WzM2LDJd" + } + ], + "version": "7.4.0" +} diff --git a/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-messages-overview.json b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-messages-overview.json new file mode 100644 index 00000000000..a57ad13dc88 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-messages-overview.json @@ -0,0 +1,1250 @@ +{ + "objects": [ + { + "attributes": { + "description": "The dashboard presents metric data describing IBM MQ persistent and non-persistent messages. Metric data are collected by a queue manager.", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "31635dc4-663e-4ad1-adae-eb96687c7810", + "w": 16, + "x": 0, + "y": 0 + }, + "panelIndex": "31635dc4-663e-4ad1-adae-eb96687c7810", + "panelRefName": "panel_0", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "5452998b-5149-4ac6-93df-b3fccab74f58", + "w": 16, + "x": 16, + "y": 0 + }, + "panelIndex": "5452998b-5149-4ac6-93df-b3fccab74f58", + "panelRefName": "panel_1", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "0e58849b-8742-4ed4-aae2-33ca19553ac2", + "w": 16, + "x": 32, + "y": 0 + }, + "panelIndex": "0e58849b-8742-4ed4-aae2-33ca19553ac2", + "panelRefName": "panel_2", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "45cd1f23-ef32-4785-b8c0-dcd4cf4c0c1f", + "w": 16, + "x": 0, + "y": 12 + }, + "panelIndex": "45cd1f23-ef32-4785-b8c0-dcd4cf4c0c1f", + "panelRefName": "panel_3", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "2fbdb686-f624-4b2d-a26d-4e7f70e8d902", + "w": 16, + "x": 16, + "y": 12 + }, + "panelIndex": "2fbdb686-f624-4b2d-a26d-4e7f70e8d902", + "panelRefName": "panel_4", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "355b12f6-56cb-4b8c-8498-b379d3e7d8b0", + "w": 16, + "x": 32, + "y": 12 + }, + "panelIndex": "355b12f6-56cb-4b8c-8498-b379d3e7d8b0", + "panelRefName": "panel_5", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "c1eed75c-610c-4741-b384-de866f30b79b", + "w": 16, + "x": 0, + "y": 24 + }, + "panelIndex": "c1eed75c-610c-4741-b384-de866f30b79b", + "panelRefName": "panel_6", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "78bd7680-0f3f-4d3f-994b-eeb58ef0a340", + "w": 16, + "x": 16, + "y": 24 + }, + "panelIndex": "78bd7680-0f3f-4d3f-994b-eeb58ef0a340", + "panelRefName": "panel_7", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "6edef0c3-4c5f-4d0a-8e58-076cb5249ca2", + "w": 16, + "x": 32, + "y": 24 + }, + "panelIndex": "6edef0c3-4c5f-4d0a-8e58-076cb5249ca2", + "panelRefName": "panel_8", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "0ecb7983-d4f9-453d-ade4-d02dfa6b6c72", + "w": 16, + "x": 0, + "y": 36 + }, + "panelIndex": "0ecb7983-d4f9-453d-ade4-d02dfa6b6c72", + "panelRefName": "panel_9", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "1c8071e7-c89a-45b1-aae6-31471939b73c", + "w": 16, + "x": 32, + "y": 36 + }, + "panelIndex": "1c8071e7-c89a-45b1-aae6-31471939b73c", + "panelRefName": "panel_10", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "e27955d6-ce96-48b9-b9d0-04f4d61a757f", + "w": 16, + "x": 16, + "y": 36 + }, + "panelIndex": "e27955d6-ce96-48b9-b9d0-04f4d61a757f", + "panelRefName": "panel_11", + "version": "7.4.0" + } + ], + "timeRestore": false, + "title": "[Metricbeat IBM MQ] Messages Overview", + "version": 1 + }, + "id": "d2112e90-36ea-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "49abed00-36eb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "0abb72e0-36ec-11ea-9f7a-097fe7ab3ddd", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "195b5860-36ec-11ea-9f7a-097fe7ab3ddd", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "60b5a440-36ec-11ea-9f7a-097fe7ab3ddd", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "e98d7660-36ee-11ea-9f7a-097fe7ab3ddd", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "d82919b0-36ee-11ea-9f7a-097fe7ab3ddd", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "23c5f140-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_6", + "type": "visualization" + }, + { + "id": "3ed28890-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_7", + "type": "visualization" + }, + { + "id": "58abd000-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_8", + "type": "visualization" + }, + { + "id": "67eeac40-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_9", + "type": "visualization" + }, + { + "id": "96d27500-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_10", + "type": "visualization" + }, + { + "id": "855debb0-36ef-11ea-9f7a-097fe7ab3ddd", + "name": "panel_11", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-01-14T17:09:00.139Z", + "version": "WzYwLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Message commits [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_commit_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Message commits [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "49abed00-36eb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:36:10.861Z", + "version": "WzQwLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Expired messages [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_expired_message_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Expired messages [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "0abb72e0-36ec-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:36:40.846Z", + "version": "WzQxLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Purged queue [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_purged_queue_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Purged queue [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "195b5860-36ec-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:37:05.382Z", + "version": "WzQyLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Failed browse count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_browse_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Failed browse count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "60b5a440-36ec-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T17:02:57.717Z", + "version": "WzU5LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Non-persistent message MQPUT1 [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_persistent_message_mqput1_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Non-persistent message MQPUT1 [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "e98d7660-36ee-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:58:23.452Z", + "version": "WzQ5LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Non-persistent message MQPUT [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_persistent_message_mqput_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Non-persistent message MQPUT [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "d82919b0-36ee-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:57:47.695Z", + "version": "WzQ3LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Non-persistent message browse count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_persistent_message_browse_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Non-persistent message browse count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "23c5f140-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:58:51.348Z", + "version": "WzUwLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Non-persistent message destructive get count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_persistent_message_destructive_get_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Non-persistent message destructive get count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "3ed28890-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T16:59:36.729Z", + "version": "WzUxLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Persistent message MQPUT count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_persistent_message_mqput_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Persistent message MQPUT count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "58abd000-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T17:01:06.699Z", + "version": "WzU1LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Persistent message MQPUT1 count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_persistent_message_mqput1_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Persistent message MQPUT1 count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "67eeac40-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T17:00:53.118Z", + "version": "WzU0LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Persistent message destructive get count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_persistent_message_destructive_get_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Persistent message destructive get count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "96d27500-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T17:02:14.424Z", + "version": "WzU4LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Persistent message browse count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_persistent_message_browse_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Persistent message browse count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "855debb0-36ef-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T17:01:35.083Z", + "version": "WzU2LDJd" + } + ], + "version": "7.4.0" +} diff --git a/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-subscriptions-overview.json b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-subscriptions-overview.json new file mode 100644 index 00000000000..2698136c631 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/_meta/kibana/7/dashboard/Metricbeat-ibmmq-subscriptions-overview.json @@ -0,0 +1,752 @@ +{ + "objects": [ + { + "attributes": { + "description": "The dashboard presents metric data describing IBM MQ subscriptions. Metrics show statistics of actions performed on durable and non-durable subscriptions, collected by a queue manager.", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "e17294e6-0911-47dc-b28b-de87507924b5", + "w": 16, + "x": 0, + "y": 0 + }, + "panelIndex": "e17294e6-0911-47dc-b28b-de87507924b5", + "panelRefName": "panel_0", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "040d5750-fa77-45c6-82c1-26fc6f3859a6", + "w": 16, + "x": 16, + "y": 0 + }, + "panelIndex": "040d5750-fa77-45c6-82c1-26fc6f3859a6", + "panelRefName": "panel_1", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "fe5933aa-17b4-455e-8ab4-88d1f50ba73a", + "w": 16, + "x": 32, + "y": 0 + }, + "panelIndex": "fe5933aa-17b4-455e-8ab4-88d1f50ba73a", + "panelRefName": "panel_2", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "87a5c31a-6456-4839-a9ec-24802f51889d", + "w": 16, + "x": 0, + "y": 12 + }, + "panelIndex": "87a5c31a-6456-4839-a9ec-24802f51889d", + "panelRefName": "panel_3", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "1af1ab03-5cfd-4495-9d50-7dd77f43f1a4", + "w": 16, + "x": 16, + "y": 12 + }, + "panelIndex": "1af1ab03-5cfd-4495-9d50-7dd77f43f1a4", + "panelRefName": "panel_4", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "a9a53a87-592f-480f-997d-73fcb1843167", + "w": 16, + "x": 32, + "y": 12 + }, + "panelIndex": "a9a53a87-592f-480f-997d-73fcb1843167", + "panelRefName": "panel_5", + "version": "7.4.0" + }, + { + "embeddableConfig": {}, + "gridData": { + "h": 12, + "i": "38525462-b0f6-4cc9-a052-6e5f66f1cba3", + "w": 16, + "x": 0, + "y": 24 + }, + "panelIndex": "38525462-b0f6-4cc9-a052-6e5f66f1cba3", + "panelRefName": "panel_6", + "version": "7.4.0" + } + ], + "timeRestore": false, + "title": "[Metricbeat IBM MQ] Subscriptions Overview", + "version": 1 + }, + "id": "8f788c70-36c9-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "b455bc00-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "bdf17380-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "9939e270-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "89984460-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "908afbf0-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "d8dbdcd0-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "3901ed30-36cb-11ea-9f7a-097fe7ab3ddd", + "name": "panel_6", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-01-14T12:58:08.915Z", + "version": "WzIzLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Create non-durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_durable_subscription_create_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "b5619140-36cc-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Create non-durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "b455bc00-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:52:51.700Z", + "version": "WzE2LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Delete non-durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_non_durable_subscription_delete_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "cd9fed60-36cc-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Delete non-durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "bdf17380-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:53:21.649Z", + "version": "WzE3LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Resume durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_durable_subscription_resume_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "e0ece030-36cc-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Resume durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "9939e270-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:53:56.259Z", + "version": "WzE4LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Create durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_durable_subscription_create_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "alpha": 0.3, + "beta": 0.1, + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "gamma": 0.3, + "id": "f9af6070-36cc-11ea-b7bc-e7f346d59677", + "model_type": "simple", + "multiplicative": true, + "period": 1, + "type": "derivative", + "unit": "", + "window": 5 + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Create durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "89984460-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:54:34.978Z", + "version": "WzE5LDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Delete durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_durable_subscription_delete_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "0a276150-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Delete durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "908afbf0-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:55:01.483Z", + "version": "WzIwLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Failed create/alter/resume subscription count [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "rgba(211,49,21,1)", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_failed_subscription_create_alter_resume_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "2809d4f0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Failed create/alter/resume subscription count [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "d8dbdcd0-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:55:50.813Z", + "version": "WzIxLDJd" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Alter durable subscription [Metricbeat IBM MQ]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": "0", + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "6fa6af70-36ca-11ea-b7bc-e7f346d59677" + } + ], + "default_index_pattern": "metricbeat-*", + "default_timefield": "@timestamp", + "id": "61ca57f0-469d-11e7-af02-69e470af7417", + "index_pattern": "", + "interval": "", + "isModelInvalid": false, + "legend_position": "bottom", + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#68BC00", + "fill": 0.5, + "formatter": "number", + "id": "61ca57f1-469d-11e7-af02-69e470af7417", + "label": "", + "line_width": 1, + "metrics": [ + { + "field": "prometheus.metrics.ibmmq_qmgr_durable_subscription_alter_total", + "id": "61ca57f2-469d-11e7-af02-69e470af7417", + "type": "max" + }, + { + "field": "61ca57f2-469d-11e7-af02-69e470af7417", + "id": "3b91ade0-36cd-11ea-b7bc-e7f346d59677", + "type": "derivative", + "unit": "" + } + ], + "point_size": 1, + "separate_axis": 0, + "split_mode": "terms", + "stacked": "none", + "terms_field": "prometheus.labels.qmgr", + "type": "timeseries" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "", + "type": "timeseries" + }, + "title": "Alter durable subscription [Metricbeat IBM MQ]", + "type": "metrics" + } + }, + "id": "3901ed30-36cb-11ea-9f7a-097fe7ab3ddd", + "migrationVersion": { + "visualization": "7.3.1" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-14T12:56:29.734Z", + "version": "WzIyLDJd" + } + ], + "version": "7.4.0" +} diff --git a/x-pack/metricbeat/module/ibmmq/docker-compose.yml b/x-pack/metricbeat/module/ibmmq/docker-compose.yml new file mode 100644 index 00000000000..0a0230dc629 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/docker-compose.yml @@ -0,0 +1,11 @@ +version: '2.3' + +services: + ibmmq: + image: docker.elastic.co/integrations-ci/beats-ibmmq:${IBMMQ_VERSION:-9.1.4.0-r1-amd64}-1 + build: + context: ./_meta + args: + IBMMQ_VERSION: ${IBMMQ_VERSION:-9.1.4.0-r1-amd64} + ports: + - 9157 diff --git a/x-pack/metricbeat/module/ibmmq/fields.go b/x-pack/metricbeat/module/ibmmq/fields.go new file mode 100644 index 00000000000..734332594b9 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/fields.go @@ -0,0 +1,23 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. + +package ibmmq + +import ( + "github.com/elastic/beats/libbeat/asset" +) + +func init() { + if err := asset.SetFields("metricbeat", "ibmmq", asset.ModuleFieldsPri, AssetIbmmq); err != nil { + panic(err) + } +} + +// AssetIbmmq returns asset data. +// This is the base64 encoded gzipped contents of module/ibmmq. +func AssetIbmmq() string { + return "eJxUzjEOgkAQheF+T/GHhooLTGFhZ0FhbSxARty4C+vuUHB7o5ioU07el/ca7roKvo/x4cC8BRXqw76lPdYOsgbtigq9Wudg0HLJPpmfJ2HnALYwcR6WoA6KmvlpLMKpupml6uzg6jUMRd6gYeqifltfZ2tSYczzkj6fX7Gp/y3PAAAA//8gwjWY" +} diff --git a/x-pack/metricbeat/module/ibmmq/module.yml b/x-pack/metricbeat/module/ibmmq/module.yml new file mode 100644 index 00000000000..96c8a4d6233 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/module.yml @@ -0,0 +1,3 @@ +name: ibmmq +metricsets: +- qmgr diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/data.json b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/data.json new file mode 100644 index 00000000000..58cdc88f30c --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/data.json @@ -0,0 +1,114 @@ +{ + "@timestamp": "2020-01-13T12:58:04.412Z", + "@metadata": { + "beat": "metricbeat", + "type": "_doc", + "version": "8.0.0" + }, + "service": { + "address": "localhost:9157", + "type": "ibmmq" + }, + "agent": { + "version": "8.0.0", + "type": "metricbeat", + "ephemeral_id": "752a92a2-5881-49b6-a6c8-a2848dd2a074", + "hostname": "MacBook-Elastic.local", + "id": "d662b58a-49c9-4241-aaaf-c5489341138c" + }, + "ecs": { + "version": "1.4.0" + }, + "host": { + "hostname": "MacBook-Elastic.local", + "architecture": "x86_64", + "os": { + "platform": "darwin", + "version": "10.14.6", + "family": "darwin", + "name": "Mac OS X", + "kernel": "18.7.0", + "build": "18G95" + }, + "name": "MacBook-Elastic.local", + "id": "24F065F8-4274-521D-8DD5-5D27557E15B4" + }, + "prometheus": { + "labels": { + "qmgr": "QM1", + "instance": "localhost:9157", + "job": "ibmmq" + }, + "metrics": { + "ibmmq_qmgr_mqctl_total": 0, + "ibmmq_qmgr_mqcb_total": 0, + "ibmmq_qmgr_durable_subscription_delete_total": 0, + "ibmmq_qmgr_non_persistent_message_browse_bytes_total": 0, + "ibmmq_qmgr_failed_mqset_total": 0, + "ibmmq_qmgr_failed_subscription_delete_total": 0, + "ibmmq_qmgr_destructive_get_total": 1772, + "ibmmq_qmgr_mqput_mqput1_bytes_total": 659084, + "ibmmq_qmgr_failed_mqsubrq_total": 0, + "ibmmq_qmgr_topic_put_bytes_total": 473772, + "ibmmq_qmgr_topic_mqput_mqput1_total": 1761, + "ibmmq_qmgr_persistent_topic_mqput_mqput1_total": 0, + "ibmmq_qmgr_failed_mqput_total": 0, + "ibmmq_qmgr_non_durable_subscription_delete_total": 0, + "ibmmq_qmgr_non_persistent_message_browse_total": 0, + "ibmmq_qmgr_expired_message_total": 0, + "ibmmq_qmgr_non_durable_subscription_create_total": 0, + "ibmmq_qmgr_non_persistent_message_destructive_get_total": 1772, + "ibmmq_qmgr_failed_mqcb_total": 0, + "ibmmq_qmgr_commit_total": 0, + "ibmmq_qmgr_mqset_total": 0, + "ibmmq_qmgr_mqsubrq_total": 0, + "ibmmq_qmgr_mqopen_total": 0, + "ibmmq_qmgr_durable_subscription_resume_total": 0, + "ibmmq_qmgr_non_persistent_message_mqput1_total": 0, + "ibmmq_qmgr_failed_browse_total": 0, + "ibmmq_qmgr_non_persistent_topic_mqput_mqput1_total": 1761, + "ibmmq_qmgr_mqconn_mqconnx_total": 0, + "ibmmq_qmgr_mqstat_total": 0, + "ibmmq_qmgr_log_logical_written_bytes_total": 0, + "ibmmq_qmgr_log_physical_written_bytes_total": 0, + "ibmmq_qmgr_failed_mqput1_total": 0, + "ibmmq_qmgr_published_to_subscribers_bytes_total": 473772, + "ibmmq_qmgr_failed_mqclose_total": 0, + "ibmmq_qmgr_failed_mqget_total": 1481, + "ibmmq_qmgr_rollback_total": 0, + "ibmmq_qmgr_failed_subscription_create_alter_resume_total": 0, + "ibmmq_qmgr_failed_topic_mqput_mqput1_total": 0, + "ibmmq_qmgr_mqdisc_total": 0, + "ibmmq_qmgr_failed_mqinq_total": 0, + "ibmmq_qmgr_non_persistent_message_mqput_total": 1761, + "ibmmq_qmgr_durable_subscription_create_total": 0, + "ibmmq_qmgr_failed_mqopen_total": 0, + "ibmmq_qmgr_failed_mqconn_mqconnx_total": 0, + "ibmmq_qmgr_persistent_message_put_bytes_total": 0, + "ibmmq_qmgr_non_persistent_message_get_bytes_total": 663212, + "ibmmq_qmgr_durable_subscription_alter_total": 0, + "ibmmq_qmgr_persistent_message_browse_total": 0, + "ibmmq_qmgr_mqput_mqput1_total": 1761, + "ibmmq_qmgr_published_to_subscribers_message_total": 1761, + "ibmmq_qmgr_destructive_get_bytes_total": 663212, + "ibmmq_qmgr_mqclose_total": 2, + "ibmmq_qmgr_persistent_message_browse_bytes_total": 0, + "ibmmq_qmgr_persistent_message_get_bytes_total": 0, + "ibmmq_qmgr_persistent_message_mqput1_total": 0, + "ibmmq_qmgr_purged_queue_total": 0, + "ibmmq_qmgr_persistent_message_destructive_get_total": 0, + "ibmmq_qmgr_persistent_message_mqput_total": 0, + "ibmmq_qmgr_mqinq_total": 634, + "ibmmq_qmgr_non_persistent_message_put_bytes_total": 659084 + } + }, + "event": { + "dataset": "ibmmq.qmgr", + "module": "ibmmq", + "duration": 4421890 + }, + "metricset": { + "name": "qmgr", + "period": 10000 + } +} diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/docs.asciidoc b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/docs.asciidoc new file mode 100644 index 00000000000..c78215fc43b --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/docs.asciidoc @@ -0,0 +1,3 @@ +This is the `qmgr` metricset of the IBM MQ module. It collects status information for the Queue Manager. +The manager is a system program that is responsible for maintaining the queues and ensuring that the messages +in the queues reach their destination. diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/fields.yml b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/fields.yml new file mode 100644 index 00000000000..8033a27f5ac --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/fields.yml @@ -0,0 +1 @@ +- release: beta diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/config.yml b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/config.yml new file mode 100644 index 00000000000..0301667e940 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/config.yml @@ -0,0 +1,4 @@ +type: http +url: "/metrics" +suffix: plain +remove_fields_from_comparison: ["prometheus.labels.instance"] diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain new file mode 100644 index 00000000000..ca8bc1c9f0b --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain @@ -0,0 +1,180 @@ +# HELP ibmmq_qmgr_commit_total Commit count +# TYPE ibmmq_qmgr_commit_total counter +ibmmq_qmgr_commit_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_destructive_get_bytes_total Interval total destructive get - byte count +# TYPE ibmmq_qmgr_destructive_get_bytes_total counter +ibmmq_qmgr_destructive_get_bytes_total{qmgr="QM1"} 7812 +# HELP ibmmq_qmgr_destructive_get_total Interval total destructive get- count +# TYPE ibmmq_qmgr_destructive_get_total counter +ibmmq_qmgr_destructive_get_total{qmgr="QM1"} 23 +# HELP ibmmq_qmgr_durable_subscription_alter_total Alter durable subscription count +# TYPE ibmmq_qmgr_durable_subscription_alter_total counter +ibmmq_qmgr_durable_subscription_alter_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_durable_subscription_create_total Create durable subscription count +# TYPE ibmmq_qmgr_durable_subscription_create_total counter +ibmmq_qmgr_durable_subscription_create_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_durable_subscription_delete_total Delete durable subscription count +# TYPE ibmmq_qmgr_durable_subscription_delete_total counter +ibmmq_qmgr_durable_subscription_delete_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_durable_subscription_resume_total Resume durable subscription count +# TYPE ibmmq_qmgr_durable_subscription_resume_total counter +ibmmq_qmgr_durable_subscription_resume_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_expired_message_total Expired message count +# TYPE ibmmq_qmgr_expired_message_total counter +ibmmq_qmgr_expired_message_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_browse_total Failed browse count +# TYPE ibmmq_qmgr_failed_browse_total counter +ibmmq_qmgr_failed_browse_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqcb_total Failed MQCB count +# TYPE ibmmq_qmgr_failed_mqcb_total counter +ibmmq_qmgr_failed_mqcb_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqclose_total Failed MQCLOSE count +# TYPE ibmmq_qmgr_failed_mqclose_total counter +ibmmq_qmgr_failed_mqclose_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqconn_mqconnx_total Failed MQCONN/MQCONNX count +# TYPE ibmmq_qmgr_failed_mqconn_mqconnx_total counter +ibmmq_qmgr_failed_mqconn_mqconnx_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqget_total Failed MQGET - count +# TYPE ibmmq_qmgr_failed_mqget_total counter +ibmmq_qmgr_failed_mqget_total{qmgr="QM1"} 16 +# HELP ibmmq_qmgr_failed_mqinq_total Failed MQINQ count +# TYPE ibmmq_qmgr_failed_mqinq_total counter +ibmmq_qmgr_failed_mqinq_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqopen_total Failed MQOPEN count +# TYPE ibmmq_qmgr_failed_mqopen_total counter +ibmmq_qmgr_failed_mqopen_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqput1_total Failed MQPUT1 count +# TYPE ibmmq_qmgr_failed_mqput1_total counter +ibmmq_qmgr_failed_mqput1_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqput_total Failed MQPUT count +# TYPE ibmmq_qmgr_failed_mqput_total counter +ibmmq_qmgr_failed_mqput_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqset_total Failed MQSET count +# TYPE ibmmq_qmgr_failed_mqset_total counter +ibmmq_qmgr_failed_mqset_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_mqsubrq_total Failed MQSUBRQ count +# TYPE ibmmq_qmgr_failed_mqsubrq_total counter +ibmmq_qmgr_failed_mqsubrq_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_subscription_create_alter_resume_total Failed create/alter/resume subscription count +# TYPE ibmmq_qmgr_failed_subscription_create_alter_resume_total counter +ibmmq_qmgr_failed_subscription_create_alter_resume_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_subscription_delete_total Subscription delete failure count +# TYPE ibmmq_qmgr_failed_subscription_delete_total counter +ibmmq_qmgr_failed_subscription_delete_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_failed_topic_mqput_mqput1_total Failed topic MQPUT/MQPUT1 count +# TYPE ibmmq_qmgr_failed_topic_mqput_mqput1_total counter +ibmmq_qmgr_failed_topic_mqput_mqput1_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_log_logical_written_bytes_total Log - logical bytes written +# TYPE ibmmq_qmgr_log_logical_written_bytes_total counter +ibmmq_qmgr_log_logical_written_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_log_physical_written_bytes_total Log - physical bytes written +# TYPE ibmmq_qmgr_log_physical_written_bytes_total counter +ibmmq_qmgr_log_physical_written_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqcb_total MQCB count +# TYPE ibmmq_qmgr_mqcb_total counter +ibmmq_qmgr_mqcb_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqclose_total MQCLOSE count +# TYPE ibmmq_qmgr_mqclose_total counter +ibmmq_qmgr_mqclose_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqconn_mqconnx_total MQCONN/MQCONNX count +# TYPE ibmmq_qmgr_mqconn_mqconnx_total counter +ibmmq_qmgr_mqconn_mqconnx_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqctl_total MQCTL count +# TYPE ibmmq_qmgr_mqctl_total counter +ibmmq_qmgr_mqctl_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqdisc_total MQDISC count +# TYPE ibmmq_qmgr_mqdisc_total counter +ibmmq_qmgr_mqdisc_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqinq_total MQINQ count +# TYPE ibmmq_qmgr_mqinq_total counter +ibmmq_qmgr_mqinq_total{qmgr="QM1"} 4 +# HELP ibmmq_qmgr_mqopen_total MQOPEN count +# TYPE ibmmq_qmgr_mqopen_total counter +ibmmq_qmgr_mqopen_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqput_mqput1_bytes_total Interval total MQPUT/MQPUT1 byte count +# TYPE ibmmq_qmgr_mqput_mqput1_bytes_total counter +ibmmq_qmgr_mqput_mqput1_bytes_total{qmgr="QM1"} 1860 +# HELP ibmmq_qmgr_mqput_mqput1_total Interval total MQPUT/MQPUT1 count +# TYPE ibmmq_qmgr_mqput_mqput1_total counter +ibmmq_qmgr_mqput_mqput1_total{qmgr="QM1"} 6 +# HELP ibmmq_qmgr_mqset_total MQSET count +# TYPE ibmmq_qmgr_mqset_total counter +ibmmq_qmgr_mqset_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqstat_total MQSTAT count +# TYPE ibmmq_qmgr_mqstat_total counter +ibmmq_qmgr_mqstat_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_mqsubrq_total MQSUBRQ count +# TYPE ibmmq_qmgr_mqsubrq_total counter +ibmmq_qmgr_mqsubrq_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_durable_subscription_create_total Create non-durable subscription count +# TYPE ibmmq_qmgr_non_durable_subscription_create_total counter +ibmmq_qmgr_non_durable_subscription_create_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_durable_subscription_delete_total Delete non-durable subscription count +# TYPE ibmmq_qmgr_non_durable_subscription_delete_total counter +ibmmq_qmgr_non_durable_subscription_delete_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_persistent_message_browse_bytes_total Non-persistent message browse - byte count +# TYPE ibmmq_qmgr_non_persistent_message_browse_bytes_total counter +ibmmq_qmgr_non_persistent_message_browse_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_persistent_message_browse_total Non-persistent message browse - count +# TYPE ibmmq_qmgr_non_persistent_message_browse_total counter +ibmmq_qmgr_non_persistent_message_browse_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_persistent_message_destructive_get_total Non-persistent message destructive get - count +# TYPE ibmmq_qmgr_non_persistent_message_destructive_get_total counter +ibmmq_qmgr_non_persistent_message_destructive_get_total{qmgr="QM1"} 23 +# HELP ibmmq_qmgr_non_persistent_message_get_bytes_total Got non-persistent messages - byte count +# TYPE ibmmq_qmgr_non_persistent_message_get_bytes_total counter +ibmmq_qmgr_non_persistent_message_get_bytes_total{qmgr="QM1"} 7812 +# HELP ibmmq_qmgr_non_persistent_message_mqput1_total Non-persistent message MQPUT1 count +# TYPE ibmmq_qmgr_non_persistent_message_mqput1_total counter +ibmmq_qmgr_non_persistent_message_mqput1_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_non_persistent_message_mqput_total Non-persistent message MQPUT count +# TYPE ibmmq_qmgr_non_persistent_message_mqput_total counter +ibmmq_qmgr_non_persistent_message_mqput_total{qmgr="QM1"} 6 +# HELP ibmmq_qmgr_non_persistent_message_put_bytes_total Put non-persistent messages - byte count +# TYPE ibmmq_qmgr_non_persistent_message_put_bytes_total counter +ibmmq_qmgr_non_persistent_message_put_bytes_total{qmgr="QM1"} 1860 +# HELP ibmmq_qmgr_non_persistent_topic_mqput_mqput1_total Non-persistent - topic MQPUT/MQPUT1 count +# TYPE ibmmq_qmgr_non_persistent_topic_mqput_mqput1_total counter +ibmmq_qmgr_non_persistent_topic_mqput_mqput1_total{qmgr="QM1"} 6 +# HELP ibmmq_qmgr_persistent_message_browse_bytes_total Persistent message browse - byte count +# TYPE ibmmq_qmgr_persistent_message_browse_bytes_total counter +ibmmq_qmgr_persistent_message_browse_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_browse_total Persistent message browse - count +# TYPE ibmmq_qmgr_persistent_message_browse_total counter +ibmmq_qmgr_persistent_message_browse_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_destructive_get_total Persistent message destructive get - count +# TYPE ibmmq_qmgr_persistent_message_destructive_get_total counter +ibmmq_qmgr_persistent_message_destructive_get_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_get_bytes_total Got persistent messages - byte count +# TYPE ibmmq_qmgr_persistent_message_get_bytes_total counter +ibmmq_qmgr_persistent_message_get_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_mqput1_total Persistent message MQPUT1 count +# TYPE ibmmq_qmgr_persistent_message_mqput1_total counter +ibmmq_qmgr_persistent_message_mqput1_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_mqput_total Persistent message MQPUT count +# TYPE ibmmq_qmgr_persistent_message_mqput_total counter +ibmmq_qmgr_persistent_message_mqput_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_message_put_bytes_total Put persistent messages - byte count +# TYPE ibmmq_qmgr_persistent_message_put_bytes_total counter +ibmmq_qmgr_persistent_message_put_bytes_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_persistent_topic_mqput_mqput1_total Persistent - topic MQPUT/MQPUT1 count +# TYPE ibmmq_qmgr_persistent_topic_mqput_mqput1_total counter +ibmmq_qmgr_persistent_topic_mqput_mqput1_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_published_to_subscribers_bytes_total Published to subscribers - byte count +# TYPE ibmmq_qmgr_published_to_subscribers_bytes_total counter +ibmmq_qmgr_published_to_subscribers_bytes_total{qmgr="QM1"} 1224 +# HELP ibmmq_qmgr_published_to_subscribers_message_total Published to subscribers - message count +# TYPE ibmmq_qmgr_published_to_subscribers_message_total counter +ibmmq_qmgr_published_to_subscribers_message_total{qmgr="QM1"} 6 +# HELP ibmmq_qmgr_purged_queue_total Purged queue count +# TYPE ibmmq_qmgr_purged_queue_total counter +ibmmq_qmgr_purged_queue_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_rollback_total Rollback count +# TYPE ibmmq_qmgr_rollback_total counter +ibmmq_qmgr_rollback_total{qmgr="QM1"} 0 +# HELP ibmmq_qmgr_topic_mqput_mqput1_total Topic MQPUT/MQPUT1 interval total +# TYPE ibmmq_qmgr_topic_mqput_mqput1_total counter +ibmmq_qmgr_topic_mqput_mqput1_total{qmgr="QM1"} 6 +# HELP ibmmq_qmgr_topic_put_bytes_total Interval total topic bytes put +# TYPE ibmmq_qmgr_topic_put_bytes_total counter +ibmmq_qmgr_topic_put_bytes_total{qmgr="QM1"} 1224 diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain-expected.json b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain-expected.json new file mode 100644 index 00000000000..ade0022e09e --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/_meta/testdata/ibmmq-status.9.1.4.0-r1-amd64.plain-expected.json @@ -0,0 +1,86 @@ +[ + { + "event": { + "dataset": "ibmmq.qmgr", + "duration": 115000, + "module": "ibmmq" + }, + "metricset": { + "name": "qmgr", + "period": 10000 + }, + "prometheus": { + "labels": { + "instance": "127.0.0.1:55911", + "job": "ibmmq", + "qmgr": "QM1" + }, + "metrics": { + "ibmmq_qmgr_commit_total": 0, + "ibmmq_qmgr_destructive_get_bytes_total": 7812, + "ibmmq_qmgr_destructive_get_total": 23, + "ibmmq_qmgr_durable_subscription_alter_total": 0, + "ibmmq_qmgr_durable_subscription_create_total": 0, + "ibmmq_qmgr_durable_subscription_delete_total": 0, + "ibmmq_qmgr_durable_subscription_resume_total": 0, + "ibmmq_qmgr_expired_message_total": 0, + "ibmmq_qmgr_failed_browse_total": 0, + "ibmmq_qmgr_failed_mqcb_total": 0, + "ibmmq_qmgr_failed_mqclose_total": 0, + "ibmmq_qmgr_failed_mqconn_mqconnx_total": 0, + "ibmmq_qmgr_failed_mqget_total": 16, + "ibmmq_qmgr_failed_mqinq_total": 0, + "ibmmq_qmgr_failed_mqopen_total": 0, + "ibmmq_qmgr_failed_mqput1_total": 0, + "ibmmq_qmgr_failed_mqput_total": 0, + "ibmmq_qmgr_failed_mqset_total": 0, + "ibmmq_qmgr_failed_mqsubrq_total": 0, + "ibmmq_qmgr_failed_subscription_create_alter_resume_total": 0, + "ibmmq_qmgr_failed_subscription_delete_total": 0, + "ibmmq_qmgr_failed_topic_mqput_mqput1_total": 0, + "ibmmq_qmgr_log_logical_written_bytes_total": 0, + "ibmmq_qmgr_log_physical_written_bytes_total": 0, + "ibmmq_qmgr_mqcb_total": 0, + "ibmmq_qmgr_mqclose_total": 0, + "ibmmq_qmgr_mqconn_mqconnx_total": 0, + "ibmmq_qmgr_mqctl_total": 0, + "ibmmq_qmgr_mqdisc_total": 0, + "ibmmq_qmgr_mqinq_total": 4, + "ibmmq_qmgr_mqopen_total": 0, + "ibmmq_qmgr_mqput_mqput1_bytes_total": 1860, + "ibmmq_qmgr_mqput_mqput1_total": 6, + "ibmmq_qmgr_mqset_total": 0, + "ibmmq_qmgr_mqstat_total": 0, + "ibmmq_qmgr_mqsubrq_total": 0, + "ibmmq_qmgr_non_durable_subscription_create_total": 0, + "ibmmq_qmgr_non_durable_subscription_delete_total": 0, + "ibmmq_qmgr_non_persistent_message_browse_bytes_total": 0, + "ibmmq_qmgr_non_persistent_message_browse_total": 0, + "ibmmq_qmgr_non_persistent_message_destructive_get_total": 23, + "ibmmq_qmgr_non_persistent_message_get_bytes_total": 7812, + "ibmmq_qmgr_non_persistent_message_mqput1_total": 0, + "ibmmq_qmgr_non_persistent_message_mqput_total": 6, + "ibmmq_qmgr_non_persistent_message_put_bytes_total": 1860, + "ibmmq_qmgr_non_persistent_topic_mqput_mqput1_total": 6, + "ibmmq_qmgr_persistent_message_browse_bytes_total": 0, + "ibmmq_qmgr_persistent_message_browse_total": 0, + "ibmmq_qmgr_persistent_message_destructive_get_total": 0, + "ibmmq_qmgr_persistent_message_get_bytes_total": 0, + "ibmmq_qmgr_persistent_message_mqput1_total": 0, + "ibmmq_qmgr_persistent_message_mqput_total": 0, + "ibmmq_qmgr_persistent_message_put_bytes_total": 0, + "ibmmq_qmgr_persistent_topic_mqput_mqput1_total": 0, + "ibmmq_qmgr_published_to_subscribers_bytes_total": 1224, + "ibmmq_qmgr_published_to_subscribers_message_total": 6, + "ibmmq_qmgr_purged_queue_total": 0, + "ibmmq_qmgr_rollback_total": 0, + "ibmmq_qmgr_topic_mqput_mqput1_total": 6, + "ibmmq_qmgr_topic_put_bytes_total": 1224 + } + }, + "service": { + "address": "127.0.0.1:55555", + "type": "ibmmq" + } + } +] diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/manifest.yml b/x-pack/metricbeat/module/ibmmq/qmgr/manifest.yml new file mode 100644 index 00000000000..ec802f1ca1b --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/manifest.yml @@ -0,0 +1,6 @@ +default: true +input: + module: prometheus + metricset: collector + defaults: + metrics_path: /metrics diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_integration_test.go b/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_integration_test.go new file mode 100644 index 00000000000..4261a9fbf89 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_integration_test.go @@ -0,0 +1,48 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build integration + +package stats + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/libbeat/tests/compose" + "github.com/elastic/beats/metricbeat/mb" + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + + // Register input module and metricset + _ "github.com/elastic/beats/metricbeat/module/prometheus" + _ "github.com/elastic/beats/metricbeat/module/prometheus/collector" +) + +func init() { + // To be moved to some kind of helper + os.Setenv("BEAT_STRICT_PERMS", "false") + mb.Registry.SetSecondarySource(mb.NewLightModulesSource("../../../module")) +} + +func TestFetch(t *testing.T) { + service := compose.EnsureUp(t, "ibmmq") + + f := mbtest.NewFetcher(t, getConfig(service.Host())) + events, errs := f.FetchEvents() + if len(errs) > 0 { + t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs) + } + assert.NotEmpty(t, events) + t.Logf("%s/%s event: %+v", f.Module().Name(), f.Name(), events[0]) +} + +func getConfig(host string) map[string]interface{} { + return map[string]interface{}{ + "module": "ibmmq", + "metricsets": []string{"qmgr"}, + "hosts": []string{host}, + } +} diff --git a/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_test.go b/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_test.go new file mode 100644 index 00000000000..458bd7e5dc0 --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/qmgr/qmgr_test.go @@ -0,0 +1,32 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build !integration + +package qmgr + +import ( + "os" + "testing" + + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/metricbeat/mb" + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + + // Register input module and metricset + _ "github.com/elastic/beats/metricbeat/module/prometheus" + _ "github.com/elastic/beats/metricbeat/module/prometheus/collector" +) + +func init() { + // To be moved to some kind of helper + os.Setenv("BEAT_STRICT_PERMS", "false") + mb.Registry.SetSecondarySource(mb.NewLightModulesSource("../../../module")) +} + +func TestEventMapping(t *testing.T) { + logp.TestingSetup() + + mbtest.TestDataFiles(t, "ibmmq", "qmgr") +} diff --git a/x-pack/metricbeat/module/ibmmq/test_ibmmq.py b/x-pack/metricbeat/module/ibmmq/test_ibmmq.py new file mode 100644 index 00000000000..c882860d6bd --- /dev/null +++ b/x-pack/metricbeat/module/ibmmq/test_ibmmq.py @@ -0,0 +1,35 @@ +import os +import sys +import unittest + +sys.path.append(os.path.join(os.path.dirname(__file__), '../../tests/system')) +from xpack_metricbeat import XPackTest, metricbeat + + +class Test(XPackTest): + + COMPOSE_SERVICES = ['ibmmq'] + + @unittest.skipUnless(metricbeat.INTEGRATION_TESTS, "integration test") + def test_qmgr(self): + """ + ibmmq qmgr test + """ + self.render_config_template(modules=[{ + "name": "ibmmq", + "metricsets": ["qmgr"], + "hosts": self.get_hosts(), + "period": "5s", + }]) + proc = self.start_beat(home=self.beat_path) + self.wait_until(lambda: self.output_lines() > 0) + proc.check_kill_and_wait() + self.assert_no_logged_warnings() + + output = self.read_output_json() + self.assertGreater(len(output), 0) + + for evt in output: + self.assert_fields_are_documented(evt) + self.assertIn("prometheus", evt.keys(), evt) + self.assertIn("metrics", evt["prometheus"].keys(), evt) diff --git a/x-pack/metricbeat/modules.d/ibmmq.yml.disabled b/x-pack/metricbeat/modules.d/ibmmq.yml.disabled new file mode 100644 index 00000000000..93d77367a97 --- /dev/null +++ b/x-pack/metricbeat/modules.d/ibmmq.yml.disabled @@ -0,0 +1,31 @@ +# Module: ibmmq +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-ibmmq.html + +- module: ibmmq + metricsets: ['qmgr'] + period: 10s + hosts: ['localhost:9157'] + + # This module uses the Prometheus collector metricset, all + # the options for this metricset are also available here. + metrics_path: /metrics + + # The custom processor is responsible for filtering Prometheus metrics + # not stricly related to the IBM MQ domain, e.g. system load, process, + # metrics HTTP server. + processors: + - script: + lang: javascript + source: > + function process(event) { + var metrics = event.Get("prometheus.metrics"); + Object.keys(metrics).forEach(function(key) { + if (!(key.match(/^ibmmq_.*$/))) { + event.Delete("prometheus.metrics." + key); + } + }); + metrics = event.Get("prometheus.metrics"); + if (Object.keys(metrics).length == 0) { + event.Cancel(); + } + } From 32525f6a207239245932ee18862b3122089a0c19 Mon Sep 17 00:00:00 2001 From: Michael Madden Date: Thu, 16 Jan 2020 15:03:19 -0600 Subject: [PATCH 12/37] Cleanup changelogs for master (#15617) * Cleanup changelogs for master * Remove extra header in CHANGELOG.asciidoc --- CHANGELOG-developer.asciidoc | 73 +++ CHANGELOG.asciidoc | 979 +++++++++++++++++++++++++++++++++- CHANGELOG.next.asciidoc | 553 +------------------ libbeat/docs/release.asciidoc | 12 + 4 files changed, 1064 insertions(+), 553 deletions(-) diff --git a/CHANGELOG-developer.asciidoc b/CHANGELOG-developer.asciidoc index 607a20c0146..15efed8ed5d 100644 --- a/CHANGELOG-developer.asciidoc +++ b/CHANGELOG-developer.asciidoc @@ -12,6 +12,79 @@ other Beats should be migrated. Note: This changelog was only started after the 6.3 release. +=== Beats version 7.5.1 +https://github.com/elastic/beats/compare/v7.5.0..v7.5.1[Check the HEAD diff] + +=== Beats version 7.5.0 +https://github.com/elastic/beats/compare/v7.4.1..v7.5.0[Check the HEAD diff] + +==== Breaking changes + +- Build docker and kubernetes features only on supported platforms. {pull}13509[13509] +- Need to register new processors to be used in the JS processor in their `init` functions. {pull}13509[13509] + +==== Added + +- Compare event by event in `testadata` framework to avoid sorting problems {pull}13747[13747] + +=== Beats version 7.4.1 +https://github.com/elastic/beats/compare/v7.4.0..v7.4.1[Check the HEAD diff] + +=== Beats version 7.4.0 +https://github.com/elastic/beats/compare/v7.3.1..v7.4.0[Check the HEAD diff] + +==== Breaking changes + +- For "metricbeat style" generated custom beats, the mage target `GoTestIntegration` has changed to `GoIntegTest` and `GoTestUnit` has changed to `GoUnitTest`. {pull}13341[13341] + +==== Added + +- Add ClientFactory to TCP input source to add SplitFunc/NetworkFuncs per client. {pull}8543[8543] +- Introduce beat.OutputChooses publisher mode. {pull}12996[12996] +- Ensure that beat.Processor, beat.ProcessorList, and processors.ProcessorList are compatible and can be composed more easily. {pull}12996[12996] +- Add support to close beat.Client via beat.CloseRef (a subset of context.Context). {pull}13031[13031] +- Add checks for types and formats used in fields definitions in `fields.yml` files. {pull}13188[13188] +- Makefile included in generator copies files from beats repository using `git archive` instead of cp. {pull}13193[13193] + +=== Beats version 7.3.2 +https://github.com/elastic/beats/compare/v7.3.1..v7.3.2[Check the HEAD diff] + +=== Beats version 7.3.1 +https://github.com/elastic/beats/compare/v7.3.0..v7.3.1[Check the HEAD diff] + +=== Beats version 7.3.0 +https://github.com/elastic/beats/compare/v7.2.1..v7.3.0[Check the HEAD diff] + +==== Added + +- Add new option `IgnoreAllErrors` to `libbeat.common.schema` for skipping fields that failed while converting. {pull}12089[12089] + +=== Beats version 7.2.1 +https://github.com/elastic/beats/compare/v7.2.0..v7.2.1[Check the HEAD diff] + +=== Beats version 7.2.0 +https://github.com/elastic/beats/compare/v7.1.1..v7.2.0[Check the HEAD diff] + +==== Breaking changes + +- Move Fields from package libbeat/common to libbeat/mapping. {pull}11198[11198] + +==== Added + +- Metricset generator generates beta modules by default now. {pull}10657[10657] +- The `beat.Event` accessor methods now support `@metadata` keys. {pull}10761[10761] +- Assertion for documented fields in tests fails if any of the fields in the tested event is documented as an alias. {pull}10921[10921] +- Support for Logger in the Metricset base instance. {pull}11106[11106] +- Filebeat modules can now use ingest pipelines in YAML format. {pull}11209[11209] +- Prometheus helper for metricbeat contains now `Namespace` field for `prometheus.MetricsMappings` {pull}11424[11424] +- Update Jinja2 version to 2.10.1. {pull}11817[11817] +- Reduce idxmgmt.Supporter interface and rework export commands to reuse logic. {pull}11777[11777],{pull}12065[12065],{pull}12067[12067],{pull}12160[12160] +- Update urllib3 version to 1.24.2 {pull}11930[11930] +- Add libbeat/common/cleanup package. {pull}12134[12134] +- Only Load minimal template if no fields are provided. {pull}12103[12103] +- Add new option `IgnoreAllErrors` to `libbeat.common.schema` for skipping fields that failed while converting. {pull}12089[12089] +- Deprecate setup cmds for `template` and `ilm-policy`. Add new setup cmd for `index-management`. {pull}12132[12132] + === Beats version 7.1.1 https://github.com/elastic/beats/compare/v7.1.0..v7.1.1[Check the HEAD diff] diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 6035ec84d14..5adbffbdee2 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -3,6 +3,890 @@ :issue: https://github.com/elastic/beats/issues/ :pull: https://github.com/elastic/beats/pull/ +[[release-notes-7.5.1]] +=== Beats version 7.5.1 +https://github.com/elastic/beats/compare/v7.5.0...v7.5.1[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fix `proxy_url` option in Elasticsearch output. {pull}14950[14950] +- Fix bug with potential concurrent reads and writes from event.Meta map by Kafka output. {issue}14542[14542] {pull}14568[14568] + +*Filebeat* + +- Change iis url path grok pattern from URIPATH to NOTSPACE. {issue}12710[12710] {pull}13225[13225] {issue}7951[7951] {pull}13378[13378] {pull}14754[14754] +- Fix azure filesets test files. {issue}14185[14185] {pull}14235[14235] +- Update Logstash module's Grok patterns to support Logstash 7.4 logs. {pull}14743[14743] + +*Metricbeat* + +- Fix perfmon expanding counter path/adding counter to query when OS language is not english. {issue}14684[14684] {pull}14800[14800] +- Add extra check on `ignore_non_existent_counters` flag if the PdhExpandWildCardPathW returns no errors but does not expand the counter path successfully in windows/perfmon metricset. {pull}14797[14797] +- Fix rds metricset from reporting same values for different instances. {pull}14702[14702] +- Closing handler after verifying the registry key in diskio metricset. {issue}14683[14683] {pull}14759[14759] +- Fix docker network stats when multiple interfaces are configured. {issue}14586[14586] {pull}14825[14825] +- Fix ListMetrics pagination in aws module. {issue}14926[14926] {pull}14942[14942] +- Fix CPU count in docker/cpu in cases where no `online_cpus` are reported {pull}15070[15070] + +[[release-notes-7.5.0]] +=== Beats version 7.5.0 +https://github.com/elastic/beats/compare/v7.4.1...v7.5.0[View commits] + +==== Breaking changes + +*Affecting all Beats* + +- By default, all Beats-created files and folders will have a umask of 0027 (on POSIX systems). {pull}14119[14119] + +*Filebeat* + +*Heartbeat* + +- JSON/Regex checks against HTTP bodies will only consider the first 100MiB of the HTTP body to prevent excessive memory usage. {pull}14223[14223] + +*Metricbeat* + +==== Bugfixes + +*Affecting all Beats* + +- Disable `add_kubernetes_metadata` if no matchers found. {pull}13709[13709] +- Better wording for xpack beats when the _xpack endpoint is not reachable. {pull}13771[13771] +- Kubernetes watcher at `add_kubernetes_metadata` fails with StatefulSets {pull}13905[13905] +- Fix panics that could result from invalid TLS certificates. This can affect Beats that connect over TLS or Beats that accept connections over TLS and validate client certificates. {pull}14146[14146] +- Fix memory leak in kubernetes autodiscover provider and add_kubernetes_metadata processor happening when pods are terminated without sending a delete event. {pull}14259[14259] +- Fix kubernetes `metaGenerator.ResourceMetadata` when parent reference controller is nil {issue}14320[14320] {pull}14329[14329] + +*Auditbeat* + +- Socket dataset: Fix start errors when IPv6 is disabled on the kernel. {issue}13953[13953] {pull}13966[13966] + +*Filebeat* + +- Fix a denial of service flaw when parsing malformed DSA public keys in Go. +If {filebeat} is configured to accept incoming TLS connections with client +authentication enabled, a remote attacker could cause the Beat to stop +processing events. (CVE-2019-17596) See https://www.elastic.co/community/security/ +- Fix timezone parsing of rabbitmq module ingest pipelines. {pull}13879[13879] +- Fix conditions and error checking of date processors in ingest pipelines that use `event.timezone` to parse dates. {pull}13883[13883] +- Fix timezone parsing of Cisco module ingest pipelines. {pull}13893[13893] +- Fix timezone parsing of logstash module ingest pipelines. {pull}13890[13890] +- Fix timezone parsing of iptables, mssql and panw module ingest pipelines. {pull}13926[13926] +- Fixed increased memory usage with large files when multiline pattern does not match. {issue}14068[14068] +- Fix azure fields names. {pull}14098[14098] {pull}14132[14132] +- Fix calculation of `network.bytes` and `network.packets` for bi-directional netflow events. {pull}14111[14111] +- Accept '-' as http.response.body.bytes in apache module. {pull}14137[14137] +- Fix timezone parsing of MySQL module ingest pipelines. {pull}14130[14130] +- Improve error message in s3 input when handleSQSMessage failed. {pull}14113[14113] +- Fix race condition in S3 input plugin. {pull}14359[14359] + +*Heartbeat* + +- Fix storage of HTTP bodies to work when JSON/Regex body checks are enabled. {pull}14223[14223] + +*Metricbeat* + +- Fix a denial of service flaw when parsing malformed DSA public keys in Go. +If {metricbeat} is configured to accept incoming TLS connections with client +authentication enabled, a remote attacker could cause the Beat to stop +processing events. (CVE-2019-17596) See https://www.elastic.co/community/security/ +- PdhExpandWildCardPathW will not expand counter paths in 32 bit windows systems, workaround will use a different function. {issue}12590[12590] {pull}12622[12622] +- Fix `docker.cpu.system.pct` calculation by using the reported number online cpus instead of the number of metrics per cpu. {pull}13691[13691] +- Change kubernetes.event.message to text {pull}13964[13964] +- Fix performance counter values for windows/perfmon metricset.{issue}14036[14036] {pull}14039[14039] {pull}14108[14108] +- Add FailOnRequired when applying schema and fix metric names in mongodb metrics metricset. {pull}14143[14143] +- Convert indexed ms-since-epoch timestamp fields in `elasticsearch/ml_job` metricset to ints from float64s. {issue}14220[14220] {pull}14222[14222] +- Fix ARN parsing function to work for ELB ARNs. {pull}14316[14316] +- Update azure configuration example. {issue}14224[14224] +- Limit some of the error messages to the logs only {issue}14317[14317] {pull}14327[14327] +- Fix cloudwatch metricset with names and dimensions in config. {issue}14376[14376] {pull}14391[14391] +- Fix marshaling of ms-since-epoch values in `elasticsearch/cluster_stats` metricset. {pull}14378[14378] + +*Packetbeat* + +- Fix parsing of the HTTP host header when it contains a port or an IPv6 address. {pull}14215[14215] + + +==== Added + +*Affecting all Beats* + +- Fail with error when autodiscover providers have no defined configs. {pull}13078[13078] +- Add autodetection mode for add_docker_metadata and enable it by default in included configuration files{pull}13374[13374] +- Add autodetection mode for add_kubernetes_metadata and enable it by default in included configuration files. {pull}13473[13473] +- Use less restrictive API to check if template exists. {pull}13847[13847] +- Do not check for alias when setup.ilm.check_exists is false. {pull}13848[13848] +- Add support for numeric time zone offsets in timestamp processor. {pull}13902[13902] +- Add condition to the config file template for add_kubernetes_metadata {pull}14056[14056] +- Marking Central Management deprecated. {pull}14018[14018] +- Add `keep_null` setting to allow Beats to publish null values in events. {issue}5522[5522] {pull}13928[13928] +- Add shared_credential_file option in aws related config for specifying credential file directory. {issue}14157[14157] {pull}14178[14178] +- Ensure that init containers are no longer tailed after they stop. {pull}14394[14394] +- Libbeat HTTP's Server can listen to a unix socket using the `unix:///tmp/hello.sock` syntax. {pull}13655[13655] +- Libbeat HTTP's Server can listen to a Windows named pipe using the `npipe:///hello` syntax. {pull}13655[13655] +- Adding new `Enterprise` license type to the licenser. {issue}14246[14246] + +*Auditbeat* + +- Socket: Add DNS enrichment. {pull}14004[14004] + +*Filebeat* + +- Add support for virtual host in Apache access logs {pull}12778[12778] +- Update CoreDNS module to populate ECS DNS fields. {issue}13320[13320] {pull}13505[13505] +- Parse query steps in PostgreSQL slowlogs. {issue}13496[13496] {pull}13701[13701] +- Add filebeat azure module with activitylogs, auditlogs, signinlogs filesets. {pull}13776[13776] +- Add support to set the document id in the json reader. {pull}5844[5844] +- Add input httpjson. {issue}13545[13545] {pull}13546[13546] +- Filebeat Netflow input: Remove beta label. {pull}13858[13858] +- Remove `event.timezone` from events that don't need it in some modules that support log formats with and without timezones. {pull}13918[13918] +- Add ExpandEventListFromField config option in the kafka input. {pull}13965[13965] +- Add ELB fileset to AWS module. {pull}14020[14020] +- Add module for MISP (Malware Information Sharing Platform). {pull}13805[13805] +- Add filebeat azure module with activitylogs, auditlogs, signinlogs filesets. {pull}13776[13776] {pull}14033[14033] {pull}14107[14107] +- Add support for all the ObjectCreated events in S3 input. {pull}14077[14077] +- Add `source.bytes` and `source.packets` for uni-directional netflow events. {pull}14111[14111] +- Add Kibana Dashboard for MISP module. {pull}14147[14147] +- Add support for gzipped files in S3 input {pull}13980[13980] +- Add Filebeat Azure Dashboards {pull}14127[14127] + + +*Heartbeat* +- Add non-privileged icmp on linux and darwin(mac). {pull}13795[13795] {issue}11498[11498] +- Allow `hosts` to be used to configure http monitors {pull}13703[13703] + +*Metricbeat* + +- Add refresh list of perf counters at every fetch {issue}13091[13091] +- Add proc/vmstat data to the system/memory metricset on linux {pull}13322[13322] +- Add support for NATS version 2. {pull}13601[13601] +- Add `docker.cpu.*.norm.pct` metrics for `cpu` metricset of Docker Metricbeat module. {pull}13695[13695] +- Add `instance` label by default when using Prometheus collector. {pull}13737[13737] +- Add azure module. {pull}13196[13196] {pull}13859[13859] {pull}13988[13988] +- Add Apache Tomcat module {pull}13491[13491] +- Add ECS `container.id` and `container.runtime` to kubernetes `state_container` metricset. {pull}13884[13884] +- Add `job` label by default when using Prometheus collector. {pull}13878[13878] +- Add `state_resourcequota` metricset for Kubernetes module. {pull}13693[13693] +- Add tags filter in ec2 metricset. {pull}13872[13872] {issue}13145[13145] +- Add cloud.account.id and cloud.account.name into events from aws module. {issue}13551[13551] {pull}13558[13558] +- Add `metrics_path` as known hint for autodiscovery {pull}13996[13996] +- Leverage KUBECONFIG when creating k8s client. {pull}13916[13916] +- Add ability to filter by tags for cloudwatch metricset. {pull}13758[13758] {issue}13145[13145] +- Release cloudwatch, s3_daily_storage, s3_request, sqs and rds metricset as GA. {pull}14114[14114] {issue}14059[14059] +- Add `elasticsearch/enrich` metricset. {pull}14243[14243] {issue}14221[14221] +- Add new dashboards for Azure vms, vm guest metrics, vm scale sets {pull}14000[14000] + +*Functionbeat* + +- Make `bulk_max_size` configurable in outputs. {pull}13493[13493] + +*Winlogbeat* + +- Fill `event.provider`. {pull}13937[13937] +- Add support for user management events to the Security module. {pull}13530[13530] + +==== Deprecated + +*Metricbeat* + +- `kubernetes.container.id` field for `state_container` is deprecated in favour of ECS `container.id` and `container.runtime`. {pull}13884[13884] + +[[release-notes-7.4.1]] +=== Beats version 7.4.1 +https://github.com/elastic/beats/compare/v7.4.0...v7.4.1[View commits] + +==== Breaking changes + +*Affecting all Beats* + +*Auditbeat* + +*Filebeat* + +*Heartbeat* + +*Journalbeat* + +*Metricbeat* + +*Packetbeat* + +*Winlogbeat* + +*Functionbeat* + +==== Bugfixes + +*Affecting all Beats* + +- Recover from panics in the javascript process and log details about the failure to aid in future debugging. {pull}13690[13690] +- Make the script processor concurrency-safe. {issue}13690[13690] {pull}13857[13857] + +*Auditbeat* + +*Filebeat* + +- Fixed early expiration of templates (Netflow v9 and IPFIX). {pull}13821[13821] +- Fixed bad handling of sequence numbers when multiple observation domains were exported by a single device (Netflow V9 and IPFIX). {pull}13821[13821] +- cisco asa and ftd filesets: Fix parsing of message 106001. {issue}13891[13891] {pull}13903[13903] +- Fix merging of fields specified in global scope with fields specified under an input's scope. {issue}3628[3628] {pull}13909[13909] +- Fix delay in enforcing close_renamed and close_removed options. {issue}13488[13488] {pull}13907[13907] +- Fix missing netflow fields in index template. {issue}13768[13768] {pull}13914[13914] +- Fix cisco module's asa and ftd filesets parsing of domain names where an IP address is expected. {issue}14034[14034] + +*Heartbeat* + +*Journalbeat* + +*Metricbeat* + +- Mark Kibana usage stats as collected only if API call succeeds. {pull}13881[13881] + +*Packetbeat* + +*Winlogbeat* + +*Functionbeat* + +==== Added + +*Affecting all Beats* + +*Auditbeat* + +*Filebeat* + +*Heartbeat* + +*Journalbeat* + +*Metricbeat* + +*Packetbeat* + +*Functionbeat* + +*Winlogbeat* + +==== Deprecated + +*Affecting all Beats* + +*Filebeat* + +*Heartbeat* + +*Journalbeat* + +*Metricbeat* + +*Packetbeat* + +*Winlogbeat* + +*Functionbeat* + +==== Known Issue + +*Journalbeat* + +[[release-notes-7.4.0]] +=== Beats version 7.4.0 +https://github.com/elastic/beats/compare/v7.3.1...v7.4.0[View commits] + +==== Breaking changes + +*Affecting all Beats* + +- Update to Golang 1.12.7. {pull}12931[12931] +- Remove `in_cluster` configuration parameter for Kuberentes, now in-cluster configuration is used only if no other kubeconfig is specified {pull}13051[13051] + +*Auditbeat* + +- Socket dataset: New implementation using Kprobes for finer-grained monitoring and UDP support. {pull}13058[13058] + +*Filebeat* + +- Fix a race condition in the TCP input when close the client socket. {pull}13038[13038] +- cisco/asa fileset: Renamed log.original to event.original and cisco.asa.list_id to cisco.asa.rule_name. {pull}13286[13286] +- cisco/asa fileset: Fix parsing of 302021 message code. {pull}13476[13476] + +*Metricbeat* + +- Add new Dashboard for PostgreSQL database stats {pull}13187[13187] +- Add new dashboard for CouchDB database {pull}13198[13198] +- Add new dashboard for Ceph cluster stats {pull}13216[13216] +- Add new dashboard for Aerospike database stats {pull}13217[13217] +- Add new dashboard for Couchbase cluster stats {pull}13212[13212] +- Add new dashboard for Prometheus server stats {pull}13126[13126] +- Add statistic option into cloudwatch metricset. If there is no statistic method specified, default is to collect Average, Sum, Maximum, Minimum and SampleCount. {issue}12370[12370] {pull}12840[12840] +- Fix rds metricset dashboard. {pull}13721[13721] + +*Functionbeat* + +- Separate management and functions in Functionbeat. {pull}12939[12939] + +==== Bugfixes + +*Affecting all Beats* + +- ILM: Use GET instead of HEAD when checking for alias to expose detailed error message. {pull}12886[12886] +- Fix unexpected stops on docker autodiscover when a container is restarted before `cleanup_timeout`. {issue}12962[12962] {pull}13127[13127] +- Fix some incorrect types and formats in field.yml files. {pull}13188[13188] +- Load DLLs only from Windows system directory. {pull}13234[13234] {pull}13384[13384] +- Fix mapping for kubernetes.labels and kubernetes.annotations in add_kubernetes_metadata. {issue}12638[12638] {pull}13226[13226] +- Fix case insensitive regular expressions not working correctly. {pull}13250[13250] + +*Auditbeat* + +- Host dataset: Export Host fields to gob encoder. {pull}12940[12940] + +*Filebeat* + +- Fix filebeat autodiscover fileset hint for container input. {pull}13296[13296] +- Fix incorrect references to index patterns in AWS and CoreDNS dashboards. {pull}13303[13303] +- Fix timezone parsing of system module ingest pipelines. {pull}13308[13308] +- Fix timezone parsing of elasticsearch module ingest pipelines. {pull}13367[13367] +- Change iis url path grok pattern from URIPATH to NOTSPACE. {issue}12710[12710] {pull}13225[13225] {issue}7951[7951] {pull}13378[13378] +- Add timezone information to apache error fileset. {issue}12772[12772] {pull}13304[13304] +- Fix timezone parsing of nginx module ingest pipelines. {pull}13369[13369] +- Allow path variables to be used in files loaded from modules.d. {issue}13184[13184] +- Fix incorrect field references in envoyproxy dashboard {issue}13420[13420] {pull}13421[13421] + +*Heartbeat* + +- Fix integer comparison on JSON responses. {pull}13348[13348] + +*Metricbeat* + +- Ramdisk is not filtered out when collecting disk performance counters in diskio metricset {issue}12814[12814] {pull}12829[12829] +- Fix redis key metricset dashboard references to index pattern. {pull}13303[13303] +- Check if fields in DBInstance is nil in rds metricset. {pull}13294[13294] {issue}13037[13037] +- Fix silent failures in kafka and prometheus module. {pull}13353[13353] {issue}13252[13252] +- Fix module-level fields in Kubernetes metricsets. {pull}13433[13433] {pull}13544[13544] +- Fix panic in Redis Key metricset when collecting information from a removed key. {pull}13426[13426] +- In the elasticsearch/node_stats metricset, if xpack is enabled, make parsing of ES node load average optional as ES on Windows doesn't report load average. {pull}12866[12866] +- Print errors that were being omitted in vSphere metricsets. {pull}12816[12816] +- Fix issue with aws cloudwatch module where dimensions and/or namespaces that contain space are not being parsed correctly {pull}13389[13389] +- Fix reporting empty events in cloudwatch metricset. {pull}13458[13458] +- Fix data race affecting config validation at startup. {issue}13005[13005] + +*Packetbeat* + +- Fix parsing the extended RCODE in the DNS parser. {pull}12805[12805] + +*Functionbeat* + +- Fix Cloudwatch logs timestamp to use timestamp of the log record instead of when the record was processed {pull}13291[13291] +- Look for the keystore under the correct path. {pull}13332[13332] + +==== Added + +*Affecting all Beats* + +- Add support for reading the `network.iana_number` field by default to the community_id processor. {pull}12701[12701] +- Add a check so alias creation explicitely fails if there is an index with the same name. {pull}13070[13070] +- Update kubernetes watcher to use official client-go libraries. {pull}13051[13051] +- Add support for unix epoch time values in the `timestamp` processor. {pull}13319[13319] +- add_host_metadata is now GA. {pull}13148[13148] +- Add an `ignore_missing` configuration option the `drop_fields` processor. {pull}13318[13318] +- Add `registered_domain` processor for deriving the registered domain from a given FQDN. {pull}13326[13326] +- Add support for RFC3339 time zone offsets in JSON output. {pull}13227[13227] +- Added `monitoring.cluster_uuid` setting to associate Beat data with specified ES cluster in Stack Monitoring UI. {pull}13182[13182] + +*Filebeat* + +- Add netflow dashboards based on Logstash netflow. {pull}12857[12857] +- Parse more fields from Elasticsearch slowlogs. {pull}11939[11939] +- Update module pipelines to enrich events with autonomous system fields. {pull}13036[13036] +- Add module for ingesting IBM MQ logs. {pull}8782[8782] +- Add S3 input to retrieve logs from AWS S3 buckets. {pull}12640[12640] {issue}12582[12582] +- Add aws module s3access metricset. {pull}13170[13170] {issue}12880[12880] +- Update Suricata module to populate ECS DNS fields and handle EVE DNS version 2. {issue}13320[13320] {pull}13329[13329] +- Update PAN-OS fileset to use the ECS NAT fields. {issue}13320[13320] {pull}13330[13330] +- Add fields to the Zeek DNS fileset for ECS DNS. {issue}13320[13320] {pull}13324[13324] +- Add container image in Kubernetes metadata {pull}13356[13356] {issue}12688[12688] +- Add module for ingesting Cisco FTD logs over syslog. {pull}13286[13286] + +*Heartbeat* + +- Record HTTP body metadata and optionally contents in `http.response.body.*` fields. {pull}13022[13022] + +*Metricbeat* + +- Add Kubernetes proxy dashboard to Kubernetes module {pull}12734[12734] +- Add Kubernetes controller manager dashboard to Kubernetes module {pull}12744[12744] +- Add metrics to kubernetes apiserver metricset. {pull}12922[12922] +- Add Kubernetes scheduler dashboard to Kubernetes module {pull}12749[12749] +- Collect client provided name for rabbitmq connection. {issue}12851[12851] {pull}12852[12852] +- Add support to load default aws config file to get credentials. {pull}12727[12727] {issue}12708[12708] +- Add statistic option into cloudwatch metricset. {issue}12370[12370] {pull}12840[12840] +- Add support for kubernetes cronjobs {pull}13001[13001] +- Add cgroup memory stats to docker/memory metricset {pull}12916[12916] +- Add AWS elb metricset. {pull}12952[12952] {issue}11701[11701] +- Add AWS ebs metricset. {pull}13167[13167] {issue}11699[11699] +- Add `metricset.period` field with the configured fetching period. {pull}13242[13242] {issue}12616[12616] +- Add rate metrics for ec2 metricset. {pull}13203[13203] +- Add Performance metricset to Oracle module {pull}12547[12547] +- Use DefaultMetaGeneratorConfig in MetadataEnrichers to initialize configurations {pull}13414[13414] +- Add module for statsd. {pull}13109[13109] + +*Packetbeat* + +- Update DNS protocol plugin to produce events with ECS fields for DNS. {issue}13320[13320] {pull}13354[13354] + +*Functionbeat* + +- Add timeout option to reference configuration. {pull}13351[13351] +- Configurable tags for Lambda functions. {pull}13352[13352] +- Add input for Cloudwatch logs through Kinesis. {pull}13317[13317] +- Enable Logstash output. {pull}13345[13345] + +*Winlogbeat* + +- Add support for event ID 4634 and 4647 to the Security module. {pull}12906[12906] +- Add `network.community_id` to Sysmon network events (event ID 3). {pull}13034[13034] +- Add `event.module` to Winlogbeat modules. {pull}13047[13047] +- Add `event.category: process` and `event.type: process_start/process_end` to Sysmon process events (event ID 1 and 5). {pull}13047[13047] +- Add support for event ID 4672 to the Security module. {pull}12975[12975] +- Add support for event ID 22 (DNS query) to the Sysmon module. {pull}12960[12960] +- Add support for event ID 4634 and 4647 to the Security module. {pull}12906[12906] +- Add `network.community_id` to Sysmon network events (event ID 3). {pull}13034[13034] +- Add `event.module` to Winlogbeat modules. {pull}13047[13047] +- Add `event.category: process` and `event.type: process_start/process_end` to Sysmon process events (event ID 1 and 5). {pull}13047[13047] +- Add support for event ID 4672 to the Security module. {pull}12975[12975] +- Add support for event ID 22 (DNS query) to the Sysmon module. {pull}12960[12960] +- Add certain winlog.event_data.* fields to the index template. {issue}13700[13700] {pull}13704[13704] + +[[release-notes-7.3.2]] +=== Beats version 7.3.2 +https://github.com/elastic/beats/compare/v7.3.1...v7.3.2[View commits] + +==== Bugfixes + +*Filebeat* + +- Fix filebeat autodiscover fileset hint for container input. {pull}13296[13296] +- Fix timezone parsing of system module ingest pipelines. {pull}13308[13308] +- Fix timezone parsing of elasticsearch module ingest pipelines. {pull}13367[13367] +- Fix timezone parsing of nginx module ingest pipelines. {pull}13369[13369] + +*Metricbeat* + +- Fix module-level fields in Kubernetes metricsets. {pull}13433[13433] {pull}13544[13544] +- Fix panic in Redis Key metricset when collecting information from a removed key. {pull}13426[13426] + +[[release-notes-7.3.1]] +=== Beats version 7.3.1 +https://github.com/elastic/beats/compare/v7.3.0...v7.3.1[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fix install-service.ps1's ability to set Windows service's delay start configuration. {pull}13173[13173] +- Fix `decode_base64_field` processor. {pull}13092[13092], {pull}13144[13144] + +*Filebeat* + +- Fix multiline pattern in Postgres which was too permissive. {issue}12078[12078] {pull}13069[13069] + +*Metricbeat* + +- Fix `logstash/node_stats` metricset to also collect `logstash_stats.events.duration_in_millis` field when `xpack.enabled: true` is set. {pull}13082[13082] +- Fix `logstash/node` metricset to also collect `logstash_state.pipeline.representation.{type,version,hash}` fields when `xpack.enabled: true` is set. {pull}13133[13133] + +==== Added + +*Metricbeat* + +- Make the `beat` module defensive about determining ES cluster UUID when `xpack.enabled: true` is set. {pull}13020[13020] + +[[release-notes-7.3.0]] +=== Beats version 7.3.0 +https://github.com/elastic/beats/compare/v7.2.0...v7.3.0[View commits] + +==== Breaking changes + +*Affecting all Beats* + +- Update to ECS 1.0.1. {pull}12284[12284] {pull}12317[12317] +- Default of output.kafka.metadata.full is set to false by now. This reduced the amount of metadata to be queried from a kafka cluster. {pull}12738[12738] + +*Filebeat* + +- `convert_timezone` option is removed and locale is always added to the event so timezone is used when parsing the timestamp, this behaviour can be overriden with processors. {pull}12410[12410] + +==== Bugfixes + +*Affecting all Beats* + +- Fix typo in TLS renegotiation configuration and setting the option correctly {issue}10871[10871], {pull}12354[12354] +- Add configurable bulk_flush_frequency in kafka output. {pull}12254[12254] +- Fixed setting bulk max size in kafka output. {pull}12254[12254] +- Add additional nil pointer checks to Docker client code to deal with vSphere Integrated Containers {pull}12628[12628] +- Fix seccomp policy preventing some features to function properly on 32bit Linux systems. {issue}12990[12990] {pull}13008[13008] + +*Auditbeat* + +- Package dataset: Close librpm handle. {pull}12215[12215] +- Package dataset: Improve dpkg parsing. {pull}12325[12325] +- Host dataset: Fix reboot detection logic. {pull}12591[12591] +- Add syscalls used by librpm for the system/package dataset to the default Auditbeat seccomp policy. {issue}12578[12578] {pull}12617[12617] +- Host dataset: Export Host fields to gob encoder. {pull}12940[12940] + +*Filebeat* + +- Parse timezone in PostgreSQL logs as part of the timestamp {pull}12338[12338] +- When TLS is configured for the TCP input and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] +- Syslog input will now omit the `process` object from events if it is empty. {pull}12700[12700] +- Apply `max_message_size` to incoming message buffer. {pull}11966[11966] + +*Heartbeat* + + +*Journalbeat* + +- Iterate over journal correctly, so no duplicate entries are sent. {pull}12716[12716] +- Preserve host name when reading from remote journal. {pull}12714[12714] + +*Metricbeat* + +- Refactored Windows perfmon metricset: replaced method to retrieve counter paths with PdhExpandWildCardPathW, separated code by responsibility, removed unused functions {pull}12212[12212] +- Validate that kibana/status metricset cannot be used when xpack is enabled. {pull}12264[12264] +- In the kibana/stats metricset, only log error (don't also index it) if xpack is enabled. {pull}12265[12265] +- Fix an issue listing all processes when run under Windows as a non-privileged user. {issue}12301[12301] {pull}12475[12475] +- When TLS is configured for the http metricset and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] +- Reuse connections in PostgreSQL metricsets. {issue}12504[12504] {pull}12603[12603] +- PdhExpandWildCardPathW will not expand counter paths in 32 bit windows systems, workaround will use a different function.{issue}12590[12590]{pull}12622[12622] +- Print errors that were being omitted in vSphere metricsets {pull}12816[12816] +- In the elasticsearch/node_stats metricset, if xpack is enabled, make parsing of ES node load average optional as ES on Windows doesn't report load average. {pull}12866[12866] +- Fix incoherent behaviour in redis key metricset when keyspace is specified both in host URL and key pattern {pull}12913[12913] +- Fix connections leak in redis module {pull}12914[12914] {pull}12950[12950] + +*Packetbeat* + + +==== Added + +*Affecting all Beats* + +- Add `proxy_disable` output flag to explicitly ignore proxy environment variables. {issue}11713[11713] {pull}12243[12243] +- Processor `add_cloud_metadata` adds fields `cloud.account.id` and `cloud.image.id` for AWS EC2. {pull}12307[12307] +- Add `decode_base64_field` processor for decoding base64 field. {pull}11914[11914] +- Add aws overview dashboard. {issue}11007[11007] {pull}12175[12175] +- Add `decompress_gzip_field` processor. {pull}12733[12733] +- Add `timestamp` processor for parsing time fields. {pull}12699[12699] +- Add Oracle Tablespaces Dashboard {pull}12736[12736] +- Add `proxy_disable` output flag to explicitly ignore proxy environment variables. {issue}11713[11713] {pull}12243[12243] + +*Auditbeat* + + +*Filebeat* + +- Add timeouts on communication with docker daemon. {pull}12310[12310] +- Add specific date processor to convert timezones so same pipeline can be used when convert_timezone is enabled or disabled. {pull}12253[12253] +- Add MSSQL module {pull}12079[12079] +- Add ISO8601 date parsing support for system module. {pull}12568[12568] {pull}12578[12579] +- Update Kubernetes deployment manifest to use `container` input. {pull}12632[12632] +- Add `google-pubsub` input type for consuming messages from a Google Cloud Pub/Sub topic subscription. {pull}12746[12746] +- Add module for ingesting Cisco IOS logs over syslog. {pull}12748[12748] +- Add module for ingesting Google Cloud VPC flow logs. {pull}12747[12747] +- Report host metadata for Filebeat logs in Kubernetes. {pull}12790[12790] + +*Metricbeat* + +- Add overview dashboard to Consul module {pull}10665[10665] +- New fields were added in the mysql/status metricset. {pull}12227[12227] +- Add Kubernetes metricset `proxy`. {pull}12312[12312] +- Always report Pod UID in the `pod` metricset. {pull}12345[12345] +- Add Vsphere Virtual Machine operating system to `os` field in Vsphere virtualmachine module. {pull}12391[12391] +- Add CockroachDB module. {pull}12467[12467] +- Add support for metricbeat modules based on existing modules (a.k.a. light modules) {issue}12270[12270] {pull}12465[12465] +- Add a system/entropy metricset {pull}12450[12450] +- Add kubernetes metricset `controllermanager` {pull}12409[12409] +- Allow redis URL format in redis hosts config. {pull}12408[12408] +- Add tags into ec2 metricset. {issue}[12263]12263 {pull}12372[12372] +- Add kubernetes metricset `scheduler` {pull}12521[12521] +- Add Kubernetes scheduler dashboard to Kubernetes module {pull}12749[12749] +- Add `beat` module. {pull}12181[12181] {pull}12615[12615] +- Collect tags for cloudwatch metricset in aws module. {issue}[12263]12263 {pull}12480[12480] +- Add AWS RDS metricset. {pull}11620[11620] {issue}10054[10054] +- Add Oracle Module {pull}11890[11890] +- Add Kubernetes proxy dashboard to Kubernetes module {pull}12734[12734] +- Add Kubernetes controller manager dashboard to Kubernetes module {pull}12744[12744] + +*Functionbeat* + +- Export automation templates used to create functions. {pull}11923[11923] +- Configurable Amazon endpoint. {pull}12369[12369] + +==== Deprecated + +*Filebeat* + +- `postgresql.log.timestamp` field is deprecated in favour of `@timestamp`. {pull}12338[12338] + +[[release-notes-7.2.1]] +=== Beats version 7.2.1 +https://github.com/elastic/beats/compare/v7.2.0...v7.2.1[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fix Central Management enroll under Windows {issue}12797[12797] {pull}12799[12799] +- Fixed a crash under Windows when fetching processes information. {pull}12833[12833] + +*Filebeat* + +- Add support for client addresses with port in Apache error logs {pull}12695[12695] +- Load correct pipelines when system module is configured in modules.d. {pull}12340[12340] + +*Metricbeat* + +- Fix wrong uptime reporting by system/uptime metricset under Windows. {pull}12915[12915] + +*Packetbeat* + +- Limit memory usage of Redis replication sessions. {issue}12657[12657] + +[[release-notes-7.2.0]] +=== Beats version 7.2.0 +https://github.com/elastic/beats/compare/v7.1.1...v7.2.0[View commits] + +==== Breaking changes + +*Affecting all Beats* + +- Update to Golang 1.12.4. {pull}11782[11782] + +*Auditbeat* + +- Auditd module: Normalized value of `event.category` field from `user-login` to `authentication`. {pull}11432[11432] +- Auditd module: Unset `auditd.session` and `user.audit.id` fields are removed from audit events. {issue}11431[11431] {pull}11815[11815] +- Socket dataset: Exclude localhost by default {pull}11993[11993] + +*Filebeat* + +- Add read_buffer configuration option. {pull}11739[11739] + +*Heartbeat* + +- Removed the `add_host_metadata` and `add_cloud_metadata` processors from the default config. These don't fit well with ECS for Heartbeat and were rarely used. + +*Journalbeat* + +*Metricbeat* + +- Add new option `OpMultiplyBuckets` to scale histogram buckets to avoid decimal points in final events {pull}10994[10994] +- system/raid metricset now uses /sys/block instead of /proc/mdstat for data. {pull}11613[11613] + +*Packetbeat* + +- Add support for mongodb opcode 2013 (OP_MSG). {issue}6191[6191] {pull}8594[8594] +- NFSv4: Always use opname `ILLEGAL` when failed to match request to a valid nfs operation. {pull}11503[11503] + +*Winlogbeat* + +*Functionbeat* + +==== Bugfixes + +*Affecting all Beats* + +- Ensure all beat commands respect configured settings. {pull}10721[10721] +- Add missing fields and test cases for libbeat add_kubernetes_metadata processor. {issue}11133[11133], {pull}11134[11134] +- decode_json_field: process objects and arrays only {pull}11312[11312] +- decode_json_field: do not process arrays when flag not set. {pull}11318[11318] +- Report faulting file when config reload fails. {pull}11304[11304] +- Fix a typo in libbeat/outputs/transport/client.go by updating `c.conn.LocalAddr()` to `c.conn.RemoteAddr()`. {pull}11242[11242] +- Management configuration backup file will now have a timestamps in their name. {pull}11034[11034] +- [CM] Parse enrollment_token response correctly {pull}11648[11648] +- Not hiding error in case of http failure using elastic fetcher {pull}11604[11604] +- Escape BOM on JsonReader before trying to decode line {pull}11661[11661] +- Fix matching of string arrays in contains condition. {pull}11691[11691] +- Replace wmi queries with win32 api calls as they were consuming CPU resources {issue}3249[3249] and {issue}11840[11840] +- Fix queue.spool.write.flush.events config type. {pull}12080[12080] +- Fixed a memory leak when using the add_process_metadata processor under Windows. {pull}12100[12100] +- Fix of docker json parser for missing "log" jsonkey in docker container's log {issue}11464[11464] +- Fixed Beat ID being reported by GET / API. {pull}12180[12180] +- Add host.os.codename to fields.yml. {pull}12261[12261] +- Fix `@timestamp` being duplicated in events if `@timestamp` is set in a + processor (or by any code utilizing `PutValue()` on a `beat.Event`). +- Fix leak in script processor when using Javascript functions in a processor chain. {pull}12600[12600] + +*Auditbeat* + +- Process dataset: Fixed a memory leak under Windows. {pull}12100[12100] +- Login dataset: Fix re-read of utmp files. {pull}12028[12028] +- Package dataset: Fixed a crash inside librpm after Auditbeat has been running for a while. {issue}12147[12147] {pull}12168[12168] +- Fix formatting of config files on macOS and Windows. {pull}12148[12148] +- Fix direction of incoming IPv6 sockets. {pull}12248[12248] +- Package dataset: Auto-detect package directories. {pull}12289[12289] +- System module: Start system module without host ID. {pull}12373[12373] + +*Filebeat* + +- Add support for Cisco syslog format used by their switch. {pull}10760[10760] +- Cover empty request data, url and version in Apache2 module{pull}10730[10730] +- Fix registry entries not being cleaned due to race conditions. {pull}10747[10747] +- Improve detection of file deletion on Windows. {pull}10747[10747] +- Add missing Kubernetes metadata fields to Filebeat CoreDNS module, and fix a documentation error. {pull}11591[11591] +- Reduce memory usage if long lines are truncated to fit `max_bytes` limit. The line buffer is copied into a smaller buffer now. This allows the runtime to release unused memory earlier. {pull}11524[11524] +- Fix memory leak in Filebeat pipeline acker. {pull}12063[12063] +- Fix goroutine leak caused on initialization failures of log input. {pull}12125[12125] +- Fix goroutine leak on non-explicit finalization of log input. {pull}12164[12164] +- Require client_auth by default when ssl is enabled for tcp input {pull}12333[12333] +- Fix timezone offset parsing in system/syslog. {pull}12529[12529] + +*Heartbeat* + +- Fix NPEs / resource leaks when executing config checks. {pull}11165[11165] +- Fix duplicated IPs on `mode: all` monitors. {pull}12458[12458] + +*Journalbeat* + +- Use backoff when no new events are found. {pull}11861[11861] + +*Metricbeat* + +- Change diskio metrics retrieval method (only for Windows) from wmi query to DeviceIOControl function using the IOCTL_DISK_PERFORMANCE control code {pull}11635[11635] +- Call GetMetricData api per region instead of per instance. {issue}11820[11820] {pull}11882[11882] +- Update documentation with cloudwatch:ListMetrics permission. {pull}11987[11987] +- Check permissions in system socket metricset based on capabilities. {pull}12039[12039] +- Get process information from sockets owned by current user when system socket metricset is run without privileges. {pull}12039[12039] +- Avoid generating hints-based configuration with empty hosts when no exposed port is suitable for the hosts hint. {issue}8264[8264] {pull}12086[12086] +- Fixed a socket leak in the postgresql module under Windows when SSL is disabled on the server. {pull}11393[11393] +- Change some field type from scaled_float to long in aws module. {pull}11982[11982] +- Fixed RabbitMQ `queue` metricset gathering when `consumer_utilisation` is set empty at the metrics source {pull}12089[12089] +- Fix direction of incoming IPv6 sockets. {pull}12248[12248] +- Ignore prometheus metrics when their values are NaN or Inf. {pull}12084[12084] {issue}10849[10849] +- Require client_auth by default when ssl is enabled for module http metricset server{pull}12333[12333] +- The `elasticsearch/index_summary` metricset gracefully handles an empty Elasticsearch cluster when `xpack.enabled: true` is set. {pull}12489[12489] {issue}12487[12487] + +*Packetbeat* + +- Prevent duplicate packet loss error messages in HTTP events. {pull}10709[10709] +- Fixed a memory leak when using process monitoring under Windows. {pull}12100[12100] +- Improved debug logging efficiency in PGQSL module. {issue}12150[12150] + +*Winlogbeat* + +*Functionbeat* + +- Fix function name reference for Kinesis streams in CloudFormation templates {pull}11646[11646] + +==== Added + +*Affecting all Beats* + +- Add an option to append to existing logs rather than always rotate on start. {pull}11953[11953] +- Add `network` condition to processors for matching IP addresses against CIDRs. {pull}10743[10743] +- Add if/then/else support to processors. {pull}10744[10744] +- Add `community_id` processor for computing network flow hashes. {pull}10745[10745] +- Add output test to kafka output {pull}10834[10834] +- Gracefully shut down on SIGHUP {pull}10704[10704] +- New processor: `copy_fields`. {pull}11303[11303] +- Add `error.message` to events when `fail_on_error` is set in `rename` and `copy_fields` processors. {pull}11303[11303] +- New processor: `truncate_fields`. {pull}11297[11297] +- Allow a beat to ship monitoring data directly to an Elasticsearch monitoring clsuter. {pull}9260[9260] +- Updated go-seccomp-bpf library to v1.1.0 which updates syscall lists for Linux v5.0. {pull}NNNN[NNNN] +- Add `add_observer_metadata` processor. {pull}11394[11394] +- Add `decode_csv_fields` processor. {pull}11753[11753] +- Add `convert` processor for converting data types of fields. {issue}8124[8124] {pull}11686[11686] +- New `extract_array` processor. {pull}11761[11761] +- Add number of goroutines to reported metrics. {pull}12135[12135] + +*Auditbeat* + +- Auditd module: Add `event.outcome` and `event.type` for ECS. {pull}11432[11432] +- Process: Add file hash of process executable. {pull}11722[11722] +- Socket: Add network.transport and network.community_id. {pull}12231[12231] +- Host: Fill top-level host fields. {pull}12259[12259] + +*Filebeat* + +- Add more info to message logged when a duplicated symlink file is found {pull}10845[10845] +- Add option to configure docker input with paths {pull}10687[10687] +- Add Netflow module to enrich flow events with geoip data. {pull}10877[10877] +- Set `event.category: network_traffic` for Suricata. {pull}10882[10882] +- Allow custom default settings with autodiscover (for example, use of CRI paths for logs). {pull}12193[12193] +- Allow to disable hints based autodiscover default behavior (fetching all logs). {pull}12193[12193] +- Change Suricata module pipeline to handle `destination.domain` being set if a reverse DNS processor is used. {issue}10510[10510] +- Add the `network.community_id` flow identifier to field to the IPTables, Suricata, and Zeek modules. {pull}11005[11005] +- New Filebeat coredns module to ingest coredns logs. It supports both native coredns deployment and coredns deployment in kubernetes. {pull}11200[11200] +- New module for Cisco ASA logs. {issue}9200[9200] {pull}11171[11171] +- Added support for Cisco ASA fields to the netflow input. {pull}11201[11201] +- Configurable line terminator. {pull}11015[11015] +- Add Filebeat envoyproxy module. {pull}11700[11700] +- Add apache2(httpd) log path (`/var/log/httpd`) to make apache2 module work out of the box on Redhat-family OSes. {issue}11887[11887] {pull}11888[11888] +- Add support to new MongoDB additional diagnostic information {pull}11952[11952] +- New module `panw` for Palo Alto Networks PAN-OS logs. {pull}11999[11999] +- Add RabbitMQ module. {pull}12032[12032] +- Add new `container` input. {pull}12162[12162] + +*Heartbeat* + +- Enable `add_observer_metadata` processor in default config. {pull}11394[11394] + +*Journalbeat* + +*Metricbeat* + +- Add AWS SQS metricset. {pull}10684[10684] {issue}10053[10053] +- Add AWS s3_request metricset. {pull}10949[10949] {issue}10055[10055] +- Add s3_daily_storage metricset. {pull}10940[10940] {issue}10055[10055] +- Add `coredns` metricbeat module. {pull}10585[10585] +- Add SSL support for Metricbeat HTTP server. {pull}11482[11482] {issue}11457[11457] +- The `elasticsearch.index` metricset (with `xpack.enabled: true`) now collects `refresh.external_total_time_in_millis` fields from Elasticsearch. {pull}11616[11616] +- Allow module configurations to have variants {pull}9118[9118] +- Add `timeseries.instance` field calculation. {pull}10293[10293] +- Added new disk states and raid level to the system/raid metricset. {pull}11613[11613] +- Added `path_name` and `start_name` to service metricset on windows module {issue}8364[8364] {pull}11877[11877] +- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878] +- Add AWS cloudwatch metricset. {pull}11798[11798] {issue}11734[11734] +- Add `regions` in aws module config to specify target regions for querying cloudwatch metrics. {issue}11932[11932] {pull}11956[11956] +- Keep `etcd` followers members from reporting `leader` metricset events {pull}12004[12004] +- Add validation for elasticsearch and kibana modules' metricsets when xpack.enabled is set to true. {pull}12386[12386] + +*Packetbeat* + +*Functionbeat* + +- New options to configure roles and VPC. {pull}11779[11779] + +*Winlogbeat* + +- Add support for reading from .evtx files. {issue}4450[4450] + +==== Deprecated + +*Affecting all Beats* + +*Filebeat* + +- `docker` input is deprecated in favour `container`. {pull}12162[12162] + +*Heartbeat* + +*Journalbeat* + +*Metricbeat* + +*Packetbeat* + +*Winlogbeat* + +*Functionbeat* + +==== Known Issue + +*Journalbeat* + [[release-notes-7.1.1]] === Beats version 7.1.1 https://github.com/elastic/beats/compare/v7.1.0...v7.1.1[View commits] @@ -818,12 +1702,105 @@ https://github.com/elastic/beats/compare/v6.5.0...v7.0.0-alpha1[View commits] - Added support to calculate certificates' fingerprints (MD5, SHA-1, SHA-256). {issue}8180[8180] - Support new TLS version negotiation introduced in TLS 1.3. {issue}8647[8647]. +[[release-notes-6.8.3]] +=== Beats version 6.8.3 +https://github.com/elastic/beats/compare/v6.8.2...v6.8.3[View commits + +==== Bugfixes + +*Journalbeat* + +- Iterate over journal correctly, so no duplicate entries are sent. {pull}12716[12716] + +*Metricbeat* + +- Fix panic in Redis Key metricset when collecting information from a removed key. {pull}13426[13426] + +==== Added + +*Metricbeat* + +- Remove _nodes field from under cluster_stats as it's not being used. {pull}13010[13010] +- Collect license expiry date fields as well. {pull}11652[11652] + +[[release-notes-6.8.2]] +=== Beats version 6.8.2 +https://github.com/elastic/beats/compare/v6.8.1...v6.8.2[View commits] + +==== Bugfixes + +*Auditbeat* + +- Process dataset: Do not show non-root warning on Windows. {pull}12740[12740] + +*Filebeat* + +- Skipping unparsable log entries from docker json reader {pull}12268[12268] + +*Packetbeat* + +- Limit memory usage of Redis replication sessions. {issue}12657[12657 + +[[release-notes-6.8.1]] +=== Beats version 6.8.1 +https://github.com/elastic/beats/compare/v6.8.0...v6.8.1[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fixed a memory leak when using the add_process_metadata processor under Windows. {pull}12100[12100] + +*Auditbeat* + +- Package dataset: Log error when Homebrew is not installed. {pull}11667[11667] +- Process dataset: Fixed a memory leak under Windows. {pull}12100[12100] +- Login dataset: Fix re-read of utmp files. {pull}12028[12028] +- Package dataset: Fixed a crash inside librpm after Auditbeat has been running for a while. {issue}12147[12147] {pull}12168[12168] +- Fix direction of incoming IPv6 sockets. {pull}12248[12248] +- Package dataset: Auto-detect package directories. {pull}12289[12289] +- System module: Start system module without host ID. {pull}12373[12373] +- Host dataset: Fix reboot detection logic. {pull}12591[12591] + +*Filebeat* + +- Fix goroutine leak happening when harvesters are dynamically stopped. {pull}11263[11263] +- Fix initialization of the TCP input logger. {pull}11605[11605] +- Fix goroutine leak caused on initialization failures of log input. {pull}12125[12125] +- Fix memory leak in Filebeat pipeline acker. {pull}12063[12063] +- Fix goroutine leak on non-explicit finalization of log input. {pull}12164[12164] +- When TLS is configured for the TCP input and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] + +*Metricbeat* + +- Avoid generating hints-based configuration with empty hosts when no exposed port is suitable for the hosts hint. {issue}8264[8264] {pull}12086[12086] +- Fix direction of incoming IPv6 sockets. {pull}12248[12248] +- Validate that kibana/status metricset cannot be used when xpack is enabled. {pull}12264[12264] +- In the kibana/stats metricset, only log error (don't also index it) if xpack is enabled. {pull}12353[12353] +- The `elasticsearch/index_summary` metricset gracefully handles an empty Elasticsearch cluster when `xpack.enabled: true` is set. {pull}12489[12489] {issue}12487[12487] +- When TLS is configured for the http metricset and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] + +*Packetbeat* + +- Fixed a memory leak when using process monitoring under Windows. {pull}12100[12100] +- Improved debug logging efficiency in PGQSL module. {issue}12150[12150] + +==== Added + +*Auditbeat* + +- Add support to the system package dataset for the SUSE OS family. {pull}11634[11634] + +*Metricbeat* + +- Add validation for elasticsearch and kibana modules' metricsets when xpack.enabled is set to true. {pull}12386[12386] + [[release-notes-6.8.0]] === Beats version 6.8.0 * Updates to support changes to licensing of security features. + -Some Elastic Stack security features, such as encrypted communications, file and native authentication, and +Some Elastic Stack security features, such as encrypted communications, file and native authentication, and role-based access control, are now available in more subscription levels. For details, see https://www.elastic.co/subscriptions. [[release-notes-6.7.2]] diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 647632f6bfb..2974adb6239 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -10,634 +10,86 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* -- Update to Golang 1.12.1. {pull}11330[11330] -- Update to Golang 1.12.4. {pull}11782[11782] -- Update to ECS 1.0.1. {pull}12284[12284] {pull}12317[12317] -- Default of output.kafka.metadata.full is set to false by now. This reduced the amount of metadata to be queried from a kafka cluster. {pull}12738[12738] -- Fixed a crash under Windows when fetching processes information. {pull}12833[12833] -- Update to Golang 1.12.7. {pull}12931[12931] -- Remove `in_cluster` configuration parameter for Kuberentes, now in-cluster configuration is used only if no other kubeconfig is specified {pull}13051[13051] -- Disable Alibaba Cloud and Tencent Cloud metadata providers by default. {pull}13812[12812] -- Libbeat HTTP's Server can listen to a unix socket using the `unix:///tmp/hello.sock` syntax. {pull}13655[13655] -- Libbeat HTTP's Server can listen to a Windows named pipe using the `npipe:///hello` syntax. {pull}13655[13655] -- By default, all Beats-created files and folders will have a umask of 0027 (on POSIX systems). {pull}14119[14119] -- Adding new `Enterprise` license type to the licenser. {issue}14246[14246] -- Change wording when we fail to load a CA file to the cert pool. {issue}14309[14309] -- Allow Metricbeat's beat module to read monitoring information over a named pipe or unix domain socket. {pull}14558[14558] -- Remove version information from default ILM policy for improved upgrade experience on custom policies. {pull}14745[14745] -- Running `setup` cmd respects `setup.ilm.overwrite` setting for improved support of custom policies. {pull}14741[14741] -- Libbeat: Do not overwrite agent.*, ecs.version, and host.name. {pull}14407[14407] -- Libbeat: Cleanup the x-pack licenser code to use the new license endpoint and the new format. {pull}15091[15091] -- Users can now specify `monitoring.cloud.*` to override `monitoring.elasticsearch.*` settings. {issue}14399[14399] {pull}15254[15254] -- Refactor metadata generator to support adding metadata across resources {pull}14875[14875] -- Update to ECS 1.4.0. {pull}14844[14844] *Auditbeat* -- Auditd module: Normalized value of `event.category` field from `user-login` to `authentication`. {pull}11432[11432] -- Auditd module: Unset `auditd.session` and `user.audit.id` fields are removed from audit events. {issue}11431[11431] {pull}11815[11815] -- Socket dataset: Exclude localhost by default {pull}11993[11993] -- Socket dataset: New implementation using Kprobes for finer-grained monitoring and UDP support. {pull}13058[13058] *Filebeat* -- Add Filebeat Azure Dashboards {pull}14127[14127] -- Add read_buffer configuration option. {pull}11739[11739] -- `convert_timezone` option is removed and locale is always added to the event so timezone is used when parsing the timestamp, this behaviour can be overriden with processors. {pull}12410[12410] -- Fix a race condition in the TCP input when close the client socket. {pull}13038[13038] -- cisco/asa fileset: Renamed log.original to event.original and cisco.asa.list_id to cisco.asa.rule_name. {pull}13286[13286] -- cisco/asa fileset: Fix parsing of 302021 message code. {pull}13476[13476] -- google pubsub & httpjson inputs: HTTP User agent is now `Elastic-Heartbeat/Version` instead of `Elastic Heartbeat/Version` to stay RFC compliant. {pull}14748[14748] -- CEF extensions are now mapped to the data types defined in the CEF guide. {pull}14342[14342] -- Remove --machine-learning from setup subcommand. {pull}14705[14705] *Heartbeat* -- Removed the `add_host_metadata` and `add_cloud_metadata` processors from the default config. These don't fit well with ECS for Heartbeat and were rarely used. -- Fixed/altered redirect behavior. `max_redirects` now defaults to 0 (no redirects). Following redirects now works across hosts, but some timing fields will not be reported. {pull}14125[14125] -- Removed `host.name` field that should never have been included. Heartbeat uses `observer.*` fields instead. {pull}14140[14140] -- Changed default user-agent to be `Elastic-Heartbeat/VERSION (PLATFORM_INFO)` as the current default `Go-http-client/1.1` is often blacklisted. {pull}14291[14291] -- JSON/Regex checks against HTTP bodies will only consider the first 100MiB of the HTTP body to prevent excessive memory usage. {pull}14223[pull] -- Heartbeat now starts monitors scheduled with the '@every X' syntax instantaneously on startup, rather than waiting for the given interval to pass before running them. {pull}14890[14890] *Journalbeat* -- Remove broken dashboard. {pull}15288[15288] *Metricbeat* -- Add new dashboards for Azure vms, vm guest metrics, vm scale sets {pull}14000[14000] -- Add new Dashboard for PostgreSQL database stats {pull}13187[13187] -- Add new dashboard for CouchDB database {pull}13198[13198] -- Add new dashboard for Ceph cluster stats {pull}13216[13216] -- Add new dashboard for Aerospike database stats {pull}13217[13217] -- Add new dashboard for Couchbase cluster stats {pull}13212[13212] -- Add new dashboard for Prometheus server stats {pull}13126[13126] -- Add new dashboard for VSphere host cluster and virtual machine {pull}14135[14135] -- Add new option `OpMultiplyBuckets` to scale histogram buckets to avoid decimal points in final events {pull}10994[10994] -- system/raid metricset now uses /sys/block instead of /proc/mdstat for data. {pull}11613[11613] -- kubernetes.container.cpu.limit.cores and kubernetes.container.cpu.requests.cores are now floats. {issue}11975[11975] -- Add statistic option into cloudwatch metricset. If there is no statistic method specified, default is to collect Average, Sum, Maximum, Minimum and SampleCount. {issue}12370[12370] {pull}12840[12840] -- Update cloudwatch metricset mapping for both metrics and dimensions. {pull}15245[15245] -- Add sql module that fetches metrics from a SQL database {pull}13257[13257] *Packetbeat* -- Add dns.question.subdomain and dns.question.top_level_domain fields. {pull}14578[14578] -- Add support for mongodb opcode 2013 (OP_MSG). {issue}6191[6191] {pull}8594[8594] -- NFSv4: Always use opname `ILLEGAL` when failed to match request to a valid nfs operation. {pull}11503[11503] -- Added redact_headers configuration option, to allow HTTP request headers to be redacted whilst keeping the header field included in the beat. {pull}15353[15353] -- TLS: Fields have been changed to adapt to ECS. {pull}15497[15497] -- TLS: The behavior of send_certificates and include_raw_certificates options has changed. {pull}15497[15497] *Winlogbeat* *Functionbeat* -- Separate management and functions in Functionbeat. {pull}12939[12939] ==== Bugfixes *Affecting all Beats* -- Make the behavior of clientWorker and netClientWorker consistent when error is returned from publisher pipeline -- Fix a bug, publisher pipeline exits if output returns an error, irrespective of pipeline is closed or not -- Fix typo in TLS renegotiation configuration and setting the option correctly {issue}10871[10871], {pull}12354[12354] -- Ensure all beat commands respect configured settings. {pull}10721[10721] -- Add missing fields and test cases for libbeat add_kubernetes_metadata processor. {issue}11133[11133], {pull}11134[11134] -- decode_json_field: process objects and arrays only {pull}11312[11312] -- decode_json_field: do not process arrays when flag not set. {pull}11318[11318] -- Report faulting file when config reload fails. {pull}11304[11304] -- Fix a typo in libbeat/outputs/transport/client.go by updating `c.conn.LocalAddr()` to `c.conn.RemoteAddr()`. {pull}11242[11242] -- Management configuration backup file will now have a timestamps in their name. {pull}11034[11034] -- [CM] Parse enrollment_token response correctly {pull}11648[11648] -- Not hiding error in case of http failure using elastic fetcher {pull}11604[11604] -- Escape BOM on JsonReader before trying to decode line {pull}11661[11661] -- Fix matching of string arrays in contains condition. {pull}11691[11691] -- Replace wmi queries with win32 api calls as they were consuming CPU resources {issue}3249[3249] and {issue}11840[11840] -- Fix a race condition with the Kafka pipeline client, it is possible that `Close()` get called before `Connect()` . {issue}11945[11945] -- Fix queue.spool.write.flush.events config type. {pull}12080[12080] -- Fixed a memory leak when using the add_process_metadata processor under Windows. {pull}12100[12100] -- Fix of docker json parser for missing "log" jsonkey in docker container's log {issue}11464[11464] -- Fixed Beat ID being reported by GET / API. {pull}12180[12180] -- Fixed setting bulk max size in kafka output. {pull}12254[12254] -- Add host.os.codename to fields.yml. {pull}12261[12261] -- Fix `@timestamp` being duplicated in events if `@timestamp` is set in a - processor (or by any code utilizing `PutValue()` on a `beat.Event`). -- Fix leak in script processor when using Javascript functions in a processor chain. {pull}12600[12600] -- Add additional nil pointer checks to Docker client code to deal with vSphere Integrated Containers {pull}12628[12628] -- Fixed `json.add_error_key` property setting for delivering error messages from beat events {pull}11298[11298] -- Fix Central Management enroll under Windows {issue}12797[12797] {pull}12799[12799] -- ILM: Use GET instead of HEAD when checking for alias to expose detailed error message. {pull}12886[12886] -- Fix seccomp policy preventing some features to function properly on 32bit Linux systems. {issue}12990[12990] {pull}13008[13008] -- Fix unexpected stops on docker autodiscover when a container is restarted before `cleanup_timeout`. {issue}12962[12962] {pull}13127[13127] -- Fix install-service.ps1's ability to set Windows service's delay start configuration. {pull}13173[13173] -- Fix some incorrect types and formats in field.yml files. {pull}13188[13188] -- Load DLLs only from Windows system directory. {pull}13234[13234] {pull}13384[13384] -- Fix mapping for kubernetes.labels and kubernetes.annotations in add_kubernetes_metadata. {issue}12638[12638] {pull}13226[13226] -- Fix case insensitive regular expressions not working correctly. {pull}13250[13250] -- Disable `add_kubernetes_metadata` if no matchers found. {pull}13709[13709] -- Better wording for xpack beats when the _xpack endpoint is not reachable. {pull}13771[13771] -- Recover from panics in the javascript process and log details about the failure to aid in future debugging. {pull}13690[13690] -- Make the script processor concurrency-safe. {issue}13690[13690] {pull}13857[13857] -- Kubernetes watcher at `add_kubernetes_metadata` fails with StatefulSets {pull}13905[13905] -- Fix panics that could result from invalid TLS certificates. This can affect Beats that connect over - TLS or Beats that accept connections over TLS and validate client certificates. {pull}14146[14146] -- Support usage of custom builders without hints and mappers {pull}13839[13839] -- Fix memory leak in kubernetes autodiscover provider and add_kubernetes_metadata processor happening when pods are terminated without sending a delete event. {pull}14259[14259] -- Fix kubernetes `metaGenerator.ResourceMetadata` when parent reference controller is nil {issue}14320[14320] {pull}14329[14329] -- Allow users to configure only `cluster_uuid` setting under `monitoring` namespace. {pull}14338[14338] -- Fix `proxy_url` option in Elasticsearch output. {pull}14950[14950] -- Fix bug with potential concurrent reads and writes from event.Meta map by Kafka output. {issue}14542[14542] {pull}14568[14568] -- Fix spooling to disk blocking infinitely if the lock file can not be acquired. {pull}15338[15338] -- Fix `metricbeat test output` with an ipv6 ES host in the output.hosts. {pull}15368[15368] -- Fix `convert` processor conversion of string to integer with leading zeros. {issue}15513[15513] {pull}15557[15557] +TLS or Beats that accept connections over TLS and validate client certificates. {pull}14146[14146] *Auditbeat* -- Process dataset: Fixed a memory leak under Windows. {pull}12100[12100] -- Login dataset: Fix re-read of utmp files. {pull}12028[12028] -- Package dataset: Fixed a crash inside librpm after Auditbeat has been running for a while. {issue}12147[12147] {pull}12168[12168] -- Fix formatting of config files on macOS and Windows. {pull}12148[12148] -- Fix direction of incoming IPv6 sockets. {pull}12248[12248] -- Package dataset: Close librpm handle. {pull}12215[12215] -- Package dataset: Auto-detect package directories. {pull}12289[12289] -- Package dataset: Improve dpkg parsing. {pull}12325[12325] -- System module: Start system module without host ID. {pull}12373[12373] -- Host dataset: Fix reboot detection logic. {pull}12591[12591] -- Add syscalls used by librpm for the system/package dataset to the default Auditbeat seccomp policy. {issue}12578[12578] {pull}12617[12617] -- Process dataset: Do not show non-root warning on Windows. {pull}12740[12740] -- Host dataset: Export Host fields to gob encoder. {pull}12940[12940] -- Socket dataset: Fix start errors when IPv6 is disabled on the kernel. {issue}13953[13953] {pull}13966[13966] -- Removed GUID index pattern reference from Auditbeat dashboard definition. {pull}15314[15314] *Filebeat* -- Add support for Cisco syslog format used by their switch. {pull}10760[10760] -- Cover empty request data, url and version in Apache2 module{pull}10730[10730] -- Fix registry entries not being cleaned due to race conditions. {pull}10747[10747] -- Improve detection of file deletion on Windows. {pull}10747[10747] -- Add missing Kubernetes metadata fields to Filebeat CoreDNS module, and fix a documentation error. {pull}11591[11591] -- Reduce memory usage if long lines are truncated to fit `max_bytes` limit. The line buffer is copied into a smaller buffer now. This allows the runtime to release unused memory earlier. {pull}11524[11524] -- Fix memory leak in Filebeat pipeline acker. {pull}12063[12063] -- Fix goroutine leak caused on initialization failures of log input. {pull}12125[12125] -- Fix goroutine leak on non-explicit finalization of log input. {pull}12164[12164] -- Skipping unparsable log entries from docker json reader {pull}12268[12268] -- Parse timezone in PostgreSQL logs as part of the timestamp {pull}12338[12338] -- Load correct pipelines when system module is configured in modules.d. {pull}12340[12340] -- Fix timezone offset parsing in system/syslog. {pull}12529[12529] -- When TLS is configured for the TCP input and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] -- Apply `max_message_size` to incoming message buffer. {pull}11966[11966] -- Syslog input will now omit the `process` object from events if it is empty. {pull}12700[12700] -- Fix multiline pattern in Postgres which was too permissive {issue}12078[12078] {pull}13069[13069] -- Allow path variables to be used in files loaded from modules.d. {issue}13184[13184] -- Fix filebeat autodiscover fileset hint for container input. {pull}13296[13296] -- Fix incorrect references to index patterns in AWS and CoreDNS dashboards. {pull}13303[13303] -- Fix timezone parsing of system module ingest pipelines. {pull}13308[13308] -- Fix timezone parsing of elasticsearch module ingest pipelines. {pull}13367[13367] -- Change iis url path grok pattern from URIPATH to NOTSPACE. {issue}12710[12710] {pull}13225[13225] {issue}7951[7951] {pull}13378[13378] {pull}14754[14754] -- Fix timezone parsing of nginx module ingest pipelines. {pull}13369[13369] -- Fix incorrect field references in envoyproxy dashboard {issue}13420[13420] {pull}13421[13421] -- Fixed early expiration of templates (Netflow v9 and IPFIX). {pull}13821[13821] -- Fixed bad handling of sequence numbers when multiple observation domains were exported by a single device (Netflow V9 and IPFIX). {pull}13821[13821] -- Fix timezone parsing of rabbitmq module ingest pipelines. {pull}13879[13879] -- Fix conditions and error checking of date processors in ingest pipelines that use `event.timezone` to parse dates. {pull}13883[13883] -- Fix timezone parsing of Cisco module ingest pipelines. {pull}13893[13893] -- Fix timezone parsing of logstash module ingest pipelines. {pull}13890[13890] -- cisco asa and ftd filesets: Fix parsing of message 106001. {issue}13891[13891] {pull}13903[13903] -- Fix timezone parsing of iptables, mssql and panw module ingest pipelines. {pull}13926[13926] -- Fix merging of fields specified in global scope with fields specified under an input's scope. {issue}3628[3628] {pull}13909[13909] -- Fix delay in enforcing close_renamed and close_removed options. {issue}13488[13488] {pull}13907[13907] -- Fix missing netflow fields in index template. {issue}13768[13768] {pull}13914[13914] -- Fix cisco module's asa and ftd filesets parsing of domain names where an IP address is expected. {issue}14034[14034] -- Fixed increased memory usage with large files when multiline pattern does not match. {issue}14068[14068] -- panw module: Use geo.name instead of geo.country_iso_code for free-form location. {issue}13272[13272] -- Fix azure fields names. {pull}14098[14098] -- Fix calculation of `network.bytes` and `network.packets` for bi-directional netflow events. {pull}14111[14111] -- Accept '-' as http.response.body.bytes in apache module. {pull}14137[14137] -- Fix timezone parsing of MySQL module ingest pipelines. {pull}14130[14130] -- Fix azure filesets test files. {issue}14185[14185] {pull}14235[14235] -- Improve error message in s3 input when handleSQSMessage failed. {pull}14113[14113] -- Close chan of Closer first before calling callback {pull}14231[14231] -- Fix race condition in S3 input plugin. {pull}14359[14359] -- Decode hex values in auditd module. {pull}14471[14471] -- Fix parse of remote addresses that are not IPs in nginx logs. {pull}14505[14505] -- Fix handling multiline log entries in nginx module. {issue}14349[14349] {pull}14499[14499] -- Fix parsing of Elasticsearch node name by `elasticsearch/slowlog` fileset. {pull}14547[14547] -- cisco/asa fileset: Fix parsing of 302021 message code. {pull}14519[14519] -- Fix filebeat azure dashboards, event category should be `Alert`. {pull}14668[14668] -- Update Logstash module's Grok patterns to support Logstash 7.4 logs. {pull}14743[14743] -- Fix a problem in Filebeat input httpjson where interval is not used as time.Duration. {issue}14752[14752] {pull}14753[14753] -- Fix SSL config in input.yml for Filebeat httpjson input in the MISP module. {pull}14767[14767] -- Check content-type when creating new reader in s3 input. {pull}15252[15252] {issue}15225[15225] -- Fix session reset detection and a crash in Netflow input. {pull}14904[14904] -- Handle errors in handleS3Objects function and add more debug messages for s3 input. {pull}15545[15545] -- netflow: Allow for options templates without scope fields. {pull}15449[15449] -- netflow: Fix bytes/packets counters on some devices (NSEL and Netstream). {pull}15449[15449] -- netflow: Fix compatibility with some Cisco devices by changing the field `class_id` from short to long. {pull}15449[15449] -- Fixed dashboard for Cisco ASA Firewall. {issue}15420[15420] {pull}15553[15553] *Heartbeat* -- Fix NPEs / resource leaks when executing config checks. {pull}11165[11165] -- Fix duplicated IPs on `mode: all` monitors. {pull}12458[12458] -- Fix integer comparison on JSON responses. {pull}13348[13348] -- Fix storage of HTTP bodies to work when JSON/Regex body checks are enabled. {pull}14223[14223] -- Fix recording of SSL cert metadata for Expired/Unvalidated x509 certs. {pull}13687[13687] -- The heartbeat scheduler no longer drops scheduled items when under very high load causing missed deadlines. {pull}14890[14890] *Journalbeat* -- Use backoff when no new events are found. {pull}11861[11861] -- Iterate over journal correctly, so no duplicate entries are sent. {pull}12716[12716] -- Preserve host name when reading from remote journal. {pull}12714[12714] *Metricbeat* -- Change diskio metrics retrieval method (only for Windows) from wmi query to DeviceIOControl function using the IOCTL_DISK_PERFORMANCE control code {pull}11635[11635] -- Call GetMetricData api per region instead of per instance. {issue}11820[11820] {pull}11882[11882] -- Update documentation with cloudwatch:ListMetrics permission. {pull}11987[11987] -- Check permissions in system socket metricset based on capabilities. {pull}12039[12039] -- Get process information from sockets owned by current user when system socket metricset is run without privileges. {pull}12039[12039] -- Avoid generating hints-based configuration with empty hosts when no exposed port is suitable for the hosts hint. {issue}8264[8264] {pull}12086[12086] -- Fixed a socket leak in the postgresql module under Windows when SSL is disabled on the server. {pull}11393[11393] -- Change some field type from scaled_float to long in aws module. {pull}11982[11982] -- Fixed RabbitMQ `queue` metricset gathering when `consumer_utilisation` is set empty at the metrics source {pull}12089[12089] -- Fix direction of incoming IPv6 sockets. {pull}12248[12248] -- Refactored Windows perfmon metricset: replaced method to retrieve counter paths with PdhExpandWildCardPathW, separated code by responsibility, removed unused functions {pull}12212[12212] -- Validate that kibana/status metricset cannot be used when xpack is enabled. {pull}12264[12264] -- Ignore prometheus metrics when their values are NaN or Inf. {pull}12084[12084] {issue}10849[10849] -- In the kibana/stats metricset, only log error (don't also index it) if xpack is enabled. {pull}12265[12265] -- Fix an issue listing all processes when run under Windows as a non-privileged user. {issue}12301[12301] {pull}12475[12475] -- The `elasticsearch/index_summary` metricset gracefully handles an empty Elasticsearch cluster when `xpack.enabled: true` is set. {pull}12489[12489] {issue}12487[12487] -- When TLS is configured for the http metricset and a `certificate_authorities` is configured we now default to `required` for the `client_authentication`. {pull}12584[12584] -- Reuse connections in PostgreSQL metricsets. {issue}12504[12504] {pull}12603[12603] -- PdhExpandWildCardPathW will not expand counter paths in 32 bit windows systems, workaround will use a different function. {issue}12590[12590] {pull}12622[12622] -- In the elasticsearch/node_stats metricset, if xpack is enabled, make parsing of ES node load average optional as ES on Windows doesn't report load average. {pull}12866[12866] -- Ramdisk is not filtered out when collecting disk performance counters in diskio metricset {issue}12814[12814] {pull}12829[12829] -- Fix incoherent behaviour in redis key metricset when keyspace is specified both in host URL and key pattern {pull}12913[12913] -- Fix connections leak in redis module {pull}12914[12914] {pull}12950[12950] -- Fix wrong uptime reporting by system/uptime metricset under Windows. {pull}12915[12915] -- Print errors that were being omitted in vSphere metricsets. {pull}12816[12816] -- Fix redis key metricset dashboard references to index pattern. {pull}13303[13303] -- Check if fields in DBInstance is nil in rds metricset. {pull}13294[13294] {issue}13037[13037] -- Fix silent failures in kafka and prometheus module. {pull}13353[13353] {issue}13252[13252] -- Fix issue with aws cloudwatch module where dimensions and/or namespaces that contain space are not being parsed correctly {pull}13389[13389] -- Fix panic in Redis Key metricset when collecting information from a removed key. {pull}13426[13426] -- Fix module-level fields in Kubernetes metricsets. {pull}13433[13433] {pull}13544[13544] -- Fix reporting empty events in cloudwatch metricset. {pull}13458[13458] -- Fix `docker.cpu.system.pct` calculation by using the reported number online cpus instead of the number of metrics per cpu. {pull}13691[13691] -- Fix rds metricset dashboard. {pull}13721[13721] -- Ignore prometheus untyped metrics with NaN value. {issue}13750[13750] {pull}13790[13790] -- Change kubernetes.event.message to text. {pull}13964[13964] -- Fix performance counter values for windows/perfmon metricset. {issue}14036[14036] {pull}14039[14039] -- Add FailOnRequired when applying schema and fix metric names in mongodb metrics metricset. {pull}14143[14143] -- Change `server_status_path` default setting for nginx module {issue}13806[13806] {pull}14099[14099] -- Convert increments of 100 nanoseconds/ticks to milliseconds for WriteTime and ReadTime in diskio metricset (Windows) for consistency. {issue}14233[14233] -- Limit some of the error messages to the logs only {issue}14317[14317] {pull}14327[14327] -- Convert indexed ms-since-epoch timestamp fields in `elasticsearch/ml_job` metricset to ints from float64s. {issue}14220[14220] {pull}14222[14222] -- Fix ARN parsing function to work for ELB ARNs. {pull}14316[14316] -- Update azure configuration example. {issue}14224[14224] -- Fix cloudwatch metricset with names and dimensions in config. {issue}14376[14376] {pull}14391[14391] -- Fix marshaling of ms-since-epoch values in `elasticsearch/cluster_stats` metricset. {pull}14378[14378] -- Fix checking tagsFilter using length in cloudwatch metricset. {pull}14525[14525] -- Log bulk failures from bulk API requests to monitoring cluster. {issue}14303[14303] {pull}14356[14356] -- Fixed bug with `elasticsearch/cluster_stats` metricset not recording license expiration date correctly. {issue}14541[14541] {pull}14591[14591] -- Fix regular expression to detect instance name in perfmon metricset. {issue}14273[14273] {pull}14666[14666] -- Vshpere module splits `virtualmachine.host` into `virtualmachine.host.id` and `virtualmachine.host.hostname`. {issue}7187[7187] {pull}7213[7213] -- Fixed bug with `elasticsearch/cluster_stats` metricset not recording license ID in the correct field. {pull}14592[14592] -- Fix perfmon expanding counter path/adding counter to query when OS language is not english. {issue}14684[14684] {pull}14800[14800] -- Add extra check on `ignore_non_existent_counters` flag if the PdhExpandWildCardPathW returns no errors but does not expand the counter path successfully in windows/perfmon metricset. {pull}14797[14797] -- Fix rds metricset from reporting same values for different instances. {pull}14702[14702] -- Closing handler after verifying the registry key in diskio metricset. {issue}14683[14683] {pull}14759[14759] -- Fix docker network stats when multiple interfaces are configured. {issue}14586[14586] {pull}14825[14825] -- Fix ListMetrics pagination in aws module. {issue}14926[14926] {pull}14942[14942] -- Fix CPU count in docker/cpu in cases where no `online_cpus` are reported {pull}15070[15070] -- Fix mixed modules loading standard and light metricsets {pull}15011[15011] -- Fix `docker.container.size` fields values {issue}14979[14979] {pull}15224[15224] -- Make `kibana` module more resilient to Kibana unavailability. {issue}15258[15258] {pull}15270[15270] -- Fix panic exception with some unicode strings in perfmon metricset. {issue}15264[15264] -- Make `logstash` module more resilient to Logstash unavailability. {issue}15276[15276] {pull}15306[15306] -- Add username/password in Metricbeat autodiscover hints {pull}15349[15349] *Packetbeat* -- Prevent duplicate packet loss error messages in HTTP events. {pull}10709[10709] -- Fixed a memory leak when using process monitoring under Windows. {pull}12100[12100] -- Improved debug logging efficiency in PGQSL module. {issue}12150[12150] -- Limit memory usage of Redis replication sessions. {issue}12657[12657] -- Fix parsing the extended RCODE in the DNS parser. {pull}12805[12805] -- Fix parsing of the HTTP host header when it contains a port or an IPv6 address. {pull}14215[14215] *Winlogbeat* -- Fix data race affecting config validation at startup. {issue}13005[13005] -- Set host.name to computername in Windows event logs & sysmon. Requires {pull}14407[14407] in libbeat to work {issue}13706[13706] *Functionbeat* -- Fix function name reference for Kinesis streams in CloudFormation templates {pull}11646[11646] -- Fix Cloudwatch logs timestamp to use timestamp of the log record instead of when the record was processed {pull}13291[13291] -- Look for the keystore under the correct path. {pull}13332[13332] ==== Added *Affecting all Beats* -- Add a friendly log message when a request to docker has exceeded the deadline. {pull}15336[15336] -- Decouple Debug logging from fail_on_error logic for rename, copy, truncate processors {pull}12451[12451] -- Add an option to append to existing logs rather than always rotate on start. {pull}11953[11953] -- Add `network` condition to processors for matching IP addresses against CIDRs. {pull}10743[10743] -- Add if/then/else support to processors. {pull}10744[10744] -- Add `community_id` processor for computing network flow hashes. {pull}10745[10745] -- Add output test to kafka output {pull}10834[10834] -- Gracefully shut down on SIGHUP {pull}10704[10704] -- New processor: `copy_fields`. {pull}11303[11303] -- Add `error.message` to events when `fail_on_error` is set in `rename` and `copy_fields` processors. {pull}11303[11303] -- New processor: `truncate_fields`. {pull}11297[11297] -- Allow a beat to ship monitoring data directly to an Elasticsearch monitoring cluster. {pull}9260[9260] -- Updated go-seccomp-bpf library to v1.1.0 which updates syscall lists for Linux v5.0. {pull}11394[11394] -- Add `add_observer_metadata` processor. {pull}11394[11394] -- Add `decode_csv_fields` processor. {pull}11753[11753] -- Add `convert` processor for converting data types of fields. {issue}8124[8124] {pull}11686[11686] -- New `extract_array` processor. {pull}11761[11761] -- Add number of goroutines to reported metrics. {pull}12135[12135] -- Add `proxy_disable` output flag to explicitly ignore proxy environment variables. {issue}11713[11713] {pull}12243[12243] -- Processor `add_cloud_metadata` adds fields `cloud.account.id` and `cloud.image.id` for AWS EC2. {pull}12307[12307] -- Add configurable bulk_flush_frequency in kafka output. {pull}12254[12254] -- Add `decode_base64_field` processor for decoding base64 field. {pull}11914[11914] -- Add support for reading the `network.iana_number` field by default to the community_id processor. {pull}12701[12701] -- Add aws overview dashboard. {issue}11007[11007] {pull}12175[12175] -- Add `decompress_gzip_field` processor. {pull}12733[12733] -- Add `timestamp` processor for parsing time fields. {pull}12699[12699] -- Fail with error when autodiscover providers have no defined configs. {pull}13078[13078] -- Add a check so alias creation explicitely fails if there is an index with the same name. {pull}13070[13070] -- Update kubernetes watcher to use official client-go libraries. {pull}13051[13051] -- Add support for unix epoch time values in the `timestamp` processor. {pull}13319[13319] -- add_host_metadata is now GA. {pull}13148[13148] -- Add an `ignore_missing` configuration option the `drop_fields` processor. {pull}13318[13318] -- add_host_metadata is no GA. {pull}13148[13148] -- Add `registered_domain` processor for deriving the registered domain from a given FQDN. {pull}13326[13326] -- Add support for RFC3339 time zone offsets in JSON output. {pull}13227[13227] -- Add autodetection mode for add_docker_metadata and enable it by default in included configuration files{pull}13374[13374] -- Added `monitoring.cluster_uuid` setting to associate Beat data with specified ES cluster in Stack Monitoring UI. {pull}13182[13182] -- Add autodetection mode for add_kubernetes_metadata and enable it by default in included configuration files. {pull}13473[13473] -- Add `providers` setting to `add_cloud_metadata` processor. {pull}13812[13812] -- Use less restrictive API to check if template exists. {pull}13847[13847] -- Do not check for alias when setup.ilm.check_exists is false. {pull}13848[13848] -- Add support for numeric time zone offsets in timestamp processor. {pull}13902[13902] -- Add condition to the config file template for add_kubernetes_metadata {pull}14056[14056] -- Marking Central Management deprecated. {pull}14018[14018] -- Add `keep_null` setting to allow Beats to publish null values in events. {issue}5522[5522] {pull}13928[13928] -- Add shared_credential_file option in aws related config for specifying credential file directory. {issue}14157[14157] {pull}14178[14178] -- GA the `script` processor. {pull}14325[14325] -- Add `fingerprint` processor. {issue}11173[11173] {pull}14205[14205] -- Add support for API keys in Elasticsearch outputs. {pull}14324[14324] -- Ensure that init containers are no longer tailed after they stop {pull}14394[14394] -- Add consumer_lag in Kafka consumergroup metricset {pull}14822[14822] -- Make use of consumer_lag in Kafka dashboard {pull}14863[14863] -- Refactor kubernetes autodiscover to enable different resource based discovery {pull}14738[14738] -- Add `add_id` processor. {pull}14524[14524] -- Enable TLS 1.3 in all beats. {pull}12973[12973] -- Enable DEP (Data Execution Protection) for Windows packages. {pull}15149[15149] -- Spooling to disk creates a lockfile on each platform. {pull}15338[15338] -- Fingerprint processor adds a new xxhash hashing algorithm {pull}15418[15418] *Auditbeat* -- Auditd module: Add `event.outcome` and `event.type` for ECS. {pull}11432[11432] -- Process: Add file hash of process executable. {pull}11722[11722] -- Socket: Add network.transport and network.community_id. {pull}12231[12231] -- Host: Fill top-level host fields. {pull}12259[12259] -- Socket: Add DNS enrichment. {pull}14004[14004] *Filebeat* -- Add more info to message logged when a duplicated symlink file is found {pull}10845[10845] -- Add option to configure docker input with paths {pull}10687[10687] -- Add Netflow module to enrich flow events with geoip data. {pull}10877[10877] -- Set `event.category: network_traffic` for Suricata. {pull}10882[10882] -- Allow custom default settings with autodiscover (for example, use of CRI paths for logs). {pull}12193[12193] -- Allow to disable hints based autodiscover default behavior (fetching all logs). {pull}12193[12193] -- Change Suricata module pipeline to handle `destination.domain` being set if a reverse DNS processor is used. {issue}10510[10510] -- Add the `network.community_id` flow identifier to field to the IPTables, Suricata, and Zeek modules. {pull}11005[11005] -- New Filebeat coredns module to ingest coredns logs. It supports both native coredns deployment and coredns deployment in kubernetes. {pull}11200[11200] -- New module for Cisco ASA logs. {issue}9200[9200] {pull}11171[11171] -- Added support for Cisco ASA fields to the netflow input. {pull}11201[11201] -- Configurable line terminator. {pull}11015[11015] -- Add Filebeat envoyproxy module. {pull}11700[11700] -- Add apache2(httpd) log path (`/var/log/httpd`) to make apache2 module work out of the box on Redhat-family OSes. {issue}11887[11887] {pull}11888[11888] -- Add support to new MongoDB additional diagnostic information {pull}11952[11952] -- New module `panw` for Palo Alto Networks PAN-OS logs. {pull}11999[11999] -- Add RabbitMQ module. {pull}12032[12032] -- Add new `container` input. {pull}12162[12162] -- Add timeouts on communication with docker daemon. {pull}12310[12310] -- `container` and `docker` inputs now support reading of labels and env vars written by docker JSON file logging driver. {issue}8358[8358] -- Add specific date processor to convert timezones so same pipeline can be used when convert_timezone is enabled or disabled. {pull}12253[12253] -- Add MSSQL module {pull}12079[12079] -- Add ISO8601 date parsing support for system module. {pull}12568[12568] {pull}12578[12579] -- Update Kubernetes deployment manifest to use `container` input. {pull}12632[12632] -- Use correct OS path separator in `add_kubernetes_metadata` to support Windows nodes. {pull}9205[9205] -- Add support for virtual host in Apache access logs {pull}12778[12778] -- Add support for client addresses with port in Apache error logs {pull}12695[12695] -- Add `google-pubsub` input type for consuming messages from a Google Cloud Pub/Sub topic subscription. {pull}12746[12746] -- Add module for ingesting Cisco IOS logs over syslog. {pull}12748[12748] -- Add module for ingesting Google Cloud VPC flow logs. {pull}12747[12747] -- Report host metadata for Filebeat logs in Kubernetes. {pull}12790[12790] -- Add netflow dashboards based on Logstash netflow. {pull}12857[12857] -- Parse more fields from Elasticsearch slowlogs. {pull}11939[11939] -- Update module pipelines to enrich events with autonomous system fields. {pull}13036[13036] -- Add module for ingesting IBM MQ logs. {pull}8782[8782] -- Add S3 input to retrieve logs from AWS S3 buckets. {pull}12640[12640] {issue}12582[12582] -- Add aws module s3access metricset. {pull}13170[13170] {issue}12880[12880] -- Update Suricata module to populate ECS DNS fields and handle EVE DNS version 2. {issue}13320[13320] {pull}13329[13329] -- Update PAN-OS fileset to use the ECS NAT fields. {issue}13320[13320] {pull}13330[13330] -- Add fields to the Zeek DNS fileset for ECS DNS. {issue}13320[13320] {pull}13324[13324] -- Add container image in Kubernetes metadata {pull}13356[13356] {issue}12688[12688] -- Add timezone information to apache error fileset. {issue}12772[12772] {pull}13304[13304] -- Add module for ingesting Cisco FTD logs over syslog. {pull}13286[13286] -- Update CoreDNS module to populate ECS DNS fields. {issue}13320[13320] {pull}13505[13505] -- Parse query steps in PostgreSQL slowlogs. {issue}13496[13496] {pull}13701[13701] -- Add filebeat azure module with activitylogs, auditlogs, signinlogs filesets. {pull}13776[13776] {pull}14033[14033] -- Add support to set the document id in the json reader. {pull}5844[5844] -- Add input httpjson. {issue}13545[13545] {pull}13546[13546] -- Filebeat Netflow input: Remove beta label. {pull}13858[13858] -- Remove `event.timezone` from events that don't need it in some modules that support log formats with and without timezones. {pull}13918[13918] -- Add ExpandEventListFromField config option in the kafka input. {pull}13965[13965] -- Add ELB fileset to AWS module. {pull}14020[14020] -- Add module for MISP (Malware Information Sharing Platform). {pull}13805[13805] -- Add `source.bytes` and `source.packets` for uni-directional netflow events. {pull}14111[14111] -- Add support for gzipped files in S3 input. {pull}13980[13980] -- Add support for all the ObjectCreated events in S3 input. {pull}14077[14077] -- Add Kibana Dashboard for MISP module. {pull}14147[14147] -- Add JSON options to autodiscover hints {pull}14208[14208] -- Add more filesets to Zeek module. {pull}14150[14150] -- Add `index` option to all inputs to directly set a per-input index value. {pull}14010[14010] -- Remove beta flag for some filebeat modules. {pull}14374[14374] -- Add support for http hostname in nginx filebeat module. {pull}14505[14505] -- Add attack_pattern_kql field to MISP threat indicators. {pull}14470[14470] -- Add fileset to the Zeek module for the intel.log. {pull}14404[14404] -- Add vpc flow log fileset to AWS module. {issue}13880[13880] {pull}14345[14345] -- New fileset googlecloud/firewall for ingesting Google Cloud Firewall logs. {pull}14553[14553] -- Add document for Filebeat input httpjson. {pull}14602[14602] -- Add more configuration options to the Netflow module. {pull}14628{14628} -- Add dashboards to the CEF module (ported from the Logstash ArcSight module). -- Add dashboards to the CEF module (ported from the Logstash ArcSight module). {pull}14342[14342] -- Fix timezone parsing in haproxy pipeline. {pull}14755[14755] -- Add module for ActiveMQ. {pull}14840[14840] -- Add dashboards for the ActiveMQ Filebeat module. {pull}14880[14880] -- Add STAN Metricbeat module. {pull}14839[14839] -- Add new fileset googlecloud/audit for ingesting Google Cloud Audit logs. {pull}15200[15200] -- Add expand_event_list_from_field support in s3 input for reading json format AWS logs. {issue}15357[15357] {pull}15370[15370] -- Add azure-eventhub input which will use the azure eventhub go sdk. {issue}14092[14092] {pull}14882[14882] -- Expose more metrics of harvesters (e.g. `read_offset`, `start_time`). {pull}13395[13395] -- Integrate the azure-eventhub with filebeat azure module (replace the kafka input). {pull}15480[15480] -- Include log.source.address for unparseable syslog messages. {issue}13268[13268] {pull}15453[15453] -- Release aws elb fileset as GA. {pull}15426[15426] {issue}15380[15380] -- Release aws s3access fileset to GA. {pull}15431[15431] {issue}15430[15430] -- Add cloudtrail fileset to AWS module. {issue}14657[14657] {pull}15227[15227] *Heartbeat* -- Add non-privileged icmp on linux and darwin(mac). {pull}13795[13795] {issue}11498[11498] -- Enable `add_observer_metadata` processor in default config. {pull}11394[11394] -- Record HTTP body metadata and optionally contents in `http.response.body.*` fields. {pull}13022[13022] -- Add `monitor.timespan` field for optimized queries in kibana. {pull}13672[13672] -- Allow `hosts` to be used to configure http monitors {pull}13703[13703] -- google-pubsub input: ACK pub/sub message when acknowledged by publisher. {issue}13346[13346] {pull}14715[14715] -- Remove Beta label from google-pubsub input. {issue}13346[13346] {pull}14715[14715] *Journalbeat* -- Add `index` option to all inputs to directly set a per-input index value. {issue}15063[15063] {pull}15071[15071] *Metricbeat* -- Add AWS SQS metricset. {pull}10684[10684] {issue}10053[10053] -- Add AWS s3_request metricset. {pull}10949[10949] {issue}10055[10055] -- Add s3_daily_storage metricset. {pull}10940[10940] {issue}10055[10055] -- Add `coredns` metricbeat module. {pull}10585[10585] -- Add SSL support for Metricbeat HTTP server. {pull}11482[11482] {issue}11457[11457] -- The `elasticsearch.index` metricset (with `xpack.enabled: true`) now collects `refresh.external_total_time_in_millis` fields from Elasticsearch. {pull}11616[11616] -- Allow module configurations to have variants {pull}9118[9118] -- Add `timeseries.instance` field calculation. {pull}10293[10293] -- Added new disk states and raid level to the system/raid metricset. {pull}11613[11613] -- Added `path_name` and `start_name` to service metricset on windows module {issue}8364[8364] {pull}11877[11877] -- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878] -- Add AWS cloudwatch metricset. {pull}11798[11798] {issue}11734[11734] -- Add `regions` in aws module config to specify target regions for querying cloudwatch metrics. {issue}11932[11932] {pull}11956[11956] -- Keep `etcd` followers members from reporting `leader` metricset events {pull}12004[12004] -- Add overview dashboard to Consul module {pull}10665[10665] -- New fields were added in the mysql/status metricset. {pull}12227[12227] -- Add Kubernetes metricset `proxy`. {pull}12312[12312] -- Add Kubernetes proxy dashboard to Kubernetes module {pull}12734[12734] -- Always report Pod UID in the `pod` metricset. {pull}12345[12345] -- Add Vsphere Virtual Machine operating system to `os` field in Vsphere virtualmachine module. {pull}12391[12391] -- Add validation for elasticsearch and kibana modules' metricsets when xpack.enabled is set to true. {pull}12386[12386] -- Add CockroachDB module. {pull}12467[12467] -- Add support for metricbeat modules based on existing modules (a.k.a. light modules) {issue}12270[12270] {pull}12465[12465] -- Add a system/entropy metricset {pull}12450[12450] -- Add kubernetes metricset `controllermanager` {pull}12409[12409] -- Add Kubernetes controller manager dashboard to Kubernetes module {pull}12744[12744] -- Allow redis URL format in redis hosts config. {pull}12408[12408] -- Add tags into ec2 metricset. {issue}[12263]12263 {pull}12372[12372] -- Add metrics to kubernetes apiserver metricset. {pull}12922[12922] -- Add kubernetes metricset `scheduler` {pull}12521[12521] -- Add Kubernetes scheduler dashboard to Kubernetes module {pull}12749[12749] -- Add `beat` module. {pull}12181[12181] {pull}12615[12615] -- Collect tags for cloudwatch metricset in aws module. {issue}[12263]12263 {pull}12480[12480] -- Add AWS RDS metricset. {pull}11620[11620] {issue}10054[10054] -- Add Oracle Module {pull}11890[11890] -- Add Oracle Tablespaces Dashboard {pull}12736[12736] -- Collect client provided name for rabbitmq connection. {issue}12851[12851] {pull}12852[12852] -- Add support to load default aws config file to get credentials. {pull}12727[12727] {issue}12708[12708] -- Add statistic option into cloudwatch metricset. {issue}12370[12370] {pull}12840[12840] -- Add support for kubernetes cronjobs {pull}13001[13001] -- Add cgroup memory stats to docker/memory metricset {pull}12916[12916] -- Add AWS elb metricset. {pull}12952[12952] {issue}11701[11701] -- Add AWS ebs metricset. {pull}13167[13167] {issue}11699[11699] -- Add `metricset.period` field with the configured fetching period. {pull}13242[13242] {issue}12616[12616] -- Add rate metrics for ec2 metricset. {pull}13203[13203] -- Add refresh list of perf counters at every fetch {issue}13091[13091] -- Add Performance metricset to Oracle module {pull}12547[12547] -- Add proc/vmstat data to the system/memory metricset on linux {pull}13322[13322] -- Use DefaultMetaGeneratorConfig in MetadataEnrichers to initialize configurations {pull}13414[13414] -- Add module for statsd. {pull}13109[13109] -- Add support for NATS version 2. {pull}13601[13601] -- Add `docker.cpu.*.norm.pct` metrics for `cpu` metricset of Docker Metricbeat module. {pull}13695[13695] -- Add `instance` label by default when using Prometheus collector. {pull}13737[13737] -- Add azure module. {pull}13196[13196] {pull}13859[13859] {pull}13988[13988] -- Add Apache Tomcat module {pull}13491[13491] -- Add ECS `container.id` and `container.runtime` to kubernetes `state_container` metricset. {pull}13884[13884] -- Add `job` label by default when using Prometheus collector. {pull}13878[13878] -- Add `state_resourcequota` metricset for Kubernetes module. {pull}13693[13693] -- Add tags filter in ec2 metricset. {pull}13872[13872] {issue}13145[13145] -- Add cloud.account.id and cloud.account.name into events from aws module. {issue}13551[13551] {pull}13558[13558] -- Add `metrics_path` as known hint for autodiscovery {pull}13996[13996] -- Leverage KUBECONFIG when creating k8s client. {pull}13916[13916] -- Add ability to filter by tags for cloudwatch metricset. {pull}13758[13758] {issue}13145[13145] -- Release cloudwatch, s3_daily_storage, s3_request, sqs and rds metricset as GA. {pull}14114[14114] {issue}14059[14059] -- Add Oracle overview dashboard {pull}14021[14021] -- Release CoreDNS module as GA. {pull}14308[14308] -- Release CouchDB module as GA. {pull}14300[14300] -- Add `elasticsearch/enrich` metricset. {pull}14243[14243] {issue}14221[14221] -- Add support for Application ELB and Network ELB. {pull}14123[14123] {issue}13538[13538] {issue}13539[13539] -- Release aws ebs metricset as GA. {pull}14312[14312] {issue}14060[14060] -- Add `connection.state` field for RabbitMQ module. {pull}13981[13981] -- Add more TCP states to Metricbeat system socket_summary. {pull}14347[14347] -- Add Kafka JMX metricsets. {pull}14330[14330] -- Add metrics to envoyproxy server metricset and support for envoy proxy 1.12. {pull}14416[14416] {issue}13642[13642] -- Release kubernetes modules `controllermanager`, `scheduler`, `proxy`, `state_cronjob` and `state_resourcequota` as GA. {pull}14584[14584] -- Add module for ActiveMQ. {pull}14580[14580] -- Enable script processor. {pull}14711[14711] -- Enable wildcard for cloudwatch metricset namespace. {pull}14971[14971] {issue}14965[14965] -- Add `kube-state-metrics` `state_service` metrics for kubernetes module. {pull}14794[14794] -- Add `kube-state-metrics` `state_persistentvolume` metrics for kubernetes module. {pull}14859[14859] -- Add `kube-state-metrics` `state_persistentvolumeclaim` metrics for kubernetes module. {pull}15066[15066] -- Add usage metricset in aws modules. {pull}14925[14925] {issue}14935[14935] -- Add billing metricset in aws modules. {pull}14801[14801] {issue}14934[14934] -- Add AWS SNS metricset. {pull}14946[14946] -- Add overview dashboard for AWS SNS module {pull}14977[14977] -- Add `index` option to all modules to specify a module-specific output index. {pull}15100[15100] -- Add a `system/service` metricset for systemd data. {pull}14206[14206] -- Expand data for the `system/memory` metricset {pull}15492[15492] -- Add azure `storage` metricset in order to retrieve metric values for storage accounts. {issue}14548[14548] {pull}15342[15342] -- Add cost warnings for the azure module. {pull}15356[15356] -- Add DynamoDB AWS Metricbeat light module {pull}15097[15097] -- Release elb module as GA. {pull}15485[15485] -- Add a `system/network_summary` metricset {pull}15196[15196] -- Add IBM MQ light-weight Metricbeat module {pull}15301[15301] *Packetbeat* -- Update DNS protocol plugin to produce events with ECS fields for DNS. {issue}13320[13320] {pull}13354[13354] *Functionbeat* -- New options to configure roles and VPC. {pull}11779[11779] -- Export automation templates used to create functions. {pull}11923[11923] -- Configurable Amazon endpoint. {pull}12369[12369] -- Add timeout option to reference configuration. {pull}13351[13351] -- Configurable tags for Lambda functions. {pull}13352[13352] -- Add input for Cloudwatch logs through Kinesis. {pull}13317[13317] -- Enable Logstash output. {pull}13345[13345] -- Make `bulk_max_size` configurable in outputs. {pull}13493[13493] -- Add `index` option to all functions to directly set a per-function index value. {issue}15064[15064] {pull}15101[15101] -- Add monitoring info about triggered functions. {pull}14876[14876] -- Add Google Cloud Platform support. {pull}13598[13598] *Winlogbeat* -- Add support for reading from .evtx files. {issue}4450[4450] -- Add support for event ID 4634 and 4647 to the Security module. {pull}12906[12906] -- Add `network.community_id` to Sysmon network events (event ID 3). {pull}13034[13034] -- Add `event.module` to Winlogbeat modules. {pull}13047[13047] -- Add `event.category: process` and `event.type: process_start/process_end` to Sysmon process events (event ID 1 and 5). {pull}13047[13047] -- Add support for event ID 4672 to the Security module. {pull}12975[12975] -- Add support for event ID 22 (DNS query) to the Sysmon module. {pull}12960[12960] -- Add certain winlog.event_data.* fields to the index template. {issue}13700[13700] {pull}13704[13704] -- Fill `event.provider`. {pull}13937[13937] -- Add support for user management events to the Security module. {pull}13530[13530] -- GA the Winlogbeat `sysmon` module. {pull}14326[14326] -- Add support for event ID 4688 & 4689 (Process create & exit) to the Security module. {issue}14038[14038] ==== Deprecated @@ -645,8 +97,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Filebeat* -- `docker` input is deprecated in favour `container`. {pull}12162[12162] -- `postgresql.log.timestamp` field is deprecated in favour of `@timestamp`. {pull}12338[12338] *Heartbeat* @@ -654,7 +104,6 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Metricbeat* -- `kubernetes.container.id` field for `state_container` is deprecated in favour of ECS `container.id` and `container.runtime`. {pull}13884[13884] *Packetbeat* diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index 290369a6363..19d710515e9 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -8,6 +8,15 @@ This section summarizes the changes in each release. Also read <> for more detail about changes that affect upgrade. +* <> +* <> +* <> +* <> +* <> +* <> +* <> +* <> +* <> * <> * <> * <> @@ -18,6 +27,9 @@ upgrade. * <> * <> * <> +* <> +* <> +* <> * <> * <> * <> From 9c1e3a68039395b22d456087be3b3a91ec223a4c Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Fri, 17 Jan 2020 07:46:17 -0700 Subject: [PATCH 13/37] [Metricbeat] Add lambda metricset in aws module (#15260) * Add lambda metricset --- CHANGELOG.next.asciidoc | 94 +++ metricbeat/docs/fields.asciidoc | 6 + .../images/metricbeat-aws-lambda-overview.png | Bin 0 -> 507498 bytes metricbeat/docs/modules/aws.asciidoc | 16 +- metricbeat/docs/modules/aws/lambda.asciidoc | 24 + metricbeat/docs/modules_list.asciidoc | 3 +- x-pack/metricbeat/module/aws/_meta/config.yml | 4 +- .../metricbeat/module/aws/_meta/docs.asciidoc | 12 +- .../Metricbeat-aws-lambda-overview.json | 654 ++++++++++++++++++ x-pack/metricbeat/module/aws/fields.go | 2 +- .../module/aws/lambda/_meta/data.json | 48 ++ .../module/aws/lambda/_meta/docs.asciidoc | 55 ++ .../module/aws/lambda/_meta/fields.yml | 6 + .../aws/lambda/lambda_integration_test.go | 24 + .../module/aws/lambda/lambda_test.go | 21 + .../metricbeat/module/aws/lambda/manifest.yml | 20 + x-pack/metricbeat/module/aws/module.yml | 1 + x-pack/metricbeat/modules.d/aws.yml.disabled | 4 +- 18 files changed, 982 insertions(+), 12 deletions(-) create mode 100644 metricbeat/docs/images/metricbeat-aws-lambda-overview.png create mode 100644 metricbeat/docs/modules/aws/lambda.asciidoc create mode 100644 x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json create mode 100644 x-pack/metricbeat/module/aws/lambda/_meta/data.json create mode 100644 x-pack/metricbeat/module/aws/lambda/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/aws/lambda/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/aws/lambda/lambda_integration_test.go create mode 100644 x-pack/metricbeat/module/aws/lambda/lambda_test.go create mode 100644 x-pack/metricbeat/module/aws/lambda/manifest.yml diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 2974adb6239..e166e9d6e47 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -82,6 +82,100 @@ TLS or Beats that accept connections over TLS and validate client certificates. *Metricbeat* +- Add AWS SQS metricset. {pull}10684[10684] {issue}10053[10053] +- Add AWS s3_request metricset. {pull}10949[10949] {issue}10055[10055] +- Add s3_daily_storage metricset. {pull}10940[10940] {issue}10055[10055] +- Add `coredns` metricbeat module. {pull}10585[10585] +- Add SSL support for Metricbeat HTTP server. {pull}11482[11482] {issue}11457[11457] +- The `elasticsearch.index` metricset (with `xpack.enabled: true`) now collects `refresh.external_total_time_in_millis` fields from Elasticsearch. {pull}11616[11616] +- Allow module configurations to have variants {pull}9118[9118] +- Add `timeseries.instance` field calculation. {pull}10293[10293] +- Added new disk states and raid level to the system/raid metricset. {pull}11613[11613] +- Added `path_name` and `start_name` to service metricset on windows module {issue}8364[8364] {pull}11877[11877] +- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878] +- Add AWS cloudwatch metricset. {pull}11798[11798] {issue}11734[11734] +- Add `regions` in aws module config to specify target regions for querying cloudwatch metrics. {issue}11932[11932] {pull}11956[11956] +- Keep `etcd` followers members from reporting `leader` metricset events {pull}12004[12004] +- Add overview dashboard to Consul module {pull}10665[10665] +- New fields were added in the mysql/status metricset. {pull}12227[12227] +- Add Kubernetes metricset `proxy`. {pull}12312[12312] +- Add Kubernetes proxy dashboard to Kubernetes module {pull}12734[12734] +- Always report Pod UID in the `pod` metricset. {pull}12345[12345] +- Add Vsphere Virtual Machine operating system to `os` field in Vsphere virtualmachine module. {pull}12391[12391] +- Add validation for elasticsearch and kibana modules' metricsets when xpack.enabled is set to true. {pull}12386[12386] +- Add CockroachDB module. {pull}12467[12467] +- Add support for metricbeat modules based on existing modules (a.k.a. light modules) {issue}12270[12270] {pull}12465[12465] +- Add a system/entropy metricset {pull}12450[12450] +- Add kubernetes metricset `controllermanager` {pull}12409[12409] +- Add Kubernetes controller manager dashboard to Kubernetes module {pull}12744[12744] +- Allow redis URL format in redis hosts config. {pull}12408[12408] +- Add tags into ec2 metricset. {issue}[12263]12263 {pull}12372[12372] +- Add metrics to kubernetes apiserver metricset. {pull}12922[12922] +- Add kubernetes metricset `scheduler` {pull}12521[12521] +- Add Kubernetes scheduler dashboard to Kubernetes module {pull}12749[12749] +- Add `beat` module. {pull}12181[12181] {pull}12615[12615] +- Collect tags for cloudwatch metricset in aws module. {issue}[12263]12263 {pull}12480[12480] +- Add AWS RDS metricset. {pull}11620[11620] {issue}10054[10054] +- Add Oracle Module {pull}11890[11890] +- Add Oracle Tablespaces Dashboard {pull}12736[12736] +- Collect client provided name for rabbitmq connection. {issue}12851[12851] {pull}12852[12852] +- Add support to load default aws config file to get credentials. {pull}12727[12727] {issue}12708[12708] +- Add statistic option into cloudwatch metricset. {issue}12370[12370] {pull}12840[12840] +- Add support for kubernetes cronjobs {pull}13001[13001] +- Add cgroup memory stats to docker/memory metricset {pull}12916[12916] +- Add AWS elb metricset. {pull}12952[12952] {issue}11701[11701] +- Add AWS ebs metricset. {pull}13167[13167] {issue}11699[11699] +- Add `metricset.period` field with the configured fetching period. {pull}13242[13242] {issue}12616[12616] +- Add rate metrics for ec2 metricset. {pull}13203[13203] +- Add refresh list of perf counters at every fetch {issue}13091[13091] +- Add Performance metricset to Oracle module {pull}12547[12547] +- Add proc/vmstat data to the system/memory metricset on linux {pull}13322[13322] +- Use DefaultMetaGeneratorConfig in MetadataEnrichers to initialize configurations {pull}13414[13414] +- Add module for statsd. {pull}13109[13109] +- Add support for NATS version 2. {pull}13601[13601] +- Add `docker.cpu.*.norm.pct` metrics for `cpu` metricset of Docker Metricbeat module. {pull}13695[13695] +- Add `instance` label by default when using Prometheus collector. {pull}13737[13737] +- Add azure module. {pull}13196[13196] {pull}13859[13859] {pull}13988[13988] +- Add Apache Tomcat module {pull}13491[13491] +- Add ECS `container.id` and `container.runtime` to kubernetes `state_container` metricset. {pull}13884[13884] +- Add `job` label by default when using Prometheus collector. {pull}13878[13878] +- Add `state_resourcequota` metricset for Kubernetes module. {pull}13693[13693] +- Add tags filter in ec2 metricset. {pull}13872[13872] {issue}13145[13145] +- Add cloud.account.id and cloud.account.name into events from aws module. {issue}13551[13551] {pull}13558[13558] +- Add `metrics_path` as known hint for autodiscovery {pull}13996[13996] +- Leverage KUBECONFIG when creating k8s client. {pull}13916[13916] +- Add ability to filter by tags for cloudwatch metricset. {pull}13758[13758] {issue}13145[13145] +- Release cloudwatch, s3_daily_storage, s3_request, sqs and rds metricset as GA. {pull}14114[14114] {issue}14059[14059] +- Add Oracle overview dashboard {pull}14021[14021] +- Release CoreDNS module as GA. {pull}14308[14308] +- Release CouchDB module as GA. {pull}14300[14300] +- Add `elasticsearch/enrich` metricset. {pull}14243[14243] {issue}14221[14221] +- Add support for Application ELB and Network ELB. {pull}14123[14123] {issue}13538[13538] {issue}13539[13539] +- Release aws ebs metricset as GA. {pull}14312[14312] {issue}14060[14060] +- Add `connection.state` field for RabbitMQ module. {pull}13981[13981] +- Add more TCP states to Metricbeat system socket_summary. {pull}14347[14347] +- Add Kafka JMX metricsets. {pull}14330[14330] +- Add metrics to envoyproxy server metricset and support for envoy proxy 1.12. {pull}14416[14416] {issue}13642[13642] +- Release kubernetes modules `controllermanager`, `scheduler`, `proxy`, `state_cronjob` and `state_resourcequota` as GA. {pull}14584[14584] +- Add module for ActiveMQ. {pull}14580[14580] +- Enable script processor. {pull}14711[14711] +- Enable wildcard for cloudwatch metricset namespace. {pull}14971[14971] {issue}14965[14965] +- Add `kube-state-metrics` `state_service` metrics for kubernetes module. {pull}14794[14794] +- Add `kube-state-metrics` `state_persistentvolume` metrics for kubernetes module. {pull}14859[14859] +- Add `kube-state-metrics` `state_persistentvolumeclaim` metrics for kubernetes module. {pull}15066[15066] +- Add usage metricset in aws modules. {pull}14925[14925] {issue}14935[14935] +- Add billing metricset in aws modules. {pull}14801[14801] {issue}14934[14934] +- Add AWS SNS metricset. {pull}14946[14946] +- Add overview dashboard for AWS SNS module {pull}14977[14977] +- Add `index` option to all modules to specify a module-specific output index. {pull}15100[15100] +- Add a `system/service` metricset for systemd data. {pull}14206[14206] +- Add lambda metricset in aws module. {pull}15260[15260] +- Expand data for the `system/memory` metricset {pull}15492[15492] +- Add azure `storage` metricset in order to retrieve metric values for storage accounts. {issue}14548[14548] {pull}15342[15342] +- Add cost warnings for the azure module. {pull}15356[15356] +- Add DynamoDB AWS Metricbeat light module {pull}15097[15097] +- Release elb module as GA. {pull}15485[15485] +- Add a `system/network_summary` metricset {pull}15196[15196] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index d16ff59da4a..7d2b1f7f642 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -1738,6 +1738,12 @@ Metrics that returned from Cloudwatch API query. - name: billing `elb` contains the metrics that were scraped from AWS CloudWatch which contains monitoring metrics sent by AWS ELB. release: ga fields: +- name: lambda + type: group + description: > + `lambda` contains the metrics that were scraped from AWS CloudWatch which contains monitoring metrics sent by AWS Lambda. + release: beta + fields: - name: rds type: group description: > diff --git a/metricbeat/docs/images/metricbeat-aws-lambda-overview.png b/metricbeat/docs/images/metricbeat-aws-lambda-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..84a228b51e399407ccd6014ece0858e51cdeca88 GIT binary patch literal 507498 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%0DX>6>ni~kmt4J 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

      (%ocLjuW?nHe7Kn4F8$vw7 z+fm>U+#86XnL#!SJ3dv2!;~1qb1{#%s@mQ;4u5B>4dWpRU+TV0W{{%fctxw?yxhlT za`9E(BgpK0M9z-)3Ig40$%ai!9<{caNa9EWt=%RY4BboYI-y2>;?)Ene+Pg~ObG6Q~S7D#x`~;CUmI0NU z9VF&pCQU2G)x7TS6)zsrIn{6VOujX5gtI`;$WEIDV^Mp=ND0~~HWBemEZg|tK9`YH zS*WEFtsuW#7NI<;$Z4is_DKZHNOmrxS%wjtLlArZex85hu(RK;Fo`jcSD~aP-@xuI z{cMSHw}PJP2#;F9yusWLa4PKTqDV9cM)9GOp^{G)Kl8^NbDPyRuA3~|g0@4bM8)%* ziWnwTtfG>FZ(rg4JrY%)1c_ie&C=@|Ub2eud7BG`O&dQR%k2->>WTyW6O|?{Te#s#4g=py z8@#ZIr4Y8@uDn5|{g>#8^XJ3msYc|hAt3hS6CNgml<9jPsb5&}*;dc9!_IkgRV-aH zWo)Kgew6oL7OWcV*E3x@U0PuGqZ2?Wdf?cq*&q~{CA7^frhY53=q)4Hy{Tz5 ztW^I|kc!R4#btDC^mFYJ{>(;3DAxv_raTf7QnsSclRf*a=%<=iSL~#rXg`A}YGa;w zlv?)#pdc<3c@7=NfKXId$GE5wa#HaDx_ROhcqy{#;v zS=8o2fa*@O!tDh8}%~v z9@>PO55e7y%owCLDnMWXW&$#G4JBYrsZ=T)?a5^w${9VzilFVky z=4MPW&nt5W>e$XI*L0??oU=00yrgC;@RMjluX2q%i2sb#@^L=x(&eYVrv;jQSy#iZ z+RRFC717?sQ7?ENSbB8Zz_!zg!zGiuIj*-}q1vU+tsNbwCv_5}7Y+&McibwkfRkq( zm%QcFnw$#N$zU>u%s*H=4vM#Rns=A2}-8JV)LidDK|HH-U#1o5n+ZD_h$}nP65C$kt$jm?p1fW}tieq>62Az%`ih#oW*iG9n0Gl5!Pm}%rb zd-^c=2du<=bK??T98!H$fm6p$lcH{Gh!vY66EE9*A54yq>EE4?4XW%(Hm$&M16rpF z(%|DbJ=z-317~jrN*<&ek*gSso_tmJJovlogMLdPTZ+iPfm_=o!3>h%Ee{cYRM4l= zxfqM=%NPp^C(F*EcpK(X&k>`(*lnYWY?Qm8!#12i92qA8ZJB&v_t;1UGfAyP;A4f| z#>1aI&yys95Jw3#j@Y83=Hgq|IkUYU&=QaQbSvsRimhn|gImZbjldS4iz>}M^};Z! zMv8zUN$!IE$s@-H)LLYLkHB}OX&>dBX*V9Hus$(U9X|!HnHl%KDxfd=l!x0>lU+&V zQ({lm`T-R>orO8-0h^aE`Z_gUuZ7`q*;@Z3Uc#{|7J7MQnpQ76PxgT0$plh5(LD_) zykb03#X=lW>FW3lW(yz&_Z3*vdDacyn#e1fdikxd2u0^tuQBY3| zz6jy-6CLb35>=ge^Isg{V@V{deaW^BvZj7V7N|wt>+IRlB8%|VEid&F&O^xC*|6!G zXdHp){m(^G-vigFeIK$oGJien)M2RVxmSLa#3rJ57iF9-QbANe^^IZRjXI1_B2 z$<8;GrR=UN;b+fytW+8nqhj@AyBn-t+AT^nm~+~{yPC6=5S>-2n{;-^w^Tb)6Q)*p zDRo^|ux6%N#nz~kfti=e>7|LCUQ0v8&=CZUXbjd@Yi)anqZql>Prn~G?Epo} zYj%WEXSDiEHyY0>P99#2AvYrBagSShY#OaTtZ^^wgQ^(cZOH-Q%HNxH79jR(ES_J3 zfVx%LqK?T^8ta3-&)sNMj5Ta0 z;tFQRBBc!({0lpZgbbub>EaNCODSm`wC~=m99_u zJwB<-3CvlFP_Hag*%naVwo~@?C*tZJ_01*PXjivj*)$ah4@H&)BY0mhX&06!J}~nF zXb)`dKjl-r;YgnNbQ%?we)foQs(uOoaRo_6mHcTUTEg&i_sY>==vJK+CG5ZuXv>oW zLdXu@$O#Q=jC1Kh^omyqc27&QQ}@&d{XCYe_~%;=ULUGr%kmZ z6qZ=V7}Iv*P*Jg3&r}qyfM`CrK~*NJ9~&%319GA{P(2jxm9M!0e)Q6disxdsEDcex zQZ;b^odRBPM4f$3la}RZzw)t;sIPy=${Y|phfZbT{0y4ihra{#y-=HXo;wR0t{th^ zlV4jK;Z*?S4)xo8&>R&MlPlJrzbONjW(Tt@HM+2<)adDiE@Skr4u8_PH$}JLpp+D@ z4mmW@cAQJo@jmLX;n5pGB(B|A0UREj>9zx6oy;`Cc+nt3JJS&UwP=B~3$s83QR99WLG- z-FlOis!qZ0-ZH7{HGPq@u%V?JeJ=QAk zYl+f?y7n%Nc!nK^Zx(p9%QNR&Oz6H>+yJ3pplZKA^dH5nRVDaCPE?Ot-1l;Gv{rJ}qc4MrffOo9eqRzv}@QxQIfn!>YQm!RmPHK}wtyY#lrr+I! zTEP4A_RTxXb9ctZLn-z-rNV4BKzcRse6R&>K!nb`*78Z&cT zO?u^R~>KPwt&SI(kZt#s%Sx;uAyq}2M89Dn{)i=&CGGNGir*0!w} zj;_!5I^Xoek6M|cSy(4m%otznGn+7CVO;&j1z5bjan|ctv~3fi6e}Yw$-_61WmM9g z(0tq_45T*w!!G3Dm?0~}CaW9=Iz2Htm?V9I31Vp&hHP@QC||UfHBDI=6l+8rH+scW zw3A+NT!UFK&*2$1p1#Z126#!Ld^&WBAkB@*4{!=Rc*2I^&dBge2Yy=C!NG9HNpC#wQX{eVo&Y* zm>ep~c4|ADV1GW)hkAuar?_T*mkS~YGH*teuhWqU69xfSmz~QHmFhGPEFp9G>+B7k^#1rv>t!+)#bK0XA|c45TznHi!DVu#d8uaJL#T#s`kTx#I#FjsEJ4VnBG#RtRo0qSU42(Y_#xONO{fcUph>hiZoz_nn5y z^corUs##aBM_^eQ+6yDE2%ZXsrZ53D=mJj%G#*&VF=xI;FBarvjIgj)A^OS*m?N}R z%c#AqL?l1{!_rF?1JK z*tl|bZmt2V3PpFG@IG|~6+lmIyGqC7vK3oXY|q*pPT#lk^O@&#u-4m2n;4>d6A1@y z9%4rU2SBKYU$Zu{ayJ0%pcxmC*Whu|ng!Fn9Bo6OWp?IHog3VUb;yh9~JvauM+ zGM!)kU1ra69IcJ`-bhl`S#;f|1KhTMyy-_l8YCSjnEJ&rh??%U&+T&KP7{~Q?YXmz zu-?y5(s@(hdV~yC{F)zLvRn{(UJbiR>vi8yjZ)cWhS9+v;LIa(mHac7fY)Q`XzaAK zI7;;j034&g(q!iv_Zt4Wh8S35o_d*dGZl%gF8t>+;aagAfE!v`WkBfUJJ7=L*P zKCU|XpbuCno~p-LaDQaoC>>2)uzv_to)ZX$11G?TALEk@tdtN^j2A{$dGjUH2K7aZxJ(?D$Z2o}- z=rzvuG#dXH+qp@ygnX^YQ!eW>sC{zTm&NU9VBzCj&Igry0L&PsTX3ZfQI_}h6`6NG zv9!RjVE>um=KhYxjinP|U_wW#s+>gSSfF+8yQjven5L2_l8t_(&`>Y@+-p!#$)WhYlG9c^j^$)eTnLR2rHjlR#D}|bRwqP5{7H#zd z;Y)?(sRhR_uDy5MY_HFpgP&kq@hU5K8j?;bp3~2|s;Nnp(g`5U74|Q+LeK$_QwFgD zNFC&M{;lLJano*zM>a4;UjA6DU-@Eaa6tVkpf)tFGgLQjG@exk&M@bB zkQsWS2bNmcdbDS%!KyLuvd&;4zl)uxnZGk6kSrsSo~VAfqEvJbB)8qJgkNd*N~x9^ zHC)4i*JHO%Dwt140p+Xf6MSc)8FqQK35M0u>=IZQbcfyU@ZAQFS+X<*KO9cOIRz0n z2{ecgyUl)n`pP$(o#X0atH$43#Pq-v zZ-Mtxjm!BmY>I&jiFD~u z-NU^S0oj=6Z!nWhjWsd3o@b`Ga~SwSJlv)e6Y;V5NJ4D9@awpoC|=8xzY#*Z^90Gl z@M-T@lcGVX0%3`nZq~O?g59J9(HS<7opj6rAcz+SSQoR2REqGr$n_h}xT1EA_e6MtRowX(&UJUFM69YT4 z&81vY)F$8eMHUn!);&gMsl;>PJG9oS)AW#l{F~H7nCZTp5Hl`ZH6DZd;(z+?Q9X}4r4!N z7P`7H3qRPL0;QQwjE^?)Apit7&-cgAoYw!25$WXq^47ihYrr+6o~I^B`PXcE_4XU( zywj`H@2+_q_M9Pd84W~pN#kg(LL)CX(0>Cd{)spIzy7xc`Imggu8bjY_SZC2nv)OL zj6%dq164JZtW`)MH&Nzi&YOOJyc8ag+AbzJ5NDfJ^Q*zy82O12HV&`N@I?&Rw)Vfu z(?aXS%~u_SONV$RU4?!Z%o9+1?WV)X@7GMf!7t=TP#A?a`JK;jAb-6Smf>P zrp4NLLRWx|hN4*aH}#9TP3KOSA(VTu>;aX* z*UTKedgCC1mx{>(j9%s`0M3wT9cPFBA5931a={Ix{qJv%ifq2?t5$nvNmAv+^KZ?b zazXGxb2&#%mLjD?6D%#e|Is8ukvvK1DzTM7lo~b0L51qo?-(?j3h84Ct3H0Tjpk8i zD2mR&e4s{4WEf{csgeLP47T~}hP406Xs-?wjK?6DhmO21-BC(a9l-im1^7$d>q@%e zDe_wVmk9coBD(qD|3MQojSWixSTik)?jywrF^#!zcxPh`(6_(;J*fuZIMyLU`V>dFEhO>A(~RAu>(u0 zfsSqfrW?nyl!{B&S3~6XJ0a+ghYLDY-g(-6_vu*OMAvcttnMv|-g)WT{fZuIofgct z8?RaFvw>Q}9l>uf)Excwr8wU8R!6`)qT%b`%f-8GKn} zG5q7RetGJSPs{F79yzb_qvrf|3b%@;gl8)2IT(BL)qwc%=;r?DFT5v^`_3**J8nS~ zjRT&0kbUF3T|q;LM|Uv)q;{00RS2A5nJBs$atnq_*IEx1{0q&3E+NIWcdpQ~(LxSyksv$(ekX{nLnW zq0*rj{DV%ED(khnN}E1t@v0_Ok7)lny}o+ZvX8ty;P+F5xgQ4>?JbrIr#ZG?p_6?x z@R@*vW1q>2xY|GT^?$nS(ge(I@Lq*H4sU6nM8y}Ce^Sc(J2C0636q z-9P4QOZo_M1pX-Rf2DfyC)SAjKG*QEMGYPWlYjv#$@=pF>NJ+mk~T~i>dOQhwlMx$ptCVKcJ#^ zoxYR-s*CM`n5jlP?L>MB zuRog4H;da9{LOVdGN2;4OYLxeyIF+q<$XbbVO$J!%L38aSDQY=$6|45`+@WJhBhDB z9k}LWKGxF4eZP0f%a=BjH;3oBSAe z@7lX@0YxB&dmpAq0UB%s6iP(zy1YC!hh_IaA1*}~(k%IfXk3oC_C2G(gEeROcTN`7Cx3zvmcbt#~ zSY94k!{Y%DgQ}O8e_UPfY81e%HwQQsfGicnA?tB%DfB;kMSq ztR8#y2UjN8GJ|C3;pt$M60f6Mp7Vau3|KuTeNtriXVxzIc17=X1-;LjLnFL(bUXT` z=KORrASs>;L^yPpp23gE{@L6;scy_&Cg>;3ooA^M73)DvGzCYikQ4e8+U<07jmJ|O zzCiuV=lNJaJUUi?re6EDJH2!)pu7LlDxewnn~SegURxofAv%GpQ(E6v>Uod(yR$!W zs;#gR4o}BYZSd&q--dbI-)RIWrwfBVZ(jg0Hm-L3Od{a4EPEck`sZ2j6aMn>mj6Ed zPtoXq#qwWm`Tx;~5aY9Xc8AZ0E8cM3a4X7D(1PpO88js$0bq(+Pw7b$n=Ch0dR!-P zxoLfPj{f5Q;GXaxm`72_*N>cBz4QYzinujUhlz>`)aZCiu65jz1SeeN;sTz^kmk|9 z^rcZ1^G z+;ApXC!?$U>DR{+m$Kk`;e;)Iw!O7je=ByWYR&iZbWI1!dDvNQTSzL$n1G$ZF2*yxc(R&3GFT`J5Hi=G1Y9RR-Dbzqa=0hE{; zh8WrcJOvh_+0H<~!~buUagit}Hy&P`<)=J6GS-{uPX13{QJT*3cs^`wDP#%CsIq;6 zAfweOeUx&@UtL)Pz5Rvdj93^!jffp&tZ)?#so*vNpf&lkFt6ox7_uzRQpF{xbf;^` z(AFsJ$MhpgdS0?rBg?}n=RWRIU~ys}IwY2zO0;N$g_Nv#UtG<D-G-7<3w<5#dG9;Zf$n-}+Kgt0-qPyjct^Qi4sbvfvWXr`Mu2}k<*1dyC+xzL|o0h`C zlC6}%B0M^}#1|rICCVC^y@ZkLA20CIUWhE!IMct5-{z<7Jx+;Q;7E-f=iz1TRt@jTVcp$ra1_avXIXq@zGGff?`EUXNEefN<>KxWlzREd0k)Ze!HXNclligND!T z0+tHU;%#guC>(b&RV(e|G@9JMtm=>5spV!Xkl1%4mTcw0)W`ln`gA3td9_<$A1o#( z7kSq`ulmEj$WA2T^zg9hz;!@2tPCfJv-Y5ZFi24Rwic7Hl4?REo?3MM|y%LSQ4 zvRb=^G#}=}CwmL0SSw!F=StxuJeGC^>}KO4XhZilsRZUB z0C5H%cx6S1h{VcP<7l%ca38u69e+Va42?lSQG*@f!)YA9bqf$2e;}vZrfL@6TZ3|L zaA-2Ktt@=!&N9N#V7WFRCtHlaQ#(!Nrkw6cy%5jF0l%FAACaA?JKr<$#|_OY0CR+L z>1ol+R6U90kzM-v5Fmq`)9u-86$0HW_3A};X|S{b%UpNHz12VYF~@$p9Vi3zJXm9x za$fgEp3m2L6#3kig8yCS3rw-VGm3*A*Ub;37Y7%PS)rN^pL6!@^1e1GoA&a>VVTsY zHQcBAvXICaR4qr(16+4f5)2d(*V)x4R7U`+QE`}5l&XKxNuQc#?pmVm#9XBSx<4a5 zlig@vAAr^Gsk6}&=X@}Uae6Wmgy*%y;Wje8wmV*wt$WE`Z0{xsd*?L~_LS!}HVHS4 zkB<+t7z);@#dmena4w=hWe;SuSP7TBi}g3eEF5*#Xal}Yi6Yz6)IBKvEaPun0HDfF zvhO3s8Q6HUw*qvzDf#97qO03s;@J#EpoZ3C!;TTqO4;;)a)q^nhT&ii5LP!DvYo3gT0Yk%g6-Uz!bt?4@wpz@p+B5w6r040HOBZ-P3r?>fly5Klx4*jnw^>{0&4t-YB4j^)}*3+#NKW z5NM$aWO&ZD)8Zmzb-o65{lN`@0Tka)dTj=?5;xA~Q1E$qHr4T}WPR-KKHsd6R!Z`z zIU$E|aVj}#*D>hbl%j0eT`yz|47lxvv)EplHsse?^%u-iPYE$=-5wz2>%YkpY7JI& z7O}=Kd)Ki+hnpW*lu4qRK_DR*O-oqM2O8%|);9Ssr4}TTCvqUBzVkDUR9c{PQk

      J@zYXdtObPdmo{}nM=sny>kRxxXLMJ4UhIul z_CJ;~ZEahQedu!4%eHqJer+#k6vr-l4O2fGoYM1~tud~dRo=i3l9h;>QkUUUJWjaK z$2ZYlC=>FgUE1p~2NFA=bG84<`CyE&4TkNvxm=k74A;kWin%lzDz05ZK)V3gk6}b< zqK9@E(SG6ur(L{uK=*LcpdT8J_<0_;sk9d2D!9_>x<-AZ1SyzAd;R?b8pSb;0;PgX z`oN3B2?hP@D?ir-J%LLx({cN|WtKBl!raZ1(pJi4-!+G8_xJH0K6*Kld#R()YJHHu zC|{ywQQZMAN{y#ie|D+mrVek?>om%?%Ui3YNVzmfW;xa-VqL#u!TF%Wi!v&zdcsb} zD-o^Zmu8yZ7Lf87wZJrfgwu-ey=p~qP1JU=i%ciW`PP!@B1{GWH6IQt& zPIWXJSiH^i^>+xQiw0PlQaA+AZBL$X?H40esqq)je9A2VD&AlmJ?(Bbx6%z#;1>n* z^KXR5MZP0}n&$C3jflJKuUW`|x!9BPBNvm4o-cnqd(+VDxWQ-uTyEzgz;0N3QMYZL zGy+=*6U9?)+r#<V7D zJYTh�N=#q4>C4GTKcH1vuJ~e#$IW(ZT>p%|wnl!m}9s9dG&EB2R&D0w6|5xl~AI zm7g9CI?-aMNFH6Z6_cTVOjkSHn9AD-d2MTJ{S9$$h zTilM~z&*p_SA4ebu1^Cz?`02%p)HJ)=5iF@ZLh7l0nPxIw{B`Z^kqaErfNviIbxFp zYn}ok8Q^{diokT^MyDq+gD{U5FKD|zF8Wb;T_yJx7BI%< zy7Oo@otZ|D=jyf_6Y-mWY{~|osk*y25YWt47^RQrI>6s%JC#_T*-4CbW{bzHz^^?D z8jIso(~jmQqFM3~ZsF=wI^SiKi#5iY1bgFX`#x*+ZYInO+H7aopF$GV%@6%6c>5bO7ANl9&=(yO~ap`7#K?RM%c&V==L z4N=jUtmUlc_fz#6j6dysm5JFA2A7lGTmT9BTG17me~~*cns$?Mm6{bPOFmSNISjoZCZMnRLTfeq9f(=8MhfUH{^~(wqszw`CY5~Nu*J6RbSO;` zoKqXAGx?}#edY&Ryh&>NA$)gl>sy4#WeK$H_=tFJB^(JtXYr7f@lIf96zxQ@35MBN z)u(huKiqU3@hl^(GV*VHQ%`*T19BqA%E?TrAHlC(ZJ!+dbGyqHlG_#ORN03V;Iq&| z==~R6waVRJu~7D@c(@CzQ~82c=30*Z`F( zRiug3ByeL@FZDCRaXir4M>2 zVp^Q-2m?P+84d~vINU$uI#T;O;5v=EmlDP2mSTIF?aSKGj+9wrKy&S;Sar*|N;ugZ zsJi{afs_cgMlFOkC2-LrHDPxOZdWi^!it9r<|2QV_VH@tn8JhqeP@aPxZI+L_10bF?2-tJ6|v&YexL+>}bW zE`u#3PpZ?h%Hh1XU??i#m0}&yqj<+S=L}|VaBN39tWYvUz=2dhc3F5@F+Y8=MIS7p z=qv@qaGm?|9Uu%8I^0II@j?lCATWwo1C3{x=j!pAeY^key9@tB$M3mlO z>gwesJpwnQcd&g+A7(0_c=Aa(A>TjH)ceeS!4J^p5`g@de7u?9hoV~DambIwBxi)| zNv5p6?I~rC6x(Q#c{e1$aa9Pqro*(z;vc+zFPtzYq+;BcrfNr(Np7-THQ}HIk@Q_9 zf?gY{=V?HEeHHJSak5xC7|sk`7B))#o&O0zTuSt4g@x-F5@s{%wIe%%*&$Lpa#fqr zHn}qX61kgGfL+z4biQqPQq^I6D@5Yq)LztGYV-?9+-aoE{2fo&hqegj$44!e!xjNI z0=9i7k<=F_Pv&b*jj?LYDx~_Da0ts8ZQmo~W5( zq#;JOmgU_LZ)gz`2Is|`>U2Y|6npB|H5d%ArZWFNmV28B_m-^5(-%^`c;GY62#2Fd zccOL?r$Ob%1z-L^x!-;z1!dRf`7LIYiISTWqk?Xl$= zyJdOY^!QIJS8RUno5;w*U>*6ujnw+1L!ptPqvE>mG_i7pqv?_1FF%?u@Oqi4Yk3Mz z7YUw*_dPE$7TFvL)2|2G>ck#&mZu<7q0}+KiduWBX!nO3jS4isMx*vXSJ_yq-K!^A zl;(hsqp4cPVrw} z8V`)hMspFYzt&~Q;D9u)oFDo~HfU){rz(u54!8>jf;A1KLYoNoSf9}d=BYBdJge$B z+Rq=L;c{oNV+%zM1V z>>@z{0Y)T_@&9oD^G@tP`ev%8E5b&xti!_S#AMF75}@z7H0uk=Py$M%xargfG20U3 z4J{<(=ib{ulpl1*9likB8pdwg)R)K{INx<%UVa z!zDfsGiYLf-j$8>N{oK?&S1XZ0>Uprwf@TxtysrZ2iZ8y{NeMr2M3fNcL4J&Iqmj^ z#Kfg~v2m?XgDQ(?-BedgH!WU{l;G5QI8~eH~rWMv<(+4?98%07Ki88>!!g2F# z66A#ahy{~b#4g<;P{pZC={j!n>tvMpx?WN7Z;}GNjK{Ayg2uQ)Q6*t1mn%B-l3NA5Go?SSwfujFM{o-@BvvaLTr^prWP{jhfNu zr&cB1*w$XK#^O7!0aXjU(VnARYOn^v*9iQLy7`Y7Ie+=C*OlVda^s^g(g%i9x|oW-ouk~n@M_oDS0 zpW?=uSv8B&Wpb=x&lC)lQ0#O`V}~Zd8YUlaIjqD17UTscxNTfaD`*=ug+{Imv2zyb zWR*9JV?rE1G}XTJWiyBgrCLvh@GG6D&I-~#!|s%gG>P+*XJlr(gE~VWYOx#j#MXK3ciZdCIj zU;4Wg)Uxm(?=ZMQUZvJ!%5@})auDK89_0N6>q~hyR?fk%TN7k@#5~+$ms`DXnKf8< zghJeUy%*$7{B`BO8|{A`d;MbaSn=qqi11S7Yw=e1mE!e4=f1FkoJ!``I(<=2z24`M|n+=JiWR5wmWOzx!=0eO)%8Lhny=&*tY zc*%SC`!j=YUf>I!>GJ|3i->LOqWYsc!&_SQK8`igzRPr>*QcNfZXs+G%3<|Tq4A*M zLMSz>74lYB5ls!F$OQjrbAR@1xZc-f5_R;s-JSeeQZ(HIryI=ij>(FJd;g{Jz3uuH zxvs7ceDX7DBACOm3|jtC#)+Eqh1I2Dv|w!FKnGJKBP(wrS=WE`6A+*`UQzmws6c#x zV22cZ(^cY0!#`E#l~BQt!W?%R{MYeOFcJF_?wp`Ppe_kG?C=?Rjg;k-#Qo4lUfXz?`D?tT!MYk|4Cndy!ILX z3&UHb`CBUh027W=p8-b153RtC1uo^O;sM2WcD^V6&wrCm&Sd3f8h1_sStv=K>fT!= zPPh+{vV*N7Seeqh?+)#{LpY_V+Ow{`tflIYmtwnO%=pRHZ;B%dz2Nj z_#%QLRxLX=)P? zpE^*)qsFk$dDb#t%(>*150$Y)bNjgLu72@n$MH?+)ob_J@EN}^PFi7HHdtCmi}j<} zJN&T(TPgzZ;+xGFY`ONe_!@-liWfOMTQE&xZQ5V%5P!;W)iAxpXTR^tQDx^tw2=6`I8y&Q@;$cwucT-s!&aBjIUL{a-+$1|m zArki_z>#j0Q92dSvtKTPYAul_-Gv7jv2|xF8jX2Pz)e_<%4cv*l{FqiPrTjF63oJj z;b+HSmfF-(+>+2(PXs89L@xK+xXQK}H+ZBFJ`Zfk@!=kkaQIF2WFe7Goy+EanC0I~4AAptc_7QYB{CVL{wdbHApY6Y>MCMKd!VdkL-$t&(@O4ZRh~~{ z7Ap{5AF$oojTgk&7=;I0E*nz4__*^-I)Fy5Mc>GZbD7oiY+en7=>2ES0`n^N#T8~l z3d98j($cD-7qcTpZ6N~j1{G7?nvgN4Up(2t21brw^EBcoPoCOz9Wy$0&VY^LWqcZp z*;V3}RmWL_-xv}^t?RER-3~8`=p8k#dh{$^A*hM`L?>b?Rm@u8*?2iR=8Cdw`8dqd z&<#@t15Y6=g|ys8iO_zkMjHJCLN(kOFy^tPk0ds=-pVH{-)z7JG z(A@<#;@&aPefqr5f#V^w6gS+ZU_52JIu=<9|FqYk=*WNbuAaKcg!jcT>hilDqS5OM z(lc=QEAT0?nlo(V5<`pYOe={6jRRe~gd!68cbfHp#^nNTA2rE(9flROw7)8A{5 zW}8^IHpvR5cg+y(B+z1?P3ty)BG68S@Oq zhKvhcv(0V&LJyiOat!Le!dc?)u8hMw6NK24DStCK48VjS5s%lFgj0`>9fVE|C?&>5USo<9XyzXt; z&fWy3Z>-nx5XYvQS?ufh_6k)w^086<%DPVLf_G6;ttva(639+qy|SoZ$=u!dN+N&0 zTdEzwq)gBQ>uOHbk#=7$5$G9%s{nunAepr2l)7E8l+g-txy1R2PT3WVakextBb2`i zj;{;S3$G}m8ytjegdR}&&_35746Sv+S}jefj(1sjlmzpX(m%73Dx=IblhlW#F~`F{ z9%R%uRbd5ZEOo5#yD{_zXhlVUkyH?Io00$Kq7%iO;0znQuWn8;^8|G9dixL&BNrOl zyI+~vfouU1Ft=yZaGvkH4N<;I%5z^^(3@|YztP#9;yzwOyCIaC#$o*&yUHQF+Q(e} zZ&+=@-^Z#?=yizIkL@AK8K@;GcSgSkj|pA7fmJJP;2z&tNaOeUTHx~oq_5_zqFW6N#9jJN(78bJBYS_Rxx)cZVfQ?dFZ-ZdieUQsT5|38%D)X zdRxjB&ak)0*cA6>I3Eyii&rIv-nV<(A{RxOgc%kUxYx}>^gt0cg-_D2s(HWp76bkZ zY))nJaTCC?MnZ4;F87X5j__#R0<9EHTGjoq!#6dqQxB=WM|9}Ye3XaD#b+c+rFU9F z!ku@I-(BFobdy8WA{n*PoAhi!7<3*%h?cCne_#^H)9^ZXQLydvSU1w3K5 zYx2%K6O7D^tYPC$XXXxe?3c0v8P^)&FL3)}$|-g~qF0p-LFeK*X)v-g^}GWRG$(`4 z#PiAuDu$qP8HwvF?MXJd{#(&$!bvi-&rPTc$=wUco_FL7&dvqh*|QDUcnQ&shES=n zL|#p#%w17%>G3k}X4TcRcjONvWz`JmB8Czpfk0DR7&A&AVf?-~_j;dT%aF>E{O zu$J(fpL1vzLD{I9lHqdrc?vD|R#NPPNlTD`7E>h7BGQP~SdWW)mUq8!_E!rx4yX{(wmzwiRT}*Q^ct6-{ALoI?Ml|X@HWwf~!9y3tU>hu!?V9 z$!{%^p)EHVf$Xj`$d($Nk&`Bm{y`~z zP31rDIMbjzduL&sXGAcMaQQ-B)R|b%7&a2PF+4;A^yovzJPIJFEz*b3{)l*pnr1xv z5=pcrvraeo(96uz`*}2R7}Qq@*&}suhu!lo-=)~6kyl>!^>mrXPZJVtA+dnjP5n2r zY_SC%sD;~KvIF zm(S!QC5%r1Ho(NJMsiQn0jS{7b{p29o1DSK&?58e#yj07$?{B#Np-mA;P8(QXW3JM zo>)U*(5x-Y5rZ3ELM%n)&_^3YeViW#HG6YJF&g0cTJt(}2Gbli$i(X3`W87Js0u6T-cpoCx~$a+zg8GV&&&bG64}@YKJ{r@)gy`E&)fXka}TWA3MCZKVaxMFL{F z@#=MC-(_Jx(E3uK)svyUFXKfdLEo_ixQQw{Kc}G|N?Sv?D{89#?D~ z9_&>4EO8#t;wQ!Zx*8K@yse^KsXOJeL^_qvOcktsoarYgGq9$lWS6h6~IW{@Kbst z`i!_geh+(DY2W6vq~~y#Z6+WF1G5svpy@95nnNl485m@?$jwKH_psCgr#~*hZ@80m z({Ke0+{$hBr$*j;OaX7A8K2|B;yZfiseY%FlBCyrSjzAx-u6`5E9tzEr7Q> z`m}B8<~k&2pX#nGZk&Vy&_D2VaTt{-AguX#J>wi{;CaV@?^w&|J!#aq5vwR%Ye!#| z-IdCPxK=2mOMa;Lv4QtRVs8CNPMHtc^m_*9GtYo!OOGB@nXN?3~L0X?Sk65}7aKI(%zYJL%_& zQha%MMrO!H{id&BU!M#rkD2Y$R95`^q+wNU>*EGGQRcQOp3q=(9+ki~h#@Xk~gmWb~6 zsBLX~+niR=T@%X^hzYT1erDbS-7R+%?&lV(#-11M6?SFiiL#l;eeyWWAGMWm?w0VW z9uAG^ZE$tnJqL1*1%f))l@E6t`R_Y>D}!H_({=_-MN&#wr(xc)EYymeMc<0#D)=uM zyF~{PZqrgNwbkKOh9U&pNBH%)kyJq)z>E+)o|bPHk?cMCaiCrLvJ1;uto#6%jF*;Q z?>WNMb+z}G#yWnj2Ng=`IIp}4_?NhR`m3PLF70Fp+Gn+M7qo&W8fmY&u~Jq@e2*r> z{z{&$Usayd=L;q9Vjub7XwnL7%!IWoZ2KT@uNZ|m`MovqHG1Y`>#uPzu&u84#Rkvn zUwwkwEoCBTXDg@+f=lL}q(Qh$PC)wu*6)}W3;q?yC2ue~+(7BWJiC7}p<2e+nLIL3 zK=Anv*JT4vK0YPI6-8n7^ScUJ_3FFm)5>I1!z*%+L_$27-pfe@Xn?L|hzzgYXr_@0 zsbrpnvYB8P*3}aqDfTs<)R^5>niCx3oY@@b@}KQjhQSEgpc^Lt87j~-RG2!!vu{*y z1mc(9nN{a&Gkl3W(f&z`-qei3WR1!#eFv z-z(*oi;K|cH54#3+c%)JC`Z934x_apHmdL9w3AQe6r9|T!JCs7yegh{_cIUM zQJfID6QUR{uAH0BU+jKZm!RG{%|4FsjAmR(ZVKESnqck$C`M0&gk8864a*TUXZxEW zpJ`%^x6nM@Ns5~9+3$kA!E7w%ab`Erx*G1Ny%Ix}Lcg+XH!V?%_$0+5dmw}#E$%&H zChH?HyHPV4=RAyy%D3jUebOAoBpca+vgpU@ND>q8=8FMMzq`TZ7lGtD(D9%2U2!T1 z8k5*5EEtjzwrutRf8N;oU|$8LT1{4lSi@()&$kFI<&WR}R70+e#^$p|#g3H z(&Uwd0A~-jPl8sM-S`an06QB9=J4mwpNqtlJM~Yu6CbHrrU5j)p0Z{}H3s_VvQCAb zaz8MW5WUq(Ll(qk%@{B+Gw!8@1{wBPWKbXL=%jwIFYGEnn;6E9Oxh3q9~r=eA*LlK z!3qEfpM&xcNt7&MUm(V6P{0U;#^@5D7+=&b*y3^!Lz$(tHx+T@DdIgg0 zP5QntobP($Oi)FM@j1~_szcc+N~SC$#%XhwR%PEQ+MOkz7Qpv(z75AOi2vlcH`|O$ zW+51+$_My!uQDuh$Bv}aGSfl6TzRh}V6UO=B8aN{66D=iFIP#q)~C!w&@(_kUSDW< z!s|DP0qC-%i<6FOihvQwA_S~r9xZfr*fFS3I|MB%xJ7~NiDHMx`L!-30bK}Opg+0c z3(ueargId4-7LPUE$N);AFlQNiom4@&AjVO4P1z>!X3PltJp-1;WgPSCx za2_Yz8yS_ZFTIx!i_cXa`ywi}_zqt<5EMQYYMf1ViXvAB!E9(3Iz_Zr(l%#HZp_~> zaew&j;W>0y#fqRCKsT1V%2#?HPHTdNe>D>qOiMa=tYac4D zILQ>G1eexjG+BiyhGK|whiP!Fs4WB6fC6}19EJ9xcftwcH9PdY#WcVuSold6;$B@H zus$GeHw24jdjLb=k{Z$nfkcA+s|Yu^MZKA8Hnz9r_hx~PvG{_I9NfNG#BWDZpR7dh zYF|P+GM`Phs!QeZdl>)?v9k++Usek3>(Shy-zH`;(%3@8& zrbmSyE)Kvo)n9k{7tatlOXh9fo;bxE?Zleg_3)fyPgPzjYtJs)Wirn4=vV^fFQ?vU zaAsLgLg-4I!qKGq0nOzS=$d?xz5~W4w;I?CsPxSAnP1~661Fupg@@DiJH)j%oCs*J z5HluiS`42itz)cN_@trx?v08^q2{hTPuvB}$uErt>N$V;605W^PiCSIox6Pw_7`+T z2KqkU`(a?Iugo$vnA>bGS3OM|bLA_rC~qEu?*FF%(7+Pmo=pkocR}VSW=)S<1Z?;55Vs>LD zPP5AueO+meG{}9V6tq4fRrPb%eGA4eyC~@5)Mp@gb}<&mGc|0lZbjNnDf`xZUf7~`=Swfd-=a1%E_LDA znPJhIgk8@ow@50?g(39Ni*lAb#05>%HXpuV_})s~1DZ?$8+Tz~yWg zr_R-IZMaRsx8hCEEx+!M&|Y%>aPV1igDL$rB<8(@XVli0Stw{r2uHF;dZcyu)WV~N ze4R!aCDJV`2VEHRHb>Gs)5g+XHnRyD*-KFTm!4ei8_Fb1*PG8iua0jQ0HeD_O)I*H zO`a8ciXRdZu7=Y{@lSHLQ^1Z7phe{4A?a+wlJN`i%JkF^c^$4OCDQ0c;_SC$SS^7{ zpuJOS&MF(Q{s_JlL1>NPI!br?l4?v3qjPs>jMr=B_P^NymTdsxRBgA3mGfErX#CiB zsRtZT?kN>$-A6Y-z`G;=iEceGzNB}pq4TzPf<)yR?AG`mObp2@302xy58-lt7101O=rI#( zp5}+9$ziT+@?pfs=Vs9Un&3ChrO)FY1hu&7yBfnPjKq?xwb*)6@X?i<{WuZ(@lUUQ zo@6G-19>dG&#pyY39qnGZkus+-2?+<1`*aUucA9$;aBLBTjvGggtiZN3Hf3^og<># zen8TAte->hIbEMi&Zn-i<|`813ZGA>I|3(r4{QbYEz zrRnRb6{q=fc%b*QtjyJn=q|QRT+ynWVnb6uS?TNRVlQ~H5}2s@!w{? zW3PXgBy%n>VJQz9<3s#jJ&#}!L`5AHn(9^!H&KM~r4n0v2!OyNKYi(@{Nh8av|q}3VKHWk(UL1=5@&W2(wiR-%Kw-*l~ zTp_J0P~3Q#SA1>}gCAcnl<#*es)sy98k8JPRPCovqYWaz~GKDc?fr@WZwvd2iAJC*LK^ZiVa z=S$b622XF9gn~w~?#5_V*Ob#>n|r$bS7o96#=P8KOcz8$3nIy=Wx8>bz6LMsY0e0l zI`CZ+bI-koESP-1#!@W}2%T)oH1KQmsZcOOaAN3*{wRx zI)HlvK39p3Z$#P`@0Gw^5}OMWJauP7LqqPkbuX)~cz1Q&Fj;Dh1=@*`WyaLNH(tPR ztLQd({H_oKbCjfrkSf+#Qu3q=ix6Be<)TccPt@HRsD}_c7ST~87u5LB^$OLF4HRzT zJ)K&`SCa7S<_K}ljkzz$k{mh>6i+}5$WM*aY@-WjpP%J{)#+J>_Mw4JjudoiE-S1Y)P3OxcXl}>_y3@hT><1p2-QW#u zl>9OQrxwlp)%YfOZ%fL--t;B^Nfe@cA zv$G5O<467W#r$t1+e3p1|A# z0dLe!OTbySv$TyVGlS1BNGSVELiB$mh07upKAZgMRqMsYVjzG&SRjhGyx3ep*fc-hzrwwh*OJ*pwOQ^2$>+$ zvgpzFsu?LMrMJt_-Wp|Ym{sL93rlK=5je*^G;npH3=^&O0)={l3pNhn3$!sEkwoxg z{N@VR)j2~Bo%_|T$KWp6lhNEBjM$s!&y6i&#@`;l8iL;#&$XEF$ZnslDV7pLZ z_uVS9=f+9qI^O6+O41Vymqy*`6nbe}OiSisyyr?jA(H?>^?}$DaFp@DU-Rp&vB5|9 z_3d3kl|e;?AFwniEkED&Rufa>;R>0z8la^l&H|>cd{WVRHu^}AEmg39h-N(E zuBA44KG)-O0>I@*ZC6cQc7* z$mC;-8PRkkY6&*hM<74j9(FwNAHo?F1ptGVEZ#2mr+}E*!;}a@vOeo?j2}K-tO$H0 z0`+L*QGTX%D@+L#G67&xv6};^G<4!pp*Ri$H%c~b&(#a1fn@*DFMtyx`z2&gf<7~T|Qd5 zcBN*qVoU?`N_Hu?t$wNKL>dx@iFzV58!{mn^Ktg8LWI{pJLE{tHGh=X@XvN4sYAlx zj&p*78L|Q>Z$H6OnELW0{}hYa2`wtqA)DtCigMf>IehS=tHhZmzM7R?pvQi4s@XZm z!<0`zS9u1aqS8}{wGKaP$R=-?@&LK|I>MDlxfD=^$^{3ZdovzUh<6@9U?Z4}FZXvg z*VjF=z`#=+@yTak6#Zl0|K4l8R6X~kPCvp7_F|LIr913Qgl>Xo#}NJr$% zIq0CcNfawzN;8#=uCE3L;_R6qmo9nMh0$EH*M8+TsA`% zE+#py4Y^m@;ndCuB${K##Zuni6jgf6`#e0|LR+&|UU|c!L%liNe`Uf<0H8K)cBUb^ zef>c_Kby21>xfob3yyLZk~#!lKC68vjYx`?yR*rw2p*wnF&wGby`I%~C*X_1 z?mQEM|GRPs{#p=1t#~N`57{8^@HVOrie;710}fkAnKe}Gr5Gvi?9=Q@7deGdKNWbUvR|u@+Oz*Hng1q*T z55+o48nUH_QtO;fh}Q@&0}B~tG`6<=*5uv}<(M^u!7+J6)9Og$PPu@?Q=M$H_cwTZMa!;gBXNknonUs|)^yHnMW28lm=FehQYTkJ0` zMdKS3;G|c;nnxq`v91z2goEuOpc=0Z`oDyzfh38upO~Xt6 zX#cxQJKF};PCd- z#-3#s^@8Q7A#;RWajls|(c=gv*54uGCM-!?e_jO%NGNK63ZLMHn}yDf!3Evem{A!b z48#@P&4RX_KfM5l_b*zQvgPKAJ5>vC7jt2+i0~fVFC1&nR(QPYf&rSuODTSLNyJ64 z;%9G&C{%t5|AHd;D)m_n6Ow7-2N0i3yJ9YEJ?m35x&i!Emj?RDk(YElX--2se`2N* z-YL!VE-^}30=y~VT|2MpeEWg*JH4#&$d~7qUQ&I{0!%h9YKUUR+BdMU+rSb^tIt5- z(wfZYx~AVLJ$G$HQ7n1dn=)%CGqY4(jMIb|)nO680IAcBI*DHQlH#{6yNWQh^qqSz znZXWIEM)b@m$R`wnWos<*Na(e6&oUP&ws%sGwmRDNVV0&s$%P}Gh&wa-4WO;BswO= z{?n8b5`gAHzPdj*?9RBM87VU1?%!AML#N@>61T;`DIWn}C~*kIi!d(kSOmlpB#umO zH=w;t#^aPd?(_4s%(%)nhq_H}>1Kdtxdk@+QrDZV4h&%3kRHV9+*a{CcWr@WnI-6Y zF^-I;f}RK&ev$#oZ7|N9Q8Izkkr@)_yET0-D5!(|U6TtFAEMNb&MkgK!Wtm`dO{d! z;vIM?a_1DQ`!yS+93Ce+%V{hCZjX6W-Xb_l)-yMncR_vn;6stD&q*@f&G;D(Zp7c z?XEEO#VXfDjkxTDa~ZWDAD^lM#3_=y7Ih`N77wvT>M82Ojh?xV-M1jFpl`#mb3en4 zwL*codc0f*i!)ta;ij2W9lcGp=o9Viv1Yv4mDW(#bGyvCGkFCZm zX!GB_`#{=r^4f?W^reZo+##>ZPY~h>kHw&;?~Mb z(SPYd=Lb*50H!_awY0EFV2lWCAUSQL&j6k~NqwM+G(`80GT(#RKHD9>VT?;1r??tg zHOOdNg0+>))PL+eww&pEHU*kD4*ilWmTF=ZQd82-biLn7Nga9@04kb2!?`#E2Vrhu zBj=*y!L1C2N|!1X?ZJ+E;7LQ!DMZDzc{47x)Lc8|s?mLfd7VkV(Yp&i+eF8Mg?N+* z=Af7M>ve>T*K{(ON6xG**zHKhYV+2QXtoas{qe=|2$VVD=)id)-?)@B^&0Fh4lNc~ zeeydVgUACXa^175sO_z&p7KT=@dMVtI>~_)p)|iu@_XZM9g%^?pSaUzRSxw)VCaJ$ z!@}_srR`A^y^P5`P#Q4J^uRh?3<#WD7lxkYBj+lRKf20_JJ$j0%c$55PbJ(~DWnTF z;(Sv#Tj9&A2uhz7Ad<(_xN%vb%GQ;i>fO@WH|j}|0E<_aLW+4q7Glc`%Ds39*&A^@ zjSfHa1yWUE{0NK%oXvf-_USyIxYPP0^p0RJq|sPg#HAr*&+5Qo(KL!GCm;Wxk)q!W zkK+~Nm`2W8+A^JmYe#gSQe?jl)>r63ry zsSR383CzB8d-C=1#dW0l@XAVa>b>H78}wpVxJ^cL*t&>*N%^d^(h7l3vi2mu<+gF_ zHw|S=cbIxHnTPu5qh#rG)b}5^(H~JPZs>b!GE)UHB(_Unm!0SUwgThH<32Y;AJeD9 ztklcIBaZcD5a{@A*}rcuA{jzNJdN%P%O1p?4aHxJP6}If!szj=?MSl$B!S~T5~7dU z0bv%lSe|Y2aO7C2Hs}_@eW`vx+7vDUm%Ti$9xH*G*3nFjFz+{u_0=4yB0kI@mg!+V z-GNhk;Hkvl^ki=9Qez{h0EyDk`+lufpvx1JJ4eN?X29swFJnzpy&~cvok7ll{)j9@ ztIE{fEQr?EpN!}wy%<<=5_Xi>G16el5pLjHf8-G}{Wa^V;|7{PV#lmpF6eMr!#)6p*v-1~p_VK&1gvw4U|T)n|_L9x}te;U~gBjF{JQ<*%@PoEyU zvKzqKo!Yls`nMo^p}dsj|Ifes!>s%ATNid#UNk6bdb(qVa11jh!HYzW>}PBCMnQ3! zM<^CKk(y0fTb^ zA1;6=uopQ8a}J{FYTWl?#zv*rQ)cNDn_M?{t`6TClqXWfw~>LFz5DC7fY8h0PS19` z)!4_1-sOBDR5mfICy1wM%Ba=$pegMLMrCdVg+A4WMvrQM9_N_b&tLlf?HK6Vlr;pR z+=+L{G_y0~ZtXuKIqn3-MICpV3vHd zOOR&7L)`jMr$Nx*&@u1}BayU{<XJ=@Dtpr{x#)9nj1OI;OkQ@Ih2CM5pqh2;E*geTc{KmSOKiTDA%mL$QDvTVHq~9r8Lad zmbCxX*ml^wP7)s6Tia%>j&sjyxgdnpD6L|$#>QDk>^hYz7chMGc>QwRy94xE-@T+w z-!%)>Y%^b9eBX6z^^=jcpE;!gZXA$P0F(|my;?bWrxWchLNR+Vu~FB>B!`v}-eH^nA?pRBd2Z?J7;PzidAs=zk zhuBE=#4wTe;d5+oXuYlLucgI`YReEZ+8ZU75}j5);b~a21s$fm(u0 z2yWQ`mG^A**0VfYg)=tuTr*aQOiMhB%-|KbOfDJE6ozPaG+}DnxYH0<>^WVLtuWJ2 zzr6Kg^J?xYyFR4PF&>aKLonqv@xTxO9RC(^+P#U8BVXxIJug0jVi$ph2lR z`BH0J2?_uEFzr?`D1Eu8EdtJz>3JE%P#4KceZa&aDx4)3IG*4kRk2#fS&2-vlkG2Buyy&O-1%GzZGDt-teXmV8JVoa4W}Us@?zUY1XdTUF%a;3Irt`)aqsrL~!x zpnyKT*q0%LsqEb;6}-j5LwvckIk;-*ycoffRYR`z^_aa~8b$(8g2O;Wp2AfWchBq4 z;oWpHF(Q2FOKK$xYq_)8`-vgC;Qn5FJhKC~W;J!EibKVSU|eP)l5|TKX~7ZvR;f8e zb8Sq7UpIRi7CK6s`*9>Z68ATozX)arF1W%xP={kL7w8=S+Y#Hlmw>+%;%MH&^taRo-svcdaD~)%8wg*vaIAWmhrRzvHJx)o`hkLh|9n23N7x8^i4K{MhlMjSC1$ z7N*58jaM72rjOL8#)a2@@jEM)KEGF*>f3NRk7l|^A3ciwlzYb4Zl%PuaxfGkXaUIV z48PGCuotz>Q6-{xAg711M0BW7AlFwFQ(EbP9h59)B447TJ+4|DFQY!7cT&I8kCpZ z4R89_PPcRi=IrTDi%e3#`ABmV2rRJO#HGSZ-)U#^fJf3I&h*Ur}oNs=`Km_$?jx9YS_OoL!v^>hS4l6UDP~KouXh~M_!N8rJJ#mV!IF|qeK@&uI}0xAaI z`i}3lLgn(*X4W>bNOzx|4(&5v8y{`a_HZl1G-0r-4k@<t%f zQpxXhup^Q+u>a<@Yx+jkf_I9H1@wC0IsdOa`n5~?=?(Y zFcE8|ab;6u-%DIv2ttm0V3}ljwU9}fW@zZE0Be&zji(j9duB;VNdQ;tPCbt^Wl+qV zysoo}=KkZZpA$OnRzDp*?hR70t0FTXK0iKjG_7nQ;m72od6ozPE*vj{p&BmL61|S##!>EV7za z#^B+yvk=Ev>I3rLPSV7io0Gn`AYs$tlSS$@gMv1L78hOu2p0J0kw~jH z8lDROt8;ns{8Qnl<9rI^|>CvYS@4y^FN{M{iYBH0&UU zmp7HgfOBR3_lImb9?P3WHTcH;KF2CKgV`z`n_hF(FL-Mtn69gJGUNSS82(L&PG^_0 z`~cd7O9$usQYCOX6S{Hk*sBP$P~J1_7leC%rrmAV_&;=fR_60Bh{6^6e7(=*OrM87 z1tw*7A;GsZQ{+Q{9^d6k1FeAE!^N6@DMiUW`qE0 zXnz*;d{+-ZIIkwIzdPNk0{rvC3r_q0+CBk%s_n7kdf5y>Yv_tD1GD^-cgYM<<(iFy zD&j5nZ0+qpwD7(SUG!jSi_Mh_qS>+u9j*r%$EV-V)X=` z^M9D4EdWz=bKqg5`W!IeEV%u;gZXIb*{qCe`SCj+LDDR)>mED67vV}Z3#MFF_}?(W z-&LX2-*aKFoF`)`HXVkoZI1F{T8K$=h3KbsdzfZCsCn>Jx{t6o-<$E2I_DP)|2us0 z0&)DeHcI*mR|M|E=mg`jO=bY*Oy_oRIoZM~JpKH>R&aRT$iln|o8aMk0erfmcM$x& z|Nq>Xr((aK$ND-asWk=w2I1E+%?FWDL-g>DL4Dn|U2dr=ME`b%e5VS3u07=7Zu^+w>$ zuwVneJ;JUGDf9cmoMN_=zX6fI@olZ=3jcp<=0CUnh1i+jcRkDZy6LYtPU_V;DDaxi z=Da=|3qWZj_p7G+fv@Ld*zw}uLd90YUwao7zOOJ z|IdvC(2L*GmI9U|9aA&JPsRLq2jsODrIY2o{)qEoG{<^1P zr9?+G2mO5()27cisyP*v_z1(rmSAe$4G-j$4 z`VW-ZNXWb7nA$U%oFf~^&WX4nk1*eF%SLooAAcmKSD=%t3S+3HsP_QfqEEp+t;qc}cXIyqeQgRLdXLL-QsnBzwO5|{xa zm+Aflh)02W96G^%w@^+OOt*eRYvN_%j1L>iKVBi?%PYkH=_|;B`?@>EJsxz8uEuKRpa&it1r* zn%wTlFu}|Ds@~LcJi5(7oq!8?*V)^-#|XgV{;jn&H^mo?^!)S3fs|*k^*R;@%003_|1|h;Rd}oex8Ek<|Op&;6hBa zXgoJ^Ho%|*Lz$hrg3z08lJED$Uipi8^aeF`9EOX}pY5P7dxBVi)eHg}t_dMj2;cCrTLnFs-@U8H<&-m?rmg46KvA)7_?VwE~W|*bC79dYS1!bE(YMZ zoEPzQuZ0{DIAmPBw7J{?CizLVvAX~rSZKq&^^ZnY3TKfx9R7zmJPvOAn2nBuhf6FN z`Q^_-2a7~pM~jqP*)8NELyr3lo5PBTWZM1He0LuY;TJZ-==a3er`sp{l)#i5`Qyht ztSmH)(NSl9#x8%vSF7;g&#c1D*7F#*$oiW&R$OjBc|y7lM3c@_sPRKf-jS1bTT5ad z+k9GI)q=VM|9t4B+@UeC=(5&0eqrs!*@^CwwOe#VJ+lp9oA9=lj!T}*4QcW*Gkty=PFm98za`kRBs3Lf;|!(I&W+KgfcBhakiJ=79jki0 zdH?Tt(D|KmE8)t+%Hqn8@xba7@h6E#-vj_BX?K%K?i%O(EwS=xk2hk)=lmX(U$;qE zei4wjV$tFMTQFvT zi3ge>w~oi|w7mDx`}=+O`#^~^@O(}yl|FqkvZ@Qw4p>lNy)D;=ZX|gvkrrC99Ku2q z$5+VTIH;iy=7B3@c7;spG^hfv;G)hL+d1%RKeyIKzM7KY7eS!>EkWqHN>gzQ3`xkF zTa`E1N8s6&Js~-Jxk22>bB+FaUY{gLb|alMUjYo~4u@yl}UpAKt(6v&ddv z1;N~BEs-q6Q_Vp`$&KOi=k>n8V17StjZ0YulZH3m_jFePNdmKU^3cI{iaGPSUp&&O zb}rhBDp$(|@NKX7)^6!3LxGwD7*&@bPqVqRVYTqu)lM$q)0;?YG17tPdoo4petBu4 zDSRIMC&%KUs;tzLkq=hDL)ffpG{j11tw1w6^u+6yeXu z52V%m)XtSCY0GM#FCt(K#jGf#$fh-Gwo?6mndZV@EXfU(rFeIb=H})=P#vCIj5F1q zZP#2EKQO%H3nq%x@S~Uz)7;ds&LU&WKQAIB^>+6_Zvuorx%Qj;O*pjSy%%K4b!}d0 zPaAqLZQutt9j~-@AC>EDm-WHd8>g4%-%c1ns2>y$RoIko&JJoA_NUy@kcga(GqB83 z0nhCq@`3!rXZhk3XiC0qI&xqUkhF=mj1_`^X&y<^7lj?ei!>YCKHB zwbaAC0iNzmBMOJiA!^K0_Kssd3~XCyN}zGMy#%wcS|2^Yn))lvJJK0Rg*-82xU2Y0Qd3fw9!>z%b zD$DN2DV^%yYybAyR8x$&r8ZWeF(~R{Xrht}(|PWJjcqg)y~7=7iQq#FWhW0s-!2@s zc+RGw%#}=qk7*27jZjEgw0_$)?B=kC$c=v`Hre23zg5?ypCd)99UUA+BjV{97#5ar z6crVmk@&vvWaJ2%9dqmaKV5zxRW*?)aJ#&t-jf4^vF>fGRoE#g6bx(eKV=itr!k`4 z{t2yA5_X?w`=?{<8ZC1?JTelBYHuZ_xDy^K013e;gkHHqPI_OdH6!fIYXUY*G zlTny)?CsqR9pc~_!`@I^ruh=4d8?U@Rz?$zU}Qm?S7LQ}->U!)od=334e!Y7 z8&MW8-6)djHAOsB$bZf^B{PPJBmBO zt=3=h;2P5psyQx;625xeH?qOxac%{#1{9gUcz@ed@=-6sWZ)H*=)kIwOtJB!mnA*ykeBSXR(e3m=CO*4Vk-AMWE>4lk=sPULZ?P!JWO#G3lW{&@X^-ixⅇigV>q2Z!HNc>rA#P!K#;g#PGDf* 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 z zWlZz^?X+cvcF>&D{GD&NB&?9WobweYqXpobP^qyp^t~`CSw_j-d)|e56Q~ijF~~J^h=k(Eye#m21(jvcI?- z6UFCSrg=lDu6jJ1`ON?vjvnLjEzmr`liip?$?s9Fdxs~VBO}b-Hiq<+!O)l(OGMAf z^bRX*d8AN90zR-yOKQs*fQPQP8mDuzdGtM;)0x%Fa9EccF2CojQf3@OR*^%;t;Ck>8<_z;P&7HvvtL`tGclmGq(}R}3J){O{+6Ci+ zgSi3M8#Aez5LgR!VRr?Ale!<6uz(P}y(9QNaNI?2P1lRwL&1A-)g3`B3X>*`X@9x* z!QVq5@X^xJHmH%#96yzC5-|0jvw4}e8K-(rm8wl4QkSzN!{$=00|RLVG=k%@ zcURAh`?9Mu4vN^*5>2}+U2DUd?t0ZyolZ1rYKH9g#i*_1*OlgR43r5n;XJ053%7Hr z(#6ipG*O_=NKSquy%rsFaW;XuHkFl>fgB}eHc=CyeyS_H6NbY|LAfabpR6!JsW7@` zr(8JSZWJ|9EGTaAJP%B03>FB)F^NGbBDQ@0Iib%WjyyEuwSA?CV##dJFz_G?9ar)8 z0QLl8S&1znlG}5;~+-L=+eY&JmaX8iifG=Kg*MSk<0)Xx2MK=yyjG&`F>? zedQ0lSqpH4fxIbS+2h#?oW8<(0Hk9Z0r{kYbKP#+Q$oI^ls6zG#aM+%KoTHkbl5&yIwRWks}SD^AizQ9L45Xi(SXL%w9ADu@#0o9&Mcm!e}(s-sQa= zFAfCRmP_cepRK3YlOt{pS z+^6<1PM0QN)J?eJ_*uDf7O|ZwK65eN+sGu zb@ovRyLas>L57*a;>F|##w%yuy0Q3AqI5Eh@ zx<(DsbOl}ENDhHpH?PdR@@Q^@ur+S(8z4gPe)@9|t+s0ttm%01ORyDedHaMD&0up8 z{|lg`uxx?3dx3Cq`B?EgC|NlE8eNb}{+g@J#l=hm2bfPd(y31*bsO;S#M3U$i(hS0X;$~ zQZ7fYv?KXBLBr69I|*WcV*UKYappQ?Ew_JkQ5&E9C~a@an?FUP*vUe(wF9 z1YHO^4h0|4m^Q`!&cdfPYh$ zhLUihN)DdH2O&xG_QU2w zLj&E?0-P=b3KC&a;}y8gAup@0Yp23#`Ra5_f`{U8dSso=ROISLuU*{}Tbp zB=*NlA}2!VPlO1*ex381AeBs#S@Opw7me&5Dz>o7vnf(9a~FxCFk1DSU@{vSpnz@B z!9a#t%mOw(xS|T6r?so<#g*vER+*Xl#?TH+z{?}}!zf|nN6T+N8WF&jIwQhtx5ufq zJG`xh#9FMad4p}2NyaPLL&D1+aJ-T=oY`N4y z;DQ`==9wUdqNDn7Ve!Q z)Hr7qmRl{Gi9RI{OQuheG+qe|Grci&xV)j4<)LI)yS32rZO~@rqSF1ZvELV(->nhD z#yclvKTme&eH!~JzKe8>J%!5lAgvnfRbF60SGDdov2&`n_Zjr4!Y4>3j-cQ^U|pcm z1;`kgo`Apv8FQ_HLqV<`v4Dpg^0BJ;Wy}S67_32#IEKICfgwknY^asOK_CBj%Tf7# zONs`+;_K~o`9v6APNmfyb6=54lTb#k3#B3EM>)Sq-dl&tv0G_vf`i@4Wt-VfwWjEp z)EAkHyF`M4()FI=8{^1-D(|)3PoKC}r$Y5M#sl#%g|{QfBwVkZ{j`@_29CL&l^fIl zX?Zu_uSQ?m0vWB0#=}(<1@NS}g6B%9uPtI}o$2cL2D+>_#~E?ZIOA+wvIcq%1tY4y6F zh*)Va50wq?bmtZUNxv27ED>#Bj^3Zx zx()v0PN0VR`?R3#07;X;K);qhvKahZcDl}<|8Dc=&&;f@SL_zbEgc;~4<9~6Lzn{@ zr9Q5o2SEf`$dnKodYSGw!i6TJ>m-8MF1S@29}Hd7ag%Xvydtj||L}?4N05Og^5P{5 zJ;c9k%hvfW0P!!$LcXwfLw*I=X@QJSq26NJYlQum5Rk1Oz&`Su+4kl(f-#8IjHPMe zO-M7sDCv_{)>d3Ji7HYP|JdZIvNERs93&>+Z+flxd9^Xj@pvTTzuXJGAB{P%Bw2+;TQ zol1jtgnE^XfB?9)uCij7-e>sR??IK~|Gh1>8?vmwv9@N|bv=Ef9LyC3#ec;zng|e! zgri>TE59Tm5fJij_C!V}HUZH-!eFz)?A-R$Yx0#;u&K=HcRrLEYAI9v-Hcyi-_OrZ`1bo_QUF-l>MaI z4hM%H&hC8lOukU2**IixudOoAPVSX*V!%$(`e@F39~p%#z;@9He-Vive^Zb9hm=Z% zaloRMAhAaVX%f3|x>hrh(P}BCFG8tNGb@EgUG!jOrCuCvz-D&2RTu30%Kn2S-?%Kt z#tGoTTw%qQ)QY$)9YGNR-(UQ@8boX>R8;&R*tK5t)djECIM0DqGw@x-gLhm&F`uu6$L> zRP3T&F^5kW8@1WT!2jGDWB*h`EJwf+U~ni$mdY|^s8k>TM=pi;&X~b4Aa!$@16vZr zlHeeakUR(+IyUeAgnI%Gcvd`%l`+i9+y*r5RCW7l?tg}^gd9ZWH*T6k{7I_P6|CEn z;O?=K_*liwtqKCaVaf-He_R9~6#Q9aU!MN%wQ&M=*K0xkB!S0>Rc|LG5^4{MyW?BS zD)JNn78?3l&$0ODXsWzwUTO1SmRM?AK-dB`>@J(lD$hjac5!@-L#xc$PV<1R^H`@U zRV-76Pyf6}`SJ#{{T{}5)z97vMU{;?F@OPpgZEeh`RPcO|Fve~cV#Xo>9J}P$u4%Q z#ZKW`+qWqIeOFE>H5tV-9&89(q{Y+e?b$pS5Up;}fvfare)fjJ)pVKUmL+hrLC5jH zIFbDk3m)qM5$?(C^IhbgA)|plK|QYY*x|eZgZ{AmPGL555bGPmZ)2=1ngYtLtQcA= zqplHC1)Wl67GvEPATe!%aM9w{#FHOK->|8kGMN}X#!avYy<3KPN#b&aU18kcy-C?T z#{QOHq5376jRP=~z+rsVDbiLxC2Bms5a>5?2N<{ip-j5z|Gqq02PAOiU7xKNrCQTQ zar8t`Mx7K5d^GpB6ley0VQpaokn-)>D?_IF6!h3b1lUmfAbZu#m{dVjsbAJHGKTjM z#v$y3L-qiec7nwtC-QKU`;Q?IrNdw5Gx4vf8^#AhpYr-2ZDiUhSWzp(g)Dh9Kqg1N zxBu4@zR z>4C3Uwcl0BOVF5(0id8}sq)=od%AH>p9V42=~fK=x07>=<7p0&!;KhJ(!mTz4O`U) zvkZ$pI|U{DKjUzM_PYz_OkPUPrReQJ-usNm-3`c32#$b}=>NY47O=0R@zmD!_F%oo zoi*F2a*cerHP}n%FwJgnI6bKhzViA(FW0dlP`WXgp255J;|bnDjouhENZI;#Ua$@(AP&j#%uDMq^Z8wjxw=!h+1eH#G} zTF{SQ#s4)cj0MLcXs@~fBe&{EN8X7&{|}&i zaKR__K*NGgM~FZt`YjY?Z<6r{*Xo{B<*AMDI0k5D?F|I-VX4= zzkUcC?4S&M;UxmUpCSzaCSVS5z*Xj%7W97JX#Tf-@X75zi-0h_MjU)OvlZHx_d&nn zEyBO_2GITU#=mG2;L{0?{%$8Lzk3H|fF-Yq)Y<`fb&vkr2z}=Pf-$ul7?#&UHgPY2 zxm};m8$gAG{z_H|sv~kjGIan$D&BbK2H;D9zu;3)3LxDQ9Q|DxDG7k`x);4d4?C+tm5d}DH1Cf) z3c;UizW5*GAap&<{03Z85qbo`E#$e85nOWb&+!Ew>{lHIBBpUacJQTPl=j^GZ(DZo z8vp7PCEd?43j>4s)Byq`uj7yvbzyVvGSH^&;PT~P=<=BG@(5P!+vIB{|lE5GO z72BhH{M$0X4z3BKHQ+1v7l;<|_Wr-#-Zu!>7yCgs9^>FVeC{Il6Wol3GM$-foLCa? zdL5?ei{p3?0FY14|M)9aK1 z{UhY-I|LwY{QWnbP#5SdO}Y!~+I#TWor3x=7XaF12*sk)lfW8T$@I89VlJ29E zthPg&jKw=WQ5~K<=d48Q*(PGjlAQ^4M*2Q*Tc- z#a5bhb$(cP-)5Zs4q5q-V0ekXj)-dcXHAcpnB>D5SCrLtY`n$tT4W3;Pc;Ef6 zwc1WF_1S`GbEZ*K$m8Q(!P0B+`(&QGdafS>mN`7->!z5v~1uq#F_W_3;4Q9U`U@(l?VPyhY6 z4mL{ibxOnqeCevqK6PESXLyeV088xE!qBnHF^2~-o&<}fZdOHJLwdQKiF=v53ue{PXLr zT+K$#2x|55*+hUX(Ew_{he#w`7&sS|8e6Rn5QBaTb%t=5CqOD*lklYh1K9u^?Cvhe z1}~PNQz=avnr36&mo)ScRo;_KCqMuqWM+qat?T9mRQcHmm(7))1}fjCxEwX{P7a%r z)JhQ?Fa=?+-cABx36ET(85OJT94QbxU`^E?(=57PG8#{nl3Qf5tukB8xt1Hu+ywQm z$=toBqWUACVN&&ci1B`E^&K!i0fvPV31=SQ+AfGqua{1N*)_~rc18J9G*E)zZ zzLCJ`sNo+&rK&)oazI6)x^zn~=y$In3G=MCS?lX}2ed6_l zg+N>tSs|hOdO}fwfODs>_@OQAh+=Mh1Kp9eTSGAFC8RB?8r3_-H8 zHQ4N>+oHR$*;twL2n?9unhos3`O1U2-+alkr}hhb=GzdLdeN45FV>ih$(J@)l$gy)Fv(?<*js0kBw}EEK!#%bBQoQ= zeF=SjCr8)l_6ndAlJ=i(N4+~Y+xebZz@Wcz+iMdvU_~h-sf*=;c3(88m9jdWkP+Ci zvaSsm2tS_v_*!hJyLGe4`~LY63$g1&mB?Jst7%Y40+4+SoL(;ZYJs3^|6iwDO9jSt!Q#b0?rwbxEnccQ zrJ@jM5@Z-&VwHhgfMKP#PQ3ucZ5QhQqSh@0RKl~(VeKnUwQG1D%-3_9;gyCKK|K*k zEy}w%jHV{TlC_motwC*Wo=1gT;V{0Vo@vxo;1mUF9MCGFf?b}mEQKf^fh0-`K z#})eF%Gk_WU6aSd0Ti#mzTDw;c#vzoZ49&d{s?Y(bhJ>J_R@o|!RHscCvVQS`-yTD zGD3;1v?u5EK!AI`-eiMwO+TV?*+6Ci8zlK?nUD8)*E(<->F>RFD0*wOP+ncvi{0)D z!I{p2F$-%{N&N2l0GUz zhJW3+z&%0c7uMy{to8?^bg5?r=9yhsYBHiAdMlQZ(!;|;*=2Ffczu_~CJ3KPB2S^9 zl%edqXZG;Oq711DE}VN0)K|HG5y}te$J>5SVQPi#ug*U-QTHK%7!f`Iyl~p@eF7;W zt>5{7K`(-Ctxez@@!flGG?*z~{ecz@_&x>mpWp;@Iqv-no|)}Uy1K&cu2^|&ZF>4F z=%;Z+g%q`6{e>m9ZvuyScxePaz(})-Q$pra2tJojrhfJbs1B& zyRr&T)wsfAtvp+cKRCAp#V;;f-2GZjE4wnRxUX`?VYzYpaD$QiVya9K3!rBeCrp~8 zfF`VdKR69A=f@fIlr6%_E_a$y3@<*1V4&??&?m4D#@A`8mb|n*lA}=AFbz6-kkq1= z-Fz1X3t@g-UQ>k@z1I;{Gf`(0@ACECE{8+oes3+UNPPeOYpdj463{iO7-ny?b+70#nrDF zn(XdR_f)hToHsR~4d4Y`nu<4IUO*iY8m@nm1_4D1?n4}%QOMi)~CiHF(KEky2E=O2XlVC^e-%*UM1>u ze>NQdY(!ZyRBipuNdzBlu2QptCyI`Pb#BSXsanknRE{fqi|^Mab8rt=M*59aK;iIs z{Y{Lt%ja0XSR1Vw&(OwgRmSt1rWL<;-F^a?G5%9|4qmvN2jYKFPcSKB;8OdG86b{^ zk1q)*wY&=tP*Ch*ON!O1E#-hmR93BjBbjQ6_MOXvLCMHhAlD9U`TaggPPm?w-zE)! z*Wy{qU{fiOKN}{5g2vTe=&`r(V*c#IxXtkViwybcJm z^Kk1R$dKz^ZGfAa&gYd!w}JRtI)KaZ%(1O0X~xwjk;6XU&D%Ll?&gPsky$QwRz;W4 z7ltJ_+UPXS4o2t>p<*OZ-QmH9x064FC=@G^b`3C2Lr7k_ogF^q<+|L)K>n>j^Bbr# zov^W@7~VY%{PfyoQk{I^k7k_AW=&3E|L0x{k)Sihi+X-UeZS?fhHY`y_lX9;HGsnb zrJRE6;?IHC8McfmO{lzzlB?$9VQExs8V5VDNZNX&W3xM_XWY-4<8)9;v+T3ivgeY~ z{;aiId8c~8`p1`sNPM^2&{OsR8dt%=dIQ(TR-8(B1qvCd!KCWW=JUqXl^KPmqwVKK z4#OgIS{oBmdlk-c8%&he!KuI7%(S2%i1X_FD|7?;?|7o0=zrD{3c2f7CXoL{aDepW zrJE(tzIUlyxx-(*iiDi80h=QW;1jHq=#ysOLWu$6mdkH>f3XXKq|yLHf6{^%Ngfaq3TH@5LAYaNb1DtF_N!d^u92(oHSusOv!pAg|b8{v0pNj3ioh- zVt6J86xnk*t%wE?)6tqjL1ekB?2u(Gtc#>KhH-4~(uXppckraN+1!B+Ms z-7qLclOg@%@y9*jEAiV2f)RaQ7^&ENG^}VtwUtJUfdO=&Kxa(+3Akp>g1(2PQQdKrnnxwh@1_BF3!3?UK(*h0GcF%kKV}(&<^6nekC>@1S$XP zew4FweEz9LzHs5OdN@2D!D~xmSRMA`ZB;^ef~4>_)yQp?%2i!?-k5W%s1hlFca-)2 zvKOhR0;pmb+@jWYlXbW->O~hhCSvs_sAE=B#FvC}Bzrz9rN1K(HB@VD8axq6*gq}P z@69p?!c50|a~zmVuCV$88ESs3*~56&L%%_Pudz~HP$_FZcCJQ8A+pzH@?UHb7{W3ZV@!J+aK`U;U_Mg9HQwyO^BEX8_?Seoe*h$E2m5!7-2-7Hz`IP`fh?gz52!>&#D!a&}F=XNM5i2q|59#Oq}D(rMZceqL< z-5(%jJI^?unrrmyhkF>Ei~dJC%LWs*A_Z>H8HhV;x<~#_RT&evlc6Mj4k+X_sFytv z>xm18SiRknPuS;ds&;%S2k`c5OzJYwG-gL1Q$*vL0W;5M*G(D~q=TBCH%J*FNbQfH zYNG%oziFiTgVn(tX4an)NrN0Ohv9A6aqemGMLU77PS^cJE@riifD>1sm)+jh7R)ji z_=t!`UK%!24@fnyI@~XJ!pFc!KM4~Ms^(}D7s@kMM3;pzlLg@Z@0iJ~VK>kQ|7=N} zj2KIq8xbO&(wQ(bUyy)U&pSa{(&Of9lBYo3CLsv0sP1!F{m{J-vNVDT)OXk>gO<58 zpmi16Sw#nF_$$c4PTAZnqO6!T_eHeFD{Fs2=b;Vl`LvzZ>g;_qIx@0HIBu6*yOjdm z!)Cqdu;4dizS|TfgadhsBzB|=ehG{xr`M}4vQ;22jHr169h@P|g1(x6BIE-qEwDD( zLi$~_{^kC#O!s}f>2`5BX;JF+)+Xw`WA8!}(zJ+UfH#&dS>XcY9*bprPSm{?1MHv2sn> zl;v|+NCREapeBC0j?;4=&Kw+SBfI}{y#IG{Iqtx-UhlX8)Y^Ghl2gl3@ zEF6y}XD1ZJKJ`s$JMMyFjZ}=^8EPN5P7I0tzBm6tNzbx(0@=kVz5X-Z3(BM7>utSk zPq@tniJLr~13-zNPUyC9jM9zNLF3ZD`0PugTado)C*6hhuz~NTM!dkUr{td<7R%!w zvbEv@K=*&`g!oGd9m<1c;au!ViT@NHD6v@M0Nbnfd+Fnu$r>p&S@w5@a-VaVHGxhB zCG{Ik@s?EeQbPp=*HmBbz@OeVwOwCamwNdKg|;|gsrBwfqP=6DYC2C_v+LFmiC?WU zVZM0G&w~Sl&@upHmr|0yf2qd1lUX4Z+>0OYslM$tTaOoj{)3vF=b!bnrd_W=LsRu| z_6Dhe8i=!DxlMo@nSnf*}4*BUTLjR1) zSBsE@EfnxcXc6jQD!zf?>FTwrVgSNLpG|k!8cXy!T@1GXa34#-i;CnE@*^;&(sE>C z`3Ek`MDLGVeJ8brIB5em_a%<*QD8NGkr>u~`w6 zesE38T7x36=k4hiCOMkXMZ}j|XP(Dz=~J?hu~PH`(B{-9c6o{h|PFj|Vbi9U>ee_>I9Y zfQD?28kp!t1l*Z7VB{1St|uyvg}y@pR}lgUe=4^m&cuNu|LYlrh5fY9IqKjXIpuTd zMulaUkw$A71tQ$-Kaw$9JA(bMPXOjePHjbv>+tR8R^yqTiLlIF$E7xn9=z{iEK6mA zeUtY+4@lxm$m2Qp#8uIM@6pEK0O}i&lds zZVwjeP!GU%Lc${a?>wWVkGB{U%`BsB0^0vWgUGG%Nc1CU7pJ-UKO@cJf05>VGs*|d z$?^0mJrdn(9oerEncu4b{i}~IU^X0eG6zfK(Z*?ifl~S##5~XA{sY6+SeNV|EG#U` z)()nF)f2hjAH7cZ9(*lUTz$&vV8YAvqE0?uCxw$OwEGF%{QrD;%KBIp!KDC=wu+aBc60~syd6iI5|Yowfeq7$a?dnBo?hwjYp_dTbY=5 zzDwU4YUht?W4wr9VrxEgH%WZ1Jgw1FyU+;6L++%s{3XdO?XK`4^ zV8G+|wr?DgxN^b{3th@UOGW3MlqQiuy|1Q7~3|EAK4~c0|u~u*fPg$p9RM* z&(Ye33D~n-C&DXw05-1@9}OhZt0-)@mI{vC69(Os#KioSb=)uw5|G_rL}8_>g5l^2 zVj9U6v7hr^q!u2f6rr4R(?7}hd9K;x?bj54vkx_*K$^UJqzmB6o59zAON_wrT?F6m zLmzB67DhzCf=J6yKv#uPxWrWfi(4Pofrg?wM2$oT8|+0+$9Wfy1t8%ohtA{^pXg zVdY(P>|}pGJQ%G9Ufl^9{s9Ob)sY_biGD$WStdA!I)r~k9dG-x(%5b?f=96N!C&$= zQH|1djVx|wCEmW^rSz?{O12N8GXMeBV$mQbLM4olV4bmoh7b?R=mfv>Pq z!oKwPa{z|!hEMS?YvA_A0Pes|11PAM64;eif$}I<<;q`9EG$_067{ESD&v3L^7QW| zLtw@fHWL0uhqCbw&WksG;xJ?SMw|nE2c{mO?-$A}2GZ_7vX-|u#^RP(EFl5Low8ch zztzr5z@PeWJw7Ssc8i$(AnzUr(}Ve*R3g9?gEbpTraQX}w+Q=Mb4UVN8W;FrT`VbI zvNTxaeX{}$Fr_MFPR*C z@&mDS0wgzB|09d2R3cegH24jY25`Ivm|n>>QNhY>-{l>I|6h(;fdiy+hCjUlc4)Hq{g;;>u)|O59d6?SZgF4J-7+5`*fx$6?tt-j zfQ|oi*lBOhU*B+Un>a4A=MjO$H)ZXn=T9|TfM>$ed2q_>uo2*vQb9l>a24kkUV-1y zd(sl^0E*{A2GaQdi?oZ@pM%O>_{YDDErx+Hu{dM8bLW3@ zRm=fB<6pSKFCVbCN|zqQ4+KLPakwph$eYkJs?IqR4mQ`IKX~yN22sOW$^$@J`t%nF z*a?(@aJXH$7^d?U0e<+83<;pE0ZasL z4;lJ;tARI}$Cquf`;>x7hqzFiAs&}G5vAVAR%WKoiM2P!U)v%{^(DoBP1C(Uk+V11 zB9Pkt*+>r(j|6GPhaK(hLz5Ne`GD@JUaBvYE8uU}O+`cV6m;-_3{c5L0NlViJk*?f z@b_SvZZF}!Iw?wlE6i_+XeWe;pu9yy7-qu(`#t9Y53aQ+I0=vNu@#YTp!qMHHy#|Z zea9%h0b#G`y+JLL@5U>rOys9D{l@!*B~)M%=x~D>RP|qreaGMA&k~b3ff?9JpZMPa z{;mWD1_tOX^e6bKJe7zpe)kLErY&^j*gCevX?N!8Y^tlAAT9^0wB|8mF12I6XGxoMM=izO}7{}e9eFDQ`U7lBVY1Up9E`EFPWiCCY z(sdRtl$b4GZLB1wsHu{lz$jglY6$JWn?VFP1X!!S5AC0_k{F=tLKG&OO7=Hv8wl4|ruMBq~=319qVwp!q#__*9Vs8hen22yQD2ZeTM(e}Di~ z(cj;no`+Q$ki^kTg?t|ESx4QDp??ZSgd8mlq+LwLiM+i5P<7ysw`QUn<`KKolmR5j7T0kJC;O^qnbdR#MABy*{I@?jsw=jV5Z+0yiB>b@rc$bm%+g zw+4J_8zI}s5Ngz(=f1xb&!E9jGfhw3-U8(C>pw+J-2?S34bKNK&rTKh1z7lyp3?nw zG$TWH!{1Kms&anWGzsfERu7PnRNc9gVXq1T6LU_ux=MwBh8=l`qZnw>#zo* zd72<5h2=Ob+wGIYq{q!vCqW99kpZbpyK8afB!}5twH>sIfcCX$F#Jy2mn+47Aun^kY>(s3KpH3fGiX9pnin)kU zf7|M#RVfByz}t)pcCMk1|D#}a%bNU`ybPO0K5_rAt0ld4wcmG)45Re#u1xHvuIvwV zsDjz;#bXY~&G$!)zP_5e8Yk6^((>G;)*Z^fZ>mUSbXcqY;IrhetHn{#w=*dfZgzHD zLW+k;2>(6nU;hZW@Fq=H+hl@VDopVajO_%deW4EnVN{Q+3-=f?>i^D-pzSxC01Yrf z)S190T}ZuM_4k7V5d!B+RaWYovB1fy#_9K9R>@E7YrLWa%<_vzKnP)zU*F!lH+;K# ztcbUkpRGZg*Uf@zbH>%L?$*?o6-hDUX!h-5J}P>yA$Z*0|G08~igZDi`NC{ilTd&; zxjXSZS~!(;44nw%V&pA;a{nezcaZS^UIVOZK zYm8;ZIFbgl#+Wy zTHJYK@CV$=7{c7&ws_(zR!Gix=fv&ynejht2{HKLvtiBFi$DqxF@u%_~X2P8~<~unVmKX z3$Cy?VX!5~(%f{(;}PBsImndg<~K-YhoWR5t`fRHb*hXaPrLZBN^9H~(F0OeB+vo` zs3My?FKU?APIzcA$>9F^86bbTfP&sGe!frBNd#09k?m%iG*Ug|XjMo`gs*|R>__ju zlmHQUY?Rj7kB)6A5`ISM%e{!6m{&-uj1PSs`!PIG;X)xP9C#aYCsd+PRLj=OxAMwJ{TWBGBPFct`u4gD-U=^{iF|*Yo+F>=$qFcwLl`9u2sJ=Xa^* z^ugmZJ*mZUcaWp+AP3mNOK%lUQZ8~CrDNo)5|#0ELBR9PFhj22P;hYMtYxp*<#SP zKOmDnv1?5aLW}11a4NE%Le+`O-N}0=0TyT2et(H+#BLD5{4Ts|jv~F{dtMUYVx4?D zC+_}p@4zouaFhmqU~PU)P>MpM*WV)ikO4R7e4@e>GflgTOB8+!JU-~XG0Bds%D6yC z26qe|U(vsM^$9`N4?&j93yamkppS&U6a&Q+{R}B!&-GK~>aIpLaaS@YV)=yuzM%L1 zJ>{7ueLNJHa^EDQ)5*4{Ob4Jlciqf47~KKi4VJJrr=+oCylXpvdq#EzeUc4z<*$x(4H= zcaKAScNbQlwMAgv=W|>VegBji{6P*M_K(N?-%d2RKe7GMkiW*HnT5VKRvb}bes>25 z=>?Mr@f&r9LO{0{g?Ipx+wN~fTt?kD!5Ea{%zKWAkz*~)`)l$~j+W73KU125!-~S1P(6QuW zo>ne5CXM3DDi#&^yU-qAJeTd6+%pzINahZDiQ>O^_NCmHE<7@DL`06j(OftK8w>+% zFyW(D?_o#w(f>TMjj$t|D56JuV}p=pZ)}82w{g3;5`&=U5iz@2uOFgg?)wM{gx2C* z<(EDAShagQ7}Y;Nr>7*Y1X%v=lsGNoQ)RYBjZ@9Txhj&iJX8sVkow*&)~+J_#P7<% z^^s0Z{71d(?1AfN2UAw-Gdua64_xLXXGcUYE8;|swu2IwKD?K6r$DN<9mklixyC4Z z4nicgjFV-24i~RMetNBY9Jxwr7!L+M2}EILcjtFztJJ&LO8ls`S90cEQ`k3CVlDF( zk&Gn9-rNB_ek)^_o{TT*o?pJm|E-0D#9JDvTdfFijFvWgV?|S&N7@6*3*9OlS)B#5 z;|M(|g6`}^dX1QSzD$iimxQy2D-fI~zBS(}yz9AFh6{s?Smb6?STXp%6OLOxqop)z zL$VkuFCMLPeKixzsKfq2sK#|$c%)?fidx7r~}3?|*msAkzoioe#&uM?AX4>1@F zpj6J3aSAs|mr=YcfT0Y||HE9Y0Ygs&V7W-x9&JeSf+NQIQCTo(69e26aD20l{HBp%E~m7D1nA1kL!Qw@N^eZ~F#9V*2dVKT)V~3u%TR&MeUt8_p#l>g z&oRz;7QK5tT33<%FPfYu0=vvHKdUIb^*uw3%T;vNR%TzJmJV6aDw2$TZAFjEtW!-q z)3mu-)(=V|#y}&8W(aCtbk%+jx%%BKZF~kVMn(8^3a|+3C)!B};!=J_hIur)17bntA$lK6|k??}tI4;CUzo1Oxpw>SF=lupX_Fq!fc14@4^V z3@Qbv>KVVs2vU|}3Nff-w*YZfrNsxhy-_#{c+(NO77;UD7|m(2=>uiPxgtI**FeLz zSdW_wG)2@pY!W`eqc`+WKI3r#AE5k6p3Qo?I@9vu8C_(;=C=u275tzqxww~eX{lwd zvj%2@Qbm9z0SEevBTygLCml+K-8ltd;7Gwa7b?j^ehS_13v%*nQHDF>R!pBL;V;-`}k3muuV->ujmUyPP7U&A61~PQX+KQH#x+YTxtIXxJ04j_3z(y7Yydcq zPQSd!67@hlL$KMhN0ZZTsAHs~x^F!O5bLSk5=vFu4^Gawp2YCjkqpnaWV`oNPc)bo zdKA5w9y>|5V>xEh1_9I`8$PG@=MJbnTekm{uDxRatOXT92{wD{kcnd+2`rrGR6-WO zj)cW~GI4$B9;i2A8<%Pu-JTzVxZTU$8b{O|iS0dzby3ae(ctfM4U$$gfCULl? zTWu$%i)1L~U%#R7u2e1~2MEX`u60gvz+WmeT7BLY`FMI$UBB5UB2YXugK%mC3>TuSC8$9;!0p*I;utXNsg0^M4XE`Q$>kpL>MXvXrXkIoc zYYf$>xT=@x(sPbNUm+p86=+XnxeI(0aD{U;R}vd5dN0Atk6R&ib2G7pq#0ig*5bg! z_fr~oJWOJ@=QQd(LW!Hq)yAjM{#2mOk^n@+kmG2>xlo*~384M&<+-4$q~wFTGf&66 zXUEfwb4v9ZwnnXD z{kMRU^Q$W+lN&mPiNZAPNQFDK*7MOFWw3q#tzWUQ+t`}qQ;8pe99Z+4AFoiq7#2}% z6mP4w7sB|V5N4U~2XbF5!HM`J-5yRg=Ky|t5gCsY>o*MCCVxaIf!voxSWrVu|AY!o z0-*)8Wi9Pt2ntjZm-e5|A6~YG>cj_}Vo(~(wRIVws0}Z1v<*%6PP?3Bx~BRwN6B*k z9^cijdzC#90!g-@_VSjq^4R@Noy=($7KX>-+4eEy%V+z27m#BUa205v;<|ND9`<>q zgR{r#bkP7r{y?J9vBGAQPIF;1TTat^ds4g=^jU^i+l7l|5?Ycugf_1wNGok-zB7ua zRn=uP>us(}@hX+Xt$3Z~c{O?-O6H>4ymhvmUt+QtVqdXuOv=SW;W||_;N>(*uiBlA zJzbz%C~dY4HtxK32_8<+wwTnHZ5J293i<>`rbdy-@}dh2J^o@u@+UPxx_@g_@Q+Y_ z1AY<`5|ZB!s&`$(KvGY=g#$q=s+>|;c99Yo}SXy9zo-x#xDzJ>#ah1su*L6$54 ztY;uPaafEW3M}J;lhhQ0PbWhsX>XBvayGZxlPCs?u-ueprLHStN+4fY}me3i6 zTx^>*)QKcRCTb~`+e?EH`&Y45#93$zaVrB{nHPDZ_c?Ava|UusGh3mS!0!_P=L8dQ z-22@bW#@ujUS%AX4SzY*5lMmDjnR14G!cuFtMnlR?rmV+m3xMEUetFw@7_28JOJ$n zJFN0tK8F29ll8uSUy=o!`A)xjXG$KhQ&T`y3fc zGZn#z#x~Nc`q93ls)_-}eqqA? z)nwgWfB%6U%fJJm?8pwfFM~hEDXWWv(fnE!(awQo+Jh2}DhDaa@RQlb z*D{WULM+~s=i_h}o_m$a91$`gB}8Y@fBsHsYN~t_t=;W5=sK{xH+uXw2(_?kZh1Lq z&r~6w--bH#@^wO02di$S1puotGo(U{G!G6Y?-298#s`Rw#AkMcJm<^^Hmec3lR8_a z=M7$nL_9X_eMB`Q&rSP3VwlQ%`^VGAO>YDSr#XB)%~sID9uGjqBC}pnqDyjZo)^Q-s$op&l7Pk;54yF|(29(f); zW-XR+7wSnAz>|-sBPVKu2k7|E3-~p958e4nG#UpM_cmh3yaC;Ku@y9zF|sP<$?r zBKp~G90k>riZ?mUrO)dFTcqTZu3V%UN5<*D&*dCikK89@`W6%!`p$apmFOVKhY>!< zDQq0WfoBxBYo^_mmfz>1Hb0OJ;e(kMlMYVj)wyRJMU=Q(6HqK5kfvpGdfNWfv2d9_ zYPQaqNCiHXLchT+m`H$o;n9bXzdqg%ApquUn)Xg7vCOXyR)>>>Jge7|FYt4LwdZwM zKq@h4E+Hw@sh|-)-{4T$sLNMbR@syY2*!vJb|jD5q7{&VZ<3u`oxfjuIl!L9GQ}{_ zhiE{|(kTg_A}QL|ffs3GB7f z;I+?Ox5y$=NsZ1=-F1&ANHKTZ;kCABwT>H}QOnNl8#~iHO{YfCl48cjFdv*V)FjAN zNW`Vs2>wAO*OqQaSXstLdU4UWqYa@=?k=c%P!_0)WQx_Y(4EN!CU-#BBDO|2gI6x1sp&QGE^Bg+A z^Oj-7k6wbfXbw-!E{v{GtFfAH^#=pV!Wf|K_t{}^_-MYh3eM=DZfss6%91jNT$nD2 zr?=&JHDZ5ibKXJ^$xMBk?dDoRQis}-ZTt7np~Xd?#3TZZXU>$mV)-aj?%e~zRUf|A zJ*|>QJXk$^QHF&o@g2?l>-zEV7r4fEy#>^bNVM}hbr#h|S)|6T_YPToTI@7GtWRYN z5ss7^AN?rgv14^u;Js+__|(cbX8zjjx-W_UYo*pk2xPiuTe7rCq+rc-w*Q0B=pcQ? zR8xNf6UyGwH`9GC!@aB_x@eXtjg$yN?+EvOTs_ml40q#7%TZ2k(YqJ{_a9zN($ugu zqe?-IAfG;Yr1qM_kh41^w75P+lMmLrg8L)i8W|1-;WKSsT8mhXBR}9{l*_<%+5GX< z>FcwH$5vd|p3u=q0w9Qt&!ACksX5+)=ok%Bi>^}6sjBsWo0QX4no-bc1*u>x&xYX{ z44)(vk#3v}@xNMMf#M6;zF9rB&y>k<*-R653)Rls4hn|UU(~$sJpl7eG9~jJa;}1^ zwB4?+?k)f*bVPskDK(qVMk&MZtSsQxGCle{a@@;tsJ~A(wtM}9H8p_<5|7N%YUtr# zE`}5b7texP=^=#)4`F z=B7&gWlyY#VtpJ`a2g!>*tVpY-m16Xr||jS+ppE}5qw=BQiJdLgXP3AQTP)|+wSFH zbOJYb7WOS+#VFZHPfBO8b-evYTrIuerQFCL`F1EXekMmPK$*$p502e1@DX_omPOlC zrYI!($EalBsn7!vu6%ax5S6@WJ$s_{`sf=LRTRl%oZ&1nhfF6@t*6;8`wGk++7Bq2MJ~jN-qLXtz{3oEzsirE|ttxo;`e0=i7S&F^ zmfBk%fmYS=h`4t<#kq~;{Tg5S0ga$99kLg4J3y+x{t$#yHpK|b zeV1hP&L!k2C~ZItNuJ13^L|Lmr^$v#pwMASz$p_qV!{} zS`32r5kGr{%aUvwieGCq zs(ZoyD!!ZFy@d|v{qUG>zFsa(C^my%#d5##UOYk0lJDbFEO{^ek%Qxr)e1J7GvdRV zUae{Fz8E$M4`P0Yha6`88c|^@pWVJbtU&Uj_!aR1pNdufGxOtVx)9gXZmtR6xoFE5 z*4C|Kf+y$O(#PArs;5$dpICjUjM{^LF*3g!a4_gGrcldK{)BlB+-xJW&eq+=ynL>_ z;wK^6{NB=oC)BI$+NXLHHq|!cqX%Av2};q_3N*w5M`%lZ*D9(9*~a~kl)A4uh+vSQ z4~Qz$w_Dh;QTp1&PY<9M2c1i)9*gbRkpE`HED%W`Y)}@0OL$H=6AC(S4$30|G0;vAtsfa=eVuEUScen z>D%dkt!|hxP{yd`7NCyJu1_}+*OQ}a)gJxHt3k>Ua|fAMWiHE?D9cyi#kYX!SlPfR zj#7zkm8-BXb6zODa`03y!@jhC5#`)H?tI@FWg{++!9nB0pel;241>>0D0kpQM~n6B z=SnuW{U`{kdy;X49G9G4v=)Kr;7<89;nt53o9jem8}d_jQ~BP@-zcdRM{cGDf|J$) zRtb$?>lm!kE6F>DUABj`wvh zNv7szpp^xtMv3`=t(i;*vmTVNRVG|*0PWlqT|SYqN15_+rfdcTSR~^uXLk#X?L_Knw_t!;#Ck(rGe?Vwus3O(MajS?vhtmIWGvpz!?Ez~A(p!&J*R=&` z*9V?N%b$n)4Cndlu8kU(6mXzvdbCX4;&W;C6~QoV^5c4@Sd;prnK$|@1)7r0KWA_R zE>EQRvGe&ceXKm1W^=WjoM`}n z^lCLe&!~NL;`*p&L*jCWirfV>Bw5&Wuu$-rbo|vaX_GP*L$I?{DEtmjuI`^)f9_N) zs2G>|+%!=pXHAWwBfvhUJ2@Dxz+%4ISr{R4-H-++Z5dZ%*sA4>T@# zUIvHC9-oII%4dA1UCr!DJd+La&{1GHS?y``I(>kN!K@cqWG0@sFchG0$^Tu!d2C6# zdzD(2(kMNfuHf)l+gd;$JiHyZ6tk zzL!IYr>7aU9naB7q&t;oM(58Csr+mDKO&2^w1q@dsfkxO>^*b_?(0d=PQ-4S73plcfmq+hT_4$%0u^i%mO?ZOiJK9GT?NVBN* z_7;rRpbW7~53>OP+F%qP84ii4Ri3O|SGlapPv&UbSQ}MV6u55p1yh{0-`F)YN zWf-u&qOk#jV%lKV4FA2)*5f5+sf&voKPxSVU;k=BjKV~@);Z!T&({8p9UaHBPHDag zQC>8K5jZ*#`fX0(R*fFnf5iAQv%ectw0k#qj~#a2jN!L`Hnjvb4q=eT&NoDnc1pep z9UwM0K?QHiMdHO`QY!3XaWFv`$#139`9#s9NHv$_x6v#dglf1nS%JzCHc`1)SQ`CA z3_b`9{sG674<4mIwX^2@SfH2j+)n*h%L$FQN056Xb?a!#kpFS1_}EPFP_)NMPxQMg zI#ZP?0pBZ%CR=o;RIi~6f@sg*4kjfD6w=|rU%r^sg`8!N#3e+4Fo zvpG*OQlBvC3F^uD#U_+Kk1%ZQOp>~a>nwf@Eegtw3e1fP1{6J9AgqW9I*7T$l+8c8 zfm#|<59ndUR!J4=%)E~Vy^Io3g8w9I?SNfHTr-nrZ_Sn9Ug0YNh@@|dCqegbrr3M} z14AkXbTHw$+o0GehiYdZbx0|GFzK^O%q)*1 zP&K~F8#SaMSZ$NubhkD#wCGqY(zalN&+_@<@mWp4MKh8zA=4jBPKu~=w#w*q6_deL zaG=7KM`)g3P7qGyTSOg6Dx2%KHtF$Vl4AJE(c%Sj}(s_=|YV3@~>Sa}d2CKc-AQ8-L{DqmL{g$zA_ydL$ zy}1=ehCrb&hQ&ZQ(M3EXhDb?e>r*Q&S|}k?#|7}Xupjg-q@wy*ykZfA$KTo{|CSYR zo-Tlr^67LW}tN9D!=;Wz;sm1Pf6=0CF&Klv5?CJP(&5 zMh^)9s+4s_Fv@OdHL_yuv^7YB&ttR@Y@j^+qcSi@`kXUR;yY&-S zQer3&MTEszBz-^&)56c{&H8+2+kjyi_u-S^h#PW+9yW@|?<^hbP}uzv)gMuKcZmtk z3y%h!`L{4pw}T1$uHCM)N~2RFZ2E)u)`aFve^&l>jg@Z+IEEac>({Omv_Z@`U^~dR zwd5YdM<0o?NwAhsouT+3do9zENW3*S!+gyK*ZfuvgR6vCcKJEKcQIUSJSzWB2nff> zoDlT4`XJaLwtO$X<=>}{uH13R-RGbLF2x4Eg84;DDIAki#l zIer9Wna{$ZVF%I;x*|b&MW*DQGUVGLZupM{5HFJ~4!a?1l9(~cMcKzEe%fqCNh#&v zgtsVX1{!2a)F-St@$1Pc7Y|EPYK1}42@(t2#0hF#I17Vatu>iCfG!oQ)d9kUKmiw3 z9P`iy^YglJiJ-`rXW^f77!LL_D50t>#-Xwk8I}@&&_D<^Iw#kSr>k{bW(HuFH4QGw z`8k4a)m9b>7BUl%H2GRrir3k)Mz=6{&`M`FN!ltCsS&e#AlLTUY4v-uP)=00MOajo z`%tNv;dIToYgaNC2Z)OcmHWM}uiot<}}2t1e!X3e!LlsMNcc)ZE=Ri8>8faKQl z88*uAdAkd=-4>^uM+#|ROuUrArSeJYOO>*mZw{vi*AqaW6I{r8T){`EUXntimrkGf-P2qb z1`$}YJV8sAO0!?23(;fI=Yn(w_(#MbsP(A%Y zm?|RKL#3138XP;uMe93(g<|)!0aC!VRw&&6kqw!z!n|tAAg0x*E!g(xV-=-!RcENL zJ~m~L9-b!{H4p}7X1=FbmCG){MUmiO)(V9rhtnEg0Gvj<(&Bw+Jk1aS(MTy)MpZga zEYe#HN@>-M_rh}5i?yaPj}G6wr%bo{!)b6>?)IOhi9)9F|F+xb5Ktt{pPo{|^nP>h zE2YKks=#P_877LvFj{8Z>ys7xN}F*FoF{;d7fE_81FfbRSRMa9Cw94`amxNRdHDE6 z7}8p^HA~&`N}=|^hfAVZ8YLsm{;A!sv0@)2FtiexQo`ueDDGRckj)8#I#^UK)R+=P zyg8J$*~OrboJ_MQNxRX7GVp@)`MY|m@IxMz$``wpN6I)x1OKPoQE z3;$IPvt%ij13)y&Q6fzD7-i^6=sUYlJ$@8W1@7WMPNFvU*3G|=yK1f@5%vN^N9j4x z-0^kcE12f;62Px(EfTX$-lK@{Dzd&Tg+Uwi3H+n)eC(3Hn;xjxgyfYLvQ*P{nb$4t{Xiz4^k4YNmm5K{vv(u2GYsNVFhspVw$Q_ zamI8kX#bR(_kBczzBO4x`l9|&e24Uh{|jvJ@M?;?j8buq{&Lin9ky z6&LK4p|Aa%x(um<*{rpBzs>!xSl_)n{4NH-?; z6DRo-n!0}gV@%40=I*e_ij`{GWcQ;sKN2#gkmA6205$fdbZ83(*i4j;UZA1(!VT4X zov^(nO3*%`PmS?mJu;x)@nuLy1cH82%0TAljuTZ~$^XziK(N~Khw0I3hPxo%nx~dY z)`_Vw(gIo_zYYwbfxf+#m7z?H$`;V`mJW!zW(HlY04f|k+Zm&8<4f(!?^O{Nia3$u z5O|mP9(>$K${iyK$=pbZrq{Xj>|;rb&$D}_V7t}d+WIM(d&>vZ{deDOrX;qRMv z=0=~GynwbC!Z|;5*qjPB$MEhm6l3XnZRbJRz$-MHpVIM98NcGaa_S?|%#LCW7ru;I z^?b}=JX-Fjxu}@a2kdEGDk9gMcXZgj3o-)1>>~Wev#Y#49g;9BCB}GmkTk1hWMlzF z)Xb-lz2L_@sJ1h;ko;kDXLGm60YcOse20!0&o_dDe%|v&-|W=5Vht*tU4u ziF;GzQt;}0oBrU`Fgmn^ZttUPKnNyv<>wSBNt>SqZ~1L?V!6~NFa$1>V;f)v0+&tQ zf^pIiV&0d7s??V9-!r(nnlCv)bIbpvF-<@yRawzXrWz@Qar^%SJn&LQN`n>)9q@)QV)8c=zKSi;luhoI2!YSD~Y08PF-ASE~Zl| z_{`=z{<8okCf!es$oK+g_@TI0z47hI+H@*w*>rk`-|Xw3(L_iubcxASO<|!N#vBz% zp^wOzRECq`$J&ROa9VV|j{8V^Io#tU-7emkN9X*A;Nor*qZYrq^$XJXeVS6HJ@IYP zVwb&9xaXF| zNTW>BK>>!A2=w(u+R zPkQd+j(~vhvLl?pEJ89IUrmak7Z3v{xJg>3s2zTdzPKB+(uYc=MC8QysVm?(GhVFw z_uUvWodoo;UL%<2Mr!c9B*se^mwba%kIu8`NKFu`=(cTmPqOzXQ9cT{vpQlb;P)dT z`g5G$C!6{Nk;UDA6Z=q#rs0(4K1G&ogo_1rb4{OHt`gr9nzUy1Tn2qy&agX^`%g?k;I5 zY3VMJ?#^MD^JDLQ-+RB$^W5(_>#TMDIqO}^#bVE}ues*>)i*vt<*1S}1PTPcpTFmP z7pj3z>eqi3xj3MBn=O%_z*}=&CS0fz*h$eN@+MwP^1HyNfHFP9jv8w#OxwoyBBspo ztU2!RXc(cO7JIt*e?jG0H7Vk(i+}k-g-zkjBr2QCGVlbj21qEx&bPOz^)J8qH9)~uoj&FcQcF0rc~ZO&9L9Gw2*5P zCqVQkZyii{^{~o}<)vzk{i0KsP;`kXvi3`FWFwyU!kIs$I+BeRd)BO#ZVi z1lU!w{kc-p3!tA#*H}EUzvL{O^GH8w&#hU*!e&VN!MPrr3H~)fdgZ<-~Av+;B4EaT6t` zxR}^=PB6+y&Wi>=Xg&`9Rgd~3+;x5M7w8Ta(^t{0UaF(0Kd?rw*B3*_zkX>fp4Dn^ z#Uen8$ZE1y;TWa?Iv4gFpP(OXf9jzp|b`J){`fJXz&~VFK)9G z{eHnaJ$ z9anjmK|wF_r59fniaS{;H_`(U)>2>)FI@WJZ6MwV-KSx#x>NBrt+x$mZ7)CLyMdSq z$ghWSzc)(u72tXEL(d(4+uX;{JA2cY(mU@Nh=uSfQ;bb)v`RIvn2zZ>+myJOGM5ld z_mxXOFJBIcR_p1=Jz$6Tb+rwYd$%Q4NYA}McF>@U$9fl0sX^4Do(Ju|i?T>RPSrn8 zFYfsEeuZ0moa(Arj6Bx!a(_^}rnde1Oz8Xo*fn7DTdABi(5!?5=-^<5}?U0p_X zo_YOy9`~9s4f+S=O%Cu5n}Pwn_&=QS8R{|xbG*GFv$i5b{*poq<2f3@j2&^G3;=BT z=V$0qQ2+o`=ixsXj32RnaXcx#uTMj&xE=;~6c+QkaUMX@X>xt)@O(eYuj=!QiQPfQ z#b!vrdI@hKg&WmGsVcg&^^{PiDC*Jin)KzttPiNR=Wnc{EO&*Nk-cehWhSZ2JMC~V zz(a$LG!6;j!JBB`VvrcQ%vbaiA~3Lv{(=3*S7v1QT{uew@k$zX5Lb*GY@6hr)h zdPwx;y&2=OE>al$ghi`%+hTI7{LAEq951M&iT87++QY788y6B@x*$Emr^hnWJ&W<$ zd?-;7VPu%Vbg7{B?k*Y51)yICa$)ThP%K8R{AV;Jp03! z!{DZ#XnkgsMv{B5G zGC)ff+i}s2;FKkL3||vZ4_4b6@Yn?sJiOG6?lpazFj(Cejm^i^;W6EJF@SES#$_b+ zfEpW^J$wj%_nq$MJHwx?r(uTNahudtF`K#!^A5`ISrK=H+R!^7JGMYF#>E{18%iZ~ z&-RXS5PCSnj(SLIQu@hWSSW166MD-JAf`BSZ=bUdfVoZ~71QGiyG94qm@u$L>rHRK zJ=Z->3yu1C|Bt+^2oyJyM%_btFH zFQBB$20*|s9WWfydt7((;O*tRBye+pTli-|;-mJTOsp*M*Sw*CRr>$=XMhj-lK#IQ z6R3Y46Yjm)4F$>IeWbL(sC$6fS_GJ_5}*?QY`JR7ULH)2Z~BNxzy9^j{vs3q`6%oe z5dJudVvI7h^CH3XI;#4+6%W=5%U?`wmP8dU=ewiodzB`59(N>P+dHys$>oeI_uWiP zVY!E~RB|_v_=3-95DtkR6C(VT9DED^gO}_M8U&t>`C1q(;$-^GSJQ*pGyk0MANdgr zqPx#5g#O^{o^BR6K{mjm+*AIJ;cJWt)S7(f=R-*Z1;~M&OPHknCgtG~Sd2H91Av5R zaW^zf|D=5igKhB}21s}B{sG4JADnP$z@APPnPC0zqor_n0Wx1g#HRcgdS*#0r=no= z`QNKe=N$@z=jWPe88(IsKJK(r(=fdq4Qy`9rnx+F@>JigU#9W0?Gpa+Rl%ACk3`&z zrzyy&eIGI8bQU$<~~7hEXw4JRt-zQD$8fJPj!9$Bnjn{_^?#8LyF?vJlIDGjPq zV1F41?0(a1a~(@&hz;1FMX&4ZnW9y_q5I5ul?tz zgHsNsY(_XE8kifbk?{_)>e(gU#9S}X9osa; zfE#5=<#tK_`?df0bUq>#W8IBZ|7UPhGL!+Jl=`o)t|tX!7e`_KO~eg21s@{c+7|GVk)-3PS^ptyihtLP~xUz8gNfU3%f z52U{|@}u3IAOgh+ICB5rtd&nMsb6~iRvAdGL%IL(^li?gwT^EbY6sRx)G|r_JdT8g zhA`Gs@fbSQ_9_2O{FQq5Ga{==OJ5+GWC&;rfbUW}2ZddqS+lqbT5&i_)q{jIRuh<$*r~k zvQcjZ7&IP!ADhx&2zWg4^768h2VTJo-q*a~%^(ntl6l|Wa9+#+_U(Hh=p@m2td~qB zP0;z}>6m(i<8w*_@?QhD(F2t|ueNX1H8$bDr`N;o*0xFJ3Mt=CJw5{ht<_g2@V3GfqDalb+PmF)C5@hd({d35p!&bhYbr-@Sg#-Q@*8s60+xmU`HGrM z#o@}ane{&x_WE6@CI%i%{dYdgQA+2rS^yvF0o8+Y=8y<>V3}+X-akSFoUg@!IQ%Y# zGPBuGA{&hcabz;D^L93Kk5#XPp1gVgZRAHbq*}YBFkls!Y0&mLU$scBoSYmQO3Y70 zzM)0k%d)mhrM)ILyg6ILfI}nqj=sgX8w0>^x~!ZX*b2bZB0dVSHvh(oiOMY^gw)a- zO#=)&ChOKB74K$+fJF93AQef+lLg#;+RmdS)By5ZRVl-?P`xZI3Z5wOJsyR7*1M8s z^(0S1GEVYb1VCO=30^$+T*PlP26R=&+RiP9FM1+3@R831>USG&RmKX?5Lji#%J{QL%ChJ+ ziAJy6ya)a;;R$Tm++4PcVW7jD^|q$(@TBTC>*(bSUh%jnh&C^E9^ZvJi*)}feD#aA zZFN0D1QH3Iz~Ny$Fqy;Je;{$tyPmeyfrQs7ABRlzTRvznWv94AOER;EkQy=sCz=B2 zdY@3H;&T9%siDJWA!4`qYD@66_nBO7V8^K;B961932OZoJ)Bvqniez>tvHS9N7w*G z5noJF2{ctANZ%mVn6LSl@AeY&y9?PKYDp`3fi-6}Bze7CH8dV-y!WF-qWS(q3>B#Q z@y~QY68J5&Y&INFKG}+tt^w_RNty9Tbyr%-)FG6&t-Xc?&Y0Hiyys!S%kWOh3ck7Ov&I5(-YT~HAOvt$mHy9#ddgQBt5~Z>YT_ACp!e#Og_Db=IDd;d*Gg_VF z`jdW^Ru!loG=(mmVeMfW&KnhS{M(z8p>3jY4|vrV8Cq<}T6cDwV9WapohCu9C*LNP zY`MrOpM6G2KX-Ohhke)+yCC+Aq?9x&*5Jh)$x8ON!?5&ep(hAFRI7RG=_eLuIG8Zv zI=&Ubir(+w;F+yB#!3I^IR%nGmE}QUvQfr|!T2KgXZv04L%}g>jBKXYcondl2%vlu zL#z1s>O?BRL{R-b#)&&fwup~_{o>JXm$Y*YK3jlO>O>%<+QW%PiLzQ?Gf$3XjKJSZ#58Hv<){+b?gqc+7E-A6|7E#aS zlv;q??Dl&Kx8@LTh%_P`8;eYV94mMrTYeHKF@{dA4<<9rNJKr)x$}9WBAhHx7JpG> z#kAGG^WbrP1w-TrAUNg$h5CYn8?9<~NG1736jD>-$Kn%!VEzsI!)6^=hU$wUr(Cik zjqq%Q=HhG)3(!A()>E0c=BdeI-J?e$;PEXA?PRsrr>ymM7NqqD%PAitVR`ZNtKxKk zE3AB4eNhOg{)M!2IFiF^tjBH_fHkZ#DnNnjeRSkHrzrq?O-$~ zWa}ZzalOj9d$C4^ii)AOpvlRR<;o#&bdJ2B+-nHDL6H$iC#pxLfU2J-NHo1N{?Q3s zhl|J^rK3oadoL7bvd9nBiZvAXl&{DNRx558cMCR`;B!Q-+=KP|U3PwfGd?XB{+z&s z6xaLm;H}ViH=weid1NzL{V8~Hn~;qfSU}iOo3(&Isqy00&nF=4SMLf<;8OpE0Bf?Sg|hVhEW zWq&?Y7jm(@0Gg*dAU28=fYCha{eQw4mmA*k`inE}{36R`&*z?z6OxhnvUmiXc7>pnW@x+h)1?b_;6z6Vd^D_NIWQOs3A?F=DwVp93Pp^Mu{BkcnvPr?A81k)uQKQSNV z7|o#Wa)ae(G)ATAe1U)(j~1GM#yBk$WT&>4?pGk3wGf8xX> zu|j)h`EKn!lU>{AtH`af$At$EF<+=zzd853s?1SIt&JM-;zrXorWJOqv5Li#{SXy8 z{{H&iJ&fnvUqFbMp_9lm-Z1jx35OM)hi)A;vtG;R(B#_R>!I3KrL5*Z16gxgg!*FO zVxqOX;s2Q}4!wra?1IzUx7`ozcNO9l=~RCW7~1((I2PhheFX?9!WHSMQi<5@gio^_cO$am6Q!zvQ&Xo9+=uGVWgNzBbSbKX#8}`M?ae zl^8(*WTA>fI1sGxyXhiK&r&`4A;o)oDhebK*iLV{q@QzpJc=({`qZ?gncErkJHudq zKq8Lau!pEzd3$iKPNUN5p~T&h!#EbV}b_6)FMmcxgzE%{Nu7nPt)n%I^7mQQo`L72BRtl+yNp`g97M0E!zsxoS{GrS*o1kk|;Ptz-Q0f~iik zmV(w$k&d@a6DPo$mZ1+|dn7Jx<9FE@M$DOw4JIv}6*{I3P&x<1{B8n!8 z?P3e?(l|WHf#*o>HulpZ<*79K!i*Y9MHa$=RI@088ou-E(NY_<6hUvr-uSzU4!I4E)Tve4KNvVjpde?KB!7dP`g{GrGdOh`7Jj zMQPS#6E2(ZNfQpLeK|FLH~p3Phy3NBm7{KBwYbl<^FZ3al7}UAZ9#H9R%^#%md%0N z0f(;t700MB^;{4B(Xith%}0>3pVf(d;T>Aw&jJ_Ogsq5k={Iuf+p#29JZI zM3|80;jd4;yh_K^@@YB?!xJ=nQ~M6s65BY5lF<*C?C`d_sId!MuD2QTPPB*#`+2Ak z>?pqO3DzHxj)<)JhvjI{av85_& zy$(2aTpg6+hP@+2NeWbJR7Oejct8b00PF?X*#sm=4+@RPe-qfH*M|Li>076|M|FK*}@I4k{Z%8_zP%RC+ZHw zU+7|UzI%}|U`dT&_eVku1BhT&XS~9jmttNDEFbi!kjh$+Ir<=;oO}~;yY^pL zfc2h85wY$Thqd4aE=DLH=-LyX`NUz$-~I?_bqug*6YX(+ewRKeYL-O&FU0tX4p}1a zEb;=={-|E3&I6!qqR?uH7VWB5Vip!Edozd&gTSJv|{=+QyK2W_L}&tm;D$LSJk zCE6TfnMkPRUSn#z^Yzjbz^{#-QIor$UH?B&uGNo+i=!e4hS=Za1Z!)PlEmi&i zr4NYxhtiyrqyNZ&NMQno`L&4w&poWoryR=Q1=>=#;k94s(dB z6|0Uq2w`Q8 zNB!uN8)HFbUoq*CO50Q-a5CHjuoGe##0enN?8|ARYv}_Z(BF~-5Dv16J=UqPV)A;*DW%HsKhxsBQv9NV@gCE}T;8;PS5?j% z`cb{*IPS=*Z!^a({^Rl1`^}zL0|`9p{LGmfzaOv-2-F4oa@iV1e5VDJn|E21i)##1 z2JlZJ+wW(*XJ^YfFmG=gfy)SqiWjy#%@>j&z%AeokzT8spE^#Ehyj}Xoh_aZWy+-E zph7HGR_IncQsi-R>DcUElJ2k6ZsR19ftwiz|5BkTu1RkcYIhh6Xp6yd@jSN@97Up! z;RASRa25jM>AH?D=^9JNh|R9OkMRA~g!|49=5TSkhH-JbgpI2l4sI!m7b=Hj=)dd{ z;`ZXu+#`ScJ+%?@=u+~lX3mwP`P=>7buPTn8mlzuTK|;B4HP3<<5G5zwXK~yAoq4S z#`AplL0suf!6i^2MMbxYKY6nCihadM^WVWr`JFb{?sTQu6jlV<i$W6qmg*n-QL$&Oyqi^ZM&%bMd3i}{it z@8G?ldN~1m9u&dERc%8R6hp1lN*PJ8*3EG&Lb!L5?{%;(NCP19UBy)x@?=gS7(=Iw4Dz=sB3*3;2B_k>gomVmq84aw`mqq%Tc>(<w3f%_FJ;ex8q;*4W?wX63{qSQiz{o-Kb{XXt4$G6W$y`IdNxW6Tj zcG(^#0@XN?F8Vhk$YNeQw>C6m8=lgrs+qP{p9@#xR|@8;4+>W`G^No%v~`@OS6oFv zXTOmS8O|~v-su4KNf~j(ojKg6_Vb&DX4uGQqX*-?#z63rd8}z?L-kyF>cG9|T1+_Q zwRxdo!LWnAG>k1*p8d6pHf68NUgLviJ(ZF`ujWPum+PZ`bN0xjlhr=Mq(bjoe!q35 z*`n4n;R?}>ccV=u?#-2xX#$@u_jPy<=T={}W$F=WVlJk{8)X1Xu4ENAiYFXqnRK5s zG$zk>CXT=H007ZDDK)$KP$;Gk^Q34n9=2)lhDafviVnUOlJB#(~}3j4MVe$wl#jFoeTA2}lM42*`P- za6d&fE|pX^c{~hM?dUV}D1(BjE7PmGbEWWxK}=M%84x8ZhllzeD0)nn8;X=$WJPr^ zZkUvP9FU9ph>i$S1Y@T5JpSq9`@+MLR%wftis zja|^a>RBNkPP`qEyDvwA5#JF&I43+Fit?(DT==$xjNV#PBKrLFcSPLANLF{gc54An zYjLkx)WKhvP5R9E1Q6zg#1((fAHkIwIcDs#aZBAjf?@Ve42Kw=U(@cC8AeY^5mdUE z6xUP&hML~b(QtL+T<^tM#p)<|7H&(#q?+S6#qE^T!@=abtfh}+R`NG3MxUbcPbIHu zk8=c+GW8}$(Y&r5KsVyEsBeE9MNuLay&LR9S2s)9Uo1SzFSa_u)%km+eyG zsWO_Y6z_GJdpOi`zLY^YNwLuzMC`UXl!`E-iRqq(h?N{%&6sFs9?)$-LPpNa5k2mY z85tLsD3V42?M;CKxs$iy;VbDgPkzWvl8a@lSjZRA#)u}59*-Fn=~qh?#1PQa zQCVV>GtuwC9t9E5kI+ZaN>_?aCf1)oJX%(CHWusqc|Po?Ha7o+FAWXMJGLwxxOokw z)_?d35m?e~TwCKZmohXw8ho%&XKS-$*ZC82zQ7jg<9BuSfYoibd!10WeyzV(OiMO0 zCxRl?Doo@a0uq)GDH9S3L2eg2&6y-GET@)vC|`A`m>x$f*7A6@cYWSRHNu{Vah&Rd z9QQI(73I5c1{wR1Wj{jRmY~@2=#F2?dfzR}hZ*Y~U}t8UMhn&M%b=tv`-@BgOY#Dh z@NH#Ux|XC0L$DWguP#$sa@!HCt^LJ~hTEvqNO9s<{li!4&eB(?zmdRoB+Fk$ZRnGJ zQ)m-r5XGn0$j3*kX~x{Z8 z8BLwoHyf|-Rga3lohz6HoU`n16R0)L_EZuc{v_jnkb;cn%yXF+A6Ucar64h_hqlI9o7e$8M3ybinN@ymoEISS6)GPR?(Qh301q(K0_=Z#p+*b zoAx~A$wp`coqBm&^ zXTm2`B|0wlRk`cNaDxo~-K^L-C(Ylwjlu9=ZL@vxEHuiwEoO16H4i(AUm+L%GRJ)S z;1Svb-qz8S_%VYFXISrgC2!rSNaTcpZ#vTEqc6mYWFJLR;UwS?I_!QloPRT zz^h@d^V~9>N^nd(Z65=gM7 zP9R8g0W^yR;h+7U-1mf+v-r(#Y{OmW&{d8U!auB-?pZVSzsMJM`nr+4z^(92z55kx z@4|H2lj0mHCZz1XbPK{;k+dX9;fAiG$O)5o7Hz72fU|HU+P1@$~ zHB*bE)|0nXm;(0U>^ANOThH(!LDi=B>)d|K_1Sjc=190`&Y*oL7UN@@&Xpqq`(tSv z&s2|fpXK# zCdsFK6mE0^r??Ji`v8uUuJ}- zwr)nAEctD2)^uy243{8eIF{Q*Mzp~0bU7kUQi10nrK6hStNcmh7URdQj_2hwDPc?+i3 zMS}WHmcP=yv=|9fmSk;PDqMSw7TUpc_`Eb`Ow2*{0o{AieNJ~#mA8a5iJeENA!R{w zme~8t2h>%eur|bZv-|NUt#NReU2fCGEgVrU3)WQ97j#~KDoCqg|C89F>T|IByRT9S z=bZN+ph>fZ*}tjZfzPSC>+M2k7ay@|t!xk9ve$pue6hIJ2-{#EuQ4k7y(P$^#edup z9=su36pTDu{3{i9wL$%oaJKBo=v zKkYBD#MOA0u$8fh3*Jf;bodd`H|@7_^-Y$*r51Q=OlPa!J|EEk+O+F<@=S z&oZc&viIXYEFAr9Vo4A4`*FD3G03uojPZO^*|gWI>DJi;>|HMo<|>T4r!$9n5ltzv zw%trHk*#Wmsb!Nczep8zHG%#74Fjj;9EEro`viKU^A5E*iD&iDQA1~iS}I7o!wUTK zm(Wh@3%$>Fy{md3p$2GOH+|{ZME;cj2nmfd_WX*_A|j*ka@$ccJ=%Sx79czX0(Kmn zh*tBAv{drae&7g^s+13F5%Ud`lv((-brVAd-gmL{PbidqILkf#nfh8xME?93Ch2#A=HXa?*g?qZyFI*b_cXlyw{nX_ zEY3!N;aTjxsq%7x?lbeRaI**A3(THC%=L`Xf~AtbGAAPE_g2&l@3}Nt02=Dm+;mZ8 zET_hF`Em=Z>1dT%{h|Uwwmn&vP+R+GihA{Dzw5@}MbC#lnFn52C7iA&p>TZ2wEaz$ ze6X5dl^qe~Tx>eYVbu7>bOuurgkuFvG?|FlW;{P*lV^v3R$~(^ z8T#QuRhb$===zU-cj9eF-6F_!tKEpp-lv{Q6oPGNz5on4X=grEx!6mtvuGg(m4LXJ zhBQCIMvKIdPrHU!2ZJ|1sM^xmb(pnuBW12bB`^`*wTQE}Oue$M4Va)GHss8EbVY)v z(84d?f&=KWYjChhUv;?Y#r|&+AVOJg+?bW)UK16I(ou5_lW*-+MoBFNpi|03k<%et={o6G=%{JPqkNEwFuOJ;}>3xCSB+h~CcC$U^ z-@sX9nu7M|k?Df_QeSX)wJliy`_j@WmtEVCk_u(6aON%6sAFNqoAxh{dy6#Q$i1$> z?^sUK!}*z@arp?A}Zmmh~G8xe$WVo2($SwqXfebR2om>0$==QyjyiU zlO=3zlnYMvDIghY9Pm}!o77jcc73T}AsJqAu;Oj3;oa-GEdB3{2{7Ok$# z`#b$lU#D=PPQ(mbj4elzbc$=83KkJ_=iGj^!E`}ElLx5QB=Bb)vt?@K!{3z}UG@e> z)n`FI)rhE;UQtL~ySD z_)C~vS}Imxl~BGxMoY{1R0IzXk3;v14+#;$H8zV)nxG_XxF3EAUrwkAhw=Xca>o>& z(DO59%`NX)E!n+{0AkjIXRr>RNu^?<+b4Xk_QRaNWh5_9z7Yhj9T+&hENeOrX4EME zj)csC*Lu(bMSh;epIUwJs$2{`Mk8qO8BDOYxFoMx1ck z#RQkbo-MQ*D=*A4bpuhz%aZrKvY?>@=hg^uNpmO~-g-b+PI7YFxiKrK0p%K~o? z1ZO`PwAzIE&8;of&=;G}eyF$^U%zHO9-*NeS1O5=X;7Y>@Cuf?AuuFX>j(I-e4xYL_#C&?QC+RJ1~HRE%swNITbP+4^2`W3wxwV3g9f?!ca}RsA z0=1GtR2>MPn3I*N@~YH_ z@kS+UAG2uPK*}H9Kdaz{jz_S~yTvrZ}tFxX!=@DBs8yf;Tg(& z&1?O|+e62hO6O#rMQ_Q?n;XPLzCGiUw^O|iBm1W_&;DGHNPv=cwpKH>V6ZqXrd9tk zEkl@}H&^;;K_GENDn z)kuXeb`~1z*saEUZZbyDSei(+GKB3k(4Vq)-mrELwgm0>U1HgjV=)gKs0Iyh48^MJ z(LE$~{c7pb8%4FwlYJmtVybnYA71>d(p?6K7=xAB;CXY@y)L+L3tfUsHM^h5I4kJ} z*SMc;kG6VykE|WsKp)la)<-*YVWiUbb;qS06{Z`-j8{zE-~s_}fI;Y>?)uKGf(d}?pE(mNB)_YuKt z(K)B}q)atyhFaH1Un&6Vupcb%;v=774(7_I+b&W7=CtnZ)dq>OstOm(E!R6G*SpE6 ztT^l7;n`K;!Gn@VbF;br_-7pX$WKT-PZb??GF7CdPkBr|dMWNw$MI6#Ip{-UEvnN2 zwjp*wHdwm1TC5&yMeap7>?{vy)F+VYw&bDtGcn^I}5JTUA`kXEJK zelV$KbZwq^Jz^vM83hyO33G z&*af2eFc$;r1-UlV}9F&dY)WNO3E${Y|AsRojhEnL}#XW-3n8%&x~3(+xJIT+M9FUQY7}iA8Iieouf&2`pn0EvnY`ixcv$VZNbrBtNoi%m(EO` zmkrOiUav*cuils^Ew_?hI>(Jy4iogT*-%ZI2hV+xFRRNT=v-j${(P-XK-2Lg&0?YNIaLO%+YFPb zA$}d@uN={yTp`Kcut~(v-3tjVb$}Jxsr=n*g?5Dax=D(g#Qy=ZGuXrTtT*YZSc(4Gj021!o3t(iyUxDo}wW}qWHSs zKDfTh5xifMRBL-(br`2@8)-FBm^f5oZ&2RXkfC?5J=nS25s*wjJ2|A~d8_HUHN|c} z#M%=%z}ih&cy}m=xt;IM90OsC9vuZ$7i;fGQTBcMm>sd}Fs5CLI~7d1Uu( z4+Md+A{acK&zkDar!GP!hXnUtYnXQ0@11ZX2GQTGR0}LUZ@3Y^y3f<+&f|*IC^uj; zN)RNfN!z)0R9%8-wH~0V@NlPrqC6hWv_+T$nO5@CY-PwJ0;>|`&upbsp6`s}ABAwlAOx(v;+nOpI=+=HP% zA6_!yJB6D4xonrzi(^h$n&!W}R>$m@~9g~IV%_v7}HCn zY~XuGnT)&;u=rYM5&ny!{@0DI!%67W6?+!hFfl)*w@}sEvMDjK4wC9?GPj8)SGjFV%4MaG?<-nN`#4CUZi3w9X^41c;07ia5(=7$6&GhSwLS zYvRm4Iv9jsKRdY@w%JUrlgyKQ(Ih+TnRsJ8wzIMiA&$9Ngr}oUHXo0= z;*wXViMPcic9~}?x{gc5Gy1ABevRq1-7p8J4cFDpt5|+gOMPaZQ4rYl6m57xN%vSfUfVXy*?w~? z_c))47nrKp|LWLy*my9=_x$~IhCrKn>cK?ORDx;79+|u@f%|g%0p)8pWvv?C_B@s; z4O0)Hz6WUcnJkOBEcM;5I1;aq*_BNdxU5?VTP{^fxtZ-r8OL=jlJ|I>UNsI}E@_+A zcIuSB!e;!kn^@(tfSh=;cCpy!{Yk4pEhj2v_B;?rnyU4Bl4hOT^JuijSi7LK|G~p) zPMbw~yB5JIq)VU#L$3R}h6C~djbMMiMmx9V)mRhhq?9k=2W!Ie-NM?Vj-h_H{G+UY zVF65U>jaa}wbFT-kVvvz+D#RJ%uaA&A86x(M^_}`v2seP@mvpo-ue+nbVVnXl~NsAo500@c40kwMKzEeF(t1BUda-~dHz#;5kJeOBL& zR@b4IYLVW5gx7oa4e27{$@*Y4*P?3&lD|{ITR6SBT)Ox9hC_K@+N6VHhHwLLXl9*& z>?QkqKu@=fKX<)D$&M2GwvnzHbP>YRLVJ`lOy2^GL65x_tfUz@(4V~g+UdwMzoUze zEeC9TfYO3pdP{X?^f~^!r@bmkm_MnSk&4qLuX&Ga=WNlw4IF|8LN%5vd-7={J(>t* ze7kAV41VRZQ&Jb)k~W@RvRn(`@`+Zy4Oj3_Azrf3(Tf<+p+TR*3#W)sL0tBt-s%;- zew{$CTIkB)?=M`TS9YyVQ%&O7j@mG5xbgMEaK&%`>WC;(c8GhY<$5B@t%utj$~$j; z6qVy}S4VAj4*Cr$(~`gfl@Yq9{`_5400PI26WsHIzh>G_owvT_{jf_KTcj3QQ#2J!0J&ZgXB#xG!)%dkaM^k%5av=|&c0!a z`Fbnrdo%L^9sV)BL{+ZrzyZzz5*n;KBRxQiU~)NzsM|a()xf27Z5_eEEMSb1tL`(Z z;Fd%AK@;?o+q-$?aLFRIt_R_}Wa8+>3(nmoN(EA;mLpAx1@Fu;Kb`GBVpAYLHPwNNh`@<4Uf!O=l@}PWgSslGWcMRIPxRLHj?0s`&{*-T(SXo!G!;vVs zM779lct_JGzqxeZPHkN&LSk$buaiM_hbioJi(uz`R(Iz9-TK}f`j z7*EqF&eTkM)}cenD{1jh*@Atx&aD+U?5FQzLO_izr1o_Ux1(7ZZNbug{nYEv z7aaMjWJ(uR-hyZwQ7GYgV&%i1C!f`%d+@5KdAfX-@m`@iS=(*2jl*!>?q7J(*fSCu z5@M@eZteUGCux2D=Tsp+AXDonH8(YtDiTRfaz2374HV0;EjsUn zFmM9|pE7Ul>$khzb3R{eeT7w(oyIVrGBaMO8QpK zw42>)Kvvb7nUR~sVU3JVw{;?apI|or_N+y%#C|S5`F#ZoVlSz}>_&RBAyATSIL zN$6rI`6z)!UiDF}Z*sf-nn=axt@F<0S%EvY?6W=d{y3)fjdcG<#xv^d-Ll#!ol-(e zjav{QPgs808x9j|eI<@0m{lx$NnF{GBf9?G(Qh_%W)YTLixn6vWa<5I#Z2c~2fkC* zI&ffpYX0^1#_F9 z%jg?hm%E0%b#1~B1;sfcmjf)GESP0ZL-B6x%x4ZK_eN!tY5otFH;=1X-dn#gPXrFl zn(n$YLn^$FYaSG4a(&n*WIfDnL%@7p2IXNjUf;!$W_#%P*hN<})cU1NN9j40eMvX@ z(}1y{@`r>RPkOP0A9^92em2C78?cv0Xfgw4w>w9TQ_M z#8Zz8>8kaDA-i3U&@@dnR3FFr`yL;k-yZF4=>Lqz#tfy$W*iH)RM#6(PU1Xc+BSLc z9Z_|A)XF)jIf1+28+S~N<>kq>HAH%&>b2ArKf}{aW3_vd_XRH&AbCSknMBtkh>9UC z&^Of0ht=$MdOAFlvtE~$6*qb6`c*Mi%w0uq?4axCO{W?qH|O(?xF$Df(ao~5iKoS{ z%G=e5kdtqIJ4UIKc@T6}jv9bKR)B`Xx&fNiFEr(g+&+F;V>ve1F__E|+ttd*fuPN? zKYLdEapJY$jYaPKt5rR_=<}-j^$n!f>eoDz3UOqOp9lL z=JCZUZaCM8^A>)y?AmKc>^Fn3j8cZZeyx43;hN0w#uow68_AxQzYH8L^wXvr)QX4G z^caS|cx`}-rf+0AqsygSMty;pH4WXmr!IMPIJ4d?cgwi` z-0p9Q{<(6As=OMju7AO!Ru+kH|5`d(EdbI=yzhSN-X^>?XZLkRFv0Dm$c|gdn}J1j zT|>milXdUC6WFiZXJyepUkn|({RHR5r?ivh7W2)Mi$SiXxB!x;du;5Uws;p)8J&(D zj~2ECK&w|PiP-fc_>es7YmApuWpIa|KtwV&+4hCe`Lm1DmC^0PI63A#-{}B@?H8H&{Lf>bfMLh!DaaSw5X5CxxErdlB* zjlZpZQ~!Q-;2%wn|Nf&>TByhkzpO73*GUYcM29AgobJ#y+sL+5r7(u@$i7ApecfW( zZexEzsmi@3K{XPct4HD|gJ7#rHLuNEwcMC;IT6|p$Poic)5dpmwYqnF zM)Xt5PdN(7-Js9CO<>{W{L^Van3XkK`0993%DruN+`6w&V5>EppVADIfR~4>4oca_ zUHpEo2;nXr$0feGSh6vbTrq-5DP;)T_Kc0YO*dVUoTN<1#*4Z%{9o+7WmJ`2*EVbc zl7b3Ig9-?2q@_a;>5%U3?rsDO6r?+p&P_`Th;&FdD6#48d>1O}#&>WYFjpMs zyA+xg;Y(I|iJnLhv3^uL3d|7+JEY{KseXEzZm(d`R7tW%51j;9<3p!$&l+|@EaIkW zNXVY#sLh(PRg-UefabWBJ@_8<=bhFO31^U?4OnR+f+z5I)BgI(uM7@(g<82vSkFDL zaZ%bie%@;TrKwK;@*$KQWP{%t@PF2=&J7xj$0joOL9HWPEV)_(I-xEG{8&03lWT`{ zK0D*wJvNLEtE%qo2AJpbaAM6fuOYYaMsoc;-u(qhzw&rLK9iE=VR#U( zVpqgknHqP8LV$3PGFjYqE`NM#MtM2#p}u{Pn*1ij(ro*c{c($-z^%K_zG!ljm$c{! zbl<}mLMr;~c-NmMwt)v~ApwPI%<|>y!q7_hw$j%}Xt-I?unApN)||FCsv~gv7hY&2 zS|8_PQ`0?uEb;6eqj8tyTekO#jovW#as{{DJ>~+5jg&W2yC2Z#5SJ)&I|5b9?Ov1Z zmfM+7^=8W2alJsVsTGSZX^vj$U~)AGst_o#OQ}ulHf`xMrC*AbXj_ZK!AarO5*N4Y ztOMr_{8SV}%w9g?MT0kf%-3@Od7#c`d+a8KOxomKg*ykvo`iod6|e_dsrQc&r1#d| zJ(Fl$pQd^eUgzrAyn9oGiF_jx8w*P~H#3(>WPRRFZO3}bYok3B)TuOsgEQUjm<}C4 zcbK75<#m`BnM{6KWb}-C`U#HT$x94K40Q==mGaNDnN~!HRl~FD>js^nmuh&Gp`AhH z(_88ER$rOPR9G@sJOW$p-h$ZJR)#vkxcd&ZhtiaXRbO_<%W! z9Dx9uE0ZJhbrBm1vDgh0V%EVyGRfWb=mMRC zx3Q#OOw8*hDT1)o58@4=k{u_t))K);rPCt*VwuEhzumywkTn{v*__ZZRY8MeWHTS9uQ4uWae&RywokK za_9p0l043tcZ~(*qGVIFaSn?ltTPdx_FfzKbDt_DwwKQ}{iAwj5lVJ}u(ci(sKv*`@hTc8iWj|7ptbBo0 zzsa;@jHjNL+(5VRMoleo4X-NJ-X>i@vzPm$rhBP{;R_N==oZ4@9Q|u(S!y&`prZ5= zu0s`Y&E5f@aGka7cKXAEo(wZ5rJWrz#S*t*=E7955`#Y!>Q+Rn{ek`8LTV?-RLF68TVxl%fewx)vC8U^$~RB15SUw@hNa zi)_|=nDv{tm+C_?j>4b!Wdte_bPa*)G${y%2_}yYgGdNxeAlC>G0OR+9XT zc6b<+u-NsNp@)NO6a*Hr7QqY5L*c*;X06 z{7cJjN_%K%YPBPO`1@`CW9q~=JwuSO`ZDF^Pwi=p)ptazE+KNk>1NV!^CCW7KXCHx zR#L$w`}E=dQ!|!|H~zDB&k(h}eBP*B{P*qOe#KgiEi8vX zA|ylhO1!|7Jc_`tK$u4n5gh`dGTeXsANueoMIqk4LV*n_3^q(#twk;q2|zAKK)vIO zj5QzBm`zxz4k~FVP8}D7{>&8ys%yyF?(c@2U)VuAjhwq@vhyuBuqYs#f^vE(vr^Se z#xkM8j+iR36De)VQ}Nlu$yz?^`Nr~9J!x`^>ng<W-R94p=+7UZQ+ooMgA(zn%T*0Ik{xs1;Zs~) zy1Sv9t>FM$Dv5AEDgk7lQTGAo?&)Pm>*;0fp=N^E_BBH<4b8%b{Q66uDHUe3?6)tJ z@H!a}G|>3!-(lfT@q6}Q2$pIjx*AofK_v+Zwvr&KWvwz0m-(0PNNarn4~9Eek(#=J zixMFumskXTe3Ib+_*&adJW!}f95K$jLW~*X+oMY0*8&|c3eamSh55`U_>>OZqg1IyzrT~+ zFJ%3WoFoR7Ow}4GplK`sB-HlU_P}!A5hJ|@L#V~^x~|nBvi9`hQ-ns5%6%vOu>YOt zfw(c5ZAz6$0FOk z#!5i=2ZcgM2ExgcOcp!Sxl5ihw|19G#_uyQFw7dxAu)tf$_9a4VZ(F}sDhwA<)gZ; zl&=8dS@Z4FE;TA&cvF9b*}wmTt`0_B+X_%x0gmZYA-;>BVVthnr8j(Mi+K53m#_xl zzIB0qK2X?5nXNGnyPZknC9Q#{cSkgLSHG>#XXZwIFz(AT|J;$koKoWBg>H8k(;}@27g6E$4l(oonyMviQC^`-E6h?+Q3^35qtaVl{Dx z#aO=`0qlKCM6CHc^4UtHKrRfEi$g`3JCo3>0qbahh6Vf^z)6k@W4D9P=Ks5Dw`@`Ea#!%GB$F!^~%Z% zt&CNQv2TlUcQiF2vQM*_p58Gy}dfvNLSXT`*qZxbZ}_M=4xX?&?W$uq~ni zfjQWeQ!_KdfYJ##&n0HDCZlD&o2kklp1u(s#(QKENR?Y51x{5As&cH?0h3L{&aPO3 z$ZV!_UZFz(cA8n=Y4?;f;MnZsO9nL%kP`fDBprnFZSzB(o;K*j3K4e;L{FDLsQVmA zf`HA?3=+q$dwRA{gA^uq#@)j=+Sxmt;Y&uWURMCx^ca%;wlp5QT^3^HUAij^v61ne9hgUX8#IQV5Dm1{5kqKw+JF+c@#W^Q| zo>dqN3j?4rjLXUzXiXFjdXzbbqZSi(22O$2{Zn8$-hqxn2b-ziYEt8znit;JRM&VT zv;eBD&UOKf&*Hc`xM#9H!_2^3W*DDN>v@dReELiaE}INr%SW(|@2wNRiH>@0?Ezk> zW4O+?Kz>PL%l#YpEVL8&^9q}E2lz(HN|*D%-PU8D-n$=w))sURaa(o%XfcUn0V<_5 zF5ZHOf<~Tzkv z8PE&;4u`Fxu^mmP?K|SMkS&#`#eXZJTkNVUsF{C6RE~&cRIbD->1~PY(TzTw*FZ=G z4lt3}$wnVjF#(>@=ps-7)LTL96CPKEuOZhlrF^Ra6>kyfiDuiYA2<~ZRyvHj-IllA zHeF7+NtCzP6x&%O;}gAn0K+RECsj_P$3r_!tl@o>GN6SRWD4%BwCfA|rJEy>*-K z`BwjBtILo8>b#322WoPw$?$w*3IS({R*3wq=Djl$AOx8pf)rk{1LvQZ*=*okLM6VS zdvy$GsaD4H*3z(i)!q!=%A}JCpnyH0+Srrdb_RP!Y_$Uk3;rG+w_C+&iT*_0@#S(2 zQwths1Oi18O3Z6os|J~~c~e_fhB7fh(AWnV&rD<=EgTxF+!AA6%+#8o+)0 z5wytTXM`A-;-YW>JEQ}2I4CxjI#Vt?=;RQ_J=Op&3^cEGJEaGRkSIsXvGlAe0^C)& zp8ebb5cQmQy6J#I6s7Esfhz`FczwmgzHQyWGBSXI%H6T;qpMy3lR^PxM>i~)9gD!R z0~1GwJ5aIv{dMJ0dL-_=o_PUd4KJ#;n&Winm_}mdP@L1auNniO-((ImA5;G-Cu}89QqSyZvG3L zS-pWZX4OLd{u}SXOtnki@`oBaXC7Mo8X@x7`!~1`EnaFQ$~MuCtnKfD)^@EoKjSJW zSG!fFSM|T=N48FL8_QMajz{taUeYQTVVbKmIHY{nF~qFEBT2Nw-Dg_QyJQY}(!H0x zl1;4;os5X(%eD>52f{#Y9BU%;fkNVE`!PoWo6={mh#T^45-hX3PB2>k`(l@ z*N~+_OJvk@g%mnC%`DX+T$T8tGia}FI=vz>`S(a{Uid6MC+y%UOV zZdHR4e7a@#^NZ#hK)29$kqr9#_^{L13aRKye35LLWR1X>yW#kg8(8}RU<*oy;}e3- zrK6`8wLt@cF!thB1Ekz2l?!&+>XlCh9?cgKDg@9YrH4ZgR9aPQC3dqGhBft3zEgMI z3a!{4GR_D0M|pHy$)-$iAy?KG`<{x#_s1hn;=5pm7HZlBQxx54KTKBw-{itpDsZ%+2+4zoRKsWmPBF?QIX{(-R0(&t% zz}XgK$GzU#(h}SpO7;3AzuC;oXB){2lS(dxdE7xxEZ@=w zaPuE&eu;^}XTXZx0X1Mv0BNQGafvzcsc``U&aKH;`nS)Z@h9Y_P9p|Yb4H`nB2?;#l?)jB$!L&pn)ndgX(1^w8N?g4Aap?}@ z63E#}zK1_LEg_hZ^L~Y`V&U0gS=M8j#=1CIkgAB~4DKABVX^JANZU>y<~}*Rw=`6= zQ4GB33<-JMKR7Ugyg&zpSPVUV|Bb&#ED5FUnKM9N0)$J9Y#j%{d5TJYvovhkKtO)# z%#=9AZAJKAxxqG@AO#05wpN4Snt);*1Cy`seOhDL`ww)f9Q1Fr!Lg<40Pq}Wc!Q^Z zY@I&{;GD4tp6w`{vJc4*mzaRV0s4VerW^D%ZMlqqPYh~+(FW9j(oel%9$Rg%B>bQ$ zp{f;mo}~GOm7X@IKG$7_c(ao3{ZzHf{lIkvqPu5ZZ5w}{L%X(9wwAE(}fe53Qz`sW>RR`rYpn9ybWq+v7X~-Z=+nWI9 z?%(~&XDB}SQkw5^AyVRr!cr(UHF{=HLi-M2$m3X{9eGE2UWxNe*kVD&owsT-xzNm? zPf3{`(FaC}{`9Xl#qpF!fVO^l6ZiH4x=g^vEyX|cLN8xy7XHKyO(9{(wn}Xo9x4HV z(FpwUB!C}W>f@!>sfxIJYYjv+bULV%MrlhRV%Xt&MgZV?TCw}TaiUl2{0DT1UNztC@^I00OzK8~DkECiWFh509WppRm? z&C*csVkTBt{1Hoek?dv3Oco{Ok82Q>kDW0koQIL&;pCu!WjsVN|8x0f;fVr>x6Dfc zy6A%IOvkE}KuvnPMEE;2CO=%Mp5)*q>$Eoza4bUTvif*sz4f@ysdBccC*iTTMfa!4 zKS`+&?C;x=V>ZBTb}0h{Ix2r})lgP&MPb zz(`!;cH}fz;aD&zQ1@IZo3^Le^}tRM+;cx$ywzO3X@`uA zELIM@tazF1r~%o5TSmM%C})cM%R?7N{#creh2-_h$FfTFG>6yD&rhae0Ee_SUi<#; ztp}T*9SLU%&rO}}<;tRr%XN@j4_i0kQJ7@X(rdrZYJN8}8@mKD4kL~_I%gvGIEBNd z7OZ>cxuhRxB~2D-$1QHw;pew*4(ho4`o+NIQ+srTG;w&L>1TdX*cG$o zOdnhXkb`Ou@-FVCP)Nh)`o>$$Ln4bzphCOobq4xRh&9x&o0)&2b>#JNYX0#Z{u6h< zp`Ss00tztfVI+@K|CHugQ`=s^C=p}qPct$C0>y-iLUl+wkdaOWjv!^Mb6xgOEXJV4kxY~Nb{B)G-*;7x`sT-aoOf4r{PrIfw!;xT*Oxtx`7v~{Z~(P=%?ez>;Owl%W4*N zAKZ8I`Zr&!3rOO0ZgWnd7Gr<)_ZOd?>OmLa2EdG8f`uaYSiX4wAl{#&2+<{@-27(= z!T*#H2;fl28pMJD3C93%4$r=Yrwr*70-&_2xi{O-N~$j4_V=eBE2sn{<3bJC-y7FD zIWI<$y8d$%ij;pS_{X5? zT%CTb@2Lt4zXp=YCH3;LjJs5J;SPdS+mBJm>O<%S&-TM_i+v$6&pX#o$H@Tn8oCI4 zW--9|{7_$YCY?)H<|rp-PyyA$rc#*2{2xd9ffRY`?{`b1{k#$jq^0)U&;9g zXoO&$f{)1m4?gEhaW3}%li))|;^iYiWUr*6XLF3rFxiz`DGl~p{1x~MpbEV9O9Q+R zbzfWn!e2enVVoL{o=ZR{b(~_Dg`u6Ln9dhq`d?czSwNv^$?!^$CCSU$M`pTw>T#sE z?p=T?3&syMPrUVP`=8JF1^It~QY`nWdJ_D9Pd&M)y#e|MyokQ9aEFcn;WwGT`vq^a zwG%S`3~w$!fQerK037z|HvT^Xa5n+jfV*=~y_HeDxoTl1qSXPM-D-8^L_ht%0-X}T zsbnDnNo+<+l;aA$qC)(Gw8C6f^|2LhT9tk}cW~0*`f~09c8TGB8Lun1+9`gscNcr^ z{OQU4AI1x<>!AY6V&$CGPDQCz-8WO6Cnc}%)&|UgEYXK_A?1s`nEuPy%Tyw<(EJ&L zF5cmir^OGi%7|(SAV5HcI@V!<(AbJ)X`#8B0ShdGTO3L|^V#P7MTi5h{DJ{bMA+@W z#Q$^m_U_Fe{v(1RCd9?0?_}zW1Xoa>Y-YjHojttZVgm=l#RWV z_?7TCONV$5xEhjB4U*jWTY79b*MIxb#YE4Zc>I58Ez|QtL@c+$U4*&au4~%w9`qvF zLV)|aiIS*zE(On!n?H@Buox$~_qm0;nBv9L1aMA)v)`8D0<~yqC!qiKnw5SvIKaPd zw4pGRoh^3Ki>@hV;dN>k&5;zlSJItFmS?OiRtoC)Hu z=TraVi|9o%G&GZf$IFatOLL{M4aW~V1*2aKS_00^kmIwp(PtaEZh)nh1j2HvJ`;L% z^T9&3)-Qs;CE>1rR{jJ-m9zu#x1O-?F<=^j)tTf}-n-2{l*}1O$a$;V43?CTPz(?M$sr`68{8{RR^>&9;dzLouJH5ouh-=oiv=I_=aMKY;?&pFqNt*jI&8R8XEn^q9ZIYb z&8+UTMiub>wu}F2O<$6sH@OyRzyiTh{f7YdwwTF78a>}w8s-CE)2tBok7!s%?)*;L zg@Q=PocZ&)Z9(d@@2=wY1-+WK7G}joyNE1!h}W(auQZ42QuPCxNeW|{v{=4qJ+CVK zARg7`!O`%KmPmTCC`1ZxTw!HG(}Sy9Y3^t`^>yeGgL4S zQmU!liY{)hW?$EhpLdihk;8-$6p;V6kA?0+?T)baoVy>T%a8~d^`=1-BY`qjxQPeN z=|=q3^e;YpcJswll@c@u5$ma;)Lm1ue2v5xsg2rU*2Bfx;aS7bHXHW|x1uDihqB1` zVv&EfNIczqf*hVp>>Ij+LnT!#27PQs4$;U?M z@BZWd^_)d~;-pSJa2+sD&CTu_HG%Z-uJ3HzE1&&5a5%>=B`Nt}f!X|4C2ccIr>V*| z^VUOu12UHD=U71e_1Y%Wa=bBfQ_dmp25yO55l2&dJEa=DVx5mOJpO}IjeHU<_T`^Z z3Z2TcYfK)Q@gbnvL{a-KJq2yrQi_xkQ`3MFAd_-eOZJ%$k(DEJq{ypcl?qQINhPY- zeVV66^ZR0UAZje)JLqALTS zCz|7t%1pPQ-*10>u|LkA=&)YQxEAs7fo?*Rh$#IPf+iBKor zgM-VrmakeIQhl%&cXzPB%1ZQ$*oWVS|13;=kMBM?17CA^OVG$VYfx}3^&pu-gdrv7 zyi{W!R+duY7E5ltHj_xKN}>5%4P6`W6j|X#DlVuxmTV9ju;flM@&KWLBUkp*YD_wat}9e zV@0_mbNWaXrW$F!BSYE=p@F=;zdZQBFd{1)b@Dt23{vMgaWRsJfbM#KH%P>~*V@<` zm?esOTTeK}7g;R17DYO{Q!K4>M>qE2lqBPE6z-843s*wlCKp?TrS-SHEYJ6g5`9*I#b0yc65wrQF5#EA{~?ic_5Hc-NdY_+E18M_ z%!v(&BLsHe_feQA)joiHi2SuF?UGuATZ=npEhb1X|%|Ud=jx;@Ct>GL1CJG5uRUQIc0< zC0>3hn}3$*F2pshb3UxUL&fXQ)A(J;O%#%LKL*83q@q`MU>oh8e_fuY9e{eF~+0E1j+?z@T8jjcFG2#ZhbSJd@6o zaQn(v*X~Ij;tDsr_n*1``4wN1qL&{Sod$^Ad4Tc4mR-p#GU?Lw+r&LS5qkPp8WWMn zAOZ)~O!yA^KP_Wm@fBTHbx>>=LsOKG0>mow+nfE>g#PduG2-cgl4H>6Kffoy{_tym z_1{kdfE^Y?^TGiRS+S40{g%XUQvPQlfS>YQ_smy29^krtnto%{#(|9B5kg*VD0W?> zOn+b5zZs8b^BTRVbRH5B*wSO7{5?{P-ahq@d3m2>h+RYYXN3AswG^TV#Mts6IgQ@0 ze?`K=@=+LOu^0=yq!p7I_ZtLUc*}qHgm9(47qKl&^O(C4s}c;zi_m?uMO7FNf+CY_ z0X7OVhv4Hnh4%ZV|LhF@=iAYt4+P(b;5>kcSexn-S4;OLQ1P@%=5K{&(+srsH67Z>kYXKgqYszfZ#~Kna@`HZxyby?#u`i~mY0*P5jgl#*2jQ}r;{vSsc#ehk#mRBTuC zsJaWd(P=UYGWRq4kM0fIEk5F0l;)JkkjWv&1T5vJhQ>-?2L1lKuX2Gaq#ga`ZJc_5 z8yadpR#Me=vem5$I^TFt_3irz=+NqebTal)_L2E0#k6(4?zmHLlGa`fOFZUpS=awu zg}>Cn5T8%ms(b6OsJ48nYMu<)_E1+NnQhS4S}Nu(m}9HT3$76a38OG zGlSLvMZ61>ws^;(?#H8=Vca>&nZhw0zW<&0zLT7~&IJ&wUSZ56yEftXO||};z3b@rtKcdJrK^WCgImAq-lD4dTBmH!6Ef3)X=hiavu$Vd#}40-wJvRHbSS%JPC>hOvSm{^V+`HKOlDTAk6_dU_y&H(;? z?DMZDj=M5WqpDrTZBZQsj*v0sSXimDm2B^l5Z2L@S6!4Hf-)F^nzVXVZzJ~XJzL78h9+^2RS30lr<)gDc zxc>q;FI`Eenn1;Rl=ciC(%M6thzTk5L*c`d%marHFBUX3E%PNAWfW%D8dowOMKXX8 z8us$Pd-L`yRW-H#-=_l^=sznLbYjtiBj!`5wDB~og8!BNYh72UseOu? zAyS;K5HVM9Ex*!9GYtcrl5Mz@-N3?%oDLMLue}nGrNCDYl8Yq&)jmcf0n+Hpe5g1G z#F{N{fJu2@Ap*Vowi`MK8~L5XxcmBEy?XV8d*?O=1SPkHu<2o7d^`=i{c;F6|I~q>#FQ6Fo+jj&unXE&_ z2jB2BcpC);!TQ?Ur6?@m)EICqB-!le^au_6mt}AmoNiyPyH+6;^y8}&Q;HK3B+bfQ zUx>!h_bzTPGDrxeGIYGyHHx6$!YrMec|5a=2d_rMjPlV;VsP?B^c2r;7U1vSOc4EY zyoP2Uh(2-d$|dtsVv#jI@xgm~7Y^CH{75{Kc8z}}aNOCx4Bt|r#UeFOGN54{A6%bD zs&BJ+S0wBq6HFyjPAqbxsX+=5nA3184wetBY~zpL4p*2DNbYq^hqH}wE8118%{*T3 z>XEOgbJaX#==!#4hsfkY4(dn;W2YAj*jiqa<700blVZ?<$u=ALw}hWOB#*I)>L_G1 z8j$4LUsX+)p`e+yncE2y*N>;-KB*Wem#B2I)$MCN5efx7qJH)8CZW{g9WJ|1m)}eW z;}8i0qP)MGRTjtU#EYBbC9u{#(T5cdD?4xt2hZg=7j61V$5ynRCgj!IL*Y^9$!n)W z3bj|`54M+vn|Af%$)J&i49%bZIpYmv>N$1FP^z$oF|0p9!Wy%LNjkb6UR&7>qEooj zV!e9f1k{xr3Z;oSaUXxaqgc9r<5oqwdUc$NyQ;hSbpfL4xv*guFCXnV7tu01R`zvq zZHuH}0Kmh3L{5@UDh^f5mkGT|_=}okB2x1!!mfalP+qkdMm2Hv>8S+kjlJ-VsfrEf zT@JI8apKuR}XQMJL8DwjUo7z@Q^${_!OxQOF3 ztdU4)H=Lk6Rd(!pbDqNsl}vUfJu4?!qo$UpzeG2O+begjTYb!RHujtJo(4jZD7cEq{a_yA{Xz`(i!ej?7rB}7Mm#dVpqzCKdJ zJ4s8^OYC~xKcDrSCa1a-fbaWClnZp`5Z8f#ENebn`GVuvv~Wv?R-*6xa;fo)DQv8e zPn4}Rfx!}7O^}utQP4)?-L`(*bP-2t%OL&C%V(sNdrKpw(l+C-FsaC<=JxzbYzX(a zOTYNr0u~Ux?R;jw)^zhtZFk#w9oBEpCvUFDEP4xvI(Au8zBZ;%fJz?3Gi~r0_7xhw zWL3}8O2+Ts4!Nm*WAli=8bMb_N6-fev*Mr}6-x=hNZ}cu@5}uW;azgS@k@YiJ?u}X z_CM}@V%s15a(7tJ{i-y@F{^qkfWN z_m@aQ*k(`jtI&t#qGnZlWCsx;A(QkgZE$2N$)Mr209Bk}n!(0Q{FJvXkuWGq61$Tl zmKnA_UTm80u;#ozx-%Ya4VtA5c74>mS_%q=UEXSMbSO`KuqE$53Ass{WHl`;RWQ?L z)vl-?Ik|brFcv}0HfBllwxlDOB;#Q$dvhY6U$R>zo7HkDEW$GTX!YL9*RL6NUToRI zE}`8gZ2|=F>0pTya&Xxp!-8`=tG>{i`QBuuB4biAvM<^dHBp(iT|9mB!6&X{H#lZX z-P+}f%N{woXS~S~<8`TEG+6a$*m#e|W>@0lJepg%Z^XJ(C`G?jG?#C@V`jZFUtkOB zdm>4UBNjhw;pxUE9DR0lYjDHBphd2->;ci#1g?$4X?@*K9MU<#Hh#9iWkZZP zYRA+(nk!(RaCOc1&Gvy!{VVJy>XM!y%2293lgn|vuz@l=xd7xZ8z-=F_m)?>R7=&c zhdBy072HH(;$aKsX_^HFq0NTU>T3o*F{<+JJIuNNCj6VY4ID3$9lrb5kb{HJggeHL zbk^8c_EkcM&C2=J;#Pw`H>AqODev}a&8<5yJG-004u&>ya5BmbKkBW$XVzWs>7Uxd zG1p-^k(F1a*wE`J>{vh>+-1v+Yg9(oM5Qrw=p26JAn6X6=~agny00AvRi7<_qKc4| zHYJB_N&VPd`&_~l)EvzDH9G=zYEg#r>CrfeH+LuliX8^Ho>0Y(+6kCCo3!WIyXJ?t z##euelRj~)Ojh1e15SqF_t#eHqilq^h96VySB@ids+r7DANA!}SDVf*-4zLkgk{Lf zV8K4xa4#(M(Y0?EkF|fWj^VT}lgY3tJ+cyq%~y#h7;k}F-i6;NFR!w=^sbYV$-vy& zl!r&iowwhyTEm7Ll(Cj=cV=i^hi;c{Y!B<4_CK!RpP??$7k8K4RJ1MOXZPd7Bp8SSqs*&em3$CPhm=y=;|@%DTDWZQu^d<4U=%czLi zL5_qC1}cJ+Gfg+`?E235yPKrKyA?8eHN57arSxFwLJphSI77^VzFmM0lfvw_t(ri; z@zg9GVWRquj;*_Ehi&vhdG*MGNo@bPW#9N^SiE~&gCy_TA&tUjF~{)}``jJP>Z;0Q z^^?cj#_bxK;wlW4d5#$8vBf`xA2fg)d2g!t#dD2s(jERGh_}?Y%kK^?+trF_i>9>` zG_E^akg>B|^;!;mQ@v3|XB{=7l$kPUdUAYZWt}~&+n+OfjK+}5ew9_}GSqJLV9Cfg zGWL@?TrE$=L}|wg&BP30y!E0Y)9~(^lJql4=Iq_RsYE|9I1cyW1kWSUfxNzKdtKbB zLSF00qN3x)0-C8R1l;}dB!g9x=~u~C%Y*vSuGaMO=GYssWe&Yv>5k^4aPndG{AF(* zr8Ib4!tP-CEXf))Gb6kuCaUr9qn9rUdwb};yFY!9OF{XctLdSnE8sXHe(om#@HsGPXHzNxcUwQN~F;&PW z31Z}K*bE!!LMi2C!o2;^92awYPjE-n)#v*vnY~lXwKU}b?j3)5gWC++{L(+a6k8)` zDmGmDTHjedo7Vm-KX#Mv8$2uj2mr^0yT~KlB24M)f^Jcq+d&Q$^-R>`a!$%miDwWi7a^T!ot=u+xd)qLJ z2}utsNl-MO(k?{xQt2^^{ced-D3#79k18t;R(^Oi!Wm0*dxLRt`0W+#zK7%sQ`y2F z)Jn`(;?}?JZ_&GX>E9WYUu|` zr#G6xJ%h>4J8Fb0aJR_)gTZx4PT6LL*#*UwZduycH>ehl>iVrma!m1rgoQ(zq&ZFq zJ2O%xY`)sf`O(X8wk^TN`;|C{)-g(F-yoURfUY;GJ-OqZ_da)(NYHfiDlpq4i=rYZJ?6Cc5UgWesVL%UXJ1jV&SD=)RzJ{a zvnpLZ+(=eCg3q5@FkjR)>-w1J@3L)p>q=L%%V^vp1u}M}Y4tM7u>lhm=T6lTf(~f8 zORqJn@ij2q?B&asR?=^jm(XKN!qVEEsi=DKGga-gArailVbsbbro;C662TxYk@HaA zA5%_YS^{_F=u8BDqqm-c9E{+me9bT|tJ+~USi~S)9QZ~z*Poi2E}X7sO0+PGA>(Ae z#``ra4P3|;&c2dvEbq|sY2fpkHa{Or-wYMX_F4m8(zEUv!iCjk_ScIU&+)kSWN;Zx z=GQ(ddCKjuUX9JPR*B3G9Ud*sJs9ienN3=ooC01P{f=J|t9Sk}q+*nc=B@K%!ip0v zAt9l6!0=PZWko>Tb~yLG`4Nfnh$=gFL_CreXPv%ny)QQILRGX<*)h2N0ZAiv3{e0 zKu^2!9rxosd87Vp^Xij1=f3C-y_OTMlaWc*UW*Cml`2w9nzF`-kC`}1E4FydZc(s~ z6Hsb8J-=YKsj&X_LtLm|6eGR*aG7m1M`yyzhH=F{>#WNb`gr?1s;;9gE(HI^8o2{& zbc8q^+z&Lkvn@-u3sfglgVadSiu>WS{cXJ2yw|y){P0cl&>+DzE4lmK7Bbnx%bU18 z)M>7ON1gKI+g?j~A5863MsD!YDwyxNJXulvAU=+$mW6GZOP13l#^XtJ1O}JM5 ztLEdY2uZHPk3f`_lMoR~JKFeFTW9fO_@c4R!v4oimvx=qC+41g6v5<8;4*^HL@mt( z>t3Gd5^8cx>sDD=)OQB>MWk+Gb9OK$1?IT+xL%LKSUlH$=I&V0l$T!Us|E2{pB^z&&)ZG0@4(nZ`=Jg8w&bn3 zk-W+nXEUYQp(Boc=k07qPWE-j0GLA)`|GJ@s?2?Mj{6-aUCAv;s($U;1B|q6PE!no zm~x{v)-dZ30{Lq6#lJWW|I^8X$Bon4P%Go99YCn?sK~TaE$@o2)?LGd*vR7}%Rw!^ z);d}p+4ei3w2XSm=Bj3XX(L=RC^B6Dw)Q@V9l3y$(LXNJZJhkXoLbsd5qQNBiVCe| zzSSPeacE7zQ+G{XoJ*yW9+lTRf1F7?9BMeA$|21TEW;1ezfm~lF_ z9PS}6(!C+v${KNSWhz~pQC`e-%!C%Z!o&mYn&f!MxVY5jd(9`lZp*4K^p}(vOc#Tu z@UqL!35oqY?@NYRG7~8{{SG2(y!TtQO_hg9jBqW_xB#jB+h0R7RF>$f1Nw64HM3iJ zW1Kv4HNJt`+vR7|&+4=n`m%1Dsv4UrwOPU1V-4f6AP=xrEvgWW%YZZyZAz(u5rX}M`bYFU@!kR(zgzvpOy-hUEg_EW|Nu?$OyFy{{ z_c(d#s^!(~KQt79mVP8RID0;4`Q<#TBWqjiXFvuQN{TPP@^P{<-EtPHN7}aCB>cD# z=VaH*<@&hJ2viTRrYX!)zliSDzYoAtPRYvI+0K=d3N$!qQnl}W$9=L-Rj1j$g9~Hf z!+;dRr&2F5Jt%RTBwyddR(Hs@O7Fcx{+1}3gqHm@A_Ya@BF%Z)+bXYbQ)s!z1VtGw zmwS5qIbJiZaG(&D3vHyG&CWj;2&{B4pE+Y8;zb77O+l zub|>S+S&)|z*Jy2Gq%iGbzU0yr(Jb%7~?_uBUJFQK*NHUdfbdN(Zw^kp1jh$2aDI2 z6X0{n9xA+H2wly{%n2#MZZDv^Q8v6k&yu~Jxf~eG4*i~EV*uw4Qed1zRYrKzH{@t; zQHd6~pSYEl_AQm-LR2=l*}FU0h1HOs-ZgbuCB5?sFm z<;8`M-l=lKTK3RYFXZ;{qRen-nHQT(58bVM(REL4bK3j4%(AF*+2ULcg#-}r_L6cd z>?AT8k9AEFw6Ln%Bg?wJmCI3}gvGfQvw~bn)v4#UVCj-@S(UTV^;kfe>+U^Y)Z*cf zZd+T-R_3w$+j~D3T9#728GXW5-tpjYgC=?G2$g;$cz>iP$GQ4&cT#Ud38Xro{*60}mhlD)8*s13 zg3Lyp2i1u{FjZ*W-8|_wdU~-R3yIYGCtkOym3p4Hk2{*bY;X=c80#Vi^|!JG9ojy7 zSk()TF$a|ond98;hwTYMFj4vfq@|^kZHLha-TM_g-YMxd^x`P_2f8oQo;L;f`|#Y8 z<0eS?3v`ycMuMfbbAA6>#bT_~>hm+l=5;~A2M@RAN1_vzdV}n-nnLB}n9AFt7$lsw z=NBH|F(9T?$PV244m!_-Jw7^U&f#=U;`4h*C|j4+DfRLuDSaz{fUD&QvXyamRKCri z)m(3Re1l4sHq-TK6jGzBK1q=$)^wK}kB5J&a&g*~94xob-CSm- ztqVff$Di|DhUx@=LDiiqkcfWuLa7aESb#++dle{v_5O_@fgnRz@>~@g5-agA7sYPk+m+T*S`v6yTJ&h-0(z+_1Mgb~FxYAcw zg}ue~RpT4DqhRvcQm@l^mh%ed468!v{#C=_9PfsM@dhGSVsO;cvWmapyftz8=m}rT z5d!Kv&`M)~E2sAZwJ7nU+a1*<=tWfl#=2j@P0=E8L=5edoN5TBoC3?uIi6)VA+1a9 zu9j~9bDG@>q}iV~4*6O`X&JOKoq8q`?@bjM<|0(!dcwc=!hy7!ShyZ+20e`JQc`is zLqxG1{Ed$VGOVZcKug_Ahld{11ll&I5 zdB0t8UAvj>7hoEX`_$C!5%`Pp^~<+ob(*?#J@L)95jR=8T)|SiV_U)_Tjz^YP*ALE zd`MXz)K}jvPjVcUpJkMy#4?g)w-;F`G;+3HD(+82!E!R5iyN#JJMDScFOr!wN3F5A zpa46H4~04W^2S;X3#?S2U|;phyE7MU;m?)zXO4fmw}_vXS#7+^_D{^FGnZuy9ELt^ zbj1*_;ni2xcCU~t%20PdQ8gO1O06DU>c5KmL>KFlwO?#Z&4;Yk$I9kLFWQV0v%F*I zrf$i7qh7k#)edOUgIW=rWvi@jH&k!tdpX8(`9w+yRt+uDEyC8QNW0i~p* zrIA_^(jm>FySt>j1nF*2LSWII5=wWsNJ%RVi})t)bM}7E`Oewz-rt|^&wF`Y3c|CV zwdOPCm}A`I9``tQFE5-w=FGEq)b49izOuRn>rt)QZ6a`jpCxG9t#Xf`o7$9tAZGtO zjPn9>uyGg6kY49jqsB~MP--ZiEO#ame$%TaK9iHjDA17g_ zP-kmcNflZ~1vC}T_j#UwmK)n^UA@^Z?k0lq2xd*q)9wSgC1GAk-5E4rg7bY(#dC-QD)}nNC!sKdv&fFTTV|5jyADbnmFgTh~BPimrMg3&k$hph@Rm^ z>^;TikcWEI|EqxlPp9ztYLWt|oN1Jq<*s*sIptm#NP(=hCOGO(1g55nZ{@&(CX3v)E6>yI zu|9`(h7zB&V+$CeULI}DNnGD|RttV<;#$~Ve_X;jE1lBJ0n>p=&vx>UeRvIV zz5tPTj%Z1<(YEW(jad0WmFe=UeVb5atOM9HQ_I}~f5Na7HqTTwH*@&GUW+u% zsQOV4v8+>^G6P9eG^M0bV*Bh~Bb^^I_5rh-ZJ&wh&{u?r$haC?Qym#i(XcmP^kIkO zGsyM!>sWTnN8`N31YvbAWWQ_CZB65Y!O1S7GHgD7^hM1lr2+|kb@>{y>-#vKvPKQHK_Jb-bTjySzA<{zH?;2 z>C(6rbKJCK=>hgEN_4cr)diAK+Pr#2P_h`@$#SI)ovBoNq>O(iH|+_BeRX-Y6STr9 zjm_)yH9Yb4(~Kx1X(G7$D|c7}4{AO`Rn>fP^^YnJOMCbQ`ZCC$PMED9+6&O_9(??K ziOt4x@&(9I8LXC5$`_1%JpP!v?9eQ0z#*e;f8c0+dNAMQ7SWf)sh#c#&XQ-!#Tw$o zdt)y_4T>>hUE6u=fKj_y@D(qp!K@Fz*xhZ|J4Cgd>4a&l9&t}he2Z}2h+X2ISO)00 zIgZ_05jTs?kQ_FVM?|sH4*Lyey;CAEeR+2@eSW5VYx5v?4e75~tve8H#P~5GCMCt< zMn&-e`$ur&JVUB)0C(D1vj-dq8oj3i)6ZBeU5FUf?d-}Q^S&AKe_gq1tf7&*m}Tm= zw6gL5mp?3mY0cSde(Ch*a=G&!KQ0ZO2A7Ns-;sd{O(yOg)4YxjVO+h@Gh~)YQq2iP zMjji|;lwBW?p$Btkj}!C@G6_7HZ|h#1vf$mUMKqLT51XkgR{p=cHV)5Z}Fbd0>Cd$ z?=xb<9^#XR;=$(IC=~3gwRL$Fo3SyD<>{DBoYB$u`+s)c z)&Cuf48{iuAVN`PAR3RuuGMiW+f_g*24J$4GJ8|%{-KZa7ce0o4G;o-N0~swy8>~Z z5%{P~XuURoUa8?K$i?tiy#7D<2RMen^RTMfIOh+|us?3U5scsNHmv^(?1X>*3WN~| zX&xeMVc;p}+hkcx?-x#wo^#E$ftRx1xVu#O&)@qaPXDi8L1J%Ss{HG&+)^*@mo7`^ z30Ajat)JnQdt?1~Fx#JL01jJEx<>AwbM*gtuKjl7m1xKq5VxOi5XHAV*YKP=&)DX% zQ(d??;1nl#L3_KfMow2y(6(+jP`$tTdbakJLxv4HAZ7ODQ2USm(bDuMS;s#<&1)*0 zpFpVWL36EB4sXlG0fyujgDRKHrbE*CCdTN#Djl9#z8t4}vw)|yEz{19<*#_Gf9_2mX1w5houvr%>zE#KXg5 z|JN0S2&jVY7RPKZM|mVGm$?ip;gYn5rq5Ed+R*SA0iPu-%HRLnuh*uOclrz7@{e0} z<=wn?Ux-(Q=uA&ML(AI|FtjHHRCN8h|6H5p-*QOO7F1!8QaQT&$D6ET^?bvxX_Xth z^eqFiykz3(H5oyalp+zZI|)m>i@%njo^1Pf_CM;1Fe$BXKun%Y!pD*U=AC!c@4Q;E zu#pLA6?MRgSl7?>|K+VdY)8Ad*?Ak~kOda8KA`@+Mm}rz`e3j{>;Qj9s&GY(HP?T2 z=BmOnqT|bh=&9OAAqvbXpPRGa(3Wjnp#VgVwHBIzn)>Gx9*KuIH!XnfaF1 z!BG#M40i9?bDF=kYZ~tbC+g_J!{=9eOPb?f4`Rh6vlqIJ+XteREPsRN8=!Va-}&#{2%+TWfmhBv;WWL-bl98eUbh=eZ-9IWPchM& z>JKl3diNQyWmk%JV*eD5dP)p ziQ>NcdW#(WE-n)Ag*h5gipjaJ8KI?<^VV;$2~>Qn^)_Q|T1DGP9%7pFr=N-L&?B1KN_TND|kkHw2rkWKvr^{DWa2X$u zwW!3?J$ylj7wCp=uqE?UHPJeq8~N?uaB2QkH!rF*OTaibI9q8&CQT&py~Z_*nA3Pc zFp1MEi#sR~O_YywZqIh9v<(zYbnzbjza+W;r#<}J!be^sk+Z0pFocfds|m;gTnWsE zNFZdliVmgIpvlY7TG-AVzk3Y^dGTM^G!?;r=;P9iF$h!&I4yuN&|#?OPukoZ#;|S%_X&t5iuZjvUYS3rlYAPtXQ{CGW9=uXxL(hXSSYJ`oL>|DbL4 zUrk6j3etgs4yzjL@h4;fe}#yP11-mrwVWH5?EmevG-bQGnQ{#s!CH+Qz|%d|pMUu~ z!IgjBO>os7Bk<-uAm8&!4*VwtvwvIG-@g^E0F`-EH4jh|DUX!;U0Lv74d*{DA!^x8 zO`i!;$_O-y{$>ObY;{wFDZc^)9|N)^47WBw7hjRfsj=x1vmEJxpw|0!8f=B zJm%sSqRts+OS^#w_*Qm5B}eV{liZG?5qFV zuz%_N_`ePNmzIeX=l|yucA(j0{-0cc|8d&-i|MQ{Y3DdZ9ppfKe8~tA5`GCyq6&X4 zxvkyBO<9a(pz`O^XXQ61%&fzbBWY{f4=DDl-#j+N6KBftlykcBfML3Fnc>Xw+BJmk z0h3C6opwR&M<%7-IoU2|0eW(MVIa4Sb4vG95`O8r)w-8su*8~UHVw~_*f_Tn|2Ui7 z<}LmwX)a^|jHT#P-_vLy1lZ#H)sElJ6X6e^z7H0rFlUv(Y_i_eUCvSG44er)wY!o+ z0|$8*HX>BoX=L&wB=D|>B_WH2`%g(KoPj?r;orHTbCgmDxf9>SShpDeG0TgtT7{%$JV&Jalt^i+^$4 z5LSrCsHpK}Y)%#({&nA;*e(SAgueC;GI&N##qe!jJKFMi{IwI2vTHl zYf*frxp>k2Z_8^Ve{=ge%zue<>*z~e_RI)QR(BAzSHn(w4Zj{OA~g!|{IY;MqB`T+ zgS~AGe2Dzhj;kr%?-N??{kYoxW2%%lr1CC3e3{_P9sc-?b3?sEfk~d`WkI|L1ggQo zH)E3chp6k#`hUHdpyfaJ=+|3#YC{O>#B3F`3b|5u2Ew1+AZ)GoxDp%H??>!J-tMfH z)Z546wsB~n*vROtPKij<=5f8yv0>~{`|S|1LG5@D7UMr2QzX@qB_O~seO z19Y~Us$t15e+5m!fL}!z=zph~r1kQ*pa-G_V$nYHpBnYV!18@pE4e|Gn5Zu(1Acra z_tpPHG9(lEwlri24aLmn#}t=Al}9 zrQdd;A}Ot308>~Rsr@=b-yxRC%m*I_w`~39I!RRgwUnH<^*%ssp`OyX4RwVM;S#x` z!ZmaJE!Xp=nXldW9Xui@m=Q4VyQuLrsrdKDB0@WJE=_&?Yz?IYXbzxDcJldb=+Ve}!FY-FI8U2c{2lhOFa$fncRT zIFB?MUU2Uh4emQPN!3mNL?ryT$#OnJcZD@eOO5w@%6Hq3UR^BAIE#;d!A_P4s5f10 z<37OeiO%WmUuQR0P5{^*`uwKBQqLXq3h&RwE;l21Wb5i4A)*E+Dz{V5VpwzH-GNni zv`vn8Olx1M3cS94RdhnVlv-D^$ngszB#69xYW(#;E3|7Blao zgyqM-w&gU=l*_3~(xD^YwCfL)3{i9TxG#9xv2?xsiSOuAc~`#w^m95LBH*gzpFj&% zCVkF*BoVK9#4$Pk*lv;i8f@L_}Yvdt;UBMm46Z9GC@tj4iM! z;Vkc~6nQ@%@$QE00^c?LjHTB3Gx?8VS^kv}Jq_rp5S@d`l@vA=ROudU@|4q}S;Gt& z;45`EgW4Y2a>b$vLMV3LMZCEqMwxZ{pSaH8$vD35=+gJ;QiM(Cp+Ps&TqEg^hrBJ zJMm-Lpw`5IuN9)V~uq!AlkfRgv+g+A<$2dqjp%SU$$W{Z&V}vU=CV-xhAc&+V#HUdVVjtZb za3JhqP!^dt1cFE{lghj#P&i+Tj9i6Orl~umq$GF3Z`3-`O) zUm-!cdN{Ny`LGGngI7oc%zjnp{F;r6U^nH;Z9)@o*dME@$|776?wap8%|6FK0A|nn zCxGqp0~(I};nih7J&DT3c-<&|cNa(J7>&aCl-4%mPq;4m> z2XC5Qx1)TJE({V`L_wSmClO#wt3QlnYM!I`{1z{UQ_D+afFE82!D5Gh_qwLnu6w2R zh;?C0b*9Snp4^nn(Pq_1-nAU-Zoq-Dn4qBV;B)t*qniC5x{{>lJT+S-Ez0#y8>C>E zndhhF!JQ}XslcwK8$0gwLpjFka{T^dT}plBLheRs1tQraLk5QOJwkL~41omSIV6G& zRJS{U;~XuSql1UynW6F2g>wBBaxE*4NdX%E#8(KnxY+fSnrW%`o9iI!;4VKWHB5YB zKxw#W=jZ3Y@WiDu!Ce);In?+c4uR|hoqf`OgY-9Cray}LiM@PxNN~e_^_bQ(bp^*o=7HN9=715WNdHE6( zs6LXN?tp2s#nLY#`Rfi0#qB!n>AbtJ*#-pgV@xVu*M2 zuE9}~ddp9RjTu@jka08y2Oxq2;-REvAmgw4 zXrK^xULX8BzcsjhP~&}u&~o>7ZVizW@}1FHY!aJF(g|z%p!VEFwh5cekMxOP+?9ZI z4w)#C9_&T_;v+*`GSx24o6v9t+eZuwFeQz6qWa|H22bcL z?ZI2(WosCtGmhOUcp}_&Cz_<93Rk1$**`$f&h50i3(l^z9vxjsvRwCz7!hL&%n1{l z%|QTHj5c}n(Ti_t4d>J5B{H!+3EIhf>nSAErDpvvHfF7Z7c&(-Q`IZqsm+F&N1g6-W`+KZCaN(=(_|g_7Ur^%ni`R?IeX9!2tBj`S8lqfGsur!n~JW_4Kofwj>-&Q+B{Zj^v}mbk17i z7C+P)u!s6i*XA~K@2$N{)>(4ooHN5;^CFr&Z8}TiF*vEE*Q7w@0dOuNd0rPDs20?< z^@!i=s)pEY>NX&i;SsVaA&>g`=3bUQrGFzRV*rP?@|LP@e>5d)J>=*x-9eSDrf^aQ zRP+2d%uG-4)0!8{hv~Pg1-w@WHYSF09}t&=_XG zdDq%jmx9t;?-gWR|D$T)F~vJ3f@o{&a6b64cua0Y@-6w4i3m`QCpk*&-JN&);Mg!g zrI9#}W_E^8iGk9*`yO-Ty|LGD{E z8FdL%QtxuUDblXpOoTO%|z1r>&u$yo?53oH`D*wQBJG{BzKBMP}2f@!VG5dvQ zOc7vIV9AdcB9^+m22&N~hnIN7B`AdS4&kf0Da8rvqTyXQdX z^m&3Qw&8Q`qelcY(N{k^Ge%0qC0UCA8@H=&Jv~h~SUGcjfX6CsNeD%()t8zsz|fH& z%zuhMBD$sq)9?H!C@ICuPW9}R;^;oSdPl_PD+q>oMmsO4Qw3p@#J{N8i)JyDaMLgw zZw6csO1Jpm%nA zIGXn+q%_Cl(M^iUkG!n=-i8kJO#-P7SFFKUVVKcn6EBrKQSx(Q|m{eN{T8%rml@MR|qdreoT(^Vz-Cios^)SL4M^ zFWPe|?5wvM;~QJr=B~#J7fE~LVbMoh0#UVXw(?aHhAuy@T<;SREl04@YdI@F9E;4a zadfd7Q&lUqv4!Yr!6qiRqd2H8;9c#~Ig)u!1Z#DxlZz`^MzH?L43f*(v3$?>ToFVp zwIv^uzc0uu$cmk$UxrnI=njf8E#(pxUvc~YH_YT2r(7{Gz;E|zL zYf=_Qa9OFQf0B!*SS3_kQ<^!Dv*@i$_4v)nd=2PXxMF<&Dxw#(PYv)$uD;_wSUsM# zigL1q8q}tbQV+ST9Ag6c(g^0(wz*~`Zm$nF7|bD_k!Kxcrq8F!$jmFI%jHAm4pU1j z8D)HoAbhV)9EH--#fkO-3BNkSPL~Qs5G!pNJ-(^D`GZmGfO*oS%^LY5EARn((W6ai zFPtqbl4M9Wo}hz!5yRbSuzlA-8Q0#bivS0e8Uf~QfrK!xgap&ctSI;zwY)U%G&Qd^ zrQ+Bsh_v5{EoN_50=Tkrhi>HOep{f!)2Nf2@<=sao!y+~r~e0|bvqZQFwcw;btPfC zR8@K^2Jd_?vlJtR=g+GjjNd!32&lzDRKpF<)zKx5Lz{PP1yjIUYiyaC=z$!g2}*+@@`g!d<_u@g~vpBbSk4O+00+8$_tloox|>{Wr4P00_jMUE)kj_Lftu|pz!kgZeIUu+SJme}?@g8NNROwy zpQU_usehSUsrhu$M{Hn8Vz1*b?BKdE)MUrnz_( zteGZA_h20T=f+Ww3Z5EW%X|~NgNPd(ud_q~=jgWAPR00$lp9m6vRBv=dmy3Q-$TZK zlE%I+O~7N7?V{<&wlh;5JCY;O9Sy{PBvyI_lvWpq_DR=k73GLLz#J8xRzEj4A57~-!qE3P582~{*mtI$MM3I}#(glH&lDM;t zyineFf#y@M>&p_4Md(AvMb7EEnlww(qsGno&Ed6j$1SJ293w~jor`k7r5A=)?HKHe zV2<#!>XnL8iW%RUe3E>`(Ye~I((B#&lm#}B*Qo~cvM%;~A4bfraRowmm&~R1wb&%3 zm5KstSM!(Kyd}lm7u=(LT*);i)X*pv)wruek9_?E>VEFqccVcgYyMu6tN`CkrBn5q zQnAKN#gm?QI$0!u{FBwlSLZ|laNsb1B?GKxkR4Hgv`hva4Vv}R81iGKb7^$qRSSWU zpl_KWWtI&$TptrBx#aT(cH}63INgexU|Iti3y6(gt<|&8-N6aw1=biU7EUNsx)(mdz zMl;< zPZ}1C3H!#~NGmRjGIxjHi|(wCsGzUTH=Kx#uEF}Du7wZscf#3A3uixh@`=#-zwnEh z#>A(hqUs(5z8n_`Ew~y&%2zM>B>xajX2ZOUP&smKo%leoAQLI2kN41Srx zjD0KyZ?)onMw|dZ-~vVfKvW9)Qc0=Srap)jbYZ4tjLNw2?|I{TMW9sF4{Y|m%MstY z=Wj4C(>M-{Hsm99c+dkGuc2fzoA3F7CR&o%l>3qlWSX>$#KK@(yzE#}d`)e0_$Jx_ zA7gA%D)PsajJU+Yv!(qef^|W>NZ;Ig>z{`p{Mk6N7j?GFpo={w^pIiZfJ8U}n9PO{dVo&1fSzGC0eafXeFC*Rtq`j!_ zmwP^Bx`}b0yVL4jFW)gzD1J(T_rTXU`|Vbf_k?0{5+yE&-=9awWw9&Mz4@LxyYg|= zuxD(tzjl2fi7H3J)k)aCdeCvea(zHkzQJmy>FZW=sjq!~1hv^R)jzoa2g$(mI$k0s zc~x5t;1D17bv*}T#Cg6fqUpW}s&G2G9};n*{pL&g&+&q(7kRASTwCu{C;@a{wu?S* z3<&vBDK_TzHA>DX=xJH%>u%u(TfmOb%_y(>Muk?6)y>Z}tBMww2m>pjIXtpj*Uc|R zTJ~Z*OA=IgKwv<(q0x*5%9qG%htoIZOUoBn7}4HWq)K!xiDtgaa&kg`olc3?5NhJ_ zPhYV{cVErk3+m-etITk^7VuF6=L2KWVV*l4FZhH8O)SSP;?OIC-&4OU9=36l>9jrlhx`!#d4oSeMXU7 zzn28q{6XgnL*v+Ut!TAEqZ9LUEk|ZUStrK0yw30Ns6b3U#E^}hWa*T(METrz6-t!D zXw>($21X6P>D7_mSmJ=WOw=;<{R%Kc7vdY%!fyPTIklC`lBtj(l%0NU4((xh%(VT( zt`2d9&uF;dU{p=!8~IYnbBwpp+w);TyIBGm)3fJsHbT?uK}^>1#-e_8bKUhb_6Mc` z2}M1AUWD9J4MeKv}3# z!iu*Lh)qQ5yy%j`9kI%6V541klFrj#ig=gD1$|M?NAwANtE9=|tps=IDgN7cQT+lI z@yBWPp%qF+ctGyPlyvwB&cOuj^hTcf;(ND;4cC0;m^h1_o><0aBq73^5-caW_7ot5sSIvI{WSf@_e zuy=H?9i>Opc`i9llvL%!G0^Eq5NcRz7S~g*yPS6n`k_;}J<2I49t=9rUs)9SH397z zJPOB_S*t=rXoU4__56E@%;q&Ld??v#4{16-s1nOa2opv-?kOZK(WM_o%=Cu;w|*1SFdD!39(K=&RJ0BoqT*UmtR({v!us!XM-Vg8RM9XZcaMmxjL0ps-BAO*hJCE zgt>vQ>RuzeDF4M9KMbO))Vo6O9&tcCFMd)tuy4(x8>jr-!WWzB28~{XZkdVkO?YAZ z6a319Kmty+Y7=k2r{lR3-4?`Gex}XwGk{JTw)UFgty_@{>gygxNZd_NzV6ibCX~b@ z_=&!`^K8EJ#U8fxBu2+5!C2*&DCGb<;lRj*7M&&B2i%kOiDB1}@pex*pt=v zldb0!GumF4n#h&(3ms|O@U0iAeaCcP_SB0 za7I_zG79B$m%NQ{nLaPA8G@^_VMocHdsK5A5!LPdzCO8_Wy|ce&H=NufmXbLFK$dC zt}>zR%ZZ158E{{rQo2I<)f_`m^hqG!ON~}N)3|%fG6zM``MSc+IKx(38WL|JFyT4< z3Ae+*6zhC-GGlht{2ed$zG}x=Cmz+r`Q!Jl`c~&_JV3l5v`&;=@etHlr8B!`bC+s0 z-HvCJj^^MRo*R?^4Z@Wxl`F)p-ka)IBzHhY_d33~YVhnN;(Y34M8!Q@6)CsHk4i zYC45nCbwjcogZb0O;W>+xDvuQCe+OmCx+^Qc2ws4i#hVS8Y@njPxqJD^tGByTi6PJ_XCn zE5Rvb-}ncR{H7AMMr#(7qKj0^Uh$tDvQ9Ud*TnKxeHbfnsQ~?WjMJwZ>j0a+K3skk zd^Iu?(}WznU_bC9PZ^g%F4OzFTcVPO!~O?byVW?A;HwJ-b?CZ*eINmAVfn|&A194> zSg_JW;WG2Wi++b%W6baQ6SC&WIaCv8eFO?w^sKb0hf@6B2KY#nY5#+f^rL>E+dK0r z($)>SwWQA@)vLRuZz+-*TdolP!Jwqkt{Hn zwV2GR56X)fH%IAuy$C!%;<4-@2AOMNV4@b~YdYNkJ4v{;k6pH9qDKI>>@$spZ3T)z zwB;;~LYo$j);1gMtga`Ett)(MaE5^bUlfHAL_aFF?*+_>sf1USLDDosco=LMc`CRR z4~Xkd?6vyBbab_7>@lqosaO1;yuzS~O(cd&iSrSzWg_tk1}g^$7gAP?XHP4NvoWMe zCRO)?!12Hk({D*cveagGt+jl2acTN~iOU+q)UJET;)(f_6^tpqxyBHO&7oJ}PYx~@ zH$X!+mDH*QW$HYTN8B(QDT*U_i#%d9kVwCt>Sz?c_8vuD31zgPAM=Eed0(k)h@kQ@ z-{v#iFK$Ow1X{Q42=$WLjhjDCO&*1Wj}(~-xov~^N+$ihUMlIu{GHH+Hy#qX_(179 zwzih5LYB0(t>}{xeyp8J#P)n)p<=_a*)yecwh$)hn8p{hIJMTcu`%3{CSw6yEPIty z`|w_MlYX=eBYao;;uOdJ?S-Af+29jy(G zp)3?`c&WXATq(frkf?<@e0HSqMC=yzWOX9+?sKx@RFkQpE3V?kyHsWX0c^5y33&!t z-M=OF)C>$wyH}M;mLjzo5_^c|+c4tAZJ(ET+?HFPY5Yd65Np$XW`ci?qj0CRLQlut z!c@GFT=mO^DZlJBS9o>%Qnmj*KEU6&*VK5An;XWqRi$Jv0sSnj!2Z06R&QijGxx=} zrPxbd>#V)Yg&DSo5j@ky)9PGNo58v*l`n~OD(|3sEnZiJU0n27)E(8Y(Q#kL(%xhu za->U1K#3qE?7U;Pnqd7iK`4{ ztS9ZXAI2?$oA`ZvldJm~B;j$a17hZ~+jFT|U&NQSBh8Ds>yVkky+n+fpHJ$088;aB z_SX3|JaKUH3z(P!VmljyPSHS;^CtVp*=JGxuF+ttpAkb;(lXF4(XPwqhRx<9Y0NH0 zXYt+Kijd!8^2%00WTYl-P_8OKq? zdR%Q+tzUJ3<-wM6po=rrHdDU;?25RNnl8Cg38p#K-iCQtq!3JrpQG> zl2&?opuSyP;2Zum^NPce%i?@C>|BVKjyeD3O9iE&Vb`ewwtRs@eL!|v1ZG^v18AT= z7i0i;_bS4D-$&#FX$vBhA1l?%=foVZZ4aV~Gzq|YLSil{TYYiEl)Ns{wd#YYx5Lqp zsdBa@u08v@3w)QRs76(0b?IpGmmtoLF9k{JY&mTQbZ$^j(1CN;7y&cQIEOa7$~wO= z1kO6%5>vUE#Txm&*#FU<$*e`e(=V~v`?Ug7%pQDD-+-Qsw1R-vd}R}c%in4h@I=|p zFi&WKN=xf}cbqzalk%;95&2lLqjW^(Kd6l|hcXhU& z98ra7RygrQnpwQv3jin2OtJ*|u5U^_3$E|_s@NLGT4b>!%uEM1T^0nbGCYq19CkV+>&m5mzRCVu(jEW6@lBDC3hv|a_%9VkQa~|A zw#+zl2Z#(4tW>R*A>%2?E3oz{t0V0#wrJP$rpKcby~r;~bzb0>zY5!5O9n8RE&TWi z5URub;IJ{;H<_v{qCJ>YA>B{{DP$+TF=`QM*pK`yaSyAs*?$zG*F2uX1he;a3~u!j z$7-VDzeR0r`_)HnFQil)`8>?ap*PNG__x9gy49%%)u>S|>vXABj=@2EGP;k!6B84JXg&*)cvo-I5 z^Ioar{j9Lp2JP5v_w|~1p_3|k6MIDkVzy@yUh`BNV2tXX7E3dWI?)*Jbsx8NHy5Ho z@sJ~)2t4TPMOoD-LkdkVdh|%;iy~%a;oW)x&XPE^9!KuGh)d*P!)Pe`+WNo$6cyVM z=F@T56TDjxk}I#bZ^a#LNBTJL+jFWNs}+XG?*QUN#;vlnpEH%0LkqZ^BX{v0en3Cw znEFGB?#ycN&^x~JkJ4^rTIx88@P5g<7NxM%eYdvtO%IrLs18lIWDHkhr!5If5|@!8+QpD`$As?mac zOg31$pJv(6^se%{b1wt?2ZIoRu5MRIL5f{Mo%Z2-URN1StUfVyp3A2dHB}8JWny;z z{&pl}qANv|D!XtE{~~xZt!TM!w+E2Kc|iWmpS-e1yZAwOz4b(~;dRM+gXgHVkumt= z)xzC;aMq+XzT0==x-e)>WwZ$A6~tL?TxUwmNT(3U^$Q9gDqYgYv>0|QG|>$d zHjAFRRk=6p<=tk}(J9zAm!;FSXL?XY+G)34nsxi5#fD0UhyBkHLujeavnO0{#H0*E zqCQJ|!uE55lTxwc&GDYg)-A?fQppkut@g%KdG3TgW*z=<&SB}+1hl^262E{-Ewc-} z@p=q;CFB|t!U(RLb&1h^F^MLsHXH}P*~4Y{K5LBjWSRNMG2BWi_i9oGf_z!;A{qDQ z8blkK7lktV&J?!?`zDID^vVjzBE)6sSDtT55%{VoK^y!Ab`!nuVY`}9`X&?rmbfh!@xm0K)1Nx>`= z9eFlX%>8gBOS1jo=%?hUr&<)wxFC6r3D)uTUQM&6s|nN0W4)|(%9KLxoGbY?ubsfS z<2FHz6)&j*G=8!{3m$steStXSVW+8sU8Pi2bwnKWs@0Hj$k)5qkC#m)job<-_IaI~ zPX`z1pVD62#0gggcg5lKS6Lc`+)LoN(@r zRIu&gCAM3KkOZB|s>>*vYc4F-C6z&MDb|$L^fFM|bmf)$fE6u|DFgogRz%^ga^8Fm z`ZNzh9tB0Oxx*t)Hq-qvhf!TxD?6h3d+(`+t}?JbB=wdntxDj1PqE|)qs6DaeX@HQ zg8V9ixxx6r=$+~MNkagJS$*Eqlj?ZAEa(Gi!_%_J^D(7uE*i%p(WcT;_~+@ zyQ3G$1i0poFG8I)T-fO8`(RJ0R9@2`qlHZ-h)y*4cj49HOGB4sl>`|DFyJDm|FmN?}3 zoTFRUauWBD7^;ZZ-uh~oGRJ7+r|jZlAR^${Fdzg66t70izr1w^@<|yyUQ5aVThdGc zAC&HzFgnuYkAeA$;s(0iaSyNC9-;@nYRf7h%zhJojrA}w1@ZFA+;pXf)$M!%2VFDc zT94;}WuL^vER=^{`X=h`XKH@;BnnfFICpo7iA z+Qt`^VQR8K=AUE6kFxs8!%hBu4WXPI1d@Dt&E=8|cmtR)vp59$T@ew-Ja?B2_P*yZ z2P1|@_6&hLchl7i0mw4RcKKe-^jiq=n5?2nHplJPk5wMoq>b!3cRyxOuO3Aq@riYg(selRp$ClbyodT6>0-~y@tNRRT_P22T;< zGQix5TkLK;Bjh!FZYQH3x<|u4@Ox$?F*|XM=fCcsi0t4hR-K|V%gldcdJa`UFV|SL z8~Wt=%J|!Q%c)&O7FxcmKJj8Xx5}5kgk6`|<3)|MxJ9Nh%i-~ux+jO>X$>X|d7;9+ z`bSEu;}T<8Lgut8xr+60Zu46mf;SE|?a1t4!~^)AmFl*)G@w7><<&c9=Q??T#Bi}o zU3oc1H1s!6r6H-DmseR27=i1oLxs@C(q#lA-+@51z#drbXCRMBxfLp%J(CsU-W6d> zWaOFJvSwS{%yMS@yiyyOpW1Ev(4GT&5+h8B%b7vy9qcF#4^QW561}YBBrzNore2?q zN=N||`S)*27oycmQlqfnt$Z?Z)%@u#Y2<5g3swo7gO{Hi@6_V>RTTuEL>CYHtq|$; z&F5(!=s!E`a15%}HNK)mC=Nc=4(PD)i|k@Z5~A-4DOV9aR4y9|RDX3srlA&kR`K|N z`B_N0Kn#Pll7M~CSMCU6%1{Y?1O$W!goN2}HOp!5L5G85%bo|1Xed4usZ~rph+r_^ z;tTW&x8M09P3BNu)Mbo~fidQ${{HC9Q^(532f_4s?Lf26PMWuKMDfij>qhx17yV}) zm>_Y+OHCl*EmqZKD&1j!xG+Ft(~NR<(b{V2wJ>o1Be!nCG{5V`)V4hVH#RHK*L&dd zjj!C`tVA%&Rnu{6(@K*^Zg4k^!K(K@ZHqPq1r^%QG3By2I;nmB>II(g4oh^=)%BdY zc=+(L0a|~m+Q}q=%HB%t**^M@nxv$s7?0C#m*MDsrbc%FKhlJ80U6Lvd z(%sy-(0#_)W8A&J^PTV9d;hs(ynnD*HP@U^KfmXhX_4;Jlnkzq=9}GfR8qP`Gbn98 zIEPZSd>CC(Cq3A;X?RmUSN6&SEchkRo1^K>j<*oN0X+Kk0@2{A)pVY-a@fY_iB3kO!JhRUi-1sz_a8|W4XAZ zdk>#bXtdid)eNZ8GY7uQz2=kh4G8_%Rr6FKUUqXh*cZY zn;+f=eU1cffu`@4r#yNI1?I{2o|X-2lwWqD!Q`kS(hc|dUjjf%`*&Xf537BA{`)$$ z_P#(4Q4as0!LJf_!c7ZD>|Uhs-s)Dz`Fh?<@O~NiO+S9Da^gg zYrtSPGF#+uLPCzP_F^@sIN>4Y$Dl~+-X8{yKwu2WsNHM0rdCE)nnFo_fB%%ZgmBSP zHL1E4ey5;K@Ja*8M^5zl)!YD%GVd&X1lJ>^?@~bJHnuSl-f4J$>sq=y+TK`3LE7bv zRoyAO1G~#F6gN`)g@3SlUL01P2dh^pU#FMOL^F>bvd8HP63Js7PwQcLlUAZ`)-ZRn z!uyu(&vZH|C_oh>BUnbv)aX{?W>hwMoGxL0tY50LTQPCmKosWPM7Ye%v-l0ugQEm! z*B@subjk&8Cv%#?HAa`aqEb(`e|`3v5m(IVe>`BL`2%clC+}Q+Jtaa$6OK`9yF|+# zENxNuFejY(;6NQ6Wh7tCnC2@w3jgJJ=jkEoj@^ZA@aOudaGlHH4Oq5alT5ZPM@Eke zkFo0=*b|w;`$>|%>!!Y14_XLHzFiIARuQU9p(huz&j9JB5zX>&KT$Y;>7L;cQ7g zO0S9Q`HvJTRHa)v?>U`bPHOe7))i4`2aRSlD$paGv z5+9IQt0GVd@qwf4J?gW0dke{#2#~>CyqyRtVn6u~@oCPiklwKV#I=IFYpBm<#WRbs z6paT%d6M%Zl7Y*MB3GhlnhaOG-Ct(a*M{_eiwc|=84^u2$W)h@_0EC*OT<6<5Px%+ zf6O0Ipb(T&%~zFF*w}~&)floZoVDaXA8Nkt&`jm!HGB$MVb8fBNHn}B^%?hAa7g0v zjG?yn@BIuUj6Ks2bQFR+D;*;YTD5|pItpDG-^0Tr|3wsOjDVMCvfQ`Jl?Vb}u}6e_ z=&__OmQC)b-})!aiuwY^Y<>bOmz7#^;j92GaEC_u4c2BaTds`g@DatJhrkH6C%#oCe?LzR^Nt{~@SR$g zy2j$9*`*czam3^O2W*(=#mW+VUMuJxHimf*@jdc7dw=Iii?HH#=pg}Gy|!cu-nXI*T=iZ5>o!CGNEt0e|mloLlqqrC6E|~7+V^yUf zK~v_N^mvU{%sn|lD{&>-_I2r4@oP~m0eKovnAi7|G~7JcgW28teb1gXJ%&ZHhEW?E zv*Jhk3f%@M8evXkO5a;Z-yx?$CV>eFyy!O4PI}!of4!x$WJ9vO3?E|$r8bsV$-zOP z-j?HNT^q98quVR@5lX3cR$sE%yr%T>@^Vetdne@MYhh@6eRUfdX(u-;OZ+i@3XOJY z>#`p+_>?b#f*NJk>oGw}CDJr~Vd~X3kFH%~{80($i3u;(+-ho58MNx3BV2htMqiaf z@bsLQiInZ*}lMt)4c%O<=RJ|uC~Yo4V{DN z)ydu0vg4^47{VEJq>J-Z>+MZU#|mQG$v}JJ_-7|SZwqI)PF0zW9R8kI>xv@NlLdP{ zS)J*{p~I_n{R{+*7;fTZ z@wRuuHzF?+a2}5&+Wrk2)Q>X2OvC}ksR2NV+`2RK7ErHK7vharrbV1_OcZTB zcqekWKQlL(T0-26p7e47c6xU5d8Eu52B}Q&iwyRz)XRv@wl$DaOyjGgaoW;Ssx*G> zYuq)QQT2N;sy3JOJ3o)ZI;wWPeWGkC=y0K;3)IK?;TM4fx9iJe8WNJX>!bN(R~SSO zafTa3`X)mERlw9o*-fln2A za?+%HDo;;RU*8g38j+sooxn|;!Z3F}oAZJ7G~nf1c&teK^X!6Gd+*7UmwD_WtEyWs zCPQAbKd&TkG&KE$1D@CcR?8IiaWBvzFXV{*6!1;QQZC3};&5nTyX%cr#PBO3XpeV( zgiMW_pU7~K-|lYwYQU_UN$>ck{nudA)pdY7hZ$+t;)%b16gOnAth*;Q?RsJ&rI&s9seYK)D=*?^ z?FGMhf|=Sh@_zyi^*<}+S~|$P7oiX-ai@MK47T@3SCMd!-utfII(VsdR7rq_(fld# z{e?TCy#Nl!4N*7&sXRzf?#&9O-T5}c)m_q(@VpECV#)dDW6z2@8M|NRVtkfo_#}Yl%>Y6duT6-)Q%p>Z2iAaAK}iIc!P(OAvY?s1cV?KQH~ITw!k>%D zr?%$<`rY(u0wFVeg6MY?H=z$yU@+9u-*7A|(AEc`e7|DAylsj9oXadUToQ(1*0Hln z1zoU5*d5b-VN7U2w2jWg$4yWS^d`B=7b5mztmod@muv1YqT5P)neqt8wOB|2M?X6P zmiaA&{X0#(0;wD+gyy#iiA+`A@Qk@!@&8d%7g>Zz+Q*H z+Yu943_dov>|?6ZEe89#C#tY0Z9gU=l4E9O{wTwu%8vTr0W(h**s{?0_js`oyhuL7 zhe3Z<0zPvw!8K*;*dWtwtYi&uR5wnM(PsuS9GC`zx_~eamqNy%FBhZ(2UVm&4maP< zhfrcpP2QR%B{qgWwwJNTt|~n`FIlt6)a#4DEs;-&yNFZJUafZf<~iO#QO*A$kYh4y z`d@NS8=I}`?@L+uUQihfC^5~J;r@e9Agd$LFTBF8FcDZma`(NQnQZ1oLQqf%cw*9A zmY-A%=+;`lH5^EzFL;7R^em;Nr6sh3M(?$=GZ$ckU{IFKPJ~B5U{Rg)aY5uorK98G z+3}SX+vY?thYW$n7W&ddm-d`8+&edH`GFAuhC;;WOnl`P&24As!P&b0hg;FGUX?{& z7ZIYP3qF7T9Iezh=+FP30DaXh{Bm<=v6!H8S&1kacCfpfN!Z@}!H9*QO5}M7Ltu3) zM@B0#B!LF~Zh664(t~!4NS1kEYvnYsyEk(4MSvi3JHAKiRYT*zI#=cMj<7$YxrNvd zRP`Wtio=h)fWQN>Ffmubt_Ey@_UvZkS)lIwZGQ^4Fxblu7IJoeK9az!PtC-{)JItz z?3XPSpHrY*IGn<5H;j$4NpKGKZj6kGh|s?U|5oohwmU9hCp(ta`zS(_f1n~!HwS^D z_}Wi!#QPKO9~M+bj35%o0d-=**Xe@rwmw8?dbXsz3kxdLy1c~Ss;xG;v~+`oZwM1a z_CP;Io|Wc_xBST%z?pO8r<%o!b{is!TX#}~z1v%2Vjd552Y$x<1;U148mx&Bz2;7% zuAJ;x2|k~)&q~%4qruYFTxe7GEocdLIk3A`T0PK0-b1ng5(jO78ziH(01;5^ZA@0M zd0n}aC>(4|zDIsc{Youxnq(lASJmArpP-z@U%(!h!#trq*bfxowukd&M5=sCz-4+Ik}Y`C~|) zR{!{xwQ&lN}fyqQ35u^6DI4Qg291-O!y-F z&0=9sm5MdkwL3VBe>QmqF2@O;U!8?21mfkPj03qkvV^>q6A@pec- zJqZa({gz)l#L|#5{Gvyqny{qO1-NY`FcBj25A1IRtTwYRcSF`D=Sp0VEhuk_=o^9x8?-~ zZIy)_4h63)I=kOfVb#z9(S?UitMnqi%nt>}5$;UYr!Ymk@-1;hf>#gk&xqW>TPovm zJAg&%?QI4*R1cjtkfAj`LO~Q(^QV^bc=ZV*=?T zix_4B(KE3xAVouT;vDEv;3s$wJnh>pKBpw)vcWQQt-peZ(oXrS>*0FP59v4g))OV# zl^*AgyIQ3>jUvg5Be`-TSC{8BW?+A`Cr@ZP_7aFZPoBH?ZN}`c3^3B-GHBN;g&LXI z9IOs~6sghCCkUD2t^i^^fYlKJtlQgAV7Me;xF(=L~dCSZGs$ApBkLqkJCl#4y@6mw;|3;ZQO{tCqTwA zksUDM+{g=PQ2T27RM66OA%VGnk`Yh`5h3_RGJ~&S?HI5y6o%XLVQXnyFLZ?2uMTFg zg(wxNMJ2JBklqn$Lc`}G?hq3Z8T3ZDjT-Tz-XR1;=uvGm%H=Q54)YEBlEi+mvya;# zp7p;|%VX3nLW7>I0j4$Yu4oYgbZ~|R4g~Z!Zr=J|JOgeE#{h(k%UP3rw~T3l#%1Rx zf_9U;dS%|P9v@(@<$U_|i4DbSt|4)Le%`n(5aV81sj1*cnV;L|f<055*(7~!OIC!R2M*F{U2Hf^t7TmU3G~-I%CbW{Z zGMcYg>Ab6#dDPWEIcetv#Ccs^Yd4Sp4FSOH-|l871=PP|4yK!**NclE@Xaw~F!R@m zWq}V(g9c=@@+kK{xQGy3)JQcE2)s$aAzv<`rEN~(vL_AnLwjA}hFK#t_t}Y2R8;h( zwe_dj{YD$aHX*BTJbJ*k*I7oncc=4bW{QX)10~0*U9?}@`3U>f~5z_z~il&6U zhU{{Pxa?^}1;MS+;C0j{dKj>Oz8pOE=W}qkt9*G80X8IxW0+6_{V*x9N&agO_*d@( zuOx)r;rkT5Q!oGj0sp@;!$B>zF*^xOeDQ+m>GcwzZOv%;3l&#hFQg^pqgZOmcQ;0j zEg)=aaYBr{fDkUg%J-z}ivRp6G{zKh6X@RB_sfT+E~F-ZRTa)>w+A>uTg8%}w8L!88+`01Cz6IkhL zVdSLWBN%F2WPOY=5Fz34UwGiZdOsLKngke*(K3Bs{tdA{dZhnb;KAtXG#!U%S(W7- z_AVUr5j7|e44FjnKxlZJ>N(sT1cQU(7kUK$8)v{XK0z!`etf@8NCI>1*K7M9ZmF=e z1|!ACv%09+r(@;QY%pI)z}&iXKmo#6x=m^X&_N~00?X4ytKI+KI0J4gf&@qRB|@2e zw1}%SF1M=A2eU^+(~m{Nr9JJd=%+}gK}T-rb%I7f`Z(MRUAl32$iM+RVvxaq>C6UY zFV!?8KrfL z>35=L7L=;k<}S>`iGLp6alEcg|9C$ltEb6L#Z;)BDr*;HiMx9uGbV5-Lr)S7$nd6s$#;p1IJ*3p-@GYGSb3&JZt{*O1+ljUDWSO z%f_4>yf@jZ7`_1P)E7b!V+D!e0*V=i~AWgq77d+M#LGpqO59Q_^QQfFGPbIewH2IN84%wudTPTJm7iK zCe+x)wDpwa7^kNnzV4OiaE48^CLl?8S+Qef5Jhv55V9oqml4$A_v33SVXS@ z5ql6#x(80AMNy@Ifd4J<)OkX{R<{rah<{q>y*}QIH~HmvCpmg#v+k9KJY&3!{w6`& zW{}tS#`ylLL!4|ri43FkJ^<*7&p=-4QM2%PigS#&IaLt>HkKppSOSQ$MwKetq;(gs zYmab^%60Pas;m7akZ);X6IY^r`Zq_T?E!>2k_ zJgPA7-Z=>|0XQC%rd+ve3C(It9QsIJCsR6F4u8XbX#gvuAR?Nk{mSpW<6Uhz{XCvg zH#@smCHN4eBx3fK+`^-yqw`!wIzXtr+j{2wm}rnOz>A_EdnITfp2~>#JyV=ZwMz$)CBB<8DoRd2h`$ zksZM}>XU)YR0G zPn*Xg!`le5t(@HD!2IO4Fh2fRU95?&>R-7s&(0lx&Fd+Yk_wu1f~fJP#u$wz$Nub- z)27MK*G6YcgBZdM6v53R%DTlb>TE@`CetRFH4R;U_iKaf3`!Y!Pr1o{PSnBisn=>x zY#|hFjv}+0n7h2c3c8}?3=X0PyH_Bbo}NDOpWN42_NaE>FRpDaRCbH4wm1(z+B{E0 z^hM0K&yUZaoQ|qI@AN28=`x{%O}%Gbiu|_mGo#i1#5yG~wp7RuS)q|rCl`Rr`^~?J zdtDP<9*jKaaoTEderD8Hsc-NkS zx@m5&4$R+Qd_8cyLU;WvXo!sRY4efLt-n$pG6l|9JJ4a1&=HTC*vBE^@ z-2N=PAUjiqQZOEiqNt!iZ8*-SQD<5_X}8#y8~|fX5dQUR0GEHjWqsNUi9o=!WupP4 z?*{{4`=YjB^;!V36}`H;QYv?5-qjtE!a&iic255ITVu=l1wmuh@B1Jd$FvwC=#hN;$s42WwYh&?SDy7Pkgf+&OA}^*J@^>uFcH zD|;wXm1R;-j1rQ}SJ+x4E6L@Sb)MU(I_ZiizqxDu8*m$iL1C2@8 zY#k&~*`^cZ0o++`^5oVh*LMKTkLm%$q_QvP2+Suu?9K)%MsqAwL+r%D@P)#Dn7(p;M)HfK3e@2b z9!=ZNZzPyJK3^lFpJfw|EZ1rV%0_8(YEoo@7;z2r5gi6 z8#@>aXT;O(8o~JLI<>z^!#2d2KL^UCN4%-xT!anVsZFUYS{M+=9m(ksK zV`oT$-8TH`uAKa+Dg375zlo|NdQgO*|N8IQgbku_K3DE2Nvm)tY7-l)Bi7JJwU>7WX%&4l{9ke1=vE<8a@6>5L#!O!pkJKY5Yj+yorJ(Tq*r zw%GM$Mm0Tj|EU@?(e0y66U9)i!y=h;OQ9FNFX$Fqn+daZ8t>yCZOj#uVKW|)LddaV z?PI@RyNsMgq;Zs|^Bms}@z`1Ujtw)<4yMeMSBJBE4|czC`*(ImJYguFZL+=&)5|OXacizvAUzHGlSD5mrTu2Yn! zZ4p{md@#p5)j;0k8u`3!bifIAz$6EU?EWC^s}{RVv#NkmytLUTgr{ z!pF?dd*))N7i0V`gLfUj-kQl*zE!ubI|ADb+bV^icY=c6#>}(%!g$GB{Df`F`%guy z*+N$mq#Ct+Y9;43xcA!^+?%a?O`ZkV{;0H^7(>TdsRy;gCR@n~iHdoWOTl_*sxcei zvuoaB2#n{w=6`v2Z*+~7&2SO@Y`63B9&_BZL9)t@Vs9vsOuF<~p)!UU@1BOr6h7Ts zJ9BNGn#_}vUMMY8pp?(2ZtA!3qF*g|V=6QK`3u9KT9vSg)t)Ldv16o_#KawTUPlCa z&88k}Id-e@cNZQWCha`~54WFVQH6dyb1<7uu|lnc;sNANNRWL*^BPyRG$*d0FOfC( z-4F>mWS&O)0xO<-FOV9j)A`k?T1fe9+(f~8*9q4lJnm|9S z63iT3AE8hGjZW1?l=_CJW1~J@dj4;?D_xEj6|Bo!QF;&tO76g~~<)lhC_d;*3>XU9p?B zdl_d6D<*qc%pbAKY;CY>0mS&-&+HPyE{k{54jT+vAQ47eXFB8ky!GMly!Mudc+EMF za=)PuB=!VrmD#rCJ*d3Sy*=+zrIy!^XQy6Itx{R1T%sFsCCl&HMAu|7`H@Dnc|uhw zTq(rQef;kJGv*|tN2-?ed^?Rw5~DHM8XwN}W|2vJ_p+6~FP5%&ojr)9IV^uI1;ai+ zB9fkoQ}cL~5bTGt+%CU1T#8E&+diaH%!~4x*>&*qfow=kSekCVdu-lW*YSdXRj;Un zB)v}W1tF8O{59Kg7B_(ZrsQu=N??hHjCc05`;?NJ(r$A$$Q|okwtMuZXZsJ?78WKA+qnokTYmh^ z$OKr(E+dg=kH?PrU(ytf(ow99)Ul3Kni_PQEPqo&e)urs_}&3Vv3Ifdx}=%bVJW~j zp|y96E!8`0(=B)Op9Rt?Q70Rwwo9o7_gGiymOi%{Es-z{3Zdvuo8`?-+y_eiWnr~; z+roN}ad4z@i2*%I95AXf8eDAgc3+ayS3O>q|3ry>F0F}4XJ+fZGN6k-cC6N+s2jZ4 zwHZkzhcDdJ^vwQeeCsHLx-yh?UFgKlh;CLnGUzTe+D5QHsL@xdGBr3eUe97X_S2wM z4DnlUNW>y{Nk7yz|45@~^t9XFv}{nz&CIRV@<-Eqv9MI~ws9a_AD`zj&V^))i=sDz z&i7U3vl3li3ms^=Vh^th-{gPe1&9@gtzk{~LTd#SmpEFxz2BC@_ea(WORID8VLi$u zypC%W??fF$<;8V+o0^*LNqnEWG?sCx!Oi-=7O|-SNHi6=0jv!Bp*(MY}-?^*;7PD>hCPcag(ZTr&5*1+nTL_fEC_hH{ z_eMFu+OvjS=V;P|FOerd8tP-nw-6#|RMSafGNHAYD-WwBps9f`!|K-QfXxU1*Njt} zw0r78LWotHgEC5$iZ#v-2lzkCufsb+Q{g!k<{TD1cgRTkw0^4{>S#T*TrvuwCg)0M z0#5=4NVHf-xg$q*F&xEUW?97~q9`rXQ297)!esvBrBI7zxp{U5HnXam*;x4#{$nj2 zWVHS_Hd1DK8Fk}L>wa8vL)(X}NIvVkacx3}?pKq8o6}CKbH4Y5T(#=$DL{!xSDxz! z1&6_Cww~XqJP!U-j;joDDo0Bb7Eq~&$7_joB>*c9@zbo?{7|+qhqDn+pGNgPCr<~@ z6XD8!{^Y^>*a|;MWU+ePi$EjEiwj(oAQF;%`rz2!%Dz$)g;DJNQTocdDkr6F%a4AJ z08TWiRbZf4(vwIfXQ@}GP^UJvupVK>?m`tiQho{=35$kmknCToWObn!PN=2_OfYKI zM&fqHp4Y~*=mtx#t(qlr(}j-O=C8f|7UUPc9IBbd>0D9w-AC81)gLV@c&S&T$g}{a z;v$=#xAk$)utW>Pq)pkZ)Q-;x0>d5c+D;FFECL6+ju%s)pN<#GEhvn29|{N~NVH(w z-#+EAZ3rAlNy!OSoti6{zE@aCP%u%vXG&qJcKxtGJ|ExDh_%E$9-}N$bJ_Fh zd0ED0CA}U=4e^!d1mV=_rR6+F$1;QH-hz+6WHz4}YTssIiAe4X`{g5+WiE*q@77gD zt7kZSJaSW76{;E!+FGu*k8(g$#bA2%S9m<`MS1=CO=_zl?u8`Eg$mt+h>7W{TX>rN zz4|fZgQhRXlTZshJ<6pgfWc5UcHt*w^0mc4Y%`X?gMQzvBZbZQ>H9inuoe?4HEOCy z^Ak29%QAV6#p@uE@iKEg3A}v0qU@XIXGa;}OvYqHXBD4*;rb2v?6v`r%O8d553I_T zEK*2a|Fe|M`@aip|8rdWi)NdUYK>5}s@S|^Gu*yix85AoZ{$ZCt=&`Z6@vSFRGT-o zJLbS6wLjai%FyW=Y+^EEXL{fA3TPA3)WiZQ_fROLlsD5QgsWQK0TGfe2tqE*$a~&vH**WhV7A-s2sBkf_^JD6`2Z+_ed+~uV2(}8v zHSC9i6a?#b;8T!-r~pFnpve7KCGgGWpxDvzGGP>mvpB;5ucXB?rog~OP|EROZidVj zEY1MwPaykFJUESKf_Tv=jI=;RrP{Ps*e+J0ySsZ76f>Z^L8iBdt5aqc`Mwa|zynlN zbRU@Nm)|q=l1k{(a-rq+f)04nm~$B$$fbhGx_dqK zI2==9_OqM$phM7;%8O&rj}N!aR|-{<@}yHO%}iu2Ya7E*4_>s%iRba^;r~!F$K`Z{ zN~?P%kf@MYYB^arrx?Ydu5)QViCBnqap6wG#3UaI>eng*ve(pLC<9j>;b;UrLMS-& zoP3RMe&N%qmvhk^KNKii3sHtLiTLStzaL}=s?54iYLrEG7I1qtnLgMxdL)Ur$T(ii z^dc&}DbD4Qc)O6eoncSFkL_!)>kAK1d-PhB--zuC3MC3wK8d)j4IA*-tg~5s|I|%P znWVD+?Zp;zJQ8H5ApDQmDdMH%3Tvec1UB!6Ek`;@JVyr*&}?~dG=V}?b*+A85tyE3+juD-CZ18hwRtdLK@*31GKaQXTeQV3ro z0ig-l%8&qt4O~7)3bUQZ&)3KktrA+wc`5aVNX{$0K-q0<)l;EY540`K7~f{YLYy65 zDm0cgH#MlkmJ$G)3kN^#J9q8nNMf=Hb~Xp`0Hsf_Ja^eut9}o&2VY%s>U4R9EDsDz z(=Hy?>AkuX>ub}AvSR-b)tVW$NEer=0jk1}N>xiaWbiqo)#eo5)dKugpyPl$$6>b8 z?n39|$t@738m+m0^|H?9tg>5ap^8?_PWIX*ZmM#VmQWGJb-HFd>!m)`0}RuJvsjZw zS~s0RuXJ9kGJ5tJgsq`{ZIZM6>1EpAAg!Iu zynNWHfbu@448WQFpC#_+vwgcClB5=cq?F(_Y}q&4}S3cNSh02qBO&ko+coP&jbn-_O6Bk9wxv>A?Qoo)0m%_ zIva?`syS9+fZgqsIf<d~vAIRiZBC^or5-L^P#;MU2Y+4p7 z+Llignj2jjLo7g~%j0o|YJ;a2ho@93_ zdR#t~N#Yx`j(PTS*3Y~<`s47tx{Ct6OgZ28YGF6G_1g8Xuh`y#*I&hwm|pi#_uRqxEK z6IhvCV~%w`kd7y8(9=NLq|)mSf88YD0>`G)Q0wx&|A;ULluL%#T!7YWAtFn%ZtX%N z6G>7U;E&FaOA%gEdN3dfvf`w)nHtY-$Jn8 z(D#B#_JQM5lxu~G<;|iJ&A*k)nd^FRbTmSio^?KlDj^4l#si;MK^FTt>|*pWBgvV3 z17l0BhfjbXBZY$^<9qK2%fc$wZ0>@h(szPfL+A^@)=&rd`OYfOkT;@5dH z9eKGus8tpPwaO!_eAR8e*mIQ9Nv4r=&f)d8c&w}6vz_WetD)2-0FTy`0DFb8@WvOO zK>2NB@)u$2%4-(_I3gQ4EMzD-{F(RE`tW|>n5i;mXw{LnMQa56 z_E(py7~tc@e{7Cq4v@V?!Jc~7!9OzeB@I&dK>*)+;4tMq65dA99) zCd*nt73X;IB|C1-P^9Tc1yg(jnG@Kz>QD1=ogpy#ObRL0r~Y=lE2N@2=s$>fJ$=N& z(jqA-VT8WEz9yrqK}vr;T9X9pswUt*Jw_zDZal7A*;7d6sp_Jl@B{V+{WvE!$|>`+ zkzcLN!$X;!s~usAk&B@F z1%(Y-ldg(qbs$ua@!Ze`wX?g__YjXGh*^>$cH;SaN~@<;<0`PJ>;30RJQjveJG7W9 z%yJ$5wRW7V)Qn5QYU^6_3oqysaL5Yw)$2Dr=;?s3?N05chNo}U?=0gPaXsJL=T930 zFnlaZEK7V&=0B!Zt2&AcoHk}eS)ZlRzf; zPOBd|(r@2>bg&sOQa29{@T0JF`ZoNyh6W84RhpB~GWna^o1Vua-Q5v=l7TrPOjc=F zxVW!I2*=UBmVu7E!7820cX;ETa8p{6;1Q3je}v-!B^iqJ#qAflgMv#dS`1L zLRKY^DFj@E5?Kvw*M5H)nkWwo97eSxH|qJ#YNnR=GliS2t>{b9T&Qj`NckMB+LYG{ zu+qNgd0M&wpyQI!uWvvsEll9=1f_QndWrxzHN)AD5g_mr1WnBf5>*3Ab{N7>XiH+C z1Ld0qIi*Qz??8dre_ZZ@`xdI-{;(Rwc2nCHQ$0U_V`yz4zT}pjO-g95k9d|O3Pstz zPZDKEApmfsm<6vrPV92M!=@nrXQv}37NFXlA-F^I;u9bw{zrgVgd*N_cpM=3@vCk7 z;f7S{gnO8fkWk?CM#=OJg-6p7$}V5cVk)PRe+JL5zdrkX-F$lp#sK|}`!lE@$@BV> zOUBbHDH8cqvNXH&K1u7#=QqYFg#^w2u@w6oL*)wxR#;8~$vCNQ~W38ub}>U?h<{8dX#3?&T}vZ5fz=YM9hUi_SIch+d$ zrPC<@X8Ha=mHr2CbcE8x+}w$T&!n@wKM1b=P-^@st1Z&5*X*f}+G_vg z?pDQf_`%i%nJW~dfU0y@_ueVqd_LBOI#sNe=2`#@e=5+VA~{U5Qwao zfvPTo3Z7mLVNu-tF^ItA!ohobq9xiOEDA4}m~tcBT`=oi5Of8eD1!gbmqW|JixsH@ zUqtrX|3V{3JS8{_|ELQ^Yg75qu13%45RL|3cG`+zj5z+7(IuN z#xtsb80LR2_y-67q7}fuJp)d5BE4XQg{O1*L2;R^me^h#BuQ*t5A6$1{xW%&CX0YA zAqI0`KZg{ zW`NIS?ag61W9(R7TFO{v{8crUR+*ZGrD`~Pt=%i(@~7{kHnlXx&yE)Lo|ilX+_oa9 z^y=m0RTk4KO3b5XMfyX$Mle9g)*TGcI3qE@I9Y`r+1(7y1q_WRg542<8~%F)d|ONC zV5=6GW$4$1i;&;mqHH!k@-5*zTkJhB<|n%#p=5HL=E3&C>v5II7@z*AL&C$dL7Ti_ z^t_@E?$@(UKQOKrwzuV4{U2ry%I{lz;%IXD+7gP{<_?X*8VzFgf8gLV!KWC;5HH`%za5xm zdo-hs8zAZv!2C>^cbIPqb^)8=QxSuVVV8HN_`{5vr(>M*wj%HgC^W%kLOYhH6PqKG zxXNXdYA6IBg>3-C$ryl;^oDdAU0=RMy!*{E5)=%AiohI@>@H9(B^)bI?qy=&=2qv6 zkBk)jr=q|y4(BjcU$s1DdH8*Zqj>~<8=Kwr|12a+szJbji8Ghj!Ko21OsDbW8sz*V8Z^Dk6vqExuF6q<_H#0OCMULNHoZYW+ty z1OSzeJuwQz1}6l+K+=rIm*of|j<=ye{3O`;tKC%S{L@X~G?SblNXRJ|2#L1|b;Rpr z3#-n(0i|x4&2}rYQ)T-1@7}pH_`OVDl@rGC+Q?2^==Kmcm z9z0=7@CzM?hJLM3!+rWx=*RZS)DVSz^8GS-yh=c)S-_zVY}cqZmjGg|s{Ye3%jCpF zy#FI2Sx|W+wt!v6#K)JSQDrJxR#ujE_SYw;Podfe`nQ10<{5B6#UW;M zZSdbJQvL^g0HbzNVa{^k6onoZI6xfysovn^QTY?n58fXYV{5& zZEgUu!58V{O&au={0p|>sZkA7awG7k^W( z<;T^z_otlQRB~x>Px;PGzd8>a*NMNCz4O8WuUq}qi`3M>mMOF^KfYto#{-3JbIhBb zI{7Td$0Dp)G3x>7%9S62*dgK;BtpEJ|bWqzY6)M=Vx-y?jus%;tD7h&qe3KqZ?&uURwVef4rQM|mH$IJ@&r zrBFZD7*z2DwlaoG`Yb#C9G;%xNfdC$<+3Ig6%oPp-?idl0Q-vcr}0a%n~r_}#r10} z)z5wJJ$azXf)5tQu`L3cp1;S~C) z?YTzrs^4PB1y4)@+*e=Viypej6;XzlD9+OS2Tgzm&OPB zP#+=muK$i~`lp+qalb@V2=PM|&1X{s_FWRMoByl=ac@xLd6RgqZ0bfSqUe1HDy*RRJwAHNYQ zk>+w(SK0-UPzrSgg=pi9FRHz9^!etK<@08Z|IZDd1y;h*W%~>CD4>x`n_+VuMW@xR zu2j~WxpD@rWPvFjBqS{SPN_@p<7Z%tvc@G=7!3?xobHDepd@MT0$EmRvmgd4IYAcu z9#UCkDX4~gDJ>oPoIz=Myi_+GSbZjyF*^FJVuH<+pbA?*Bo;D`{;3N4U)N{<>oX7; zc_QkNz*u0gJ9YGXQMwVxl1n{tIdyi12^8ZXKlxf~k|o=CV>LtQh5ZT&sLv~}aM?Eu z4hhM`AQQuF6Pn`(oiwhl&aEUt%K?js{l#vwE3>U(v!Z?K?@d^3LeuK6$#1w7Dh*MM z>TH7e^3@+~L5nfO4A$5{QJ0WLc-)wK&meeQ6LoutJAm7^99fXabxKsux4XyK9Sp)(_;p z1M&P!IvC9H0EX;MwXgIofMB={4P^%vypW$vj*9{sG61~r-{`$G$gVJ2e2{x1>Cq$K zdrt)UrHF~*OM`6ZK?Cm`GH@2(V_W()IBn|$2M2%r`SaC^`TDQVAQ8NCXZ{3yiw^V% z)vPDa!Kb_s1b^R=02^rk*ZvR5I;fJ(5c7SS^J;kAJGIqt^{oU|P_HrjhT=*k zkSEPPQ$`1^+jl6i%wNd_lJWmh>8fu8P0c5$!qLt6HT;GmA=uhPS!X{qg|DD!#nE7k z8gv=>4aR|!tb8OeQ@8i8*|!16Y4G!Y#44DFfA)aER6qLveyR`I5RLj%vMapOGo#x> zhAIY@hc-@Jiwh?a$|6S|)b8`!Y|nW}zIgEg?A@&xHz*Hqb7esTAi4<&rml$qcXxMc z)qecPxVQ;hT36Qq4RGAmIS>yTvQYzs`&z$*)fWK64iadV+uhBG{Q0UUiCxN7v2EWy z?)(_5YhogR#i-xhZi9oqWQe%*F$%lhib}86e>8T}ojCy!$N7#0oCw?OtR2;P-I(ZT zp$qWD5HHhz8YoX3b@fn>RH><)5R)r(8MG#sNYlsIJ+9UdI zh|v(xk%gGw+Z+0a(1qH;M9DXfRUbsNp*_00(Dz?;m6X7P$@Y6;q% zm6avhA+J6u-I+N|J2_n4K3K~QS=))?BAbJX45=x3ABAm%oA3*%4?oq!3X;FuUIPSTAF?#?MU_aCVx@*LBcF?{ zBIp#TO_^be9nU+5^`{w{p+=)Y96UvsLJB6w>c7tlN(km>6iQ>VKs5M?G9zee5Ovms zCnN5~YiN^}eF>MTb!JX`%4wl*(-;_-GVj6cc4VE&{P}1j^Q*8J_hZodPG5%xb{0Wk zj`e$Scf|bZ3YsqvRKhUpdv<^n=9~U|v$La8w$rhhY5&ZVOuM-*d5hwLG#VRI>#eQ- zM3#G9vb^)Sf@PGTL%Wb128s+FjFOx$D_q<40k^HSy_e}^L(s@~%OAV^HtcmDMNt&9 zk(b()ofDsN6}BV`E=N}*`!g;D2+)P^A4EXK zHMq+(ddvbl0FXbL>%@ut;6X+@+J%sCKp1n1!J$#eaG>{c^g!L(aAQQ?c+bQa1dlw4 zH^QzLC(IsAmSi400#&qn080#FYOGxY19I-AC4}8SytrK8%0+5A_NmI9TgL4Q{FcCp zQON`0hlRM-q&X<xCkK;=(C8gY|K^ABs~7Ve6ikfUEc?FzaBbGJp5g{oq3|6q0K{cYM6 z`twQ8cJ+tQN3@!s9himN+}4E0z;QHg3=}3NOucJ zTYz*kG$I|tNJ|VT-9rzJC=J6%H|%Hmet-Mj=bUTr{l5F`^T)Za{SUI%46bKAamVMr zKlkk{2CCySrSmb;`PaU>3DS}DK}*n&`7^eg0IIKPk(biTZ2X&JcWk_GD0qx9g7{<$JxL#!wMxW^L0BIYQ)_mq`V`>o+(=k`R_}8d zk_bXChJ_lxdCTo%kp^{2M)osO7cZU-*IS!{WZ1aHWg+*CFWXD!nYC`VY7O=12O?;M z=^cuLfIY03xQD}RX3yiK0+X6D^*klTkhE%<4h6YZ3HR29(~axSC1_1QC4feJ!Psi# z0an)#Xnn98&Tm6Lx+J1=V5@>8n67n&^Vv^Gz*tJ_hrj5UzI2XaCrJUJ75^6E@w202 z3P8^z92qwB%(;TnE%@?D-k0+9)PJX&J!oYCE^nn<+CNo$Yx4W|3oqk0hm*>8riTs= z6_E9+F#tPKoEtCGsW$*%sS?bWle^^C{;$v%%f0+-p67V6$`w7)&^#S zP0eaT7kEf!Yu&AtL8Pz1X-*=Lg2|S1NW^<@fQnIh2zUX{bAqYPMy(*3Y(;h7&`y8|;GDon|_GP34<&fPEWMdU& zEmR`%VWqYhNN}sf^-G4$esvF+6IEe%0uHJ#k7^ z@=rV*etSpYvTnxa4lc4zwj>Knor+p|iR-l$nOe=35Thom^R%U+8McA4+j|)reNrz} z1rO5BZ!h|O)m8%b`r>Ol>wA#mHE#M_y68WrcyC?)tDkeO)XTyua#S;|xhhKZJDL=F ziaje_Ms&+PEy*ngPR0W@Ge=vRfSaR+Yrv7~1|+j-LwWMA2DNED|KMDg3R;CI1NtkC zu`Z9V7O*>rP1G8|d720#Yk)EkbPFeX|9M5Dz{IoGWw+4Eqxe$*K=FsaS=*NX_H0l! zS3u-V! zm0xCld@4shVSZ{XMpAF4C2{i8%X=`Fm2(G28%%DFaRGqt2fjuxvV@j>=kp%j;Q~@5Wcl8hHkqpAWeNRzcd!s(7t&r^MOAl z)E=bY5qo5`cmospY0aZY4?y)`W$K7KK;jYuwdnOCnGiT;Z?Ayg<)WT{gwT@z{(V3> zt9L$rf)!Ao$V}B_r;?u2kr&{>ydDf8wq1@D$OsA2iCCSjW()`tlU!>&2qB;lrhBv$ zVhEdY$^jAX%vyRTG?QUHS*62B>cJA>HYtqrhUt`zJ4nf&UrU*=;S(w78}x&jxUI~z zQ|~&vwF0UZUBY$Cww4E-9{_Y5v-J_sT^|?XxAhr3X>;l^l_JOul9g4j?pyoP^w~=} zKr1V7H(w?5((Bb7awyc5b8w&%nT{LW{LR>Mmt_4K!Lp=|gyhN^VltSXr$OPjhVF(9 z6Umn7=%~ih3F@6MlXA%o-SRy=K_5CLVRK#C@YZ5baNi1a2M8QH+FN;SqJ~!crHPk` zLC$_2#nwJJke1@hF4SNi0>Jdj?<7}z>EI-RfI{_>Ck;z`jRxL3++Xd+f7!pB+k&WB zHS;!(hucf#OhHu*PqkA);vIo+<>AB2cM`~aeS8YMDz#o19)=ua$=q-Q=&yGB4wMDj zrC;uo?h7Ff?84`Evq~b`HAo-6IAdhsYF1^3-;KXwiB58Sg{-f#tKqi~?;aE}M*CQX zFBE3s8pRAgy*=^Luk#AdEX;8+iX<0NSBEVyCrvg^GZiXqjaAPSEBDSsWWT?<{V<{% zcbl?qhe)-Q_ofOfcP`^j0lk5(X?#_?&77uZTbNR{Pw05fngdCM>dos3HIFYS)1D^rkGv_8}wEHi3`IMTG%2 zb2(<6zjiv?)gUO&DL1|dbF(xQdFX1IuaKk#3ki^`Q+{Ntl%B-xk@@U9z`?G?vl~ej zujOm!R|qcf#@V=c{ivzcK7S|q!d9>0eyK_{xsI9bY(ZWW(K&i1>FuPp`|UU61O)AO zbByQ}1Lf#*1fo@+$Ptorp}U;S9&!251aqM!17qZv0F; z-|*cNutZxn;u>bxj!MRklSWbLs9j1A+uO^tYBuUctMS*3N}aYo4&<67pO%)}g6j9L zttJPHk|$a^p%%M3)`fBA@!I)YKPx&-!+8oLyFT1wP=s3#S*FZRnlpJHk0;;JjLpl~ zfYrpt2yf@2Q)z!QD)2V$BebnrEjM~vNEeRQN;Y4q4U{yiO^5w4hm&L9V}3sKRa`S& zD-8{4PN#h0p;bFnAFo63;q;Zxk|tr9BRlTahrQ#^@yiwpl$N>ydXZIXnw{zywQe@@ zHgEzdigG$`-_sFK?)rKDy8MHq_v5Pd2jiOP=&uAexqL!+3iY6MSv!Gv+xA z|ACH=k~l03UGKz9*dpO@@e1{YcL$7bwaLx}eto?A_QI7o0CMbKxODgJTkabm;6tmN zN(3&zO^<(W(uHUr{AiC~=y-XKu;%Vomz$AuK_jTl`Cvo)tj-)LIUU_Y+cDQH(7uLt zP=ci*o_R$JChU6@R|##bNh3>P|$OAz5*-5}7o#c1pjQ@MgA0J#u1A_RPUd8$=siRx(M~{%G2AROyR15UFx~xvS+q;WR z0_m$kqZIKY>f%FkpGWU?e*2{XQ$UV<)1<&omlp*EoC-C24HOm@#N8=p5fdH0-w#;rRyq*l9bQAwG>LHpqKcYcfx)rO)7Mp}48;a(ib+%9g^!xT2%& zjX_Hj*=5VRw>POtu7!oXgI1<2?1G7LLZ+qZ4e<+?o)L<}@NbcRczogF4KwnKEln^< zbQ|=o_cUNJ@3UQ#1k2UIbt#yJgzbpqMPKS63tiuM*+Q(Y2h~mM5?yDRCM;VRtWAxQw%#U*!s}8$!(m=ZelYvQjvp-RD zhMT_o(@F)H&q)HS_3%8oQj>Gb2_-#c5O-bZh;E$!5%h?gy*F7vwghINx`z{^9(nX; zxIWhsJAf*mdTr{-q?+wi>%ql+k)6!FR#pmtVNW*1ev0LG{pzv47k1*d*wZN89UZ4u z!fjTKJWk&2m=I`kRqkMelcdxbzeBW2`;Cg6LnV*h zS#zA5j{-|^PZz{&kDfEBP&Zzm)H1?FwJBF{HEI>;h~4vAO1ByvRi_IFc`pl?*@X%% zz6#NdiPajAX7t6r8X^6nN!W8MF`;iXYlN-Ned8{v%VQH`aes=obLy6+1N6%;>32&x zUUDl>fs+*roh&B3RN_l_Wy~%C%PZB_BnSjwp9B9+cKlcI-M8X2_rzfe^XvD7u2BD^ z17At9WFZ0*{2`vpWYs6V?(hXFL6y^OLSZ%y)PeoP5xwD9G%|G#&#p~X7cjI zt}*A>-aoZ&j}jJpA9@$Q1$8yVr6M0O;@FS->oar~TEua$zWu(7*Gx~wxJ`)nn~soz z_BLR#uwDIMl5^iqes^tIenLcTFCpkOn(PAX;O-}tmz8i;W(*_~daFkzr5i)xgPEo_ zV_pYVrbv4BEwXs(+hM^D~g9W>wR zT4nEKVPed&zJAg~jHmHdtyE=!k42fe0mWnS#aaM+{MxH9P1q3kGLnb9^IIx4iLUU@ zalYblUzz=+yRwj*z2gkR+lbcUs5_JwBhQmA`i!k6`=jtcarohh`OdV3BRqXzKVidk z)^uXn*`;?x>j<@2gei&bGw^yNx<9d4J9iJ!qhlkgt?0GCo{&qESw-SFR8n5Ezf$Rb zXNQ}(!1+@^G)+?L8pzXdzBDFk0QRmv0VJ_Dl|h2WnQO~UNMt<$i?RVJpNp1v0q`xA z{*)fN05?G`8tA6X{Zgmxy^CeG%0EY@*T?JTo6b~Adft8|vLVHR7xzE5Z&dgH8X=%8 zH5lH=?6G&t=u9_kVsc)03*F$`C>x&a#y!oR40H%lTFA%V6rQ+Hb~d)dtvs2HY`W4u zGNsn0S40#{rGIu-xCe9e*oUer?Ndkwi)Al2w!gul76$XqU$Hw65=px?eZefr%{2wQ zz$G;0om(geO|g9%WW#Ll>MG7^{>WO#sH;MIhjk1 zK{?6zV>R3|9U%;#iKUfx?~G@G&sJ-|PW&(q<6n(qLEqSJ?lwbDt{7(lS(rN6Sp!uu zS>cR#HNIDF)QC1HfX4_*f z?CypY-d#Q3+goG)z?bj8cigw{X}wN2bjd)^ggsGA5u3J#rox$S^0B}K8be-J7% zCPdM>305pSDZutIiN#}|s=g?o>q)NwoiBa@WKh^Sg|h^-d~z2`qrAb&L5UzBRuj#r zbQ4^Fn?nEGBmy-x4vtB5Dl_$EWDDN>wqVl#QyaB7!KgzNrm3aJ;h#W9zo1aQ7(qGP zS-_o_^XlwGwRr5@^QJ+&zE$uO>NRLEr~P{ z(=Uevp2ul9Tu%KQvdDlkKPsKA%v)K=o-{TA*WA;yasnID(xHcr=Y6FO*RdHl>%>>_ zzzJFx>(l;D1)Y=^^+aHOFg;Fe(E6N%i+Miq%U!2y;8V-_U^NMF0d5lfKW>7DRC--V1uu3ZY_#`Ai(7NYaCztD}KKHEA zF8i^edvw=~NyUrpw!zv3onRHJS@-5W_Z;?!q$lM@=@}b-u1k#!>|qaVXZDHlxNR?E zk<;ZkM%Sk76)v|4SR?U(di_HVr+k=BZBMkxTmpMT90{vXVw6UOcdoy3Bw613kuV)s z^Qi--Mc+E@d{zUE1hs-PyYV8kDS31r;SG#Wy^^5Y#^dT~ukzQ}iI;2*%OGLf@m<&h zk-myMe%N>&!}oB53+15!Nedi_j;hn9fBFfxM)hz<_BFQ1sPX)lA}eDh@p*2gm67z{ zMby_Wt_&8S=DXtQ(D)B5HpHg|D|7TP5r)!(+Ze|&1z?@5(UVAVmF$34flEcm20mgw zc2vbjObwso*_8UyP?wi`r<$I;|KWm`)E^d|t*uvo9vBbXD5lP!o;v;f%;Pxn}5O215n9?sQLY{&4OCYJL_3LF8@r8yE;?Z+%?Z zEWM(ZW{ONNXv7F*OO))UnaO@UGBBx>(7fq6mAEt{lY3-oSX7lZKk3+*N9>})ANnH+ zY=WNqgqO=c0aKCWouwYMGoFD>fPaZZ@~^4*7%~+Xk<;pShofUGw@%@yrH+~g_;l=H2BohJ8ryV`UgirK1@)8!x+~xGTQ4*_($#6^9s}lMfno#nm=(0M2jL&a!XSX*KFn z8Y-Y{vC+BNYq4ZyTCdD3ss8Dn9UB&r#NBO7-Lq~=(y&=2EM%AMS+F#emSeUOBlQ}l zpC9GfTlg!#vE=2csP)nF%S@WPy{YHr>UUBk1G-~2_Igu?!s^4-^nesQXa!L2vB6dE7fn<#RDPz?B z>5)5JUS8jB%wh5@9RCpQnoh=LQ%4+oGm5a` z;w!2(95L~?u>3z}a(Pgo?VXBI4Q{5ccamJz!*WL=SRw>qUqH!-tE4cK~YnZ4K2OG4*A z-$e~ac4&yHx?YRB#kuyp$I5-B{6ON1AFG20%>8b3E? zvW#*|Gr}`J7^jciF)`M(q?S0QC6T&8*Zn*d$c&cgGHS?F{sgK1r>Z0$fjM@U7>I_K zKf1m^GJ{45=%8ORI(MOkQwM&G)K!*HNPv8L`tJFCJmOzJW~)2yc+W;%4$|z3HqCfY z!qiEe-67!7+1mOjq3J3z^r@}w4-nGm*hz9-7`ck{#=gvbExR&YfSPhTZSHdc^}d$Pe#5PuzUD|mv zp<1`;+S^>9I2Y|f!I<05@=LVBqdCU&9GCRLDu{#*IlvSpnCs1-KD2INH)sEv|xTue<_rYf2w1 z)93*0W)@R$EeDg%!P>&fmBT_5Z8d9BSt&F(r zHq*_HhTpuG=h<7gTFAv^^@?gJWb(|crTsyk>gG1OalSy#235j}oUC$SU}8EPd^Ipu z*|lw@HX0JC5Hk`a$WUv&`Re#Jz&%_9fG2RHMGR=H z12iEcv=u)C)3XMYPWhXtT-s0W`6~{(05>oH+f8af-+$8)p~)cRGXKdsp!mHaXcZ+P zny|Q;;ji@IB^X5~((bpTGeRkWMT<><)soIbRrULE5k(TeW7&!CuaBu}UtfKHA93c} z3D|x;qGumJixYeS9moAD zNfYfc-(i$1;u=9AaOo^U^-MbAQLJ!{OH$2V7yPV`N~YMWx?G;mRci-!)`Hn-_+30! zDQKKOE0pPU=QV+e@#pMcJ^*M+Wqk53GDth|dne;-VAykliKL8WCb)I+2HjII>sJ~t ze7tk<#?wH6NSms*K6`xO-4y^8CjKOS`v;f_?U3iDQ1~=o{${@VZWjyQ!h!&@Bdp-} z{Cm6*&lfhx*KamkNjq6w^W;IJ4FkCkU#X+sfJYd_xPtr?y1@WrkYm76@bSt;KsN%9 zSW}e~2jGZ2So&I?(vMgF=eG%Hzy6#5T_{jlwN5$Kn5XaBJCeIKzcDS=k?0(2{yVpK z@l;8{$pnh=GdIT?dD!ca^DiDMOkNP;@QJ{G_mKhopD{bMB(-$WZ1~`j z0kZUTV4~fiS%9lvdJmGTfM3<06HE{LpWk+Q@(wXs1)Ps<2qyM?p#tQl=gDTR>TY^h z46QUlkW_mqSfU*ulxyc5z>ohe4}JR1|4e`hR6c}*W++|2aiceKDQl+vbpYhQ6!ac0 zV$hPxkOqRR!KQ2?A~1h~VE#(vnJ$9)W1|OCFxWyw@*lblmj45UjXlvJrzHO0vqE4! zffRWP4C2fWG4TU03IESv|If_+|85&JE6;=aCxDj1>N4L!2*@09^WAXelDZASZM68K zv_`izO#!c+e6#KZMPMX7ZVd&2PhMTq%L10g?bIY~$xn~LS-g8A9hi83dJ-=JD^989v+}t%I-`)70Q~~bZM8I5-18q;}f!^IVtY{0A zruHf)#LH?=h==^l=OJJ`*)nAWkjc3Wp&4vOng9r=zRLt28%@&*=u;Q2e31txXRVJ8 zB{aBf$m9&6TZ1qS@Y#DPbR}H=E%lu?nV0U4kyH=?B{Q=|zKnL3)NKLx^+caPKdxI0 zfEG$Cfdda7dhHBk1Z$J|wylHV ziBs!?VaySki9+KW1Je?A+tU3VG(I*kUrsl@Xv~N{hQKaLzJ$|Vh_`Fty}E-t9Z$+?zkCNKq2Cncm-;kEKIqgck6AYRGXo-IPro=*Vj zZW?p4AcY=12WAr=PQ49Ha|=-5#&%E3@u1gm0_rtTKI#zqYjD{QUG}k+SkRCJCPVAE`la09`^abnjKYf;0@D^&T@yhnZ zqf(9-Q_w?*T=x%Wa)34&ZNJ@RXua{lz>L3}GD9;%2JOekc2z)0Q{M%US`)`lP7ttp zD~=DQtnDtJ-rp1T0Zc8~pG06X{ax=^aG7}Fx4EE+u~pK+To9Gn)Hi2~ErF#}TCg*> zbe{kUAxK1JTuSpupS`UvK_TK*0d}P%=yya9rhEHAwao~#=l--uxVCntL_mJn3-Gr4 zJVSc6s<$oq@+@a&NUTL6ZY+UjOgj1f$ZC22;N_CjHv7rK#WPY-dQB%c6%2 zJr7XKhc}%-i^#2B{@FxKWwLRj-zgnP)ypmFMb-b;pvQmVkzn_g0i(}&v@~+L?^8hL9Eje+4cwC|tOlBBSA2ot2oj|VD&6@9~It->&k~-ygjO7A!6@}KOSM8#EW2P~H#M^%%o4Y&aB5jRTy09lr z4TUYVG;hVP+)Nd8liOhz+eOEMLQ+yr<_Z5ckupS2J-4zc#QdgC+LZxiEMk7J7?_)2 zt_bNq&yF0WA)p_<(3Svk3)!E`16knAk`H7U*lN){`n%GflrJ&Ax5Yf2y~MuhsjKvF ze|^`96hN==`Fo`t70)MHzn2))$wkw=5XM`%bKlTwh5qnxDFZ5!1wfZwo|N?&lwMmT zm80KsKOhIaW+7QU0r;XIv*~FX3(te|K8gQ&fS&@aB(r?0)f$+0E#Sl_eyd@00S2QE zkj828>`K6_rGq3=ORq>YkOX}o1iW1AdD;O_B+8gx!nBZ$jJpDHv&UX1hMLx~0HtArl&12R@WIH3g)t`c2uuiIjim3DV5^?|c5L?1$iSrE@)Oe}(#g zL@j~gX9AcBKg~eD7i6ZeQ;MDL#4057bl!Nkx0LR^5zVYoC{txO-qQ`b)WrhuP7-RT z253oKpoJIct(Y*7CG9;gVHRO1B9-Xks`P>Y?xEfA1HDcfa?zJeFOSvG2<-VD*Sea#Jm>JC&Fr)f9)-6Fj>(I zU0%>+eUSvSD5$UVSGi<^vmllHWDSyFp9sL2UUo9qfL1yh_>yGSUy85)6-sw+Kxp01 z;$L2LV8;w@0}0+yVLg5*L!XpCdOYZ(!T+9#0U~oUaM9;Ww}Bf)dBwQp1^Sn0dT;A zfe4E&Yt;cF>^XRq#Ex-BcOb%K!B^7aSo?0hTfTd6jQd^YFr62}sQjovC9_`3vU7R8 zqYyZS&~RewzIx!;L3a+C!|lA5T~PNfY;A{bXAV3<@bn6VQ+x!EkR)p51dsR#;S_(g zE?fYAED7FGknSbLJ&gCE`^E3P7?gIDgBe?F%#R0YhV<^oxV`NJDjIodLH|*3mzLn>`{&S&p zu53(7(VJWZ}C_@dJb}=Sb#yd8i8d@l3P-_|L2(~OICOo(Q~ zz2p+=r%qhjBXGjVf>%#Z#^0seeDpu_d=9EY(?GyuAivZ?%MwVz%aJo6&K}@3CJz`}xTb-CEblVa~6^7ddV8@J`;Pw1@Fm{Qk_z zt&H1>x3I*B?4QVQt-i+?Fp}tgiDzh5R2?cc_3ysdJJA8!d;F%cWOicnbgTiv?YJOY z5o&;QesMY1;V}iP73?Xg&qz{uKi`~fm&yOsZSYI$Jr~nMm-O{j(uk0tZ6h5kI!VOy zr|aYI7EeJ}kKnF=)-#-s=X$AhkFflsibc?(RBi8Ut0;-zuczZ%G#(+|z3t2EAM*+E z(xT}5Zd}x8E=&1WF2D^sL2$;OH(qRk&O!h<3u;`g0?=`T&cZVP+XHYq^MFzPS}yk~ zBRHMQSBPH1C~D8t$ak?3_-eB?^TdN$O^Sq#k66y@G*#<%6TZAa#|9w#5&#QH+U!ns zNWg0Ju+O&!<7|6v#Ct8mcL@QZsluMB4|uKZ3%|d7%z<~0&{B_aKKRx zLN&AN9h8C?iSgz!2otpU`O~<}W#j=86c^H{H#pi|+3@V0y#zw947mDZL;cPG;29jX zd{yiRa^Zti+ZAZLb3#s@>%83!NUK4~P>+pG0nBvaT_O~v5OCr9D^iKT+edxn{Hr2+ zZqg-dkNLGqZ%v@RFaOfd)8-^st8o!G<$k!cjrLy1iZ4=hW^j94an)sr;WiyG%2l@( z;{p9a4(J=#poOx>RomGjvNCMm)XlNx=cSs{LChF63M!HEds=oLyZksm%}_6V9aOAcs(V(qXDZ;f z6_=!yrK?f1UMAm@iflO2ozdINJULnuEms0QK+o~Y&DeKsPyoZzV+B+^z|5Mp^$1uX z+gC>uezmg4++$Sg$f~pjqW95w2b376+` z=5@2()yReA0aF*WNc{Y-P&S3;jh-a#vSqAC`1P!-Uu{HH49YCe`AL%&M!k&CWqYx^ zTMJcK21}Ai=6Du4!1?Rtm|i=*Bg$28n7$oCA^2K*qeOqe>39v9<$^=S=Ntr(zNr!h zh=k8(E4&P3+m*Ru9AbsA7rd~QTHOf#Suh67d6)7M!LbnD_8@UZ7~XjX}3=?Df9MqMBosJQ}cl%WZIl$@Sm{M-aRM63o0>U%xXAg zd-659P(Poh@B6dnlMUaM9Qx-0l=6SnoR>GR^$v+xX3QwdBd!;DqB7F8^JylR;S3$A zHOM0aW%@$v*mjUHwe)7jXlv&BAoBd~_OWXpli57~>{8Cl=7qYnI|1>!4}dS<1CWJ(<*yinR15P zgJB@uUjciREv&gT_j%(J!I|0VwUq<2>eow(DS}ERHAiv-BpsDDnEh^bkP6ME*_D9m zD$e54Y*$iFDGWS&gzyru95suqunO;7hS^W@z;O+e*7M!}s6nnFSVVFi5PV#AyBqlb zWXX2Lu`&5S5}@(k%Z_)kh4SBamzf1z=Klykred!Ng#{>LD6ikcGYJg*y;C@AyQ>-jxzcVwr4u{8n7lUyU(*(?^qw2oJEz z9*cO1nI>S+*md$)F4*#-x5}EU?}&!^{E-VL_c)EiZwk-Qz!od~khhQ#in(`x_ACd9 zIOg}*pXpvNq@MEs?mxJ|w|bcAa*VCMlI*1w;To=ORVhBY*M6@JbyvMioo$#=rJ!H; zWW$?^hoL4UK(l-PGhf8dS1nC9n#>A5L8!+QC6W&i>hT{8`~t!IiProXB&uINj(TD; zN7{&mdncf%h??(gAeb?!9u6|D2wB}{*gDGD?ooTAPADS*o?&(JtsvW7BS|%#q!GYz zaYwgPyj#kXd5gNS)zdVMCtF4J95%&E_@IPS?4-kCwT7#g$y}-@p72(N9B@SWqFwPw z6Fd^wVu@MKY)9)3eud7**9?io4~ZT)Y8Gjf2m0)dFF`6C^)$a8Q!2?q z`z1Vsqm?$D*G5}8eZ7Bzn{VtJ6zwn4Ld0JVBIx|KsV2N+H&Rw`zb9i>-Fv8=sB}HZ zW-7k{SWiiX!OA>^?9I|)d_5X%gHJ2F(oRe1c*D(Sy44gk+Fm_ET+zz1FhIwF5}=)K z7=8P~({OU{s!s_U2t=xzBQc_aD6=hRFn41T>A`<^+;X$P3q75CD>K9np)1BTS!K_^ z&FhgSR0+St#I&_nhYOaoI8p}zY4RNfD&>F|MgwIIX+aB%DUNX<12IU9P=`{7i<3CBlaB@I*bFMp=gc$CDNFmYxjj*xY8J_} zwha>%4h;0{jS75r6EL;BUM^(OvVeb|I`Wne^Bn5wUh((*?ex|D37L8%>MWsHuknW~ z5>Xdz_(-!vpS586IC+yfJ;KxaP9;P-Aij(!&X&Hz@y zSFsVV2}|SJwL3W)Yt=qQX-?P;RmCoyCa|VQfz0F1#a^S1b@(~){psOF;r#3q$FH_6 zP0?9xT_;*37894ospweAiy{-kZ!eba;pYw-bF5wGCMo40(+vx!2OCy<(1IP>u$fRE zefY!jzouj|kenyNfS?C7M744zS1TCVw5gZV)lZ;X*g_)-t^SGPBXDOP$KMzVbw|20Q2`A}D5 zVyE4q+t5Y<-zeAj-|5*9ug$+56WTVNebO@EvOna8dZ;N`pDxuG_Kq!byn`D&7h6TohL zPD|5V!P})sDpg|NXO4BZo0aqXo2UE7uJT#@tZLos9rgb0c$Lc4T>AXgH}=ZYwFZo| z?W+dK+gs|ixbap&|M*K<#k#c9=^Lhdsl2}L^XR|&ip5_v@-a??bDP8c7{jSp0gj7c z#O>9uE)}R@(k*=B-&*#j-mg$!20LjNq-d^-LE!2#J1N;!HPAGod?*l zFOX-?gqW&PMiB>Ugmj-fFRq1rDLmLGO z#7af7vi!y7>A;?o88l;s_S^sj+K5yY<3n0H254zo+1N^G13r%w|MDqdgp@rY-2a4- zsN>Y0t8e(DAXf^^JQ^<~59d$HmVfQafikSR|)S^%-uW;7V zPGwhk{I`9JhOZ|7*`Lv4^F6x5N4zql|Fm63eNP&lzmv(ImQ^NOf5>IqT+|p+(j$^}G#>MwJPw z$vZZrfxay1y1=VWG-ZyQ(36?O6*jv6+DjOB|Dn#}US&1@1C}=9x5w9c)-v}B_d%__ zP8tRrob}TMEuHhtAmb&I9ci5W4`I*jPQ-bF#BTKy6XUUb9cl=4XAqCM3Cb)wfzX*m zdtTH9ATzE!2A&pmFoOaBHa5Y!Qf5e80ss#Y049vz(&75R*t8`36na)A(y%|yi|!H?fg2IRnL6BvUa8mo17ajnj2@KF?7=a zTB9mJUnBQ*Af?D zya;;4VqRMJe+ww+A`R0{Og~xn)w=eulq1#kz!qbB$K=oF2A5fshqvJtCRb~AhcS4< zwUFqSIou#7Fw!7Zk=-IKTlHs#|0%uy*;$a?_*MWudj6c5WJ1h;MK*-|Vu)y&EwRMv=@5 zD&tH+Q^K(PsXDDfVfAvU=M9!=RiA+F;KK@b=c22gKZn&@&-?ehILaOxcS&0j0rhR` zHd6WjFX2)OaGHO<;RJ<#K)4iWkRIl(^}javQ{bKc*fimRG)OUk;S)9H$4Q}YIf3oK zy+q7X>U6jT-0XesB&ub9+I5-;q_!1ukhJ4H^HgsJ_s9*Kgtun!+X&uzI@**mD-=!{ zhR;|6svr0hQ)8Vc7o>`?#Z|PUqu+s{0Efti)g_jCBx|ur+WEvM3=!TxDi}2n%e~QO zxm#JMHNQf-vll;%EJRE?>{W>GwR4KRQ^cGCTiFv(0T!m|amR{TA`V3^Uqs*yv4i)P z)+JKtnOF7w<2kUlNB8iW1*9#$OsOeX#Ro=Wc5ihPkt0Zp{^2I%`BpnBao4i!F{d|p z4y;DwScOvX5X`H%(iWlPC3Z4nHk3Eq@aoX3H;3Kvj`&AQ@2ZwHH+jfP`)4O~!#67f zLhG~5{r5M4{8g-M4}0Dx-q4&X+~#I7_pOw6p>1nHqOY?ItCurTpJZ_sbEMpXGC#wj zuys(M+8n(|zX}P0B))t1-hq=vW0ph)K^p)JcfC%)*URR1m`q<3HH}jdcSf9VN6tpR z0Vz*8>l)_5xRs-c(cK)*d#7@i6UhggUXc*S(39H3Ok(qJoF+h z!IlMl9`=r#)|m}N0-i3Z%m8|SEby2Q77XW8C9LUsFJC9walz{ldBS8|)#e#BLd@5$4?5jMJNe@Lhpn zbgkz8PWu?!^EL^XdW}}-)QZTRz}TVlsa=sqa2RCOEIQ%}%CrB?)hrjOAMz&g+bg)w zuCDD+yR*e3sf$iyQ)`^DFhr{T;!464+t;qWUYo&aPmjXwGz}v%`~;qWTu2$!lGK_M#4Ftp#WgV`4=d4?&{3aUQ6}IM`s1C*a)FNS7B12m$ki;WVry zf%mksLF)g24an`D)^qHE^OLY903{n8rdt^p^BQ5Xe_AqKX57s1drUjhz_3RF2aT3uIT~BPxH-(%EO`lXcQsHCtVSs-Un2L?lWT^=+$w zj~05L={~+r+cUmzGh31~-hQOikxyg}5DB525kAH+Nd3m?>oOM-z-`eR zU;3Nj94WFztu{Th-?{F3S4Q7~?DvDxKWMQ?8N|dcM9A!+0+Gs7quN7R-T(TV%s{NFbaMVRv+Zs|MB~=8Qy28{ z*<`1M)X9fJjfG@abg!MZIL?xeWMld`6hb3)EdRw+Gf-RjIzJD{Z-=%zwkY={%IeNf zb7!sTPy!pMg!zX#|GqWQLEmVYNOZZ<-+Q|+b8|V)TvB6F#53T{H)8yJlEW{-nTX=Sh~(8AF;6 zLHPWxyX7ZSU*D~0zV7*yVW7FoXt+8xVvCVoViS2@B-rQe83KWm$kpToyXCsbMjU=< ziZAP|=U!pv@Aj~`hmQ54V=O;IHcJTccpvIks<68^icSv^pH}G3nL0Mu#PBbiUC-%6 z5Q_v;oDLihy0vnxxJ=((tc=#`LvlW^LA!6EY_RD~uocH!}HV9}%75z;z zI)id0{3D(|25Ws0?12suU=LCMgz_x&VB?R_G|r-hC)res=7Capc4V`-0(cl<>$zV3;A{9dN@1aoeqr zvP0&p6*_)JD3B+9@p4eI2-YOCVWvcqbo`rjxsFuP;Ivb7jm*M??_K3?LjFEJX zb*OtTeFZ%Z)KeSq5#903HBv4xL={@f0`Aku`C?D9T_J&P0XbyrjxCZs#<*EJrzXpNrPLAWpjvL>hWz91vyT#<`CQ{^FFyN7HLK0n5Kwb7 ze2chj=$iq- zrB8)oG^pK;;k6artZhF^Uv%GIGD;MNXch2-;={AUB~&hJg~8TvReuVl&b_Hyt$Ks~9 zAW;GXTPg8s|2R~yK>WrPBEY8<#%dKuVf@Yns8u5kRTSDZ3n}`?#IM_*TLkggOm*R7 zNLm5qDo*0+79iPJw(`~C=Wh-92kyYRa!NQfnjth9!sFTwt6uCflB}jC*r#)S`65a= zQ5^#Ug>q-_ug=3W{5b=1W{mbSJ&_(rbT1dgDoMas+HjRj#GTLH-+STy<^)V6V{N8 zqbCz=0)<~k8B}t zbY9lnecUAbkVON`5w%;gRDNg{G`fh{+xxCjs2&r6)s+RfZbzwU`#coWByCsPp_pWA zELW=b})y@~&=~-LYl?pJVQ__gdW!m;6Wu-%Qvh!Y*-KRA*BZ@L^Oe(c-|l zyCxCL2_Zja3BbS{-Lmw6l-N5c1ugFWZ^%_QV+C8Xcmcfued`jW-JUSDK|%Wt-AloM zfQl7oCUvj<<+9>A)Jv!wu{B!wG2wgG!~DCv&Qnj616Yf64Wv^3Mbkpx^#{_z8vbQa zPk9onM7IBazQ?ml!xj`dKn_m64pR`MKV~PJ`40a^PU$L$uP*p(}Y!ohSZLN zN+k;o-Z%ml^j??U3hQgg>wfc!3Q1D6M^Zg19J=zOIVeYG+Z}*lQjv|!UPW5|urxKa zpg;pUD{?qyfvQAdC|N)xVr81e)_}NK-Mvz)uzUt@f#MxQ6B`@Ye0i3Id4*}GeUmlE zAptAcoRK@0=)`%ZS_`CE;`pJD*u8f?XX_puS;uzp)g6kJN^T`wSc8eN*Kc(x>_ko0 z((x0DQWd?A)ee|WTCJnWq5X1Wq*LKpytl-1|LV6j z^;;?iH48D_iZ3L5-91*BF2i9l1xAkBF*jJpIidoTMYr{-o4@dZgajKaou>*w3>aTB z6NJP78ITWQ7tN|5opSdg_<-?53rRvu0@Ui<(yrCz?lm)@?cr-e!BRVy0k`m zyx;u`=h2ny+t>y7KeLuGN)l^S7jDcS{x;85vsmw%CFOs9cA4u}0B5?5fv%@KeWuT0 zpXSV<<$q=OnCo&PJYxe@%jOphm&&hj_{Y~)=uS@^B0G!6x9b<}y=;JWS5WhUPcOqG{Zz4piXnj26)$hR? z-9!7;;Uq5KHVU+=tEDn0K5Sgh{OiAQlPv43Eq1hv)fJNWx74A685U|>zD5BY<|h+P zFD&em2IC;&OZCR?|!c9Jm1bY#K|0E+~baa{9?QT_%Kq<<5jEGtcoW#t(Jv9Il%xr)oEN>}|TRu;67!X(1dZHd~? z><_2c;JpLgknKG>bqA}yY$q1u4cokR=k_YQg}a|c{5dvaOCsEYXP@o0RA9>Xvx`K( z31W8f{j62(2z&r3@U1T}%LXNGS14aAvU@`*GN4uF{?e#?thXnZC`F`XznXv39`a2i z?HdjAJP!rxz(%js-|>hdFX^yKr)MJlux4@-!>d z<*U%_Q>mPU=}$nSsGO-0c)KS07ZxD+#ueQscb^?@ zwu^JQAC&7ihw$C@>=-Xt&arl*9rd~@5>1WZdFzh2Y0g}nMxS>ZD&$HMJ-#A7Bj9#0 zqhgamCo#>T>@| zcEn}8s$5)$y|w8wj~=Ix&DETBk)3J}Arq}ESonF1t8gFJT1mOMxucJio62R!Ol_wI z&*Z%(fCNu|52_1l+-5uwwLd;AiyE7$B-D3YaZaQ|&Df-?M$S-w|6>6eaudwz_JBQL zJ%LOHfe#2G5L#^Ho!tBXgwT>b{2pUji-Oc9`pefK0%|~?x#{BthAAPjm90x

      _}U;VZL~9om;j$vDH!KP8zT+)Azj%59c%C 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%0As38!2oyd@DibZx7L;v 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ν2bUCI0HE22r@kTog_H7@#+m<~@(AH#WGZ>Vgs0>v2a% zX{(4Gt_mzr`VNC+^Fq@c!%@5USCc<`#1XjF+y^jRqBDyt!#4l@jby0E*N8g>^JfEBXKToV-HVBtF`PS;_^)ShYXWv=4WNnDBy zOW+{!s*Ei@sne)zaCnE35vzj=y3FJB(|{A`5@fXGu=BmCqd_`SI)@KTc{pO{D64E| zI(;nMfyePQIC-s-x699Sb%o0DwSWRFb;N5rzlY1BBQK9z={u(*PeW;n>fD~>X~Db4a}`mMyC698#wRe{n9NH$)v^q|bap4v zL17wiNWx3YLK{`&jkzTGQP&}|jW%<;?(1rodu^Mq);_bn%2+5$?lP$`j+r@LEp31^ zjE#inbA^eKexlY1vY<85Ji6CXRp?7q(?jpXw zB(MY2QB`_yAoonnHM(UFkDd2g8g ztvM)lB}N)i>AwkBEjcR2v)ze2mu%u4S(-#R$mm7INd5o{l4?VQ71JeU40_+G`x3; zNu)%)@ZyAjzwXyv|8q&N z?9eqpeK+sMhCGdNwDF(d^9fG_P{dC3wbwRn8{U=F25JIdTBK zTNa04cL6q|sAo*;qXlmYf#Y}6C`z6nvz{&(nrg^$YG)M!@*d-5#-yi8npF-K^u8&U z`-}_^ls-2HBIJRgO>(1%@G<=7#2MeaY{s3}Azf3ksoMKd!|N!QSZcrRDPY7H36=Fd z4e4+fph@tK@ILmPf1UYYFNbzEjR6WO01mTWdCmCxr6p&TN}jX!oP3{Bcvz3DvOu9> z8%fcVPp9}vk%QqUIXmsrP{mnlIfeH2eh~gqVd+MCR;J7WFwtmY_#QRZ`>|Bgp}%bb zb^^j>xuy(NlHgmOz7jTcxv}1+W##(uHQsf`&SUGBWJ{iM8hB7X3FMnkM>(&noYdD7 z%sHq3XL0*C+7lpuG-lOVehTc(Y6LE_-1a=8nDD`7%TN8#Du{vF5~rH;ys)7HsH8M0G}w; zVTmH153?Rug!i7`sVcv}Ip5!=4LsYpebi3QxRtdy@ zp2;SAxei#2A<=~&;IZ>?m@@>df%eAe@c#2}BDUcCi~_%o?iUNs)ST=uFS8o6?BiVs zY7YSb4(CJfi|jzM$P0=(51oLaOGW^H7T;Aj1o1fzi$wpvdFi@9SC(B>w#!j_w?I$Dj{$fJ9*){}qM(R}}VNQP|NsG5LQj3Om+%|Gl37zfiIE z>0VU(%?0>J(HiXa5$bTk)Lv$+)=hSKw5CWv^jJlBbQeS#eu-0~3=Kcvr_%#*1!5xY zc$*GRr*w`ZQI!JNB%M5a5ltFV;&ekZjOw{u(BL^W6T(Cv*Ek!x1jF%72u>}ab2vdK z!`NX2&VTfiN2Y?O##~neGz$%U;$DPIpTUA55Z3&Qi{oknDV&vlZq5(ZU`t@bL^hEDE zyE&yIfZFv&(aOg^YYe0uQm}oJ{{=r7AEY8_LyDfNAmB!;R|!s0naSdRivzu(10ukP zDcj5Pb$mo^^k1^9Jn~u7^^zO@sREz^nX;awKX!I}I5<*D8$mUR`LKUuec71%5Yyx8 zuOX@_*(;Mx>Ty4T*2-87XhL>BXDE?@ zy|GpJHf@rhdgo1N3~v`87|~v;h@`m4+i)B_=L-h6xwyyQtEAhayRVnmiWyDgrn0Vl zS}?~Q{p!7n_zA%r4tIe|$CeF>_2_mpLAToiy4_=k2Ll2tp9v!tfro}!V*rJ^eJf7l z+`GTUXe>8O_duLce2*{?VOjzkX}IunGRe0DCTlgriTSe^|16kf<-URF7jECXsfED8 zIU1ms`H9A{5;zuIAn(|YVy$>>Qo+w&l1gf6!@YWN;wj}K-Pxdn?1%q>kxy) zX6g2yf!cT^;7DqQBRlgBAJLApLg#ixF_|4FKaxT}?i$UX6>_HJH=t(Y3KBjjuK>|# zLw1~IC^}mJ@WlYXx-WJB{XjfSml^^@o-e-f5uJpBmjs#JA{CO!09el5z`$|-&xZ=# zKxPD0V}0v}>KA$5&;o_rkiVtXSoewP z@iOGlq32nuN)aAva{&%7;O|NdLot`2veJE)x0wsPlu$TMz zY^1VZ0FY5OjNN-)1PSfT_P*dQBh_^+7#UVEu77hO73hF`7F#JD?=MVr*@C)rI=iTo zgM!zR3)FxQcZhB=Xk6$?mYC3vV9_x{=jmE4$owUd<*^?# z$oa4h3^R|MJFqv%e(Aox|5DycE>3hmyi#&q)Hd;qK9UM-q$PmEC0)e>{D+>eHc%a~ z*>t@PU$5Rc1PC1ldkDr8A^HsMp_rT1D6Ywio-0Xlv4*}vfFm)2_J+54& zWx^w`F+;x7@7E~5&(D+I2lSN)DBx}=mUOdX+5@F1fs7~YA3)TC{IB=Bw!q!IG_HJE zIj#-FKz=5NK_1@Ql*#*9wmB=A27(RY*;L0QiYHF>(|m9orm!qel%<_)3gQK9QyzfY zn627I;{j^0;n*?-k}IYl|N2OyZkEkD^}so2c=4!4XXS^ql0%XQ@_q+KFnRN?vw}H_ z2h8pF{_MiLW5GO!$b`||0#XH!@%k0~fF$2g2p&TRoql4wFdiw(Gvi7;iqHqszm!ur ziQyZQ5+{|5g`&$)R@&Cn4S=ZdiM(sVciMgq8QCa)BHLhiDqH#*_SxEO4|rFN_svg@<@=vLwz){25R_d2U0SZA2T-@! z_bHv@gN?4rnn2y+pAscg*)YsUWP-i03W_N@AINm3$$x2-E+oR%CeMhHwQB#;C@Ip? z|BRbP(w#)eYslXf^x4+Su!9~gO5lsm|pDTWY$qZ#LcSM8CVFLh67HY_{wh>OQyz zIRg1rz5s**EzTzzMA#p||ITt%AA1$n9eR~rpe*;PVx#EDQ#CQ6|D;yJI~dR|60OlJA>NmiK6;w_#`N*}D%Y*zckW64k2pkHnFf*4r2GP~?=BGdcXe+#%5d*} zMt6sFBVE8CnahNXILv=2;MPK=ScmeQ8Wc@!E~5OtKq-|zoK3KuSY2DM!(I{QG#5?+ zN4_gA&%Gkd5!bFRyxk&?NkR0#P;FX4Z-tc(ju~@!x5m!)Ha)iQS1m}DfL&6-JUu4# zQIs`x+5ZU`NSgXNj8bvgVO4+&!niNvO1#1GJG&<%@FnUu26UZqb?XB@wzXC30x z$?MS?mTJEyYr|K@ajA0F`)LK3q&QsN1R%FrHAk5cU~C`@+EN%MvwU|*2SCyC^+0Dv zMe+7Nfics?OAeW|4H;B|Z2ry}2Sn=)@^5nl({@++99=0s4rFy{2n; z3p;dN$pzg(QjuY&c(_u4=+w#RYrfw5g>@hq`&wMYkmw^WEKMNlH&081GnusN)p#@d zivb;;a;vxEK#2cSgg%Yynk(A=!VDRW_qJb(?jwPb~)S8W?#ayr3)S zvF6f){uhQgc8yi(c0*=b)#15X;><7-fr)pwG1)Bxx*is{hwtl;17t$V)V86(Vz|6V z{I{H@?Q3eYGlL$(<9!+L2gcpfz8mQ=KgnbKy3>q*X=={eUZ}ry-b0SO38*W~WqlQ4 z-U3L31M-o6B1Q!z2-{Rv9O7thVcG!$*+?b9CZMr7bC|+8EisL948B<0d4fTI9L&(# zflPdnoQ7;YjAZ0bl@0YLZ&(j~@$yJ~@QS(%oTf$N8UlBHKe^s1c=FMlUtf3r|j?SqOLz?pmaNBy3Ul7Kz@BE$Bv?1e!gx zpHyN^gE{$`$zNq4MzUqd8arQv!314EFhB$%fK#jzm*ZyZyICok#`-&)AFk0O^Ek7; z&MEw*ZV|xyQ{9rX45?di*UQ&9|53MaUYS>Wtz_IpEF56h+z_p+v$JX1ml_R%o|;N& z{#Lh0^HY^YvJ+2_=%M~}G!mJ_F9(rE7U#}}gFrCU-lDOv^!4gdS$6=EMN(fM1^BEH zs0ZwY_58gWjc`QdT{>qc;-%7qh*~7D$!TP-<2QUp%x6t4Sc`lwIKxK{%|lQAxztXa zy6_8oI%%p3crjCQbGI%7@66BKtG6?}6jvsI&Em#nj6G3-jHsJR>sWVwn8CFLK%PjS z!b#+4Ftyl2RV(@tA-;=p!pkqa+i?%X_j1$M<1c&{Qn9`5i1E%f1^*jd6 z!P;XdrvP!9uRAt;{>7(PXG`IL6qNkjh<(^AwFuG=^-vos^|2;vpOLDgV()d;_8q@x zo743rsGGD?S#dMo<6zsNN8n+ul%dru@fZJEm1>OpR3I;DcQcP2Fuf6d|_rb7siVRE{6@aJyP9-Y*?)u;J zXE2`z!*R%sx_9@p{eX^fV-Qusz2`MWtuo~XEd*Lt)9pvZUVGs|HC_^u3|rFze$hx# zc|T#bSySvFC@`AN2x50@Jmb|i56z5T{yqH#vkems(3L}0W~-$~vJNCsvu``i3SH(R zXvEP>Yv7#41QEwAK$2>*kcl_l)Vmit_&AJV(cgU8NJ#EmHWdM_g%U2IM~*>+(!3Ti z*&$>E(A(thJbSMw$qFOIU!9oP!8=!BY{(J1Eq(4`bcaE{6vGrbUWuBoQkuyX4vF~$ zFh^mG9s&gEf^OX_*qN44TG~K)@4E9;uHC?7;tQH_K!fhGwadVzn+r~@A)OfBHZO6$ z6(#3+CK{G64qMX19{b$2<+GmS_f^d%>5}t>dB%og4bFvMQ0XBmAtjPj_TW;-;?=#e z*fPG!>}!s$$+rD~lL#Cr=mbN;l7!me3dhaa(pgVA*KLE|;|WMG&_C}0Oe&L38&+vv}uGO$S~AdXV00)-9237|Mn%R>C!XyacbVF6*# z8oh2$*?cc`sKNJ4B=Qa!o*_e61zXM?>QlK7OthQRFcRH!d@VZK-2{NZssowr)mkC<%YQH>Y^DXuL`HR3xq13=mo&9z8OeOp8P1WIF8yZK6daMj zWT;B!jw1gBLFOG-8q?Rarlw<^)(Fcf*X2dYv&&S$`MY`7$Vf4!FAWDR6$RU2+A>a;B z-(1UD2?Bl};w+$7Nwz3d1DrND&|=2;5Yiewm8bc0DkAcs_QI?iyirugW*(XhfPGXy zxonry2^6&*5F@|?c*AX&$A0#7( zhtSS@yrNEisn3y~SYR@pU-$9-c1MT&uG7KZ_A~&wEFFsmd6Nt!y<$uA_^6-im9rM5 zh;|}`%7^#y$<=lE;it){Ts9WT2JM=QLMpa0YITeW@5~VN74We5YJ-!vv>oYU{y{m&)V_rCr1V}8o&Z!&JE)L}B#!vrCVt^w1j}n8hq!pkq*ziNZ z%IKA5fCaW_WNT(wicb2Pdiw1~>`q%DOJ%`_#IT+w2*_a&8s1AQGMk8&<0^3mv6D4!3C!nRve5|-{K#b#uFY0&QF$^D3 z%%V9%X5TF8sioNa7-ZLkTrqD6+CZ_mtM)CcwEc1!rh&Z+tlj_Uiy9*!r8FBbc??L6n+76PP!gAF9aO zvc;3l0;6m$FvoMukadfvLE85iM{N9A0i5uhzBD<=&vlE&+~csj<&P(8Jt7wj4s&~(uj2Leg|Oaod~%P3u(@LsW&G!V)nx6aCJy>~AuUGWv_{WPNrm_{ z@~+cWq5+)I4j2zoU3V|=!q!7o=@?rzG*IQqZ@N?LTll)lACizhkh?leM8nqkMtv!9 zBwz2f)A#ohi<2BXfUnBjdp*_3v<~}qB`!GJh$&1j7f1xL-cvDW`~1CtLoN5hKwg=} zn?}+7MevNd03(E9{Z{A%Fyg_iZ-YCFXrl6{?&vayXsxuZ!L-UL((4O{ei}WObX1h~ zt4;J1quvGh$^>#W)7O+l`Q}XCD2Y&{&zaoHisLp%M*&~t#!~v*$PF97?^_((*X6ha zn+l6oxq5o!hX2HPm!z@y+)%QA%=lIs@HY$#(W1d#+%;~@@w*sxFo^PaWQtvDyB|%l zUp#IZV7NF8NOFR-Qe`BncFEeQ0D9VOM7XyJ?h2egc0Rhwf8@O|3gR`5pcKRxb`O@R z4!7Pyk(CxT*@~CVJE~Pd{*>ty1$bPAaY}2&%lGWX&f%}Wj`s%tBCu6H@IPy~*+-y; zW0~#UB(+c8ay&+FZ^5_ifsqcX#Q0t#MYOsS29S(HgIvf4C}usFOyX`LAnzBgt+EAJ zgcK-TA?}e!Xf|ESr33jGlMa)umC%B7G!ac~?{5p?DT{r54YyJ8{h@)3D!Bpjp~I9f zW3EYPE|34CG&%&dm3uR|$yUyu*9)r#LW05TZfiXj?fzy9N46CPbSf(K;DfLA$p0d{ zj{?$!#hZ`)S?XmEl^OLD&k=~rqlSqFljIYGBEr#PikEb_#Cf-XAp;o9c{%|WuC#WT zyN0-Y_;cp)(k)Puniq+KxsRaBsMAadJM)6EJFdaLpnv{+8XI~>@f<8?JqhNg6c91) z9+4qG=2zRInpy{3u%bYNTf=q8m{;A4U{o!P9e;iaiuki#ENBw{>BrH%LvOOCfMTr? z4K1h>pNh3VMtnbUCh5Yg;3Amxr8$9Lcy_jiN*j2E`;^l_TA1fdl(uq-?h11DFEJNFVO#o378at=dw8>N=a0bU#zKs-Q$ zMO2flh_=B~W%^c)YpL%8;a#AsiBxjVSO%!wz(p#dYOeNs`iTthN)FN!fbm`fom)O5 zT$(KA3P5gpyF_m%3n_^8gOJ^?e7-hh?m;vwII@mzIbF$1EAF!%TO#cK|QNsRaq1`lx?$4F+Qe@=}k={N; zG{3Z9)16Z`N>1i9yq=Bs48(Tj>}Rp~0PRgyhsP?ZaQ##GGb7+KH6nh;4;tRojzwCN z;S}adM>wt&E5D3KtJOV}hyHP@HHgbg?{0iQh7*TLoDd9n=QV|mz3iR|sQ;p~X_waD zdr#kRBN4Baf}e_h99GCFQ+sjY z|HS7Wd93QIId+0Xo!9b8hPyVu-se&_q=mMwlx!A?!}==Th%MMNx&26411am0&~czE z-9VRe&Ux*&^1k+}Ud=U)aHIdEP5+ko0!MChda4QXaJ$RnS$NWhXM!l)n4QG}aOWz4 z6s0tt^UThxx{J0zz%+Y9FAN3_%`@odotkyJL?gYh4>A)gkbN2_zPPo}e0p;B$60E# zOgZ#AS}2~^>appVsXIp9Y$4udiQb;{%UAis>t&_D^Kwg=Zuas&lNrzk&BlFC6W%xV z`Sh!qrD_o)4X~`7yITa>+1-ky+`|ddIujiCj%Q4$QwBX2!=i?6S5)2BioavyQi!3~ z8?2+-4?sP98JeiQkn8R%Pandcc1;QV%>_7oU;n4EGkM@&qnfY9fW}MYiew0X(8BBT zWh7rYj2HG%$+?S8KPbtA{?y2~Pp@we^auTbP!7bw{;mW%D}@SX8oKgmHAGUfhqPhV zHdonaRVslT(5$JV{-Rmq|3kBm1K|T`6}1lPlj`l^uXr;}uKPAJ z;NEN+RUk(QgKPnHlWCVXY~cVTz<%ABN}^B2l9dzyoFj%o{hS2ZSlGcv@WadW*qJ*G z3Gomri`~8tmRtwO@liw=k8<1Zr(kshG|h8nU;198zbi$V)9lQb#j!H?58axL0YpiI zY`bP|^${R|kEm6KTzbElhO>oyR8`k8TwvBJW#S;11nCJ_?6-2xJRa@=-~dYzy;RTf zAA0% zA}g3j5H1RzOc3^{-PhhdgsdbFQ~s=^Pn`Nf7_9jNK{oGBb|0FitLnwD=3fia+=Z{Zue*hFm zr{#WfW3qAFeN>#M)J1zUdHvoS>1fBN!(`oEUvB1_j4{^hU8f4roS|FZW;Ba4JvN)j z5qknCg44jXfL>OUGz4m_iz`wx+Fk&3X-vu<&l3193`1On z>}ET@^;&n}R0EWA8Ulm%8RtI%HI!0O0m`L`AO%>HP(u87G0vwi%yq7Eh8vZu83JPf z9_ln|hP&Y<<^vH)k066g01n@0e`+AnLEED7RZ;%~)jy}-QKbYUjN&v7tN;-)7_O{G z%N&>I1?4gv_J4xd>o(|AnblLtsZrw~QM*KaX#n_66)#GIcOy>qJ$Fx^Z;GVW@k5{n z|A>Cf>cVbw9ZcDsovvwGJn1n^NTy9 zLq78_PIAEFaZYl<-PP5;pXDd_W+jA=%0qg?iqAhFk3gafg>?f_)MKDbm5^w04keIRv9qarAvDY=J38h<{>r#9YH`qiM2Te*{Q1)v6EV z8H2R0$|t4~KX}h`{3D!?+=)3-L~~aHfvGg`?%(yj&|Fgkta*}$>h&OFODGD2VJTUY zLSd~AN*oW-8IFZ`2rK~1Lx?fj>0^HN7B!Ln|UBKT(6(=WJ1HdC#rj2ocu;nA@X+#@gn zBr(Y2b%RvdbPBS=^lj9Thf%Kq1I2bgmFWOcJO;|rj#x}dymzz4u^R=}$IY8B3xb(@ zn7|9epe4Ch+`1LM%jFEO`2OOLa~7gii(rrZ+Qk8b#KGLyrSbP|1<$D|8+aao*0lwq z(bxgE?CZdM6S9FNE*p`$vQnwdT+{G0|M6A#)(q!z<_KU!h#T z*VGA53?Y=869C-J0tWCw(gDf0-(ekby8jB$@C+d5Zf(}4BYau};x!I1(4i)03{D|l zh-6wM)6uC9S-k*`ZOLIBbl}(RZ3>RdJU2qbTe)hzWU69bQ1%DHyiwPk zYyL)OQRBZ1Lv98~{!N=U3mL6h&6O=e=YgCQ0%{IHg5^6JzhZV+=cRo5EnqEP97_Cbs~u8mA`{GOx*tp-iVZO(a5FDj z=ylouMS#_3yy3nzKJCxhX;N7eDK}n4E@@7e27pJYL`^1xA1J~o%H!M@#L5S_yhgS zgb}5&+oo$Z+GBQPl)slawBeEai7+mhDl$SDO1q@c8~UN&tIvoOM)6k`hudFS9Ps~` z#qk5cy3p`?co@k3Eb#ro3oO1NJQb!a17>^Vm#;L|KaKQv?6QmR$W25NKFakZ%L3Xg zUDh*S+tv#Sj`IRbZi8fxjvM-V*o_oy#h||zlv%UW2U>m}1K<}gy$U9;&*%qV13iq%fy|iZ>Y2~W6OQtqJJ}b3;K0{Y1t}Xw3)?c zZmXUfX!0z$CbEV zQnHvG-ofapF>_kgg`)v^JkK$*O-!Fq3yZhX<0x8D>GW8Z1=uP-9!Tq5pE_ooT+9Ia z*RAj-P@F6GJZls+o(+kz88nR4?28eTLXtSZs9TVckIkGnmvnZb9}gcH4gm&hOdP*s zsU~rWJ@6*(!JGp0Ug{k@_~FP@&iOd2(tmEf%Hf?!8STq$2@{ncQkhi zY;Wz5yPvrKwVuYUS&0Ve`EL*p-Rw3K3wJX_39<|*P6c5cAy7I~c48rcWrm2qseXii zR-Pc6e&a>+pLo&)eIRE#8rUW@f=*t*o(|&ycI?WLEDt znWO+#ruV^s5);RH=pR<~cFcK!d3T>A0?hL$+?w8u;knnCCG?;g9-ckkU_U+OOjSAV zO@S%qbl-cC<;4UqPVeY4WQpZASBr5(`JPvpItTGM->513#7FdNX!zXyW_}ffsdM!9 zmRgRO#RJ2zteS1u&KQ)U(mT#|M5&LvjO24}3g~s*+c+ZBhe+7opY-Q!hXPX+kTt&o zQ~HYjI(eM6jDLP_F3nN2 zjfDz4)2=xGI@k@xo#n%X$k4LAoQaiW<5&giTqX%5BbktGu0P<|7nI7SA! z2Jrj(Oea^A@6X*pjjGuVGa+j2G)>`owL4}M0lg*2ZE0y~e%egkz`JQPg@EMafkc{B zJ9R#%S!gOczHIFQnoge%7tjYG#3LRVIlM6i-K2MDPQWfGC7Mb;{Q_L}hJ4=K61czx z#foQtqpU?WeG&$N_Z?7M3h-ZIEgG&~qz?|rnt0U+eEEhhB${o4mB9-JWJPZ29cl5- znRo8(c`S~Y<{PNiY;K45-9Jxv2A3{fG?nq}I~96`o6linEI40giBHCmdRtw;!JjlF zzI)XofhURL>_dt(?`hu!<4}J~Qn;zmzIyXjvjDNeO|-VZ*Q=Wf_JxyWKeMyL7Z%xV zXIjQx9UXPP#|pZmM_WPczy6ljJQ?xlwtMdFSAbNEY(W!y@#?z z&Q%xBUeYEGZFuTj?xy%jlyU*U8ifzE&ORV^$0H?9y8^O}jK<5x;uY&=DO6LIre=bf zK<20BD%jLgMr#?`7lO1>CvKo;@`NOkM^lzJI1#w@xHvaoo;daENB8@e^Mqqtjl76m zh37v&qKqV`K+<4}ihMaJaS#i1AJ%G?-K>;;q$Ly1O*A%;FfFF2DSvicXZlnx7c@CA zh`RM)y*{0EV%TD`{w>Hm>Q0G#v9BdPX1+dQqdnjy*I5;3ePO{zk~NlT9XZmTzC* zD5uRV2ITF2n&qUnG%dTEwvXJ8dx`d`TsFvWW2yR1c^NHn;^Y~8k-vU;3SIpWpXzy2 z<11~M{+j7U+k6G}Y|TP|`Cg*1?29~rP)H#1>YlZ5Vm7n*hB3T%D<>;@glJTWUF0lL z*&SlRBvBm%yMh%e^X2zZ>WdOdBTo`LVKb%uYFgZWdWasmfvi)(zOK171&3+{{Iy2R zeWeWFysTyzwg~$JADwN2`H_@pzw#%3(O2>27CSFvT<1fppiH_f(crrH(g7-FI8+>$ z%}kNhuxGL%ghNv(Ze!K;(w|4PfH0d9Lvbl=n^(lo@+qemQ@IODe*T7S5!}lZBd6V0 z7HkuCwcBJ|ty39r<_=I7Lk}k4L~nDlxL>D?mTr>P$Y#|w_ptBnH_MA7;*`$P6R#W8 zxo-bVMWU^(E;G8OulC$?EG$12?OUEJTTXGs>xn88igTWHZfAw8gODk9zUx*^T+Ymh zuH6+VJ$Ll{_)PF2+No+YzqC&#>>z0cwVyP@yQi&Ct^gZnyE%k4E)I2xw7B}~#zT+b zrp`AAa$vPI>v60B6b@DnS19@zF?O&~)1c%I7-?nAR3dmNaaXI^?;V^K-KzF{;8BN&AmD zhb4O&3H{F2IuAbQUtUsUV$isTexX{XqSLC&6_b8IF&@G8dH(Hk{erTaW{HeomYyJY zCckfKP-a`D@nhx^`=ITjhj;f!L}_3gS69tl6e;~MP9%fp{&{szo^hrX z5tQ9HgXiLS-ss-X{PTFKINhYrcuyzzdcn0l>6uQ=T@v;h-xEdPsyeUsFe~QBbDvH$ zzm>F3l&+X{wk{_h7Y16q)f9Z~s!yUGFNoEY$7LQ+5|gRCd!9&19JS~0kl}0k6D|&p z-eE6a9(a=%ovMs71<}~8%;%F`u4!@fFH<9~?o39262VA`;__i^FD7jZW`teMZ@63p zqdpu)$!!Aui`fm%%$wx>)7&l04U>dbz8;-sb6F1kiqa;T6Jav@YK)4hdY){t_6lbe z1B$4Il~xqQS>BM<&gHDG4uv#paLSQXh>bj~R13)PO@tHOThqF^ImwCO)wrjc@K8^S z>@0T>NO?-lafJ#l3K7+p%F^0x$=RFvOM=9%BTVNj->ye5)YarztG^#hfU(aX#Izb0 zH}4|cZvC^9z7(0PYJ{SblB3bZkpFHe3qeV`TD#8U1jH(O$ zZGpM`jX==Q|5c7^{%0a-!$=b5P2)h`dv8v1@&2aAZtJSMNtId?^B)l_tc&;rXwRZE zc>B9btl?P^^Ic(No#nK&{kQikKL|N;2f9C!vw!Y&Ze-EB5arjVN9v#S%Il|+pwzl` z*%qavoohvAXD+NO!zf@aviynOwfr_Ezupxtzg((zlwkVHbm2+;du{rtiwQ8)_uf}t zdb?JlUZ+a`bcdpeDeFTJ9)hKRJ;$?WK1)ZK^D zD)>#T`5E}BWCKZ~Kl_JDamTkf7wyTJWEiO5cybcUuBTd}2uMWgMV?&Sd7l$w$~K%J z{4fcg2bE6DSzEhOW{d=-?uy+V9Z94&I9-#uv3pgTu9A%YRkoXyD*ou24`mt2Bp%}J z`N8vJZPwU`5_#j4Q_=NEAP9Tdme_mBHqJfD>q}j_Xqtz=yPJ4l?A}U3YuBy1kLkPx z_QDl|9B%40iFrv?yVsTSZ9xPdb3@Gfjmtx{jKPat_vV*Xto9eKPYOvibVXSTCC81n zJq!B#NCvM|&MCx&L&%kDKk+eFB|t;8>iH4}Kt*6Sbf;>awfx(uGeVXZq z-7KEO=Q=7T9h7|@o&wLlWZ4s4vpZRnGI*m1<+*wWFVx6y?R2{0<#Fj1Mb=kU3j=M5 zX582a>epVFG+o{e{-Q1J)begim3+22vQ^{hHU9Eh0U{=dws>SlYHlEDpANN(gQ9}- zMTzea+DiFs7m4roH?Io3&G!5A2GtOMh!@Y#FLQj-n0zHMFJS987r-{3%}ksr;foa| z1vg$|o#mEVny`NCs9Eh|VH+Z=sigTii~hpV3*$UmFIFAjf_s~nlXMOw;vVRJ06%LEZBe4xC3|2r<$ z65RvY1A+KKeurkF2(Yy+`G7AQBSZuyW;efbzD#gEMQ9;O{yO+GmP!wE+y- zA$Q98>Iz61ai)GRdVOrW(-FaW9q=$J#98ld?26`heWP>%~csIHeIOm zYwX7s=JKk}P^wDEIN#^B>VWNb{S+L&;zFz`kEiR6md3bmo<1zPnGq4r)24+o_BE?O zAlY(-rr+LZ2!5<_J`hi=a+2X?`c8rtUo`N_zetx1st#^l>Px3T96Sp!eemhWV<|1+ zFY81Q6VWH_hcI+F}8vzOJ>-I6T(({pv(bEH2ZU*fSJ{UONiiSwU} zWobXv7r#t6R5OCN>BadSI+S`aGaz&T)YqX9gHd?~l*krilbWx*a0N0h1-RJqF~3O- zT{-RGoV*pLEN5EUzaA7lotl&Yf3nN$l+2=bmbT*rS#3=`P1w}fc|P@$SRY1{O8q7* zZ>*~KpuEP-KHHfxyv?qn1Yqb->k*qeZ)*ZbMo`Re1e-Jt zFE+l}=E`mY9z!v0KpKDiAt`~&V!>PRjp7pofJ@}|s>|O+Bsi0!;GTZ0wdLD!-vMo} z5DN<>ahp+&g4B3t@mdI8gUR?kF?#_8W;q?6J%@V5u7b{GV2xxJ9gRw;kh4GAQO{%C8LLfo z8hZw>Pbda8zXg#rvb;Wt)@8{?@IAlAw{S-zic8BtLt;JX_HCUYbN1K`rRv-vk3s%w zx&B*_gjRCByIVCUTa`ENzU}lKn>wMC8Kn_clqpPFNrTN*4h$|$iu&aEX+}8@3POxB z{fB%4GaQC3Nt(Ko(-E;A7M7_p9jWPLGQ;&UUKK(&G|2ubPCRQ#j~4l|l~UX{w)1$Q z@O5u1MuvCD!5S4dKRDNFye|bX0r%Z6G1}q-8L!VyeqsIL^&mRkEu-5OBy2_j3Iayg zk$_1C4{yhcD-%DJx5XZ7?dPk5d)ut%*$Z6UjPl9z8zC4=gPOS_B3J`^E5U(^-U2ZB zF0xRmuTSu3=i(*yMQz-+@G&n4p$Q`{bwcY_rV#5v6X~xTC1$sg!Usv3vnW2el`G@3 z2(%glGuzC@NUnVRQ!8QNWK+3=E&2YLVBI^iG3?aXTJ-YjXamEG%#U#nSL%QyVB?ZA zvtHu8E>6T0xyJc_F8t(~RB@59b$5_5f+0zUgU&=?SBJ}D#V-x`P;6rTB=&1%HlOJI z+V-7d*|I^&Q1TA^&kQ!+i;0^nCnjxrLfF_nK;l!K)9N(02e$6z^-a-4-JnMMwGq+-f+g_KwXeNW6LbUvsg8%V9U6#@#g${LU{?6#ylJD0UXFnj zi~cos6{NFvNY-JaJzbXxC z+|P%psYQv%B8}~un_9>`h6c+bvH8O zc4vxI1Nw=0ZU{-#0*baPYGaiXF&#z|M%(sSSHIUSa*7Q3P7^ZiIqu%IDHkj8xJF4Sdp++*hg^qEIvGic0rO`w z9k+Mpx|$K`ylJc6g@xB?wP`KUu$q<~;GWKF{MjGlsD0~bvGjw*GNB7+XYR<30Y{{A z#LB?-<_>x2#Uky8X`e**y}aTTH%U)B#rG7i%xwNSxnQ$DHGkv7lSEN6Ez1gI1#tF$ zY8>;kYaYZ7uz}XAbpPt7`V5M^^4o^na%$f9ZmRHexXa!&XMS3F4sU;ns?dS* zVSV%lBw}kORV}H3j~Z#J4EW)m&#dx%WLCf)3$FD{79!fr zCwG65?HnHDf)J{vFPrH$H~Iqf*hLpBux|(lMyMG+yqE>H`5-At&|%D}aR_^74&M8! zfX~C8uD2o=guE^ls)K2c3urgEfssM8L6_8@m)1RY3e|^0vav}yA2(umiNu@vCMs72 zmYhv!l9~Q(^zs^Bp0(BT4zCy-&%gMTWQ1rQfBYD(rWYA;Q{lO3)WIO}?oJ|cq3>f( z<4zgZ(miWghCO7*+Sj?$vAki(iS(sU0#>o9#3$CNs7taTXA6sQM%M+NOdZRknx)uf zXw2hi|I%#K9l+$6FRC(rhrD4({6k3&i|%9)+mt2r$SoU|9vg!MoN~Wq7h_S%POAO< zARES+T87)5V{;vg7(&JqBy#%>v+S3|M8z!U~pU_2@Ule|*tE{9_elJ>6$*^(3GPTt3@kv{PS zqQT;c!9y^2)95q%yO_&{2{bj{VbqFhbbzkDgO|VRzJ8+awZ%K>lce&!xB{k+cibY9 zOf;VGfy^0yc-mcN_n6DXg8RJBi>`CFRTyj1O6RxpswU0?T6BQhYu+~YKC}}^^sq1| z8<^010I%^{I{yjuE2d44cHQEs9e+PpHP~Z)rG=zoYaj6W<~YlG#I{Y1jRaR_gx{XQ z8zLhseelnS>%-w06&w(6RX6m^%M}=p8siE=s(*8j3n(^v6+J4_F%$t2L=mNTL+GNRCG;X7O$>OXS?RrZf)J{J1O*fV zNC_nr5kWfAYv5ZOJmw}ofcwiCo`JIWUTdzoW_g}xzJuzXlK}7k@`Pb)Km#Ch z3jwfm5$T}?4=cM^_5oEntlEvwP~*o>1ozSD#;nkGb1*x|b4gY55C%+O zxmrfHyx0i%IHb)ijzfzF{4)ueOWD6Hdtj$yjnqX-v1dZ4;p0{L5JMowu8mLE@Pokp z=&r-NV$maxs@`tQ)%fW?1Iig!;50s^hthMuGXFd$njkA2sjh-K|fFwlHNosiBP~&le!ABX&wHVcB`7Cs<;rP{m2|eZ!=9OV{Y`KB#fA5;#nVuNY z|INu}-H(s=v2XJI(4P1W0M;%7*Vo56-#3GkFLkN&<*wcL^wG8Hu&VX5eVIY^5{UKS zs@5RPbe@ofdcHcJQ6dtfIeWKSfqdOs^k!8!Q>9(bP*GctXvjU{{XCLc)%7GfO6q_O zR;mLH7I8PrW`v_2W@uf}v#G#!oA|RK{H{z$O){jmU1z{!ZC55$hhdRFD<2x{z60*i zt8p$ImR`A05HtqS{GCbYVyz-5SY>Ka7n}v7iB1DohRukZ4Q?^&&1#H4+IcNN1qKd#HqvvRfxM9+ zn#y2;`$$krb0`P!*T{s-_fA?aO`d%60{j!qLzc-P=P)5p`kuIsg^8Exd;lDm@R&tG z>)9F8oVEbtgy5|BQ7~rDMin;x&~$5~1_Ai=s95(JFLiCw*!*p$3~0)4X;g{sD*mVN zV+)aMA+|-e=Yy}}(~;Sqyo!32V(dBxo3)tSXtiI@=kXoO0rO2KSZf%@=T{2&ciYE; z|Gq`xCm6EbCFIqBF;?EkLqTFFlP`RCZ?IM!NpOA-TF&vSVAw`~?-C#;nA4M9J=f&E zK6bpuX@Z&0rtk;fv*DuyPe0`r>QY0q9OpOYn@QgysklKL;4*)WEOvL%opR)R|Mvyz z8uh7!0(xt_kOUalf|7im{z+hMY}sT#cZi;!{3ScOtu^iRXrOQMW6e`tm6DUratQf& zK2P-!vmzY@Zj^wgdyE_HkCyiG%v48U1#{|qg4O%axj@Eoh&teXEkH~3y$9+R&gKiK zai$>Zgw4SdUgq?}9T%mJZ6PcCYnn01&LSr1hyus8I8KnA7CCIaJHC4Va6sJ^{K$`->t^)n1U7-n?CQn>_%ip5GMlN z{k|h#G|VO1OEwP!wrV3N@T0`EkB>tmR|KT}0&*1>_3kMuXC-A8rG{D8e9Fs8>39!D zp0Uq^8gP%nt&Zk}(}jk9&Wid|sv^uCmK!Pes`0iXwKnqiHxPSUWeugXwL7_oYwg^#bp?>5xX@lt#`M; z-fwY(E99J|y+t#2tFgpRolH7WZ@D4t>=r6K>!V*ISKS1Pp>5YMsSDItc@TorTV{0h z&~z+o=%1x#EW1yXIjCQZjPJX!{@uD)BQxt&eJjidm=A5)R*KPmde>0D~bO7hgppe z_gCxAAc0wqfwQh;6iDJ5@^u4b-Mbl`LDz4$8h6&>5n;B2uQr$yneSGOdb$@Vi ztY70pLxd$8=2A^!@Dmg?ps3&(bEPh;Upe0HtLrFw2y!yIjDc6EY9glDpD~9yKW?RZ zpuRp?2dbwaU5UFnXk<9r-)0tRq}J(>9U%p#FpXVY2BlKsv5Yc~ZL_1KeBiW&2CW~y z8YcR-MJ7j3k1x)Ky=^v^Toxeh>STG#6nZPTS8XolO)cy2tp(eyjip_(zl@F7rRw9| z)Wts|f0J&k#$Vg^Mwfs`T&s)*!T4_rbSK(CTt#rwF5rn+MVdATjV zX=$k^+(19prnTKKB$jSxBe-^hwK%u3E9+{~x9})+{`cZ#Y`n)vA#0rpwz}=5pDKdh zyDeHKbu*FWY)YoVO?^9*JAC!ir73xvFh3jlwQ623BPu38SZs#31Bfk)CtbjGAtI4W z#m}5nMV_+Z`$^m3`H1_b;$S0c`bVOE&ACuw2Pz!QeaJd~ZhU!g5d#zR;}h$>uGOOD zqs3=avwk%*<&M6c%6dazyT!$ggh5f*#>JdA3+?4JF`Tl!PhGo~# zpX@Zg9X)xmsu&E83pI%^SX(Y}<^xVEwJ&RfeRrZgcQpN?J(y_H6-0|H0V%{eGX;Bh zZSuE9Saac4X4z*j^6csuChf7AporB8P+L^ZNll;0x2VRS+rG&jV6o5Uon0Kajpwea z0wZHkW*gmN@|b{{Ff7(G$XZ?58T4cGak>OGMxuuFVuorr4g28t0r|}t{8`|(L@>OprEfn{L}RN5c; ziKJo=MQWA5!EKISZN9#aQsh%G&G?&QLq*8sg?eXZWcGM3Vu8XLuBtpYT6i&Rn2A`C z`LjKbjsws%m!fMJY8N*$`DY~hM|;Wf_Pw~0;M>#vcP6~G+RZ4|cLjdN5>z|ZQZnPu z2Osrc$IB}BdOx)pzi>RdGMVQEUD4kyqTILBuMYJWg^)s!KJx*lgRX0GLFvW!Nk<3L z)f5>t({f~eBLB@Tw~&m}6iE@p1I_qkXW#60|}*F8T%2+$X?mcGk(;~i_8 z)cME+^<}U23MsDUbffeD?%bt0hdX}T-RONLZ>9|0ryf$zspt5WIi0ZT6}g#V)E?+Y z!-YV4WWrDU#~OS#Pqr*C<#|k55nhW!D3p!W`SYqO)z2V$WBN@Wdcx^Nf{kZ^H2+`2 zynf>Fbj2B+oQt`!p~LGAv5{)+cCF(m>-w4(>KX<@d?zzJoZb32bHX3$zcVyz<*P(> zUm;E5`Q#|Sd=JhD`&+wV&ggcao><03mf|?u+9GTUx;MZ5@7rjzAtbLO2})c>a?7Wm zOL;lHQoDDU;5{nqHt6wI%k+z6s_wKRrnB814!cpymzgvE@axuE-qyP;S|^SbzT_bU z+r%SJ9?Od8Oxx%zf%QSjj!@yY6lBA3Gu?$e!c6EHLkHqdtpdF=Ca%}lBr-lfWShYr z2+mbqemm|C@Pji^VT=!1iSbFf7*K@Wke0uC_uq@lhZA(VZ)0uGS`V90gBrl0+XMuI z7?&H5w#{UQoVgaKtPRh2P&d$?N(;_HcxDPRPs% zPQLgejXnXJWtbimIo41m{d(MO(=8_2W#w9OkYX$djEMLT8mIbrT4Sv+84q&lf$)(f zW9Di`fqZ+wOKTRV`IbOm&zvjcDLS~zI%0=Ayldo!HZcN^tJxa}sf?XY)dNcqxCp{t zsaM>o7VEfJOtO|ta_D?TyP}vWG|Z;y5?#1{?`Lwp4%=;ktuME5%pQhWOF1XwEOAxq zeKV7*4C-f&nayhPO`VBbx%DI5s?RF7G*wqm8fcCMjo(G!b;*@$9eF*A(*V;^&m2B( z6v<@g=qS9T(~isZOKmYINw*5_5o!(>s?i5&?h;%bC*xJ_Y-R6SD|zhJ7Y%d{UB6?W zLZYEcr$eIktsX-~EozIHEnKIel~>-n(V4@ealE?|Yqj^=ardVIZG)~MEG4z%g;w9J zC&5%+YXekW8R4hJCJb9=wGOK1-vmXG&syGhs3)D=Hg${dox0(rg>6avt{_QCK^Lo~ z_H}WrN2|orOqv@xrZ0RZ8KHKG520$BY-$zwBg^zQ;ao&VQq;s4E2vQX^zKXfi7C})pC);XUXY@6Z&lkM6W<*3B5I7OqoQT{r*6M{ zSD)83J5efqJ&$8L&ieYqB+D+pGsYhuwjb0F126i@ib#{kRP_v7wH}QET}fAm7&hmw z>Y^LdoihuA;VS;d3FRXof;m@JcTq}S(2Vw#=d=#DB_ecs%>syRij|&IvWuS*tr$$!2eSdoOK|D|$7VyE z+(BwdaRx6^vU7E&SLx5B7`OZ)r$M#lV}+VOm!xk>=6uEtjdZ>lD(aNTT&|VkD6?5) z9roDl5jWahEHEwu5k?!E+La4oLV+cm3QpR`;cgdYuvoJNR>uE)^*?`N5`v8)@Qz)rh5xa0RM(x zl0r#p9GMypGZGyad_{Zvn3>NtApM1o8Z_ivVig3)xMVf~}%ev%8Zo$M#hWXLYdW3g%~&VIXljyv|Jq_@99`tj!rVZtP?i#LGY zmpBs0F)?%TJi#0g(T_&a>?fQYMO0YAaMD0@LMK>CDNef+fGTsr)FJn3%Yv+ZNc~Zj zoE;IQTx69bKmpr3UAU~E4QnS43wQ}pg>b_k0i0*;Ayyy{jdmD*dr$PlRPj0f@y9)V zC#vzz!(BB0EFJ`eS<~HqYtKsQgDO2dZAnne;+8tC;f`ZJTNuc3}P{Pdt`mhzCRkk#7O7_>lQXh8uadk#brhpUD7dKz3u-zWn z3`7V|AOgLSTjgV^QRk+|Fy?Z+71W+n;mn>Aq^b5939ZE50)A$DDg6 z0j>oGK)M91|5(Ly3Tx0HOLqmkt-%Q}aV{kOQV!V;NZt#Qj6%0aqCqB>@D&wEF63%2 zHUD~UKE!LI2KDaq#Uk9o=%~4L%(<6Yh;E?rO8`Z2iN_42Pdsj*{1u3#cnqd`2jL?v&y&IA+P+N(prwWcB6ct+$ z81tXg9bGPtA;a0mV4v|#bE^>0?VnQsj z)TEs~Jt>Ny6Mp8)TvBGw@IoZ zM}3_E#K&&?(_k?w#HUM!P-?*!biYj%4~X6~bWJh1YYq4XkMH3XA%MUt099FrIJDlq z#6&5h3$Vq8-m+XSfAoWnCGG5F)AYV^idE5S~ z6U4rC=M}No^#i{^t0W2%>~xLy+FJG!gWy0JI$29*TWg(FjXm ztDF3q<=6R@PxJtwdiDFW+=J9x3u)3I26L^o^cYh#x&pxRQ{D}BYeyXKdCQu+cyvqd za)-X>;v>HHdu@5Rmqn7jP$-m|iqzb-dB{;ai?+A7Nz5zuM7klCQQa_#m?LVc6SqQk zW2+h2ea7@v1DNHYTdf%U8<%~w%n;-)Qf}eq390r;5bV7?ti7Tpr^%;>%EyRdG}**>d--cPfn)_)DFDOe3ecM^F9kEC_4r3YKKXR&pe?BCM!kIb z(x)5_B6HY-_O`MKC8?b9%1JgKXUg<698cZu#_BQ9b}1aS`wLts>+TWv(wymiOUPUaIRmRXdd~f>W)48s zt_R%*H+ymies}%r<|gR!L_%W$bH@;z6Rf==m)PVd#wzW8W=C*a;SkfBZDh{#F6e}U zr96j@INks+fr-Z(RV|<0(9>6^`W4mdzE%oHVLa33TMN{Fe3!JWvUe=-9}!o1Wz_2_ z?5w_=x{1GKnw3vN6%cydJm;d=6-P>@2uqgpJq|6Tx&POQHhqQ=jyM~3|K_3Pc9!iN^XK4xVAFnnVL zVl-6K;~1TN1mh5BKd6cs0eC19P6xH_c!2bz@qEa&`!~Hd6I<{Z0g z|FoeeWPt_dWpo`1Yu*QF1fi}EOrhQdRQrpUQTiu~Uz;_ah#f0|hRZf*_JCqEBx{wl z9^WQ6l(4R(Gnlyk05o++OgYx!-%VPtQ#-OndYtD^AEn4Fv#Hz|79dfi=eht69%0B* zU-jzXL1-|E$jmInjhh5|tbhMZU7v)oeiP=s!JzzkcmJmhR)Hs&nEw3T*x(PwRHN?A zU<7xY{oGom7|>940Gyzr4gEo&*7aU+u^cXaSIHk>6b9JH`3mba%2Giff}`$eZ+m4$ zY;Q|XTWs?>BhIipg5|pH?G|~l<$3X6aCoB!ammn61ik`lSdpN4dA4I1P>BkCQcH#* z6+GSdk7ko)OiC)B$O12R|AEj3DEAZ;yt#~eBYYr%BYZ*!E0`7VynO8pZuA;xXjayL z&@b6!sQg9A@)#iYZjvB^0MsIYn_lbU4Mvt~a^~e3CNt zxnYIeNZFHkrPEn5Qz8eJ2su6QbrlIqm;`9_%YGL;fE4&*gW zifxjtKgj=#A}7X~*1+&<4i?#tp8>T*N?JNwt&&coRJZp>=u`Wxv;V!#K^)(5G+Vcz z_VEzQfVpAV6JKan!Xz~u`ao#fD1YgXS0fT@x$}TJC9s%M?pe*eWNeZ)z}9z_Zk8?5 zjd`)KK59ld|~QA#(V-S1w(*Nlf*dbIep=B*7?(wD**ISxiD zA(Ye_n`eWsGR%+BFWO1Kb8UoLJ|{|Q?_ky;S69DoN5lIjz!}-bYA0w zxdX>nA*FoOx-Eu=WUvs;Jvt^p)i)+kvf%nna-3aav0W2NQ+wWdwwn1+)T{-B{VF&+ z{+?`{KodXP?vXk)&fa+}jsMx|cvfCdGlv)r6^q}`VU^YsvtwowMf!cM0ka@unPzMF z)}s~s8mbkY?OJh z!_9A&JMui8G)RVop45F&dbBI*ClwQ9i{Ed|HH-j^C~DKa9IaRLEex5Uhc&)o;vzGe z_$?99%dI~g3eAi)lZ5=JNo^tqGi>+7pM8VmQoEY} zgJ6@{-6{OqM=!CbdaX0%L*FTRR`u|Rs`Jt(Q@!u$Q=_F>GpFdxr2ym>ag5HbeG^FI zyShJ1Kbb-C?4E&>HY_`}>c!VZo@XQUbmJmCW{h)zRP>gi*Q!2YWs}On$e|Sp#ldIj zczMT}sAu-GsU{fotxM$68zc=JlAQVGSD-f@=`^+J#1rlYCcujv$W(7OT+y`!J@M{{ zMPpf66Sg88Th#gb}%dehf;^>;LzRbO<`I^@zEI$l`7^?B_U3eyT6=MXuC^9cU z29jx_K$NSf;srF&7Gg!eWJuBN^jb*b=nh*gjCSs^7y+Wd97nuOj?>dG_Nn{c0lqWR zJv<{VNL0G>xm#^|nusOvp@+UpM@0X%dk2$2@Z>-a0a55;%@q`YPaD%6LT&imp`OFY zMb^+rHa5mcirMp$BleMEELv=t+j@oBVFOCcOr;%3g6V( z1TZK*%m>>00SMZ_wqpmaMXLpE#}3ni5g}$t@u3{tj_Zy-S1IwJN0b+OHklZa`RkRJ z(PwLL?*_fMCR0Agr-=y0%%86^$mjKnExU2+4$+hQ}Qs`+kAs8 zGbUKUYdRX{+9rCq2xmpm4cBXimnZZlo7GfFzv_{w0uNd8>^R0$*6iG6;y+?t)BFSs zG7$Ck9?Tc<9RcvQ`(CVztn1Ee6}27#d_~VH4w5gBpc1WDUbh%s^zpbem{TGJ3DgQ% zxFryY5PQw?YOOM32`bVof5!69PqnxVf{?7v*(|e8|Ir}kZ-M8~jHn{zcY0e-sQE|D zi`MSvp7Ri>VdkAAy2t~Ru$roS?R9v2+vWqU8HYGmFtS>|fjVot?UD^4(yix5GkV-& zY>UtI`0m?o^u!LHbx1`?JivsCer zhSQ!4HNI5cpF45RP0YOQ`Ht*%v6^&-Uzm9vQ?GO$J9d}v@z7GnM2AvPu85s})&mz_ zj2JX*K*S%W@70m1JyOeJQ&^=+)mh56@{=yt=m%^h#6X|=d!v|Z<8vxE?hj+RQW-h# zVokj+-Yi!168%tkKc`loud)MyXaGTnJozERDKwxgpc15rN#z(P7s zm$Ww1eblgm^O;;tujl-A)2Jt}XFm^|QN%s&`MJn$!5oq7ew5T`yl-TJXq8kR#T%-7 z!$+@|O=u$!`xW@W{JtuHz4SPJ887xuWTL+@0yZUj#i-C+-NBu*XyMZ3XADl*?7<6^ z741bmlq^Fk`hWptkl@uXYu+Q3SS171SEHs9$;CxvBA4zHZ;4QZd%2(6Y_ zCQ`dMl=0y9!XF;IE>Z)yRY2Ob5xV9brN4O}m_)hQ1yDR{mfm_?z?MVdqKC$5D+avc zol+pNjbf)zSF?;t27ax*3U&uMaD;9FvRiv&suiiP*poJ(0$SqFmwO#T(A3$VPBdfC zQoVMIVMnOE&;a*Sv}l7kDQJcL1yaHS)0m=doQ7!$xNMQARE*F@bSC zR%0Pm=JYC<5IS?ME>Zp#WX7duYlaiG1ht&x1zv8a#-U**-`WBbh93VZpUC?0x4Hchs z$u0aO5DOJ7Y+Tj3(Ii8%Cv*lpTo$TsYO0bR`D>^)Fz_bFB9-)kyFr-V*6%d9G*)$> zz0GaW=x*>Id^KGV&N12G^Ilyp4Kz7uoWUN}QlCk1V>^0G6Wd~wN1}O7?XqeT0}3~d zO~1lK6^;9cR{59;b12ZB)NScx91HJ)!Mj5gNx=guCHxkCqLkCZuw)9bn@@D(*4on= ziF!6{r3ysjK>$iN`SGF%psBSu4LENbxDzk%!^7!I9M(GnJtJ{yimkk^y2#%7nJqxT zF;n^(;WSxjeQ79dwgiaI1|fp$_^6IqUId=BH~-;V!IChiYkh7e@wqW(cWyKT?tA0( z71Zn|a8BW%|69AM5~rOOZLgrnSbT5jt;^&2vUj_gTt^ndJ^(zHfI}^lnXpl^)g|~! zj*UkHE2w&qolH)d!2$scuu@V(HK5XiltHPc+OVW9BZW4D#4_caD-(dL;Uj5&MEv1b zc(%>k-Dzg{I)61j=mEcD$CPY3GGCMN4h(Pcd5ylfr_2+`hey;ta&&Ch%F-^k7JGux zrLdGJGCC4ud700OV4m(=(R6;Cq6QnScggCiGRGGQolv>`Ikuk>2RFa@o zpQXL8Nv+?hgP3qc99gU@iSxy5dc1a;{LwbHV!^?qlPw5AzI4l-(Ua)-vp=^pmh;A; z>vcwH&x{k6el~ZF`ulRYPYSJ1nsf-R^4{^ZYpqz`A7P5OjMve0 z!vy05LpPFr10O+-!QcT9jeqI(3J7R>ivtk+6d+(|mX;OCst>S%>fDK!Mw*GSMd-gy zFBbl&EALx72GR*O6evVZNpnvA(QEAiq*}n2B`%{B(`LNrsLcDIbv3xsQvlPZ_o%w9~sT zgn`kk9h(oIBEGCCY6;q9;uQf6Wz$V!8Mp;vy*`ZJa!DE^)iC_7f|ruI0}l`203NoW zv4^S~j7Z{nfEj_R1t0C&lwRG_x5F4*vZ%$Y#0pKhXV&t+hm#K@I@8xt!(ZMm8O}3o zF&)+8oM0!0KZr5EmtZ2+FL9f=&UNi4koNETkV%iT(P=RCD9SkgZk_k=|C2E~SeswS+m5pt6?tr3KU+ zA@3!5$IH(z7MiZkN&Z45?z+4tlu6DvhaQhbx zV?+6hy6{ELOEoIGA>`4d5N7gMd!Q=TP0YU=(680m7|6f!hMxD>a*Al4rOyQ7Le_lDoZaPO68jVUrLWite2Y zzSqB45JPFTtFGuRBMth+=iyx;%MX8uAJ@dH`D8=x$}kN{r5I(QMyZM+(*8x|>+H$M z!+(FHgNlXkdfP=Ctm_UlTR__>Wx|V({$Yl;miswk%NiJB6kKE+=dFWyHN}h z;0P$#u|6Y0 zhfiR4$R|919f0(S%G&_$P0Xq2agGb97>Jpf-4j$7z%Q=PEwqX((YnM|yv@-1va}x8 zf2kMV$<^)Ed4&r`Prust5+u9ATTH33#PpkVtAWbe6&N>!kXPLcm-lnI12bEM9~=KD zr$7w{P-KS~7Cx@m{Vv0~7XHDZ6OC@b=u(D|Kj-x-xZXQ~;+)t4pGdxD!l6_THXyB= zZ$skQmwGmwo^n)0e3+I6wGalDt?oTEc!lG_R33|1$V_54fi{@BS-npC>mAO*;(oV= zSigb9PlOjE$dkRl9r8I7>j9SsnHQI5E|-L z_xz=b{RQBlg3v5o2M!Z#OI2E-1|z*Ai)D20B+azhVA){!ID3au1SndrCR;rM^djExR1Y^7Ss#7#L4x^7FK+?_F-@NM2Jf9RBeJ`Uk1ku=i4%aR8pv#A5EyHU z*&ZS6ik9=ZIKr04J7FcNiIG^0NR}QjBm#?|9ZEeWDJy5 zO!jLI%2FPxi5P;0x0Be)FIei7fSaOxwWxv!Bok^Hf$F1Ptpcn(gPfzc1Xj@fn%B`9 z1pi7(i&E=UUU6Rl)#s=Dk@>&UlY%Yn)MezSbb-Lu*vMGca3<2xQIYYPrs4z4A@Y2? zUI`VU^jmz96e#cLJ-O*Aq`ZEwg^xAqS9B7BbKOUfO&&&{*_Ve3c-Llq^Vx@gumGMQ zvD~T8U#VA_%BPc=4>?n`@wFn&7>PrmOF0ZZS0Ao3T#6KF!Tn7G^a?rw?)HIWT$vm? znRcW-+kLG9L7yeV!mrMG%d6;aapm++fN~^xb?~|a-E1$I+BorVDo`~De0ced(^~cD zKpxdMHW25$MozSoGj)XwsIB@!F2y~zZzx$^&T6{b+yr#2TkYMT+#D@V2DA?`FZL#y z?z>pQ_f@?&T9M}s0l>i*9#_f-A%>!i2>*oQkIx#lCP*!*RZzP-(bs$$+ z*!LT#Rv<}Q7NYNec?Lx)Ynj>sv5aC?b zOlam&N{$y`b>f~1)`+$ZW~Y^n*cR0b!dYFakR{r1%H1ti30gJpQD|VK`&XCs0RA%b z)&S>C&REwGCIfzY#;DD+=$~8Z~rfsZe1Qb3%I8wQEQwnYGe`4GsC*&`1aM@k0 zh!%^X=dN#nq?|S*jm}Oi|HST$@XqP@Se?jkmm^-S$DJ}pH^b|1`R7DZeJ(5jX{8zs zl^W(o>D4$;)F~?DS?r`9P*J)3vkTrmLmoHwU z*NS7c{jh%o7PqSOgPZF9nD3Q_)197h(rpaw;(W3WK{t3TFNxw8$RmUj$D{A7sDQ&T5FZmR%68S9}OdDc-kQ?I`$3Lq`pP3K7*8^Pb^Rk-m6T2c&=tSjESIgp`c3V$h zVdF^>EdowSrqbrfB(Nc?;K z>*16hfx4iVves@6(71z)b@c`duh5#r8p|>yhO=g=Mty&Ndc<%qqq$@FAk0|P$g3RmC5$5))FAR3ScrT`-z1znML7qXhQD=z1HjKyv8zObmq zfoL9c5mF44Ja3AS98ihd&!$*lGO9e3E?3uS^eBVi)MHi+(4P-xy3-^6qGRmvm_aD{ zug?uQ22-6gD^;mV(dz#-sRdSWW$lJ?pBd;oeNXPb8_I9cvk_36PWV1xx1Db}o^iHl-YFe`dI6mB}-J;FfvxY=N|`EGRxY9=0--wNeeGEO*@@_HtC z6RxQmwZW>PN-~#~%Bk4i#ClaPu!#hf>;G=z`Xw@f$REb%m2(yVzZ{mcH`RF7{K<%YL|Xb0z+^D;mc^IpkP1!8#Xg7wSM< z&A9N49<%1yq#i)jJgfHe2eA({hwpbb+fSA_ZG1ogn%~q_&;2}naQFf&)Y&>_(=b6{ zSvTG`wZ|HeC~F0$A2I8>3`}^r%xyTjDNmt{+Rg4u)-4r(HS=5Vedewsf}CFcTQc@~ zLoaM#Og#UOG^bD?K5ViHV3tQ{7G!%>!Qkc4u)OK2EzkM+xUKi4O*E2|#-y`9$(sY4 zy3R$zjz{R}$p&$5hy^Kms3Td`Zq|C8E+b9k>Dt5h>1io_`MbjxpK9Q;QfI$(QHhJ+ z8NEPO=((Wy#yg0y=*O|4oBsUfSJ|FmdijnVOZ0wzE0Rss>vN*a{Z@O3Wn^XrO~EFB zKI(M~CtT|zka`g=U7!8?qlblPjr7Lg31>F8Wgz|Xne9ExEt{rYY9o+mj(7MMi~LZ2 zygvThw=ZvbqF}-0be{831L06nWd4BaSN2p*tnKqV;>Rd3AnD+F^EzgCCISL#B_9A! z0ARtDl}ESM(B~xXJi`v@6^fv)M!0okO(^9cgm5o2Gqky#4;9(#`W6XQ>MlDc?n~b^ zkc-?&Kqn@}o1!Gkha4UrK619@2?#Q8%M7J+ z08l0Fwy(pDcx@1qyByqQ<)8%f;Vk%A#pCp%_pJ@1ZGpQ4{F= zPxK=^Mym>n)aDrPJkZ!@(Qw@Et`~qxdn6MK*>y6X0t0+VCLkZXquf!&tPYJr2Sglh zEw61d-^Y}i~v$V4DvC0*QxENyx;!Uqf#rpD?@-9 znLmI}eXOi68V=R#*^)}9uEyVB6K`@a11+T}{__N{-brK>oE%~72 ziBls%d`lz(!`I6ab(d2y$M5B8W3l%$MLMZUTfvZVv?9+B)^FL*Wqc^0>53rbaT#Y9 zBcWiDB;THkb$phG9YEbR63pXForaWwt^nGxSOQ+_vd%8lC1f?>DijB))7s1(a(uZ# zg-%UAcz!n;8vG5$+dcqMmOc?j%d2$a^zFlxeTDwReI^Hx`D)-qErH|6n5G(NAG+`g0QJGK<0nK720ttHBbM3q*EJLpC zpoOFLr;-Xoz?hy05F8Mim=grQ1ETJU@(|ENZrWsGVPWCFmHUS_3$P9!ih}^03Id~j zP5dX#HNg%?*`od%*)LPQjn(oms>ZLJ{8oE1;fXKRaT+~i?6+C$4H?V{JzxK?CO30f z4pC=mQ&JD-N(W789f_%DLU@taS5``Nt4w-%jS8A_VK&o~i2@k%e|dx*RA7tP4jg$M z*>&~Q?hx(wa{I6!-G(FIw|M;c+MNoV-%-UNZhgIm+LPboi*8!$yCWor{)%?Xc*A%_ z3u}7|{o)efiUHZhRM~q+&>JA2(Gxq*ve%Q375+xnvRkVB0igSRc;feM?_P~-HU8Dt z?57qt@VDWD=eS16=4z%-Er!0H&JS$VBWm7!#^UQ2#I^#X57x@6JwabK&s0nfGdMF+ zd(011ZbT8go%p|@u5mcD{$PvS>K*uY*K+@{Y%sV6!WvcyUpLIVL`kK0kyq=NV3%SM zvEG+iL@6#uD4Nh>J%}DbF#50X8<*HmMWyQG2%GU{cUTtDy{j?`x>2KBKqrdiZI`yd z^fsNZ5#8%4z5rVdft^pvhdcb2@oq0am&P`hu;f(E3l`XS5e5OJtKzp9IT#Bkko9Mf z@RU1wch?m{Xhfep`8@SPZ}~fsaQce=>bQhv78e|zzvT#{4{aD8DJ_#VKd*LG1&hsc zIViao6na#C2f9tZ`s7a>z;EQ}2dy1U`aMN#3nic~yXV}%2c42(U{<1`JT#%2qHv?m z^7xrr`I83Tg4SeYi|u`eOD(s zpaTDX;64iSrR}A`Zqlv z*^5AwaJ4)|PQn$QrBOY9QLn2jbunzMSVJ>swmjW?u-4e5BTy?VRU?C0S!a~kAzdRo zx>7>n$AaSdL1#5kw0;rZRqpP0epk=_AKN(MXtWKyH(9RpJ^$|u@7mvm;%(sU+c%;p z#=PPtHAc3J$4KW%F>;%N?AZf1G1HB&N$lmg_h(Jc*bd>=3r_oS-jp^@Hy*sBobw{f zkmtv{*h05 zwq40RNg-2{^J}S};$mzytXnqYoh0xRkOvfSuUJ##@e3i`bisw4yu{RwkoR* zJ$j7Xn;;#KK;gqftbBL?b3Vxvi+!Mw@{ZvmYO*!B`4$jzeIbod#oGSjFv;EHy=2Y? z>>P96#Jy4ajoU9qlX9FzljvATGMg+)1-dFf{h zDmtLW$^_JJOHb7o1`z1Vc+kh0RA?B91a3-dD{al3%W$|T4ncU+0MH#AK@n62oP}TM zOJ`?*cwdQbjwJYLx}C;D62TpX=7d_ z%g*64CJq+jVD}pv%@^1Ux8PThz3s~4=lB^JM6-+kqF(1imI#T%6^@=-d!g(b+EgDD zKT`W5!Lw8-KI2OquR#j|5C3 zBeLhtr@$^Xla40%DBfShgeRD7x(=v%Pd|J22MzTfS910@-{k43 zVb=eOKepGr?D96>gx$GT_95lO&=BFINz(B2E#Ol|q|lQ{fkI72Q4(u;pGsqESnFKL zfUp1Eg3VIk0`!@btjzTo)(dDw&oaZL%34zKk!LuY?7MR-$2*)-HTWXFzI+L4{IwE6 zi_FtaaP$kHf?nGgRbFB6w=Q-0YDvD$UiY8j(H-!22bZ1xUO)Fd1+A{c&sO=!{FWja z9YNdoOiv4RMLR28Ot0jYh6Dw9h&7pCeVI%u36A=jXH;k(D-XLfdfKz;!8xr_*~gU_ zsgJc5R8f9kj`VPlbU7O6i?#S8I`S&fw=ExPW?0tZBQtb(QZ>HLu-y0*`XVhx%HDKe zI{}`4bGm{wiR^l5YtrO{blU6HDt9O+UCT9}kNz36?YIR;-EDi;QsD3`=~pQzHtEGs z(RoC{5fqq6*SuLt7FUP1QRP@2oBKnxYtG$WQl$;7lr#M?l~F-010J@0xpMaBWv&Xj zCvXTx8=Gg}6Qd)*%@vRxRuhfpIhK~VcNsd|sX8n|YucsyOGt@!pG)|-Gu5&<*?vL8 z;+z*aK(Tu?*}a#Q$Qb=z^{j-U2YVewx3k+;;+En?o~T(n1hZb);`uC^n;Av%G$^++ zNO%6?=1i?j!qlvluP+PC7hFZ<2TBKUMbgvDZw71W>oxuO_}tw`A>84td!aja>Irr!U8Bv?%-p_46d%Ugo$J={L!{sF(B4rcTlmWGe!U4t1> zg7B*#xI(^o%|z|~>o5B|d+kE*Z}z~r8rEU2pYJ~j8BkettK>{Yo^S%wK)mY$t)ZrQ zj`euTtIOTqCVhbuUOWtDJoXnf?~Ud}Jc{-JU>_KI4Y6rv zg%aw!o-wJXV-dJ2o-pRAS8oNgLnb(a&fw}g9|eW5;A9Q+m(c6;pjB)4_z7lp`Y3U) zP-PUT??UV^vUF@T=bu^H_I)JdLJ9G|nv%6x%u)Vbe)?bEZTxQga*>@ryVt^w@k2K9 z5Mms`2%S&TF8Dl}p7FLJRaD}>nQ*rG?V7(YwmXO3kz60V#qxl>?gx|vfFzu= zpDZ|F7+q@jYw@gm2B$nbQFHl~gOjxXzRrJM(b)SS^tJpDpX>1Yr?AfOulbS38G^N~ zQW065G6e0y_iF+R7sy2uxc2haMv&5hp{oMLca8Y*VWY#){Z+BJSONl_knxZ!tigTSUWxt&?fcwpiLe*s}{Z!JK(#z zPwin+AH27tQiF5Vc=i(;uflX9m2X=jAG}tF>10J%;_h#8$-ueaDrY2%)<>4w_8y|_ zpwLyc$EsPGuis{Q_+M1c-oH>WZ_MD*wXWO9PSN5*z&mw$xbS%QMiy6VTUHZmI_ zk`xsjsZL4FLq*T6maa>+SjYJAsN$I$)z_+JW0(i=G>4xN_PXoVAjT^wO&A?xy7ULs z`ghpYa&vo$+W@Jgrn)U5&dVZ&i76vO87%T0^v8C~Amap~hnlU@%x7p-cyrn2J_cfj z!1{uiK|_(}L5{NI5B3mV|Ggr9D6@c`{BmxRdN2DuxqVu5LxBCtdwg!CLpl~BYeku? z8sTt0k}kD~yoqkL>`*Z*mlSQ{pP0}imSA!`K!Iai{BwHmv+(wXwB@y|1~g!N3i-*g;yy|13!LMA;* zHBJ!CZlfx#8*13oj-P`I8W1nxf#U9anK7gO_8MnF#GQPjxmIqNgoa2I7yPOQtV5yu z5Ou@w^ZZi0hN&N3{+^#(-y%_kNWl1M90gje`W+|?*xb$bi4-JOjqinsi;2hkuT-v|dWwU3 z*y|{%om?;2jMT6j@$dO)nRvb(Z;U=wu;;{`{0nuIemspu6eS3yZJ#2YM9smCx5T$!mSAHp2Cdntkv&N8`zYjg z!aQEt=s!60|KujefaeAz5TGVIIXg%^~$TRkVgNmWKSCY=t!6Za2Yj0Z;j7>^4@(XC!0xk+_scYS+nVog> z)2Z)?gud(kp5LYBz4KiZAG#^`dYa5O3DW>jqS;SuIVj$X%zv4AoIaSC2?a>+Hs3Tr zA0oQs1O~T*N~g%M zr7LI;w$T%(wuJa#^u&oGwz=mb6G|0YSLU5b{nKqWu9FOEpx`p(v$s{U{SGUiMS}9h zf3E9){^TdKeS_MA8+7HO8deQP7aSBE{`KW4&5XCo%IFt;ff(rXWcU6&j^CeG^URKB z&(GV=!z5I}=dnteHoiKvel}*`J{Ik}w{B>G%j*;aFDskSTgz^(hKHIuB`r-d=1Niz zYh`l^mw{g|V-=I+gn^sgR(vlSzl_OFKtgS5CcoFS4{&eC%YQ?!|ErnLz(nsXiHTZX zUMVM0&7`{t4(ERhdhUu&EW%pqg@$<~>4{4SPM|R{dv@xsZUM380)z!9oru;CYm|z>;T&Sf`$T*Q z(MFJ`vl5->4Nm9bS9|&rN9~;p@}B>bn7wL1$G|xO4r~~Zqi4@DFz`kvxgMM95Htn9 z@a>+zkQPLvpw@@A^>lu=+vtDqmZ0%=AtVfh*>wl3eKEixc0c$S*kPGUykctd`HfD*12MW< zx_>I$>>NMiuHS`N(x`*fUWV(seM>F@*@?VI)e`_VD*}6Wm#|rY;EMubw89Oj02Oo@ z2sL-b_3c?^_S^Ai)r^`=dkQ$XZ?C%<5O8oeeQnWvkQyeGe|j&^C;VH$fnY<=zn6f+ z2PkNCnZ}r8uVamvP_`_igpg$%bdux@8GD1s491czjrl$3ocBG={63%K zAM<%;=6#Z%7aerim+l*grZHK3}-5;TH zd!Mz{`qt?SLkBQKvvl@qy5Aa7)0eoTkvwqC{qI%E|5=%Y{q&s+qe&wCBDe1C#%AQr zW&oK{wPg|5O?Kj9N}W4E%^5vN4Ut_7o_Uf4l({G6(!1W;7XMn<{j9)JA=ff8v+R9p zbwSU?Tn8CdnPM5$V?8C$C(4!w)D7z?<_bwuIxL>TH9J}Pc2jQsicqTamP=b`s!4KT z2-1DT+)SdTq4{`1$*XyvR%ws*R`w!xY4GD@I6x%wiR5k0O+z67b=iiib?l0#a4Y#z zeK$+K1PQtm?bY&nXE1v=yU77le+LB6g{+=z+RiOE?7Fn+O0;bPu)G*94tyzp)0J=$ zaNB&4L-45LIC~X~^(=iQ(*z_9P>3{Dj2o)%ZLJPS{+WKejoUi+Yv@McenH6+1k&9GiSmZVg!kqJo-s$oToJbHXq~p;>tzSI$g_r8e(_9VLvCBJ;Ffs79T7{&3Y3iI1ZNJoSU*RJNauIZND)qU)wxRq(2w`!+4 zuZ?pHyoP~;u-3;C_r9O%?N4Wvtd<^Cx9&RwY=GVK&r=%y&gU_IY{aV9QvV+-4A7Vt z<+_r*TVmSZ+E*&iLS>r5H;vZu@m%K9Ggug=cDaLZk&t=!<9HVj4lW4FS0AJ#1q zIB*$3IS9~Q@=v^Dg|8AJnQo_tgAE-Aw1IOFocF8k;Wn%`1nA8tcKklcEiisb+O%V& zU6h;VH)bu&Q)uDjuLFi2kAq0N+A(#tl8WOi25_VnM4O-K(%-=rw9}=lV zj>>kq@Z`_L!9+=J)%Z4C_EuB^7k8|4ix0a@Hmk9|J8;_-7JJ>rj~ODE8tR6f68zmy zxmd-eJB^DISX;`LTbk=$qBZ;&nB1ndFz+4=oPzd zlTn?Pd@V*ZEpnRI@Sd3CFZe?VDg3@EPX~Ad!^adNUynSl>-^IJF`VL?0QbOa zRJne083k%hb(%?3BK2BjRAN1t&-@x%s&3E*#CC|@ww;HUPw0TIlZ8{dUcOUShrss> zxBq(Qc0;_qQ~IqwlyxbZG&>9&nKp_S3>9I|E@L5;o`bc&5tD$rdSbyQYp=8uZm{V+SYbA>OZ#TlavbY$Be~3`VQ~+~txE6>rwNxD$qZ8V%>BQo@Yf3` zB2Rx8#k3~A=b-HhqyF2%N+otRF9gn<9ta}@<)EFnl<_}O;d;((Du(7(J}XW5Yn;D7 z@KJATz=otfV296>j(F9On@m`)iAVzeFt(I&qOdS3yD%G}<){!2Hh>5l0OwKp8~6{N zh|vrENqd_#j&nc+PaZ@s`bgCJbn~qKSw3)Pbk~_p3;li1jTfb54W}2&Df@XrM(f@W zuu>*F;w_gRhtiB$y55t3Pr*GZdkeQf3Ps9qo{w7-j?Z zFboz?IsAj+0E3VmaUKkmJQG-atY-jZ8$>B6R4&Od-a$T$P!_Z5E+(kW1Z82D)@z>5 z(mH3R+B167H7Xo$SqS`y0$?!jW?oaU-qRE9YgAyXxT4E(2(;F@jUK=WnWaM{53T7j z4?ge=3i&RmZyHZ1K%@m+QFb})*n;mCaBCzlL}|ov>JQFe1j=F##Z}Waz?sUnshJgR zQlNEP5*{~q_NW*UJ3jpXTCOsKyMw8+I57Kx&qwXnHt?Ygf(t-7-e z7VCdrif^rs5JK|SW{xyouWzegqd3+r3{W9bAWR*?^xQuTv~d?$n6CKsZ^O$v9X9Ku znBk~Gg|EP()*ad9(gYEWI78XI`lUv4b9S_uHp?DL;l1Zr#~KJSys46Mh>IEgaKL7c zit#$kyIXyKqzgd@R-d_J$S3gx*9V|<*9-f`ZF&HD=eq|(nANErDRYw$$BB#&*!iK3 zk=P1t>$9TJ0Z&Cq6Al@@PwlJ=f=9<|2ktYmYLQuQG|PS?1)}U912_a;O$OWyLz7@B zAIt#;v1Vs6K{k_-s+c?%y*%@~goocL8LGW7rG`~*qqU?Iy$XUIj{KBPOC<;ebGHX4o~KbQJh`P@fvAsH5(Z}BZ3*K z7PSh@bV61$R2Vs>PXO{pqxkw*;NX>L;$WSy*KnZUl#yQuhXZft(STH)1E6FAKq=U+ zLIWuPHl?SQdz4SE!T8lN(3m69UH5!lczsPp$JYsfON`XWWHzTbYDFqVtuzPewAU2v z1XW($VI;yaRfIi`8JgN`Bq;q!;@hg3*YC0T(|{4OONmc<{y6^nWoGh8f<6i6+^e{t zHYPu;6RTWz>$l-NH(Iwn2E!TqypQ9uuF@(N%M)xwptY&&cSGnQCt9@yt#E&uLJrFR z;@4YW78B0x{7_La5x;~oY$Ps}N*BdYH9x(mlkV<8>m z(ZO@Xdh|(v@a3L{Y~78Xr2q{51{YhcLC&E|nZ$Ra>BCrJt4y9v+Pu%il0>J9m8F%a z>*cd{O9|S4GF%(U{>F6co7P&2u?D7#<@nRxlsi=;>%?wR&Pc+Cuy#rT1P>C1)=s@a z%(G;Mf`q0YN1`+$D>5Vn!Qf_v{kFfqFC*0>#KRF|_8(rl(R_u?i0vckUc?r`=Y-3z zQxGCv@*F-{1?QpUMyYzeIF6#{KZO?}EoR_s)vouM^%L!p(rqQoE2(tULbGOO`#9rP zUw7aYj2?$(bwB#@q!i?NIM|V9eHq@9nBiC0)aYz|5~;8)-=dOS_{NSLiuZT?Wm-ct zmstIc=-K-z<3qG7H9h&yZd5Yt<-Y94-F(s6oe@GHNd(%lcUR#m8E%4_Q+0BEzKnQAcc9XyE-}289zF- zcM`7yQcJOC+8-*3S=6b;?5CWUnl5k80Hs$)od^NKVXV(HTDa(&WLaBCBd|Sy@Ps!Sdl@Za)W^x;F3`x9 z@T(;Z)L>!V5~5OXv3&ZG6leA$>ELWE%|xIB!#`&--eQLDDMUjkILQarYMmf4ROXPk`0d4 zL*WH2SKn6FSsh#x%<-V7n#!vqQuPQ0ZbjQA9uz*=5Me_5l!(?_oYg|WjmF2JFhJE=Bz zcql1ctBOr_;nF`OH_R{q?aP&VixV_Wa_;rlxghD*wjWS?efc5MJNZ@dgh@fhIhw+? zRB4x!x>f3Rt}Cp|KK^470fAhmcnr5V)O+kmc4oj%NV6gbRzk;kN((a&+p5j)R*cun z?DBzmxIE(rTOUQ(0=1#lNiw>X{G|qY$hUe?iLlp3^c^LPP%Ro)+n{8|88EqB!MPni z0E`~S>R?68wLFeO@qv|Najc`&7KqOuWR`{Y$ha zr2G8q_|IJW2`-S`sO)2TH&k9!vn+kK|MYRKRKs+jH0`oV+JSd{;OUu)eZ?u^+9n^hss?ZCzy4ziZkkbk$fL=6b;q9A+K(!X3|J5yjxvjW6x*N02_1~ zE`||!E#$~4@n=k#>O;-mW3B$&z{6G5Rfl;1cq(_jVzX2ZC#dXt8HegWdpWtY3!Qdb z(#md(Y49}#4v_|l=1R!4$jLB`sbYA|`NDrKdNJ| zsx_kHIlla5*hQ1QH7@lMtHS>p61*k%H?$DF*gWdxY<}u;vTGt**i}Ge3E7wk(G*jd u@=}#b5D9P9Crm;%f<^wnmirdyn~qG(=<&80f8A}s-+2Smvn6^?VgCo))CBwh literal 0 HcmV?d00001 diff --git a/metricbeat/docs/modules/aws.asciidoc b/metricbeat/docs/modules/aws.asciidoc index d03f2ce4a55..5f25ab0e1df 100644 --- a/metricbeat/docs/modules/aws.asciidoc +++ b/metricbeat/docs/modules/aws.asciidoc @@ -12,7 +12,7 @@ This module periodically fetches monitoring metrics from AWS CloudWatch using https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricData.html[GetMetricData API] for AWS services. Note: extra AWS charges on GetMetricData API requests will be generated by this module. -The default metricsets are `ec2`, `sqs`, `s3_request`, `s3_daily_storage`, `cloudwatch` and `rds`. +All metrics are enabled by default. [float] == Module-specific configuration notes @@ -34,8 +34,12 @@ image::./images/metricbeat-aws-overview.png[] [float] == Metricsets -Currently, we have `ec2`, `sqs`, `s3_request`, `s3_daily_storage`, `cloudwatch`, `billing`,`ebs`, `elb`, `rds`, `sns`, `sqs` and `usage` metricset in `aws` module. -Collecting `tags` for `ec2`, `cloudwatch`, `ebs` and `elb` metricset is supported. +Currently, we have `billing`, `cloudwatch`, `dynamodb`, `ebs`, `ec2`, `elb`, +`lambda`, `rds`, `s3_daily_storage`, `s3_request`, `sns`, `sqs` and `usage` +metricset in `aws` module. + +Collecting `tags` for `ec2`, `cloudwatch`, and metricset created based on +`cloudwatch` using light module is supported. * *tags.*: Tag key value pairs from aws resources. A tag is a label that user assigns to an AWS resource. @@ -113,7 +117,7 @@ GetMetricData max page size: 100, based on https://docs.aws.amazon.com/AmazonClo | CloudWatch ListMetrics | Total number of results / ListMetrics max page size | Per region per namespace per collection period | CloudWatch GetMetricData | Total number of results / GetMetricData max page size | Per region per namespace per collection period |=== -`billing`, `ebs`, `elb`, `sns` and `usage` are the same as `cloudwatch` metricset. +`billing`, `ebs`, `elb`, `sns`, `usage` and `lambda` are the same as `cloudwatch` metricset. [float] === `ec2` @@ -232,6 +236,8 @@ The following metricsets are available: * <> +* <> + * <> * <> @@ -256,6 +262,8 @@ include::aws/ec2.asciidoc[] include::aws/elb.asciidoc[] +include::aws/lambda.asciidoc[] + include::aws/rds.asciidoc[] include::aws/s3_daily_storage.asciidoc[] diff --git a/metricbeat/docs/modules/aws/lambda.asciidoc b/metricbeat/docs/modules/aws/lambda.asciidoc new file mode 100644 index 00000000000..9afe68262ca --- /dev/null +++ b/metricbeat/docs/modules/aws/lambda.asciidoc @@ -0,0 +1,24 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-aws-lambda]] +=== aws lambda metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/aws/lambda/_meta/docs.asciidoc[] + +This is a default metricset. If the host module is unconfigured, this metricset is enabled by default. + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/aws/lambda/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 886add0578c..45170d67d62 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -16,12 +16,13 @@ This file is generated! See scripts/mage/docs_collector.go |<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | -.12+| .12+| |<> beta[] +.13+| .13+| |<> beta[] |<> |<> beta[] |<> |<> |<> +|<> beta[] |<> |<> |<> diff --git a/x-pack/metricbeat/module/aws/_meta/config.yml b/x-pack/metricbeat/module/aws/_meta/config.yml index 513719e5681..0fa8436d5cd 100644 --- a/x-pack/metricbeat/module/aws/_meta/config.yml +++ b/x-pack/metricbeat/module/aws/_meta/config.yml @@ -17,12 +17,14 @@ - module: aws period: 5m metricsets: + - dynamodb - ebs - ec2 - elb + - lambda + - rds - sns - sqs - - rds - module: aws period: 12h metricsets: diff --git a/x-pack/metricbeat/module/aws/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/_meta/docs.asciidoc index 0b3565a001a..1dd8c2aaf12 100644 --- a/x-pack/metricbeat/module/aws/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/aws/_meta/docs.asciidoc @@ -4,7 +4,7 @@ This module periodically fetches monitoring metrics from AWS CloudWatch using https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricData.html[GetMetricData API] for AWS services. Note: extra AWS charges on GetMetricData API requests will be generated by this module. -The default metricsets are `ec2`, `sqs`, `s3_request`, `s3_daily_storage`, `cloudwatch` and `rds`. +All metrics are enabled by default. [float] == Module-specific configuration notes @@ -26,8 +26,12 @@ image::./images/metricbeat-aws-overview.png[] [float] == Metricsets -Currently, we have `ec2`, `sqs`, `s3_request`, `s3_daily_storage`, `cloudwatch`, `billing`,`ebs`, `elb`, `rds`, `sns`, `sqs` and `usage` metricset in `aws` module. -Collecting `tags` for `ec2`, `cloudwatch`, `ebs` and `elb` metricset is supported. +Currently, we have `billing`, `cloudwatch`, `dynamodb`, `ebs`, `ec2`, `elb`, +`lambda`, `rds`, `s3_daily_storage`, `s3_request`, `sns`, `sqs` and `usage` +metricset in `aws` module. + +Collecting `tags` for `ec2`, `cloudwatch`, and metricset created based on +`cloudwatch` using light module is supported. * *tags.*: Tag key value pairs from aws resources. A tag is a label that user assigns to an AWS resource. @@ -105,7 +109,7 @@ GetMetricData max page size: 100, based on https://docs.aws.amazon.com/AmazonClo | CloudWatch ListMetrics | Total number of results / ListMetrics max page size | Per region per namespace per collection period | CloudWatch GetMetricData | Total number of results / GetMetricData max page size | Per region per namespace per collection period |=== -`billing`, `ebs`, `elb`, `sns` and `usage` are the same as `cloudwatch` metricset. +`billing`, `ebs`, `elb`, `sns`, `usage` and `lambda` are the same as `cloudwatch` metricset. [float] === `ec2` diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json new file mode 100644 index 00000000000..1fd20d1dea6 --- /dev/null +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json @@ -0,0 +1,654 @@ +{ + "objects": [ + { + "attributes": { + "description": "Overview of AWS Lambda Metrics", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "optionsJSON": { + "hidePanelTitles": false, + "useMargins": true + }, + "panelsJSON": [ + { + "embeddableConfig": { + "title": "AWS Account Filter" + }, + "gridData": { + "h": 5, + "i": "8f2d1b8f-fef3-4a9a-9cc8-7f0e2c65e35a", + "w": 14, + "x": 0, + "y": 0 + }, + "panelIndex": "8f2d1b8f-fef3-4a9a-9cc8-7f0e2c65e35a", + "panelRefName": "panel_0", + "title": "AWS Account Filter", + "version": "7.5.0" + }, + { + "embeddableConfig": { + "title": "Top Errors" + }, + "gridData": { + "h": 10, + "i": "443a9699-3451-44f7-8415-99a16c3f45b3", + "w": 34, + "x": 14, + "y": 0 + }, + "panelIndex": "443a9699-3451-44f7-8415-99a16c3f45b3", + "panelRefName": "panel_1", + "title": "Top Errors", + "version": "7.5.0" + }, + { + "embeddableConfig": { + "title": "AWS Region Filter" + }, + "gridData": { + "h": 5, + "i": "60a16bf0-2979-467a-b30e-05ea29547b41", + "w": 14, + "x": 0, + "y": 5 + }, + "panelIndex": "60a16bf0-2979-467a-b30e-05ea29547b41", + "panelRefName": "panel_2", + "title": "AWS Region Filter", + "version": "7.5.0" + }, + { + "embeddableConfig": { + "title": "Lambda Function Duration in Milliseconds" + }, + "gridData": { + "h": 14, + "i": "349ef0d1-fea1-4b91-b95d-7a668914e10b", + "w": 48, + "x": 0, + "y": 10 + }, + "panelIndex": "349ef0d1-fea1-4b91-b95d-7a668914e10b", + "panelRefName": "panel_3", + "title": "Lambda Function Duration in Milliseconds", + "version": "7.5.0" + }, + { + "embeddableConfig": { + "title": "Top Invoked Lambda Functions" + }, + "gridData": { + "h": 9, + "i": "048b1577-5aed-48e5-8f90-147aa3d56c1a", + "w": 24, + "x": 0, + "y": 24 + }, + "panelIndex": "048b1577-5aed-48e5-8f90-147aa3d56c1a", + "panelRefName": "panel_4", + "title": "Top Invoked Lambda Functions", + "version": "7.5.0" + }, + { + "embeddableConfig": { + "title": "Top Throttled Lambda Functions" + }, + "gridData": { + "h": 9, + "i": "4c8e471c-45da-47be-a866-c5bfc6d28a05", + "w": 24, + "x": 24, + "y": 24 + }, + "panelIndex": "4c8e471c-45da-47be-a866-c5bfc6d28a05", + "panelRefName": "panel_5", + "title": "Top Throttled Lambda Functions", + "version": "7.5.0" + } + ], + "timeRestore": false, + "title": "[Metricbeat AWS] Lambda Overview", + "version": 1 + }, + "id": "7ac8e1d0-28d2-11ea-ba6c-49a884eb104f", + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "deab0260-2981-11e9-86eb-a3a07a77f530", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "4bf0a740-28d1-11ea-ba6c-49a884eb104f", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "b5308940-7347-11e9-816b-07687310a99a", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "39dfc8d0-28cf-11ea-ba6c-49a884eb104f", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "1f3f00c0-28d1-11ea-ba6c-49a884eb104f", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "915bcd50-28d1-11ea-ba6c-49a884eb104f", + "name": "panel_5", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-01-09T23:14:56.640Z", + "version": "WzI3MDAsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "AWS Account Filter [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "controls": [ + { + "fieldName": "cloud.account.name", + "id": "1549397251041", + "indexPatternRefName": "control_0_index_pattern", + "label": "account name", + "options": { + "dynamicOptions": true, + "multiselect": true, + "order": "desc", + "size": 5, + "type": "terms" + }, + "parent": "", + "type": "list" + } + ], + "pinFilters": false, + "updateFiltersOnChange": true, + "useTimeFilter": false + }, + "title": "AWS Account Filter [Metricbeat AWS]", + "type": "input_control_vis" + } + }, + "id": "deab0260-2981-11e9-86eb-a3a07a77f530", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [ + { + "id": "metricbeat-*", + "name": "control_0_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-01-09T22:47:51.746Z", + "version": "WzIzMTUsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Lambda Top Errors [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": 0, + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "fbf0eac0-28d0-11ea-8789-f72e3366fb25" + } + ], + "bar_color_rules": [ + { + "id": "f679afa0-28d0-11ea-8789-f72e3366fb25" + } + ], + "default_index_pattern": "filebeat-*", + "default_timefield": "@timestamp", + "filter": { + "language": "kuery", + "query": "" + }, + "gauge_color_rules": [ + { + "id": "3eabbde0-28d1-11ea-8789-f72e3366fb25" + } + ], + "gauge_inner_width": 10, + "gauge_style": "half", + "gauge_width": 10, + "id": "ca2e4c60-28cd-11ea-822d-3ba2c0089081", + "index_pattern": "metricbeat-*", + "interval": "5m", + "isModelInvalid": false, + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#3185FC", + "fill": 0, + "filter": { + "language": "kuery", + "query": "" + }, + "formatter": "number", + "id": "ca2e4c61-28cd-11ea-822d-3ba2c0089081", + "label": "avg(aws.metrics.Duration.avg)", + "line_width": 2, + "metrics": [ + { + "field": "aws.lambda.metrics.Errors.avg", + "id": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "max" + } + ], + "point_size": "4", + "separate_axis": 0, + "split_color_mode": "rainbow", + "split_mode": "terms", + "stacked": "none", + "terms_field": "aws.dimensions.FunctionName", + "terms_order_by": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "timeseries", + "value_template": "{{value}}" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "@timestamp", + "type": "timeseries" + }, + "title": "Lambda Top Errors [Metricbeat AWS]", + "type": "metrics" + } + }, + "id": "4bf0a740-28d1-11ea-ba6c-49a884eb104f", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-09T22:58:19.013Z", + "version": "WzI2OTAsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "AWS Region Filter [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "controls": [ + { + "fieldName": "cloud.region", + "id": "1549397251041", + "indexPatternRefName": "control_0_index_pattern", + "label": "region name", + "options": { + "dynamicOptions": true, + "multiselect": true, + "order": "desc", + "size": 5, + "type": "terms" + }, + "parent": "", + "type": "list" + } + ], + "pinFilters": false, + "updateFiltersOnChange": true, + "useTimeFilter": false + }, + "title": "AWS Region Filter", + "type": "input_control_vis" + } + }, + "id": "b5308940-7347-11e9-816b-07687310a99a", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [ + { + "id": "metricbeat-*", + "name": "control_0_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-01-09T22:47:51.746Z", + "version": "WzIzMTIsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Lambda Duration in Milliseconds [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": 0, + "axis_position": "left", + "axis_scale": "normal", + "default_index_pattern": "filebeat-*", + "default_timefield": "@timestamp", + "filter": { + "language": "kuery", + "query": "" + }, + "id": "ca2e4c60-28cd-11ea-822d-3ba2c0089081", + "index_pattern": "metricbeat-*", + "interval": "5m", + "isModelInvalid": false, + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#3185FC", + "fill": 0, + "filter": { + "language": "kuery", + "query": "" + }, + "formatter": "number", + "id": "ca2e4c61-28cd-11ea-822d-3ba2c0089081", + "label": "avg(aws.metrics.Duration.avg)", + "line_width": 2, + "metrics": [ + { + "field": "aws.lambda.metrics.Duration.avg", + "id": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "avg" + } + ], + "point_size": "4", + "separate_axis": 0, + "split_color_mode": "rainbow", + "split_mode": "terms", + "stacked": "none", + "terms_field": "aws.dimensions.FunctionName", + "terms_order_by": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "timeseries", + "value_template": "{{value}}" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "@timestamp", + "type": "timeseries" + }, + "title": "Lambda Duration in Milliseconds [Metricbeat AWS]", + "type": "metrics" + } + }, + "id": "39dfc8d0-28cf-11ea-ba6c-49a884eb104f", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-09T23:09:15.122Z", + "version": "WzI2OTgsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Lambda Top Invoked Functions [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": 0, + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "fbf0eac0-28d0-11ea-8789-f72e3366fb25" + } + ], + "bar_color_rules": [ + { + "id": "f679afa0-28d0-11ea-8789-f72e3366fb25" + } + ], + "default_index_pattern": "filebeat-*", + "default_timefield": "@timestamp", + "filter": { + "language": "kuery", + "query": "" + }, + "id": "ca2e4c60-28cd-11ea-822d-3ba2c0089081", + "index_pattern": "metricbeat-*", + "interval": "5m", + "isModelInvalid": false, + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#3185FC", + "fill": 0, + "filter": { + "language": "kuery", + "query": "" + }, + "formatter": "number", + "id": "ca2e4c61-28cd-11ea-822d-3ba2c0089081", + "label": "avg(aws.metrics.Duration.avg)", + "line_width": 2, + "metrics": [ + { + "field": "aws.lambda.metrics.Invocations.avg", + "id": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "max" + } + ], + "point_size": "4", + "separate_axis": 0, + "split_color_mode": "rainbow", + "split_mode": "terms", + "stacked": "none", + "terms_field": "aws.dimensions.FunctionName", + "terms_order_by": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "timeseries", + "value_template": "{{value}}" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "@timestamp", + "type": "top_n" + }, + "title": "Lambda Top Invoked Functions [Metricbeat AWS]", + "type": "metrics" + } + }, + "id": "1f3f00c0-28d1-11ea-ba6c-49a884eb104f", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-09T22:59:29.714Z", + "version": "WzI2OTEsM10=" + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": { + "filter": [], + "query": { + "language": "kuery", + "query": "" + } + } + }, + "title": "Lambda Top Throttles [Metricbeat AWS]", + "uiStateJSON": {}, + "version": 1, + "visState": { + "aggs": [], + "params": { + "axis_formatter": "number", + "axis_min": 0, + "axis_position": "left", + "axis_scale": "normal", + "background_color_rules": [ + { + "id": "fbf0eac0-28d0-11ea-8789-f72e3366fb25" + } + ], + "bar_color_rules": [ + { + "id": "f679afa0-28d0-11ea-8789-f72e3366fb25" + } + ], + "default_index_pattern": "filebeat-*", + "default_timefield": "@timestamp", + "filter": { + "language": "kuery", + "query": "" + }, + "gauge_color_rules": [ + { + "id": "3eabbde0-28d1-11ea-8789-f72e3366fb25" + } + ], + "gauge_inner_width": 10, + "gauge_style": "half", + "gauge_width": 10, + "id": "ca2e4c60-28cd-11ea-822d-3ba2c0089081", + "index_pattern": "metricbeat-*", + "interval": "5m", + "isModelInvalid": false, + "series": [ + { + "axis_position": "right", + "chart_type": "line", + "color": "#3185FC", + "fill": 0, + "filter": { + "language": "kuery", + "query": "" + }, + "formatter": "number", + "id": "ca2e4c61-28cd-11ea-822d-3ba2c0089081", + "label": "avg(aws.metrics.Duration.avg)", + "line_width": 2, + "metrics": [ + { + "field": "aws.lambda.metrics.Duration.avg", + "id": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "max" + } + ], + "point_size": "4", + "separate_axis": 0, + "split_color_mode": "rainbow", + "split_mode": "terms", + "stacked": "none", + "terms_field": "aws.dimensions.FunctionName", + "terms_order_by": "ca2e4c62-28cd-11ea-822d-3ba2c0089081", + "type": "timeseries", + "value_template": "{{value}}" + } + ], + "show_grid": 1, + "show_legend": 1, + "time_field": "@timestamp", + "type": "top_n" + }, + "title": "Lambda Top Throttles [Metricbeat AWS]", + "type": "metrics" + } + }, + "id": "915bcd50-28d1-11ea-ba6c-49a884eb104f", + "migrationVersion": { + "visualization": "7.4.2" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-01-09T22:59:58.449Z", + "version": "WzI2OTIsM10=" + } + ], + "version": "7.5.0" +} diff --git a/x-pack/metricbeat/module/aws/fields.go b/x-pack/metricbeat/module/aws/fields.go index 3ee30ebaa25..9ac2b8fba44 100644 --- a/x-pack/metricbeat/module/aws/fields.go +++ b/x-pack/metricbeat/module/aws/fields.go @@ -19,5 +19,5 @@ func init() { // AssetAws returns asset data. // This is the base64 encoded gzipped contents of module/aws. func AssetAws() string { - return "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" + return "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" } diff --git a/x-pack/metricbeat/module/aws/lambda/_meta/data.json b/x-pack/metricbeat/module/aws/lambda/_meta/data.json new file mode 100644 index 00000000000..726a613616b --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/_meta/data.json @@ -0,0 +1,48 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "aws": { + "cloudwatch": { + "namespace": "AWS/Lambda" + }, + "dimensions": { + "FunctionName": "ec2-owner-tagger-serverless", + "Resource": "ec2-owner-tagger-serverless" + }, + "lambda": { + "metrics": { + "Duration": { + "avg": 8218.073333333334 + }, + "Errors": { + "avg": 1 + }, + "Invocations": { + "avg": 1 + }, + "Throttles": { + "avg": 0 + } + } + } + }, + "cloud": { + "account": { + "id": "627959692251", + "name": "elastic-test" + }, + "provider": "aws", + "region": "us-west-2" + }, + "event": { + "dataset": "aws.lambda", + "duration": 115000, + "module": "aws" + }, + "metricset": { + "name": "lambda", + "period": 10000 + }, + "service": { + "type": "aws" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/aws/lambda/_meta/docs.asciidoc b/x-pack/metricbeat/module/aws/lambda/_meta/docs.asciidoc new file mode 100644 index 00000000000..1d1f8e22a7e --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/_meta/docs.asciidoc @@ -0,0 +1,55 @@ +AWS Lambda monitors functions and sends metrics to Amazon CloudWatch. These +metrics include total invocations, errors, duration, throttles, dead-letter +queue errors, and iterator age for stream-based invocations. + +[float] +=== AWS Permissions +Some specific AWS permissions are required for IAM user to collect AWS EBS metrics. +---- +ec2:DescribeRegions +cloudwatch:GetMetricData +cloudwatch:ListMetrics +tag:getResources +sts:GetCallerIdentity +iam:ListAccountAliases +---- + +[float] +=== Dashboard + +The aws lambda metricset comes with a predefined dashboard. For example: + +image::./images/metricbeat-aws-lambda-overview.png[] + +[float] +=== Configuration example +[source,yaml] +---- +- module: aws + period: 300s + metricsets: + - lambda + # This module uses the aws cloudwatch metricset, all + # the options for this metricset are also available here. +---- + +[float] +=== Metrics +Please see more details for each metric in +https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-metrics.html[lambda-cloudwatch-metric]. + +|=== +|Metric Name|Statistic Method +|Invocations | Average +|Errors | Average +|DeadLetterErrors | Average +|Duration | Average +|Throttles | Average +|IteratorAge | Average +|ConcurrentExecutions | Average +|UnreservedConcurrentExecutions | Average +|ProvisionedConcurrentExecutions | Maximum +|ProvisionedConcurrencyInvocations | Sum +|ProvisionedConcurrencySpilloverInvocations | Sum +|ProvisionedConcurrencyUtilization | Maximum +|=== diff --git a/x-pack/metricbeat/module/aws/lambda/_meta/fields.yml b/x-pack/metricbeat/module/aws/lambda/_meta/fields.yml new file mode 100644 index 00000000000..1cebeff318f --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/_meta/fields.yml @@ -0,0 +1,6 @@ +- name: lambda + type: group + description: > + `lambda` contains the metrics that were scraped from AWS CloudWatch which contains monitoring metrics sent by AWS Lambda. + release: beta + fields: diff --git a/x-pack/metricbeat/module/aws/lambda/lambda_integration_test.go b/x-pack/metricbeat/module/aws/lambda/lambda_integration_test.go new file mode 100644 index 00000000000..247228254b6 --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/lambda_integration_test.go @@ -0,0 +1,24 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build integration + +package lambda + +import ( + "testing" + + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + "github.com/elastic/beats/x-pack/metricbeat/module/aws/mtest" +) + +func TestData(t *testing.T) { + config, info := mtest.GetConfigForTest("lambda", "300s") + if info != "" { + t.Skip("Skipping TestData: " + info) + } + + metricSet := mbtest.NewFetcher(t, config) + metricSet.WriteEvents(t, "/") +} diff --git a/x-pack/metricbeat/module/aws/lambda/lambda_test.go b/x-pack/metricbeat/module/aws/lambda/lambda_test.go new file mode 100644 index 00000000000..6b0c7baf2a9 --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/lambda_test.go @@ -0,0 +1,21 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package lambda + +import ( + "os" + + "github.com/elastic/beats/metricbeat/mb" + + // Register input module and metricset + _ "github.com/elastic/beats/x-pack/metricbeat/module/aws" + _ "github.com/elastic/beats/x-pack/metricbeat/module/aws/cloudwatch" +) + +func init() { + // To be moved to some kind of helper + os.Setenv("BEAT_STRICT_PERMS", "false") + mb.Registry.SetSecondarySource(mb.NewLightModulesSource("../../../module")) +} diff --git a/x-pack/metricbeat/module/aws/lambda/manifest.yml b/x-pack/metricbeat/module/aws/lambda/manifest.yml new file mode 100644 index 00000000000..71fd0b7ef1c --- /dev/null +++ b/x-pack/metricbeat/module/aws/lambda/manifest.yml @@ -0,0 +1,20 @@ +default: true +input: + module: aws + metricset: cloudwatch + defaults: + metrics: + - namespace: AWS/Lambda + statistic: ["Average"] + name: ["Invocations", "Errors", "DeadLetterErrors", "Duration", + "Throttles", "IteratorAge", "ConcurrentExecutions", + "UnreservedConcurrentExecutions"] + tags.resource_type_filter: lambda + - namespace: AWS/Lambda + statistic: ["Maximum"] + name: ["ProvisionedConcurrentExecutions", "ProvisionedConcurrencyUtilization"] + tags.resource_type_filter: lambda + - namespace: AWS/Lambda + statistic: ["Sum"] + name: ["ProvisionedConcurrencyInvocations", "ProvisionedConcurrencySpilloverInvocations"] + tags.resource_type_filter: lambda diff --git a/x-pack/metricbeat/module/aws/module.yml b/x-pack/metricbeat/module/aws/module.yml index 5e3d60759d2..d750f2bedd5 100644 --- a/x-pack/metricbeat/module/aws/module.yml +++ b/x-pack/metricbeat/module/aws/module.yml @@ -5,4 +5,5 @@ metricsets: - usage - billing - sns + - lambda - dynamodb diff --git a/x-pack/metricbeat/modules.d/aws.yml.disabled b/x-pack/metricbeat/modules.d/aws.yml.disabled index e3f727b15c5..bfcb9d5a786 100644 --- a/x-pack/metricbeat/modules.d/aws.yml.disabled +++ b/x-pack/metricbeat/modules.d/aws.yml.disabled @@ -20,12 +20,14 @@ - module: aws period: 5m metricsets: + - dynamodb - ebs - ec2 - elb + - lambda + - rds - sns - sqs - - rds - module: aws period: 12h metricsets: From 7fd545dcdf675645b4676a7f00502513760a2a01 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 17 Jan 2020 08:55:14 -0800 Subject: [PATCH 14/37] Adds missing imports (#15624) --- libbeat/cmd/instance/imports_common.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libbeat/cmd/instance/imports_common.go b/libbeat/cmd/instance/imports_common.go index 6b78ffc7d56..d8fa4b9f0cf 100644 --- a/libbeat/cmd/instance/imports_common.go +++ b/libbeat/cmd/instance/imports_common.go @@ -24,6 +24,7 @@ import ( _ "github.com/elastic/beats/libbeat/processors/actions" // Register default processors. _ "github.com/elastic/beats/libbeat/processors/add_cloud_metadata" _ "github.com/elastic/beats/libbeat/processors/add_host_metadata" + _ "github.com/elastic/beats/libbeat/processors/add_id" _ "github.com/elastic/beats/libbeat/processors/add_locale" _ "github.com/elastic/beats/libbeat/processors/add_observer_metadata" _ "github.com/elastic/beats/libbeat/processors/add_process_metadata" @@ -32,6 +33,7 @@ import ( _ "github.com/elastic/beats/libbeat/processors/dissect" _ "github.com/elastic/beats/libbeat/processors/dns" _ "github.com/elastic/beats/libbeat/processors/extract_array" + _ "github.com/elastic/beats/libbeat/processors/fingerprint" _ "github.com/elastic/beats/libbeat/processors/registered_domain" _ "github.com/elastic/beats/libbeat/publisher/includes" // Register publisher pipeline modules ) From d3fa73fc43ce68b780587e3a16b37120c0bd7ba9 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Fri, 17 Jan 2020 12:49:52 -0800 Subject: [PATCH 15/37] [docs] Clarify privileges required for the writer role (#15604) --- libbeat/docs/security/users.asciidoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libbeat/docs/security/users.asciidoc b/libbeat/docs/security/users.asciidoc index d8dff16a15f..f69ac1658a6 100644 --- a/libbeat/docs/security/users.asciidoc +++ b/libbeat/docs/security/users.asciidoc @@ -214,8 +214,9 @@ endif::serverless[] ==== Grant privileges and roles needed for publishing Users who publish events to {es} need to create and write to {beatname_uc} -indices. To minimize the privileges required by the writer role, you can use the -<> to pre-load dependencies. +indices. To minimize the privileges required by the writer role, use the +<> to pre-load dependencies. This section +assumes that you've pre-loaded dependencies. ifndef::no_ilm[] When using ILM, turn off the ILM setup check in the {beatname_uc} config file before From 9e6b014d82a7d8eb4e6028ea9337bec4c41648b3 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 17 Jan 2020 13:13:05 -0800 Subject: [PATCH 16/37] Mask password discovered via module autodiscover hint (#15616) * Mask password is string representation of config * Rename method * Adding unit test * Use const for module config password setting name * Using common.DebugString * Simplifying * Removing now-invalid unit test * Removing now-unnecessary const * Refactoring: moving debug-related var and func to common file * Refactoring: rename from black list to mask list * Implement fmt.Formatter for common.MapStr * Reintroduce debug statement * Make MarshalLogObject always filter MapStr object for logging purposes * Refactoring: renaming to be bit more generic * Forgot to add license header to new file * Fixing verb syntax --- libbeat/common/config.go | 40 +------------- libbeat/common/logging.go | 54 +++++++++++++++++++ libbeat/common/mapstr.go | 23 ++++++-- libbeat/common/mapstr_test.go | 23 ++++++++ .../autodiscover/builder/hints/metrics.go | 4 +- 5 files changed, 101 insertions(+), 43 deletions(-) create mode 100644 libbeat/common/logging.go diff --git a/libbeat/common/config.go b/libbeat/common/config.go index 7277d364f06..2f779d996bb 100644 --- a/libbeat/common/config.go +++ b/libbeat/common/config.go @@ -66,18 +66,6 @@ const ( selectorConfigWithPassword = "config-with-passwords" ) -var debugBlacklist = MakeStringSet( - "password", - "passphrase", - "key_passphrase", - "pass", - "proxy_url", - "url", - "urls", - "host", - "hosts", -) - // make hasSelector and configDebugf available for unit testing var hasSelector = logp.HasSelector var configDebugf = logp.Debug @@ -369,7 +357,7 @@ func DebugString(c *Config, filterPrivate bool) string { return fmt.Sprintf(" %v", err) } if filterPrivate { - filterDebugObject(content) + applyLoggingMask(content) } j, _ := json.MarshalIndent(content, "", " ") bufs = append(bufs, string(j)) @@ -380,7 +368,7 @@ func DebugString(c *Config, filterPrivate bool) string { return fmt.Sprintf(" %v", err) } if filterPrivate { - filterDebugObject(content) + applyLoggingMask(content) } j, _ := json.MarshalIndent(content, "", " ") bufs = append(bufs, string(j)) @@ -392,30 +380,6 @@ func DebugString(c *Config, filterPrivate bool) string { return strings.Join(bufs, "\n") } -func filterDebugObject(c interface{}) { - switch cfg := c.(type) { - case map[string]interface{}: - for k, v := range cfg { - if debugBlacklist.Has(k) { - if arr, ok := v.([]interface{}); ok { - for i := range arr { - arr[i] = "xxxxx" - } - } else { - cfg[k] = "xxxxx" - } - } else { - filterDebugObject(v) - } - } - - case []interface{}: - for _, elem := range cfg { - filterDebugObject(elem) - } - } -} - // OwnerHasExclusiveWritePerms asserts that the current user or root is the // owner of the config file and that the config file is (at most) writable by // the owner or root (e.g. group and other cannot have write access). diff --git a/libbeat/common/logging.go b/libbeat/common/logging.go new file mode 100644 index 00000000000..2c5f656abd4 --- /dev/null +++ b/libbeat/common/logging.go @@ -0,0 +1,54 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. 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 common + +var maskList = MakeStringSet( + "password", + "passphrase", + "key_passphrase", + "pass", + "proxy_url", + "url", + "urls", + "host", + "hosts", +) + +func applyLoggingMask(c interface{}) { + switch cfg := c.(type) { + case map[string]interface{}: + for k, v := range cfg { + if maskList.Has(k) { + if arr, ok := v.([]interface{}); ok { + for i := range arr { + arr[i] = "xxxxx" + } + } else { + cfg[k] = "xxxxx" + } + } else { + applyLoggingMask(v) + } + } + + case []interface{}: + for _, elem := range cfg { + applyLoggingMask(elem) + } + } +} diff --git a/libbeat/common/mapstr.go b/libbeat/common/mapstr.go index ca2a31d50b3..8cf589b0f04 100644 --- a/libbeat/common/mapstr.go +++ b/libbeat/common/mapstr.go @@ -20,6 +20,7 @@ package common import ( "encoding/json" "fmt" + "io" "sort" "strings" @@ -218,13 +219,16 @@ func (m MapStr) MarshalLogObject(enc zapcore.ObjectEncoder) error { return nil } - keys := make([]string, 0, len(m)) - for k := range m { + debugM := m.Clone() + applyLoggingMask(map[string]interface{}(debugM)) + + keys := make([]string, 0, len(debugM)) + for k := range debugM { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { - v := m[k] + v := debugM[k] if inner, ok := tryToMapStr(v); ok { enc.AddObject(k, inner) continue @@ -234,6 +238,19 @@ func (m MapStr) MarshalLogObject(enc zapcore.ObjectEncoder) error { return nil } +// Format implements fmt.Formatter +func (m MapStr) Format(f fmt.State, c rune) { + if f.Flag('+') || f.Flag('#') { + io.WriteString(f, m.String()) + return + } + + debugM := m.Clone() + applyLoggingMask(map[string]interface{}(debugM)) + + io.WriteString(f, debugM.String()) +} + // Flatten flattens the given MapStr and returns a flat MapStr. // // Example: diff --git a/libbeat/common/mapstr_test.go b/libbeat/common/mapstr_test.go index 34223344d80..784814bdac3 100644 --- a/libbeat/common/mapstr_test.go +++ b/libbeat/common/mapstr_test.go @@ -1002,3 +1002,26 @@ func BenchmarkWalkMap(b *testing.B) { } }) } + +func TestFormat(t *testing.T) { + input := MapStr{ + "foo": "bar", + "password": "SUPER_SECURE", + } + + tests := map[string]string{ + "%v": `{"foo":"bar","password":"xxxxx"}`, + "%+v": `{"foo":"bar","password":"SUPER_SECURE"}`, + "%#v": `{"foo":"bar","password":"SUPER_SECURE"}`, + "%s": `{"foo":"bar","password":"xxxxx"}`, + "%+s": `{"foo":"bar","password":"SUPER_SECURE"}`, + "%#s": `{"foo":"bar","password":"SUPER_SECURE"}`, + } + + for verb, expected := range tests { + t.Run(verb, func(t *testing.T) { + actual := fmt.Sprintf(verb, input) + assert.Equal(t, expected, actual) + }) + } +} diff --git a/metricbeat/autodiscover/builder/hints/metrics.go b/metricbeat/autodiscover/builder/hints/metrics.go index c10b39967c4..247d3046860 100644 --- a/metricbeat/autodiscover/builder/hints/metrics.go +++ b/metricbeat/autodiscover/builder/hints/metrics.go @@ -141,14 +141,14 @@ func (m *metricHints) CreateConfig(event bus.Event) []*common.Config { moduleConfig["password"] = password } - logp.Debug("hints.builder", "generated config: %v", moduleConfig.String()) + logp.Debug("hints.builder", "generated config: %v", moduleConfig) // Create config object cfg, err := common.NewConfigFrom(moduleConfig) if err != nil { logp.Debug("hints.builder", "config merge failed with error: %v", err) } - logp.Debug("hints.builder", "generated config: +%v", *cfg) + logp.Debug("hints.builder", "generated config: %+v", common.DebugString(cfg, true)) config = append(config, cfg) // Apply information in event to the template to generate the final config From 51072f9f2f0c2e7bf968f6831e3846a65d6814cf Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Fri, 17 Jan 2020 15:09:41 -0700 Subject: [PATCH 17/37] Update KQL to get estimated cost without dimension ServiceName (#15640) --- .../Metricbeat-aws-billing-overview.json | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json index 7fb9ee9b886..66cc4381c9a 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json @@ -56,12 +56,12 @@ }, "gridData": { "h": 11, - "i": "04159643-33c0-4f01-80f1-fb8d212ed959", + "i": "221aab02-2747-4d84-9dde-028ccd51bdce", "w": 16, "x": 0, "y": 5 }, - "panelIndex": "04159643-33c0-4f01-80f1-fb8d212ed959", + "panelIndex": "221aab02-2747-4d84-9dde-028ccd51bdce", "panelRefName": "panel_2", "title": "Total Estimated Charges", "version": "7.5.0" @@ -114,8 +114,8 @@ } ], "type": "dashboard", - "updated_at": "2019-12-02T18:54:47.255Z", - "version": "WzU1NywyXQ==" + "updated_at": "2020-01-17T15:11:20.337Z", + "version": "WzY2MiwxXQ==" }, { "attributes": { @@ -140,7 +140,7 @@ "fieldName": "cloud.account.name", "id": "1549397251041", "indexPatternRefName": "control_0_index_pattern", - "label": "AWS account", + "label": "account name", "options": { "dynamicOptions": true, "multiselect": true, @@ -172,8 +172,8 @@ } ], "type": "visualization", - "updated_at": "2019-12-02T18:50:52.450Z", - "version": "WzU1MywyXQ==" + "updated_at": "2020-01-17T14:43:10.917Z", + "version": "WzE1NywxXQ==" }, { "attributes": { @@ -295,8 +295,8 @@ } ], "type": "visualization", - "updated_at": "2019-12-02T18:53:50.818Z", - "version": "WzU1NSwyXQ==" + "updated_at": "2020-01-17T14:43:00.631Z", + "version": "WzU0LDFd" }, { "attributes": { @@ -329,7 +329,7 @@ "id": "ebb52700-1531-11ea-961e-c1db9cc6166e" } ], - "default_index_pattern": "filebeat-*", + "default_index_pattern": "metricbeat-*", "default_timefield": "@timestamp", "drop_last_bucket": 1, "gauge_color_rules": [ @@ -352,7 +352,7 @@ "fill": 0.5, "filter": { "language": "kuery", - "query": "aws.dimensions.ServiceName :* " + "query": "not aws.dimensions.ServiceName : * " }, "formatter": "number", "id": "61ca57f1-469d-11e7-af02-69e470af7417", @@ -365,16 +365,20 @@ "type": "sum" } ], + "override_index_pattern": 1, "point_size": 1, "separate_axis": 0, + "series_drop_last_bucket": 0, + "series_interval": "12h", "split_mode": "filter", "stacked": "none", + "time_range_mode": "entire_time_range", "value_template": "${{value}}" } ], "show_grid": 1, "show_legend": 1, - "time_field": null, + "time_field": "@timestamp", "type": "metric" }, "title": "Total Estimated Charges [Metricbeat AWS]", @@ -387,8 +391,8 @@ }, "references": [], "type": "visualization", - "updated_at": "2019-12-02T18:35:29.434Z", - "version": "WzU0NywyXQ==" + "updated_at": "2020-01-17T15:10:12.013Z", + "version": "WzY1OSwxXQ==" }, { "attributes": { @@ -472,8 +476,8 @@ }, "references": [], "type": "visualization", - "updated_at": "2019-12-02T18:49:11.978Z", - "version": "WzU1MSwyXQ==" + "updated_at": "2020-01-17T14:43:00.631Z", + "version": "WzU2LDFd" } ], "version": "7.5.0" From 9ece104ac263772b12068776fc7accfb699433eb Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Fri, 17 Jan 2020 14:12:09 -0800 Subject: [PATCH 18/37] Adding monitoring.cloud.* settings to reference files (#15648) * Adding monitoring.cloud.* settings to reference files * Missed winlogbeat somehow * Missed x-pack/winlogbeat --- auditbeat/auditbeat.reference.yml | 8 ++++++++ filebeat/filebeat.reference.yml | 8 ++++++++ heartbeat/heartbeat.reference.yml | 8 ++++++++ journalbeat/journalbeat.reference.yml | 8 ++++++++ libbeat/_meta/config.reference.yml.tmpl | 8 ++++++++ metricbeat/metricbeat.reference.yml | 8 ++++++++ packetbeat/packetbeat.reference.yml | 8 ++++++++ winlogbeat/winlogbeat.reference.yml | 8 ++++++++ x-pack/auditbeat/auditbeat.reference.yml | 8 ++++++++ x-pack/filebeat/filebeat.reference.yml | 8 ++++++++ x-pack/functionbeat/functionbeat.reference.yml | 8 ++++++++ x-pack/metricbeat/metricbeat.reference.yml | 8 ++++++++ x-pack/winlogbeat/winlogbeat.reference.yml | 8 ++++++++ 13 files changed, 104 insertions(+) diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 33b81cc0edf..db88d004264 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -1337,6 +1337,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index 80cad336d50..0ccbe5ad6ad 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -2034,6 +2034,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 8bff01bfe24..be68211d461 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -1481,6 +1481,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/journalbeat/journalbeat.reference.yml b/journalbeat/journalbeat.reference.yml index 424a38c419b..4f5ddb75c0e 100644 --- a/journalbeat/journalbeat.reference.yml +++ b/journalbeat/journalbeat.reference.yml @@ -1275,6 +1275,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/libbeat/_meta/config.reference.yml.tmpl b/libbeat/_meta/config.reference.yml.tmpl index 685adc5dd65..9f7a76ffe0f 100644 --- a/libbeat/_meta/config.reference.yml.tmpl +++ b/libbeat/_meta/config.reference.yml.tmpl @@ -1218,6 +1218,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 0ced4f40cd6..4b502f44d07 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -2020,6 +2020,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 86ceb94d6c4..bffddad50c7 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -1757,6 +1757,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 81eab60bc5f..fb7948a6579 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -1260,6 +1260,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index 55b57e87ec1..ae6b7f1b1a3 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -1388,6 +1388,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index 28f911bfa36..b448afc2195 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -2506,6 +2506,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index e04b3de57b6..61ebd49d0f8 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -1286,6 +1286,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index bf24255b4e3..b3374802037 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -2268,6 +2268,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 767e5bd03d5..1ba54b7408d 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -1263,6 +1263,14 @@ logging.files: #metrics.period: 10s #state.period: 1m +# The `monitoring.cloud.id` setting overwrites the `monitoring.elasticsearch.hosts` +# setting. You can find the value for this setting in the Elastic Cloud web UI. +#monitoring.cloud.id: + +# The `monitoring.cloud.auth` setting overwrites the `monitoring.elasticsearch.username` +# and `monitoring.elasticsearch.password` settings. The format is `:`. +#monitoring.cloud.auth: + #================================ HTTP Endpoint ====================================== # Each beat can expose internal metrics through a HTTP endpoint. For security # reasons the endpoint is disabled by default. This feature is currently experimental. From 99c6546d287ee18aa0028bc9cad7895bd90b965d Mon Sep 17 00:00:00 2001 From: Pablo Mercado Date: Mon, 20 Jan 2020 10:49:10 +0100 Subject: [PATCH 19/37] remove lablels (#15644) --- metricbeat/docs/fields.asciidoc | 9 --------- metricbeat/module/kubernetes/fields.go | 2 +- .../module/kubernetes/state_service/_meta/fields.yml | 4 ---- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 7d2b1f7f642..431ce2a5799 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -20255,15 +20255,6 @@ type: ip -- -*`kubernetes.service.labels.*`*:: -+ --- -Labels for service - -type: object - --- - *`kubernetes.service.created`*:: + -- diff --git a/metricbeat/module/kubernetes/fields.go b/metricbeat/module/kubernetes/fields.go index 6feb3a43320..7e772a7534b 100644 --- a/metricbeat/module/kubernetes/fields.go +++ b/metricbeat/module/kubernetes/fields.go @@ -32,5 +32,5 @@ func init() { // AssetKubernetes returns asset data. // This is the base64 encoded gzipped contents of ../metricbeat/module/kubernetes. func AssetKubernetes() string { - return "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" + return "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" } diff --git a/metricbeat/module/kubernetes/state_service/_meta/fields.yml b/metricbeat/module/kubernetes/state_service/_meta/fields.yml index 405c846acdd..4a32c52dc77 100644 --- a/metricbeat/module/kubernetes/state_service/_meta/fields.yml +++ b/metricbeat/module/kubernetes/state_service/_meta/fields.yml @@ -28,10 +28,6 @@ - name: ingress_hostname type: ip description: Ingress Hostname - - name: labels.* - type: object - object_type: keyword - description: Labels for service - name: created type: date description: Service creation date From 3e39fdfa22bd0371c3c4418e62a1511bcb6009f5 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 20 Jan 2020 14:22:08 +0100 Subject: [PATCH 20/37] Fix panic: don't send events if client is nil (#15568) * Fix panic: don't send events if client is nil * Use mutex * Add CHANGELOG entry * Rename changelog entry * Fix: changelog * Temporarily use specific logstash release --- CHANGELOG.next.asciidoc | 1 + libbeat/outputs/logstash/async.go | 21 ++++++++++++++++++++- testing/environments/snapshot.yml | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e166e9d6e47..c4e2170832e 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -39,6 +39,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Affecting all Beats* TLS or Beats that accept connections over TLS and validate client certificates. {pull}14146[14146] +- Fix panic in the Logstash output when trying to send events to closed connection. {pull}15568[15568] *Auditbeat* diff --git a/libbeat/outputs/logstash/async.go b/libbeat/outputs/logstash/async.go index 96374e192d0..967ae7d0f6c 100644 --- a/libbeat/outputs/logstash/async.go +++ b/libbeat/outputs/logstash/async.go @@ -18,7 +18,9 @@ package logstash import ( + "errors" "net" + "sync" "time" "github.com/elastic/beats/libbeat/beat" @@ -37,6 +39,8 @@ type asyncClient struct { win *window connect func() error + + mutex sync.Mutex } type msgRef struct { @@ -113,7 +117,11 @@ func (c *asyncClient) Connect() error { } func (c *asyncClient) Close() error { + c.mutex.Lock() + defer c.mutex.Unlock() + logp.Debug("logstash", "close connection") + if c.client != nil { err := c.client.Close() c.client = nil @@ -197,12 +205,23 @@ func (c *asyncClient) publishWindowed( } func (c *asyncClient) sendEvents(ref *msgRef, events []publisher.Event) error { + client := c.getClient() + if client == nil { + return errors.New("connection closed") + } window := make([]interface{}, len(events)) for i := range events { window[i] = &events[i].Content } ref.count.Inc() - return c.client.Send(ref.callback, window) + return client.Send(ref.callback, window) +} + +func (c *asyncClient) getClient() *v2.AsyncClient { + c.mutex.Lock() + client := c.client + c.mutex.Unlock() + return client } func (r *msgRef) callback(seq uint32, err error) { diff --git a/testing/environments/snapshot.yml b/testing/environments/snapshot.yml index 3ee259b0400..16c20266a6e 100644 --- a/testing/environments/snapshot.yml +++ b/testing/environments/snapshot.yml @@ -17,7 +17,7 @@ services: - "indices.id_field_data.enabled=true" logstash: - image: docker.elastic.co/logstash/logstash:8.0.0-SNAPSHOT + image: docker.elastic.co/logstash/logstash@sha256:e01cf165142edf8d67485115b938c94deeda66153e9516aa2ce69ee417c5fc33 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9600/_node/stats"] retries: 600 From b6d483d6f150602d43de238b41730d2cd4a6899c Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 20 Jan 2020 15:39:38 +0200 Subject: [PATCH 21/37] [Metricbeat] Add Istio mesh metricset (#15535) --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/fields.asciidoc | 314 +++++++ metricbeat/docs/modules/istio.asciidoc | 45 + metricbeat/docs/modules/istio/mesh.asciidoc | 23 + metricbeat/docs/modules_list.asciidoc | 3 + x-pack/metricbeat/include/list.go | 2 + x-pack/metricbeat/metricbeat.reference.yml | 6 + .../metricbeat/module/istio/_meta/Dockerfile | 0 .../module/istio/_meta/config.reference.yml | 4 + .../metricbeat/module/istio/_meta/config.yml | 4 + .../module/istio/_meta/docs.asciidoc | 9 + .../metricbeat/module/istio/_meta/fields.yml | 11 + x-pack/metricbeat/module/istio/doc.go | 6 + .../module/istio/docker-compose.yml | 0 x-pack/metricbeat/module/istio/fields.go | 23 + .../module/istio/mesh/_meta/data.json | 112 +++ .../module/istio/mesh/_meta/docs.asciidoc | 1 + .../module/istio/mesh/_meta/fields.yml | 131 +++ .../istio/mesh/_meta/testdata/config.yml | 3 + .../istio/mesh/_meta/testdata/docs.plain | 281 +++++++ .../_meta/testdata/docs.plain-expected.json | 779 ++++++++++++++++++ x-pack/metricbeat/module/istio/mesh/mesh.go | 60 ++ .../metricbeat/module/istio/mesh/mesh_test.go | 19 + x-pack/metricbeat/module/istio/module.yaml | 1 + .../metricbeat/modules.d/istio.yml.disabled | 7 + 25 files changed, 1845 insertions(+) create mode 100644 metricbeat/docs/modules/istio.asciidoc create mode 100644 metricbeat/docs/modules/istio/mesh.asciidoc create mode 100644 x-pack/metricbeat/module/istio/_meta/Dockerfile create mode 100644 x-pack/metricbeat/module/istio/_meta/config.reference.yml create mode 100644 x-pack/metricbeat/module/istio/_meta/config.yml create mode 100644 x-pack/metricbeat/module/istio/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/istio/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/istio/doc.go create mode 100644 x-pack/metricbeat/module/istio/docker-compose.yml create mode 100644 x-pack/metricbeat/module/istio/fields.go create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/data.json create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/docs.asciidoc create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/fields.yml create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/testdata/config.yml create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain create mode 100644 x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain-expected.json create mode 100644 x-pack/metricbeat/module/istio/mesh/mesh.go create mode 100644 x-pack/metricbeat/module/istio/mesh/mesh_test.go create mode 100644 x-pack/metricbeat/module/istio/module.yaml create mode 100644 x-pack/metricbeat/modules.d/istio.yml.disabled diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index c4e2170832e..dd07ca8a01e 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -177,6 +177,7 @@ TLS or Beats that accept connections over TLS and validate client certificates. - Add DynamoDB AWS Metricbeat light module {pull}15097[15097] - Release elb module as GA. {pull}15485[15485] - Add a `system/network_summary` metricset {pull}15196[15196] +- Add mesh metricset for Istio Metricbeat module{pull}15535[15535] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 431ce2a5799..e86c0975b17 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -42,6 +42,7 @@ grouped in the following categories: * <> * <> * <> +* <> * <> * <> * <> @@ -15861,6 +15862,319 @@ IBM MQ module +[[exported-fields-istio]] +== istio fields + +istio Module + + + +[float] +=== istio + +`istio` contains statistics that were read from Istio + + + +[float] +=== mesh + +Contains statistics related to the Istio mesh service + + + +*`istio.mesh.instance`*:: ++ +-- +The prometheus instance + + +type: text + +-- + +*`istio.mesh.job`*:: ++ +-- +The prometheus job + + +type: keyword + +-- + +*`istio.mesh.requests`*:: ++ +-- +Total requests handled by an Istio proxy + + +type: long + +-- + +*`istio.mesh.request.duration.ms.bucket.*`*:: ++ +-- +Request duration histogram buckets in milliseconds + + +type: object + +-- + +*`istio.mesh.request.duration.ms.sum`*:: ++ +-- +Requests duration, sum of durations in milliseconds + + +type: long + +format: duration + +-- + +*`istio.mesh.request.duration.ms.count`*:: ++ +-- +Requests duration, number of requests + + +type: long + +-- + +*`istio.mesh.request.size.bytes.bucket.*`*:: ++ +-- +Request Size histogram buckets + + +type: object + +-- + +*`istio.mesh.request.size.bytes.sum`*:: ++ +-- +Request Size histogram sum + + +type: long + +-- + +*`istio.mesh.request.size.bytes.count`*:: ++ +-- +Request Size histogram count + + +type: long + +-- + +*`istio.mesh.response.size.bytes.bucket.*`*:: ++ +-- +Request Size histogram buckets + + +type: object + +-- + +*`istio.mesh.response.size.bytes.sum`*:: ++ +-- +Request Size histogram sum + + +type: long + +-- + +*`istio.mesh.response.size.bytes.count`*:: ++ +-- +Request Size histogram count + + +type: long + +-- + +*`istio.mesh.reporter`*:: ++ +-- +Reporter identifies the reporter of the request. It is set to destination if report is from a server Istio proxy and source if report is from a client Istio proxy. + + +type: keyword + +-- + +*`istio.mesh.source.workload.name`*:: ++ +-- +This identifies the name of source workload which controls the source. + + +type: keyword + +-- + +*`istio.mesh.source.workload.namespace`*:: ++ +-- +This identifies the namespace of the source workload. + + +type: keyword + +-- + +*`istio.mesh.source.principal`*:: ++ +-- +This identifies the peer principal of the traffic source. It is set when peer authentication is used. + + +type: keyword + +-- + +*`istio.mesh.source.app`*:: ++ +-- +This identifies the source app based on app label of the source workload. + + +type: keyword + +-- + +*`istio.mesh.source.version`*:: ++ +-- +This identifies the version of the source workload. + + +type: keyword + +-- + +*`istio.mesh.destination.workload.name`*:: ++ +-- +This identifies the name of destination workload. + + +type: keyword + +-- + +*`istio.mesh.destination.workload.namespace`*:: ++ +-- +This identifies the namespace of the destination workload. + + +type: keyword + +-- + +*`istio.mesh.destination.principal`*:: ++ +-- +This identifies the peer principal of the traffic destination. It is set when peer authentication is used. + + +type: keyword + +-- + +*`istio.mesh.destination.app`*:: ++ +-- +This identifies the destination app based on app label of the destination workload.. + + +type: keyword + +-- + +*`istio.mesh.destination.version`*:: ++ +-- +This identifies the version of the destination workload. + + +type: keyword + +-- + +*`istio.mesh.destination.service.host`*:: ++ +-- +This identifies destination service host responsible for an incoming request. + + +type: keyword + +-- + +*`istio.mesh.destination.service.name`*:: ++ +-- +This identifies the destination service name. + + +type: keyword + +-- + +*`istio.mesh.destination.service.namespace`*:: ++ +-- +This identifies the namespace of destination service. + + +type: keyword + +-- + +*`istio.mesh.request.protocol`*:: ++ +-- +This identifies the protocol of the request. It is set to API protocol if provided, otherwise request or connection protocol. + + +type: keyword + +-- + +*`istio.mesh.response.code`*:: ++ +-- +This identifies the response code of the request. This label is present only on HTTP metrics. + + +type: long + +-- + +*`istio.mesh.connection.security.policy`*:: ++ +-- +This identifies the service authentication policy of the request. It is set to mutual_tls when Istio is used to make communication secure and report is from destination. It is set to unknown when report is from source since security policy cannot be properly populated. + + +type: keyword + +-- + [[exported-fields-jolokia]] == Jolokia fields diff --git a/metricbeat/docs/modules/istio.asciidoc b/metricbeat/docs/modules/istio.asciidoc new file mode 100644 index 00000000000..8d9cd5fe006 --- /dev/null +++ b/metricbeat/docs/modules/istio.asciidoc @@ -0,0 +1,45 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-module-istio]] +[role="xpack"] +== istio module + +beta[] + +This is the Istio module. The Istio module collects metrics from the +Istio https://istio.io/docs/tasks/observability/metrics/querying-metrics/#about-the-prometheus-add-on[prometheus exporters endpoints]. + +The default metricset is `mesh`. + +[float] +=== Compatibility + +The Istio module is tested with Istio 1.4 + + +[float] +=== Example configuration + +The istio module supports the standard configuration options that are described +in <>. Here is an example configuration: + +[source,yaml] +---- +metricbeat.modules: +- module: istio + metricsets: ["mesh"] + period: 10s + hosts: ["localhost:42422"] +---- + +[float] +=== Metricsets + +The following metricsets are available: + +* <> + +include::istio/mesh.asciidoc[] + diff --git a/metricbeat/docs/modules/istio/mesh.asciidoc b/metricbeat/docs/modules/istio/mesh.asciidoc new file mode 100644 index 00000000000..33ca6d19965 --- /dev/null +++ b/metricbeat/docs/modules/istio/mesh.asciidoc @@ -0,0 +1,23 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-istio-mesh]] +=== istio mesh metricset + +beta[] + +include::../../../../x-pack/metricbeat/module/istio/mesh/_meta/docs.asciidoc[] + + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../../x-pack/metricbeat/module/istio/mesh/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 45170d67d62..c07155249a3 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -103,6 +103,8 @@ This file is generated! See scripts/mage/docs_collector.go |<> |<> beta[] |image:./images/icon-yes.png[Prebuilt dashboards are available] | .1+| .1+| |<> beta[] +|<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | +.1+| .1+| |<> beta[] |<> |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | @@ -259,6 +261,7 @@ include::modules/graphite.asciidoc[] include::modules/haproxy.asciidoc[] include::modules/http.asciidoc[] include::modules/ibmmq.asciidoc[] +include::modules/istio.asciidoc[] include::modules/jolokia.asciidoc[] include::modules/kafka.asciidoc[] include::modules/kibana.asciidoc[] diff --git a/x-pack/metricbeat/include/list.go b/x-pack/metricbeat/include/list.go index f1d2485b128..e1e6943c058 100644 --- a/x-pack/metricbeat/include/list.go +++ b/x-pack/metricbeat/include/list.go @@ -29,6 +29,8 @@ import ( _ "github.com/elastic/beats/x-pack/metricbeat/module/googlecloud" _ "github.com/elastic/beats/x-pack/metricbeat/module/googlecloud/stackdriver" _ "github.com/elastic/beats/x-pack/metricbeat/module/ibmmq" + _ "github.com/elastic/beats/x-pack/metricbeat/module/istio" + _ "github.com/elastic/beats/x-pack/metricbeat/module/istio/mesh" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql/performance" _ "github.com/elastic/beats/x-pack/metricbeat/module/mssql/transaction_log" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index b3374802037..7eef53265a2 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -533,6 +533,12 @@ metricbeat.modules: } } +#-------------------------------- Istio Module -------------------------------- +- module: istio + metricsets: ["mesh"] + period: 10s + hosts: ["localhost:42422"] + #------------------------------- Jolokia Module ------------------------------- - module: jolokia #metricsets: ["jmx"] diff --git a/x-pack/metricbeat/module/istio/_meta/Dockerfile b/x-pack/metricbeat/module/istio/_meta/Dockerfile new file mode 100644 index 00000000000..e69de29bb2d diff --git a/x-pack/metricbeat/module/istio/_meta/config.reference.yml b/x-pack/metricbeat/module/istio/_meta/config.reference.yml new file mode 100644 index 00000000000..8fe23bdf2ad --- /dev/null +++ b/x-pack/metricbeat/module/istio/_meta/config.reference.yml @@ -0,0 +1,4 @@ +- module: istio + metricsets: ["mesh"] + period: 10s + hosts: ["localhost:42422"] diff --git a/x-pack/metricbeat/module/istio/_meta/config.yml b/x-pack/metricbeat/module/istio/_meta/config.yml new file mode 100644 index 00000000000..8fe23bdf2ad --- /dev/null +++ b/x-pack/metricbeat/module/istio/_meta/config.yml @@ -0,0 +1,4 @@ +- module: istio + metricsets: ["mesh"] + period: 10s + hosts: ["localhost:42422"] diff --git a/x-pack/metricbeat/module/istio/_meta/docs.asciidoc b/x-pack/metricbeat/module/istio/_meta/docs.asciidoc new file mode 100644 index 00000000000..24b262314e5 --- /dev/null +++ b/x-pack/metricbeat/module/istio/_meta/docs.asciidoc @@ -0,0 +1,9 @@ +This is the Istio module. The Istio module collects metrics from the +Istio https://istio.io/docs/tasks/observability/metrics/querying-metrics/#about-the-prometheus-add-on[prometheus exporters endpoints]. + +The default metricset is `mesh`. + +[float] +=== Compatibility + +The Istio module is tested with Istio 1.4 diff --git a/x-pack/metricbeat/module/istio/_meta/fields.yml b/x-pack/metricbeat/module/istio/_meta/fields.yml new file mode 100644 index 00000000000..62608c294b1 --- /dev/null +++ b/x-pack/metricbeat/module/istio/_meta/fields.yml @@ -0,0 +1,11 @@ +- key: istio + title: "istio" + description: > + istio Module + release: beta + fields: + - name: istio + type: group + description: > + `istio` contains statistics that were read from Istio + fields: diff --git a/x-pack/metricbeat/module/istio/doc.go b/x-pack/metricbeat/module/istio/doc.go new file mode 100644 index 00000000000..facfbe7beb1 --- /dev/null +++ b/x-pack/metricbeat/module/istio/doc.go @@ -0,0 +1,6 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// Package istio is a Metricbeat module that contains MetricSets. +package istio diff --git a/x-pack/metricbeat/module/istio/docker-compose.yml b/x-pack/metricbeat/module/istio/docker-compose.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/x-pack/metricbeat/module/istio/fields.go b/x-pack/metricbeat/module/istio/fields.go new file mode 100644 index 00000000000..a6cfe7f8317 --- /dev/null +++ b/x-pack/metricbeat/module/istio/fields.go @@ -0,0 +1,23 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. + +package istio + +import ( + "github.com/elastic/beats/libbeat/asset" +) + +func init() { + if err := asset.SetFields("metricbeat", "istio", asset.ModuleFieldsPri, AssetIstio); err != nil { + panic(err) + } +} + +// AssetIstio returns asset data. +// This is the base64 encoded gzipped contents of module/istio. +func AssetIstio() string { + return "eJzUmM9y27gPx+9+CkyPv2n1AD78Znb2sjnsTKebe0uRcMSaIrgEGNd9+h3qj6PIjOI49rqrQyamRHw/AEgQ0ifY4n4NlsXSCkCsOFzDh+73hxWAQdbRBrHk1/D/FQD0z8KfZJLDFUBEh4pxDTWKWgFsLDrD6+7RT+BVi0/m8yX7gGt4iJTCMFLQyNe3btY30ORFWc/AoiSPaQZplMAOI0JEZWATqYW7icgUYgrSIjeHwRLLAk++fi+wRHRK0IAQSIM9RicEjPHRapxYmAdrvOa8z4LnWZR/ZuaJXfCHzG4s4OfrvkEIkVqUBhOXrY/S36kuqm5xv6No3iU8tz1qRvw7IQsXhR35hzeqkih3MAqN8sahgXoPyg+5CpF+7JdYKpOiygJVy1Wd9Bal+l+Rj+rvqOcJ6Qe/nuvBlx4CRghoLAs9RNVCz5KTCK11zjJq8oZP9oVTe2qYNxRbJesDxVk+8GH6R+DUAm0OA+c7oSn5ecjfGespp09tjTGjFlfmnIztT6zqveANV8pf9icer5JTsd+wKM7jmQsssFwht3Oa5xIvgHEgz/jfS+4x9w2zewzzq6Q3UBSMlzvqvgwWwRr0YjcWuesNRqVcTfrf/YqHOwHLwCi5izDIYn1f6+1mmJTvd22O6toKjNPDC5Q3wJSixuIM7Sx6mc6oipHoTVQ7iltHylR59JINgOV5RLJCjsYAPyrDrrG66Vq/SK5/dIA7GZyDeqFpuih9JzMmdObGImyI1msblLsuY0CMcNAaQSWqzcbqkWWyAHcN+n6SStJkU3pYigyJcdknFcJ1vRkCrEKAWjEaIN/9cKpGd04WHjHycTtzYepB5FW+IuikHNxiZ06r0XJEXwS9xU48D/uX2JNToHdvzKmxq+/OadCXt2gxPa97cIvdurySXkUePgJUDXG51bkI9xRyUISsOLZdtnaY3+HyW6/1mlrrHw7tx8k+XL/qlPzIqm9j/LcLToH6lRUyhj5EEtJ07XozqCz3nb99vnt60m7y/4/WoPkIJA3GneXDTKCYmzOPuvN5nFXO0qHz12TKWTnjs07By1EHss6Rq92MvgZZhhCRc0tM3u1zgfrj/v4ztCjRai578eRuxahTtLKvAjmr91fueIZdMCv6vfRyQtskSbmv4rg/PPr+fzguugfUNkerbZMf7Xa+YfdCMXuNeOFYEoLkt552vheZzRp6HbY+/x0CN9Jr5T0J1N0KDRhdvhNS9z21Wv0TAAD///m4gQY=" +} diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/data.json b/x-pack/metricbeat/module/istio/mesh/_meta/data.json new file mode 100644 index 00000000000..fd43fc1aaca --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/data.json @@ -0,0 +1,112 @@ +{ + "@timestamp": "2019-03-01T08:05:34.853Z", + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "unknown" + } + }, + "destination": { + "app": "reviews", + "principal": "unknown", + "service": { + "host": "details.default.svc.cluster.local", + "name": "details", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "reviews-v1", + "namespace": "default" + } + }, + "reporter": "source", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "25": 1, + "250": 1, + "2500": 1, + "5": 0, + "50": 1, + "500": 1, + "5000": 1 + }, + "count": 1, + "sum": 5.815905 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 178 + } + } + }, + "source": { + "app": "productpage", + "principal": "unknown", + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/docs.asciidoc b/x-pack/metricbeat/module/istio/mesh/_meta/docs.asciidoc new file mode 100644 index 00000000000..19457b9f51e --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/docs.asciidoc @@ -0,0 +1 @@ +This is the mesh metricset of the module istio. This metricset collects all Mixer-generated metrics. diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/fields.yml b/x-pack/metricbeat/module/istio/mesh/_meta/fields.yml new file mode 100644 index 00000000000..3e7534b2c98 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/fields.yml @@ -0,0 +1,131 @@ +- name: mesh + type: group + description: > + Contains statistics related to the Istio mesh service + release: beta + fields: + - name: instance + type: text + description: > + The prometheus instance + - name: job + type: keyword + description: > + The prometheus job + - name: requests + type: long + description: > + Total requests handled by an Istio proxy + - name: request.duration.ms.bucket.* + type: object + object_type: long + description: > + Request duration histogram buckets in milliseconds + - name: request.duration.ms.sum + type: long + format: duration + description: > + Requests duration, sum of durations in milliseconds + - name: request.duration.ms.count + type: long + description: > + Requests duration, number of requests + - name: request.size.bytes.bucket.* + type: object + object_type: long + description: > + Request Size histogram buckets + - name: request.size.bytes.sum + type: long + description: > + Request Size histogram sum + - name: request.size.bytes.count + type: long + description: > + Request Size histogram count + + - name: response.size.bytes.bucket.* + type: object + object_type: long + description: > + Request Size histogram buckets + - name: response.size.bytes.sum + type: long + description: > + Request Size histogram sum + - name: response.size.bytes.count + type: long + description: > + Request Size histogram count + + - name: reporter + type: keyword + description: > + Reporter identifies the reporter of the request. It is set to destination if report is from a server Istio proxy and source if report is from a client Istio proxy. + - name: source.workload.name + type: keyword + description: > + This identifies the name of source workload which controls the source. + - name: source.workload.namespace + type: keyword + description: > + This identifies the namespace of the source workload. + - name: source.principal + type: keyword + description: > + This identifies the peer principal of the traffic source. It is set when peer authentication is used. + - name: source.app + type: keyword + description: > + This identifies the source app based on app label of the source workload. + - name: source.version + type: keyword + description: > + This identifies the version of the source workload. + + - name: destination.workload.name + type: keyword + description: > + This identifies the name of destination workload. + - name: destination.workload.namespace + type: keyword + description: > + This identifies the namespace of the destination workload. + - name: destination.principal + type: keyword + description: > + This identifies the peer principal of the traffic destination. It is set when peer authentication is used. + - name: destination.app + type: keyword + description: > + This identifies the destination app based on app label of the destination workload.. + - name: destination.version + type: keyword + description: > + This identifies the version of the destination workload. + + - name: destination.service.host + type: keyword + description: > + This identifies destination service host responsible for an incoming request. + - name: destination.service.name + type: keyword + description: > + This identifies the destination service name. + - name: destination.service.namespace + type: keyword + description: > + This identifies the namespace of destination service. + + - name: request.protocol + type: keyword + description: > + This identifies the protocol of the request. It is set to API protocol if provided, otherwise request or connection protocol. + - name: response.code + type: long + description: > + This identifies the response code of the request. This label is present only on HTTP metrics. + - name: connection.security.policy + type: keyword + description: > + This identifies the service authentication policy of the request. It is set to mutual_tls when Istio is used to make communication secure and report is from destination. It is set to unknown when report is from source since security policy cannot be properly populated. diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/testdata/config.yml b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/config.yml new file mode 100644 index 00000000000..ab6bf241654 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/config.yml @@ -0,0 +1,3 @@ +type: http +url: "/metrics" +suffix: plain diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain new file mode 100644 index 00000000000..c7e0ee303a8 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain @@ -0,0 +1,281 @@ +# HELP istio_request_bytes request_bytes +# TYPE istio_request_bytes histogram +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0 +istio_request_bytes_count{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 0 +istio_request_bytes_count{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0 +istio_request_bytes_count{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0 +istio_request_bytes_count{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 0 +istio_request_bytes_count{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0 +istio_request_bytes_count{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="10"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="100"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="10000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="100000"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+06"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+07"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+08"} 1 +istio_request_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="+Inf"} 1 +istio_request_bytes_sum{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 0 +istio_request_bytes_count{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 1 +# HELP istio_request_duration_seconds request_duration_seconds +# TYPE istio_request_duration_seconds histogram +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.005"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.01"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.025"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.05"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.25"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0.001650216 +istio_request_duration_seconds_count{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.01"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.025"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.05"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.1"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.25"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.5"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 0.656875796 +istio_request_duration_seconds_count{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.01"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.025"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.05"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.1"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.25"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.5"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0.604445345 +istio_request_duration_seconds_count{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.01"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.025"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.05"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.1"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.25"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.5"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0.605792291 +istio_request_duration_seconds_count{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.01"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.025"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.05"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.1"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.25"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="0.5"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 0.657740289 +istio_request_duration_seconds_count{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.01"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.025"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.05"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.25"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="0.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 0.005815905 +istio_request_duration_seconds_count{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.005"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.01"} 0 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.025"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.05"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.25"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="0.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="2.5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="5"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="10"} 1 +istio_request_duration_seconds_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="+Inf"} 1 +istio_request_duration_seconds_sum{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 0.016062491 +istio_request_duration_seconds_count{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 1 +# HELP istio_requests_total requests_total +# TYPE istio_requests_total counter +istio_requests_total{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_requests_total{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_requests_total{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_requests_total{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_requests_total{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_requests_total{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_requests_total{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 1 +# HELP istio_response_bytes response_bytes +# TYPE istio_response_bytes histogram +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 178 +istio_response_bytes_count{connection_security_policy="none",destination_app="details",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1000"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 5183 +istio_response_bytes_count{connection_security_policy="none",destination_app="productpage",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="productpage-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 379 +istio_response_bytes_count{connection_security_policy="none",destination_app="reviews",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v2",destination_workload="reviews-v2",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="destination",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 379 +istio_response_bytes_count{connection_security_policy="unknown",destination_app="details",destination_principal="unknown",destination_service="reviews.default.svc.cluster.local",destination_service_name="reviews",destination_service_namespace="default",destination_version="v1",destination_workload="details-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1000"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 5183 +istio_response_bytes_count{connection_security_policy="unknown",destination_app="ratings",destination_principal="unknown",destination_service="productpage.default.svc.cluster.local",destination_service_name="productpage",destination_service_namespace="default",destination_version="v1",destination_workload="ratings-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="istio-ingressgateway",source_principal="unknown",source_version="unknown",source_workload="istio-ingressgateway",source_workload_namespace="istio-system"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 178 +istio_response_bytes_count{connection_security_policy="unknown",destination_app="reviews",destination_principal="unknown",destination_service="details.default.svc.cluster.local",destination_service_name="details",destination_service_namespace="default",destination_version="v1",destination_workload="reviews-v1",destination_workload_namespace="default",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="productpage",source_principal="unknown",source_version="v1",source_workload="productpage-v1",source_workload_namespace="default"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="10"} 0 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="100"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="10000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="100000"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+06"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+07"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="1e+08"} 1 +istio_response_bytes_bucket{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default",le="+Inf"} 1 +istio_response_bytes_sum{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 48 +istio_response_bytes_count{connection_security_policy="unknown",destination_app="sidecarInjectorWebhook",destination_principal="unknown",destination_service="ratings.default.svc.cluster.local",destination_service_name="ratings",destination_service_namespace="default",destination_version="unknown",destination_workload="istio-sidecar-injector",destination_workload_namespace="istio-system",permissive_response_code="none",permissive_response_policyid="none",reporter="source",request_protocol="http",response_code="200",response_flags="-",source_app="reviews",source_principal="unknown",source_version="v2",source_workload="reviews-v2",source_workload_namespace="default"} 1 diff --git a/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain-expected.json b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain-expected.json new file mode 100644 index 00000000000..4b9c124c120 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/_meta/testdata/docs.plain-expected.json @@ -0,0 +1,779 @@ +[ + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "unknown" + } + }, + "destination": { + "app": "reviews", + "principal": "unknown", + "service": { + "host": "details.default.svc.cluster.local", + "name": "details", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "reviews-v1", + "namespace": "default" + } + }, + "reporter": "source", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "25": 1, + "250": 1, + "2500": 1, + "5": 0, + "50": 1, + "500": 1, + "5000": 1 + }, + "count": 1, + "sum": 5.815905 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 178 + } + } + }, + "source": { + "app": "productpage", + "principal": "unknown", + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "none" + } + }, + "destination": { + "app": "productpage", + "principal": "unknown", + "service": { + "host": "productpage.default.svc.cluster.local", + "name": "productpage", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + }, + "reporter": "destination", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "25": 0, + "250": 0, + "2500": 1, + "5": 0, + "50": 0, + "500": 0, + "5000": 1 + }, + "count": 1, + "sum": 656.875796 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 0, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 5183 + } + } + }, + "source": { + "app": "istio-ingressgateway", + "principal": "unknown", + "version": "unknown", + "workload": { + "name": "istio-ingressgateway", + "namespace": "istio-system" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "unknown" + } + }, + "destination": { + "app": "sidecarInjectorWebhook", + "principal": "unknown", + "service": { + "host": "ratings.default.svc.cluster.local", + "name": "ratings", + "namespace": "default" + }, + "version": "unknown", + "workload": { + "name": "istio-sidecar-injector", + "namespace": "istio-system" + } + }, + "reporter": "source", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 0, + "100": 1, + "1000": 1, + "10000": 1, + "25": 1, + "250": 1, + "2500": 1, + "5": 0, + "50": 1, + "500": 1, + "5000": 1 + }, + "count": 1, + "sum": 16.062491 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 48 + } + } + }, + "source": { + "app": "reviews", + "principal": "unknown", + "version": "v2", + "workload": { + "name": "reviews-v2", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "none" + } + }, + "destination": { + "app": "details", + "principal": "unknown", + "service": { + "host": "details.default.svc.cluster.local", + "name": "details", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "details-v1", + "namespace": "default" + } + }, + "reporter": "destination", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "25": 1, + "250": 1, + "2500": 1, + "5": 1, + "50": 1, + "500": 1, + "5000": 1 + }, + "count": 1, + "sum": 1.650216 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 178 + } + } + }, + "source": { + "app": "productpage", + "principal": "unknown", + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "none" + } + }, + "destination": { + "app": "reviews", + "principal": "unknown", + "service": { + "host": "reviews.default.svc.cluster.local", + "name": "reviews", + "namespace": "default" + }, + "version": "v2", + "workload": { + "name": "reviews-v2", + "namespace": "default" + } + }, + "reporter": "destination", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "25": 0, + "250": 0, + "2500": 1, + "5": 0, + "50": 0, + "500": 0, + "5000": 1 + }, + "count": 1, + "sum": 604.445345 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 379 + } + } + }, + "source": { + "app": "productpage", + "principal": "unknown", + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "unknown" + } + }, + "destination": { + "app": "details", + "principal": "unknown", + "service": { + "host": "reviews.default.svc.cluster.local", + "name": "reviews", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "details-v1", + "namespace": "default" + } + }, + "reporter": "source", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "25": 0, + "250": 0, + "2500": 1, + "5": 0, + "50": 0, + "500": 0, + "5000": 1 + }, + "count": 1, + "sum": 605.792291 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 379 + } + } + }, + "source": { + "app": "productpage", + "principal": "unknown", + "version": "v1", + "workload": { + "name": "productpage-v1", + "namespace": "default" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + }, + { + "event": { + "dataset": "istio.mesh", + "duration": 115000, + "module": "istio" + }, + "istio": { + "mesh": { + "connection": { + "security": { + "policy": "unknown" + } + }, + "destination": { + "app": "ratings", + "principal": "unknown", + "service": { + "host": "productpage.default.svc.cluster.local", + "name": "productpage", + "namespace": "default" + }, + "version": "v1", + "workload": { + "name": "ratings-v1", + "namespace": "default" + } + }, + "reporter": "source", + "request": { + "duration": { + "ms": { + "bucket": { + "+Inf": 1, + "10": 0, + "100": 0, + "1000": 1, + "10000": 1, + "25": 0, + "250": 0, + "2500": 1, + "5": 0, + "50": 0, + "500": 0, + "5000": 1 + }, + "count": 1, + "sum": 657.7402890000001 + } + }, + "protocol": "http", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 1, + "10": 1, + "100": 1, + "1000": 1, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 0 + } + } + }, + "requests": 1, + "response": { + "code": "200", + "size": { + "bytes": { + "bucket": { + "+Inf": 1, + "1": 0, + "10": 0, + "100": 0, + "1000": 0, + "10000": 1, + "100000": 1, + "1000000": 1, + "10000000": 1, + "100000000": 1 + }, + "count": 1, + "sum": 5183 + } + } + }, + "source": { + "app": "istio-ingressgateway", + "principal": "unknown", + "version": "unknown", + "workload": { + "name": "istio-ingressgateway", + "namespace": "istio-system" + } + } + } + }, + "metricset": { + "name": "mesh", + "period": 10000 + }, + "service": { + "address": "127.0.0.1:55555", + "type": "istio" + } + } +] \ No newline at end of file diff --git a/x-pack/metricbeat/module/istio/mesh/mesh.go b/x-pack/metricbeat/module/istio/mesh/mesh.go new file mode 100644 index 00000000000..e375d5ce728 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/mesh.go @@ -0,0 +1,60 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package mesh + +import ( + "github.com/elastic/beats/metricbeat/helper/prometheus" + "github.com/elastic/beats/metricbeat/mb" + "github.com/elastic/beats/metricbeat/mb/parse" +) + +const ( + defaultScheme = "http" + defaultPath = "/metrics" +) + +var ( + hostParser = parse.URLHostParserBuilder{ + DefaultScheme: defaultScheme, + DefaultPath: defaultPath, + }.Build() +) + +var mapping = &prometheus.MetricsMapping{ + Metrics: map[string]prometheus.MetricMap{ + "istio_requests_total": prometheus.Metric("requests"), + "istio_request_duration_seconds": prometheus.Metric("request.duration.ms", prometheus.OpMultiplyBuckets(1000)), + "istio_request_bytes": prometheus.Metric("request.size.bytes"), + "istio_response_bytes": prometheus.Metric("response.size.bytes"), + }, + + Labels: map[string]prometheus.LabelMap{ + "instance": prometheus.KeyLabel("instance"), + "job": prometheus.KeyLabel("job"), + "source_workload": prometheus.KeyLabel("source.workload.name"), + "source_workload_namespace": prometheus.KeyLabel("source.workload.namespace"), + "source_principal": prometheus.KeyLabel("source.principal"), + "source_app": prometheus.KeyLabel("source.app"), + "source_version": prometheus.KeyLabel("source.version"), + "destination_workload": prometheus.KeyLabel("destination.workload.name"), + "destination_workload_namespace": prometheus.KeyLabel("destination.workload.namespace"), + "destination_principal": prometheus.KeyLabel("destination.principal"), + "destination_app": prometheus.KeyLabel("destination.app"), + "destination_version": prometheus.KeyLabel("destination.version"), + "destination_service": prometheus.KeyLabel("destination.service.host"), + "destination_service_name": prometheus.KeyLabel("destination.service.name"), + "destination_service_namespace": prometheus.KeyLabel("destination.service.namespace"), + "reporter": prometheus.KeyLabel("reporter"), + "request_protocol": prometheus.KeyLabel("request.protocol"), + "response_code": prometheus.KeyLabel("response.code"), + "connection_security_policy": prometheus.KeyLabel("connection.security.policy"), + }, +} + +func init() { + mb.Registry.MustAddMetricSet("istio", "mesh", + prometheus.MetricSetBuilder(mapping), + mb.WithHostParser(hostParser)) +} diff --git a/x-pack/metricbeat/module/istio/mesh/mesh_test.go b/x-pack/metricbeat/module/istio/mesh/mesh_test.go new file mode 100644 index 00000000000..801a2330992 --- /dev/null +++ b/x-pack/metricbeat/module/istio/mesh/mesh_test.go @@ -0,0 +1,19 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build !integration + +package mesh + +import ( + "testing" + + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + + _ "github.com/elastic/beats/x-pack/metricbeat/module/istio" +) + +func TestData(t *testing.T) { + mbtest.TestDataFiles(t, "istio", "mesh") +} diff --git a/x-pack/metricbeat/module/istio/module.yaml b/x-pack/metricbeat/module/istio/module.yaml new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/x-pack/metricbeat/module/istio/module.yaml @@ -0,0 +1 @@ + diff --git a/x-pack/metricbeat/modules.d/istio.yml.disabled b/x-pack/metricbeat/modules.d/istio.yml.disabled new file mode 100644 index 00000000000..feeefdffe2b --- /dev/null +++ b/x-pack/metricbeat/modules.d/istio.yml.disabled @@ -0,0 +1,7 @@ +# Module: istio +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-module-istio.html + +- module: istio + metricsets: ["mesh"] + period: 10s + hosts: ["localhost:42422"] From ec2673e7abab19c1b0749b78a8e4960ef19812f5 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Mon, 20 Jan 2020 08:06:26 -0700 Subject: [PATCH 22/37] [Metricbeat] Fix changelog (#15681) * Fix changelog --- CHANGELOG.next.asciidoc | 87 ----------------------------------------- 1 file changed, 87 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index dd07ca8a01e..f02abf640f6 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -83,93 +83,6 @@ TLS or Beats that accept connections over TLS and validate client certificates. *Metricbeat* -- Add AWS SQS metricset. {pull}10684[10684] {issue}10053[10053] -- Add AWS s3_request metricset. {pull}10949[10949] {issue}10055[10055] -- Add s3_daily_storage metricset. {pull}10940[10940] {issue}10055[10055] -- Add `coredns` metricbeat module. {pull}10585[10585] -- Add SSL support for Metricbeat HTTP server. {pull}11482[11482] {issue}11457[11457] -- The `elasticsearch.index` metricset (with `xpack.enabled: true`) now collects `refresh.external_total_time_in_millis` fields from Elasticsearch. {pull}11616[11616] -- Allow module configurations to have variants {pull}9118[9118] -- Add `timeseries.instance` field calculation. {pull}10293[10293] -- Added new disk states and raid level to the system/raid metricset. {pull}11613[11613] -- Added `path_name` and `start_name` to service metricset on windows module {issue}8364[8364] {pull}11877[11877] -- Add check on object name in the counter path if the instance name is missing {issue}6528[6528] {pull}11878[11878] -- Add AWS cloudwatch metricset. {pull}11798[11798] {issue}11734[11734] -- Add `regions` in aws module config to specify target regions for querying cloudwatch metrics. {issue}11932[11932] {pull}11956[11956] -- Keep `etcd` followers members from reporting `leader` metricset events {pull}12004[12004] -- Add overview dashboard to Consul module {pull}10665[10665] -- New fields were added in the mysql/status metricset. {pull}12227[12227] -- Add Kubernetes metricset `proxy`. {pull}12312[12312] -- Add Kubernetes proxy dashboard to Kubernetes module {pull}12734[12734] -- Always report Pod UID in the `pod` metricset. {pull}12345[12345] -- Add Vsphere Virtual Machine operating system to `os` field in Vsphere virtualmachine module. {pull}12391[12391] -- Add validation for elasticsearch and kibana modules' metricsets when xpack.enabled is set to true. {pull}12386[12386] -- Add CockroachDB module. {pull}12467[12467] -- Add support for metricbeat modules based on existing modules (a.k.a. light modules) {issue}12270[12270] {pull}12465[12465] -- Add a system/entropy metricset {pull}12450[12450] -- Add kubernetes metricset `controllermanager` {pull}12409[12409] -- Add Kubernetes controller manager dashboard to Kubernetes module {pull}12744[12744] -- Allow redis URL format in redis hosts config. {pull}12408[12408] -- Add tags into ec2 metricset. {issue}[12263]12263 {pull}12372[12372] -- Add metrics to kubernetes apiserver metricset. {pull}12922[12922] -- Add kubernetes metricset `scheduler` {pull}12521[12521] -- Add Kubernetes scheduler dashboard to Kubernetes module {pull}12749[12749] -- Add `beat` module. {pull}12181[12181] {pull}12615[12615] -- Collect tags for cloudwatch metricset in aws module. {issue}[12263]12263 {pull}12480[12480] -- Add AWS RDS metricset. {pull}11620[11620] {issue}10054[10054] -- Add Oracle Module {pull}11890[11890] -- Add Oracle Tablespaces Dashboard {pull}12736[12736] -- Collect client provided name for rabbitmq connection. {issue}12851[12851] {pull}12852[12852] -- Add support to load default aws config file to get credentials. {pull}12727[12727] {issue}12708[12708] -- Add statistic option into cloudwatch metricset. {issue}12370[12370] {pull}12840[12840] -- Add support for kubernetes cronjobs {pull}13001[13001] -- Add cgroup memory stats to docker/memory metricset {pull}12916[12916] -- Add AWS elb metricset. {pull}12952[12952] {issue}11701[11701] -- Add AWS ebs metricset. {pull}13167[13167] {issue}11699[11699] -- Add `metricset.period` field with the configured fetching period. {pull}13242[13242] {issue}12616[12616] -- Add rate metrics for ec2 metricset. {pull}13203[13203] -- Add refresh list of perf counters at every fetch {issue}13091[13091] -- Add Performance metricset to Oracle module {pull}12547[12547] -- Add proc/vmstat data to the system/memory metricset on linux {pull}13322[13322] -- Use DefaultMetaGeneratorConfig in MetadataEnrichers to initialize configurations {pull}13414[13414] -- Add module for statsd. {pull}13109[13109] -- Add support for NATS version 2. {pull}13601[13601] -- Add `docker.cpu.*.norm.pct` metrics for `cpu` metricset of Docker Metricbeat module. {pull}13695[13695] -- Add `instance` label by default when using Prometheus collector. {pull}13737[13737] -- Add azure module. {pull}13196[13196] {pull}13859[13859] {pull}13988[13988] -- Add Apache Tomcat module {pull}13491[13491] -- Add ECS `container.id` and `container.runtime` to kubernetes `state_container` metricset. {pull}13884[13884] -- Add `job` label by default when using Prometheus collector. {pull}13878[13878] -- Add `state_resourcequota` metricset for Kubernetes module. {pull}13693[13693] -- Add tags filter in ec2 metricset. {pull}13872[13872] {issue}13145[13145] -- Add cloud.account.id and cloud.account.name into events from aws module. {issue}13551[13551] {pull}13558[13558] -- Add `metrics_path` as known hint for autodiscovery {pull}13996[13996] -- Leverage KUBECONFIG when creating k8s client. {pull}13916[13916] -- Add ability to filter by tags for cloudwatch metricset. {pull}13758[13758] {issue}13145[13145] -- Release cloudwatch, s3_daily_storage, s3_request, sqs and rds metricset as GA. {pull}14114[14114] {issue}14059[14059] -- Add Oracle overview dashboard {pull}14021[14021] -- Release CoreDNS module as GA. {pull}14308[14308] -- Release CouchDB module as GA. {pull}14300[14300] -- Add `elasticsearch/enrich` metricset. {pull}14243[14243] {issue}14221[14221] -- Add support for Application ELB and Network ELB. {pull}14123[14123] {issue}13538[13538] {issue}13539[13539] -- Release aws ebs metricset as GA. {pull}14312[14312] {issue}14060[14060] -- Add `connection.state` field for RabbitMQ module. {pull}13981[13981] -- Add more TCP states to Metricbeat system socket_summary. {pull}14347[14347] -- Add Kafka JMX metricsets. {pull}14330[14330] -- Add metrics to envoyproxy server metricset and support for envoy proxy 1.12. {pull}14416[14416] {issue}13642[13642] -- Release kubernetes modules `controllermanager`, `scheduler`, `proxy`, `state_cronjob` and `state_resourcequota` as GA. {pull}14584[14584] -- Add module for ActiveMQ. {pull}14580[14580] -- Enable script processor. {pull}14711[14711] -- Enable wildcard for cloudwatch metricset namespace. {pull}14971[14971] {issue}14965[14965] -- Add `kube-state-metrics` `state_service` metrics for kubernetes module. {pull}14794[14794] -- Add `kube-state-metrics` `state_persistentvolume` metrics for kubernetes module. {pull}14859[14859] -- Add `kube-state-metrics` `state_persistentvolumeclaim` metrics for kubernetes module. {pull}15066[15066] -- Add usage metricset in aws modules. {pull}14925[14925] {issue}14935[14935] -- Add billing metricset in aws modules. {pull}14801[14801] {issue}14934[14934] -- Add AWS SNS metricset. {pull}14946[14946] -- Add overview dashboard for AWS SNS module {pull}14977[14977] -- Add `index` option to all modules to specify a module-specific output index. {pull}15100[15100] -- Add a `system/service` metricset for systemd data. {pull}14206[14206] - Add lambda metricset in aws module. {pull}15260[15260] - Expand data for the `system/memory` metricset {pull}15492[15492] - Add azure `storage` metricset in order to retrieve metric values for storage accounts. {issue}14548[14548] {pull}15342[15342] From 0df3a9f37dc293a612a08268effb911080be4aa3 Mon Sep 17 00:00:00 2001 From: Ivan Fernandez Calvo Date: Mon, 20 Jan 2020 16:56:49 +0100 Subject: [PATCH 23/37] ci: use APM pipeline library (#15636) it uses APM pipeline library configured in the instance --- Jenkinsfile | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 89753eec3e2..3eb0d1ff7dd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,11 +1,6 @@ #!/usr/bin/env groovy -library identifier: 'apm@master', -retriever: modernSCM( - [$class: 'GitSCMSource', - credentialsId: 'f94e9298-83ae-417e-ba91-85c279771570', - id: '37cf2c00-2cc7-482e-8c62-7bbffef475e2', - remote: 'git@github.com:elastic/apm-pipeline-library.git']) +@Library('apm@current') _ pipeline { agent { label 'ubuntu && immutable' } @@ -36,12 +31,7 @@ pipeline { stage('Checkout') { options { skipDefaultCheckout() } steps { - //TODO we need to configure the library in Jenkins to use privileged methods. - //gitCheckout(basedir: "${BASE_DIR}") - dir("${BASE_DIR}"){ - checkout scm - githubEnv() - } + gitCheckout(basedir: "${BASE_DIR}") stash allowEmpty: true, name: 'source', useDefaultExcludes: false script { env.GO_VERSION = readFile("${BASE_DIR}/.go-version").trim() From 1b0ea01c8dce179b251e64b5260b4b692e2150e4 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 20 Jan 2020 21:33:35 +0100 Subject: [PATCH 24/37] AWS Lambda: downgrade Kibana dashboard (#15682) * AWS Lambda: downgrade Kibana dashboard * Downgrade other AWS dashboards * Log command error if setup dashboards fails * Another downgrade --- metricbeat/tests/system/test_base.py | 2 +- .../Metricbeat-aws-billing-overview.json | 10 +++---- .../Metricbeat-aws-dynamodb-overview.json | 24 ++++++++--------- .../Metricbeat-aws-ebs-overview.json | 22 ++++++++-------- .../Metricbeat-aws-elb-overview.json | 20 +++++++------- .../Metricbeat-aws-lambda-overview.json | 26 +++++++++---------- .../Metricbeat-aws-rds-overview.json | 18 ++++++------- .../dashboard/Metricbeat-aws-s3-overview.json | 16 ++++++------ .../Metricbeat-aws-sns-overview.json | 24 ++++++++--------- .../Metricbeat-aws-usage-overview.json | 16 ++++++------ 10 files changed, 89 insertions(+), 89 deletions(-) diff --git a/metricbeat/tests/system/test_base.py b/metricbeat/tests/system/test_base.py index 59fb16c7c86..5e52872bb7b 100644 --- a/metricbeat/tests/system/test_base.py +++ b/metricbeat/tests/system/test_base.py @@ -71,7 +71,7 @@ def test_dashboards(self): ) exit_code = self.run_beat(extra_args=["setup", "--dashboards"]) - assert exit_code == 0 + assert exit_code == 0, 'Error output: ' + self.get_log() assert self.log_contains("Kibana dashboards successfully loaded.") @unittest.skipUnless(INTEGRATION_TESTS, "integration test") diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json index 66cc4381c9a..be1b2935b02 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-billing-overview.json @@ -32,7 +32,7 @@ "panelIndex": "89dccfe8-a25e-44ea-afdb-ff01ab1f05d6", "panelRefName": "panel_0", "title": "AWS Account Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -48,7 +48,7 @@ "panelIndex": "26670498-b079-4447-bbc8-e4ca8215898c", "panelRefName": "panel_1", "title": "Estimated Billing Chart", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -64,7 +64,7 @@ "panelIndex": "221aab02-2747-4d84-9dde-028ccd51bdce", "panelRefName": "panel_2", "title": "Total Estimated Charges", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -80,7 +80,7 @@ "panelIndex": "21e91e6b-0ff0-42ba-9132-6f30c5c6bbb7", "panelRefName": "panel_3", "title": "Top 5 Estimated Billing Per Service Name", - "version": "7.5.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -480,5 +480,5 @@ "version": "WzU2LDFd" } ], - "version": "7.5.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-dynamodb-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-dynamodb-overview.json index 7f58be85cea..c414bc2ea05 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-dynamodb-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-dynamodb-overview.json @@ -29,7 +29,7 @@ }, "panelIndex": "9642fcd0-464b-46ea-815c-cd2d9efc056d", "panelRefName": "panel_0", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -42,7 +42,7 @@ }, "panelIndex": "03807c37-c9dc-4b41-80ce-e28a13eb66e2", "panelRefName": "panel_1", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -55,7 +55,7 @@ }, "panelIndex": "18810035-5e91-409a-98d7-c03166e1f9b3", "panelRefName": "panel_2", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -68,7 +68,7 @@ }, "panelIndex": "60e6e6e4-3237-430e-80fc-63fe9b718a7e", "panelRefName": "panel_3", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -81,7 +81,7 @@ }, "panelIndex": "5e5d6509-2889-4383-bef4-9c2da0e759c6", "panelRefName": "panel_4", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -94,7 +94,7 @@ }, "panelIndex": "2db371a7-20c5-460a-a2f7-06b5b03d7b34", "panelRefName": "panel_5", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -107,7 +107,7 @@ }, "panelIndex": "1cd72292-ecba-4008-bb3c-e76c7fb6b4f4", "panelRefName": "panel_6", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -120,7 +120,7 @@ }, "panelIndex": "cea56791-2602-4079-977b-7d088727872c", "panelRefName": "panel_7", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -133,7 +133,7 @@ }, "panelIndex": "fe509a4d-700b-4092-9aae-ce14e8de103e", "panelRefName": "panel_8", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -146,7 +146,7 @@ }, "panelIndex": "3d6b1fa0-746f-40ed-8fcc-ae89013f632b", "panelRefName": "panel_9", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -159,7 +159,7 @@ }, "panelIndex": "0f9a5223-3c63-405c-a5c4-ea15416bad4a", "panelRefName": "panel_10", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -1852,5 +1852,5 @@ "version": "WzUxMzMsMV0=" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-ebs-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-ebs-overview.json index 4ff1c55910b..8c0ff27c60f 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-ebs-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-ebs-overview.json @@ -30,7 +30,7 @@ "panelIndex": "1", "panelRefName": "panel_0", "title": "Volume Write Ops", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -44,7 +44,7 @@ "panelIndex": "2", "panelRefName": "panel_1", "title": "Volume Read Ops", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -58,7 +58,7 @@ "panelIndex": "3", "panelRefName": "panel_2", "title": "Volume Write Bytes", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -72,7 +72,7 @@ "panelIndex": "4", "panelRefName": "panel_3", "title": "Volume Read Bytes", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -86,7 +86,7 @@ "panelIndex": "5", "panelRefName": "panel_4", "title": "Volume Queue Length", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -100,7 +100,7 @@ "panelIndex": "6", "panelRefName": "panel_5", "title": "Volume Total Write Time", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -114,7 +114,7 @@ "panelIndex": "7", "panelRefName": "panel_6", "title": "Volume Total Read Time", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -128,7 +128,7 @@ "panelIndex": "8", "panelRefName": "panel_7", "title": "Volume Idle Time", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -142,7 +142,7 @@ "panelIndex": "9", "panelRefName": "panel_8", "title": "EBS Volume ID Filter", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -155,7 +155,7 @@ }, "panelIndex": "10", "panelRefName": "panel_9", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -916,5 +916,5 @@ "version": "WzU2NTQsN10=" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-elb-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-elb-overview.json index cadca10e4db..6164c11bed4 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-elb-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-elb-overview.json @@ -30,7 +30,7 @@ "panelIndex": "2", "panelRefName": "panel_0", "title": "HTTP 5XX Errors", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -44,7 +44,7 @@ "panelIndex": "3", "panelRefName": "panel_1", "title": "Request Count", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -58,7 +58,7 @@ "panelIndex": "4", "panelRefName": "panel_2", "title": "Unhealthy Host Count", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -72,7 +72,7 @@ "panelIndex": "5", "panelRefName": "panel_3", "title": "Healthy Host Count", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -86,7 +86,7 @@ "panelIndex": "6", "panelRefName": "panel_4", "title": "Latency in Seconds", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -100,7 +100,7 @@ "panelIndex": "7", "panelRefName": "panel_5", "title": "HTTP Backend 4XX Errors", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -114,7 +114,7 @@ "panelIndex": "8", "panelRefName": "panel_6", "title": "Backend Connection Errors", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -127,7 +127,7 @@ }, "panelIndex": "9", "panelRefName": "panel_7", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -141,7 +141,7 @@ "panelIndex": "10", "panelRefName": "panel_8", "title": "HTTP Backend 2XX", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -1006,5 +1006,5 @@ "version": "WzI0MTIsN10=" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json index 1fd20d1dea6..ecee23ca080 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-lambda-overview.json @@ -32,7 +32,7 @@ "panelIndex": "8f2d1b8f-fef3-4a9a-9cc8-7f0e2c65e35a", "panelRefName": "panel_0", "title": "AWS Account Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -48,7 +48,7 @@ "panelIndex": "443a9699-3451-44f7-8415-99a16c3f45b3", "panelRefName": "panel_1", "title": "Top Errors", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -64,7 +64,7 @@ "panelIndex": "60a16bf0-2979-467a-b30e-05ea29547b41", "panelRefName": "panel_2", "title": "AWS Region Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -80,7 +80,7 @@ "panelIndex": "349ef0d1-fea1-4b91-b95d-7a668914e10b", "panelRefName": "panel_3", "title": "Lambda Function Duration in Milliseconds", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -96,7 +96,7 @@ "panelIndex": "048b1577-5aed-48e5-8f90-147aa3d56c1a", "panelRefName": "panel_4", "title": "Top Invoked Lambda Functions", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -112,7 +112,7 @@ "panelIndex": "4c8e471c-45da-47be-a866-c5bfc6d28a05", "panelRefName": "panel_5", "title": "Top Throttled Lambda Functions", - "version": "7.5.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -204,7 +204,7 @@ }, "id": "deab0260-2981-11e9-86eb-a3a07a77f530", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [ { @@ -310,7 +310,7 @@ }, "id": "4bf0a740-28d1-11ea-ba6c-49a884eb104f", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [], "type": "visualization", @@ -362,7 +362,7 @@ }, "id": "b5308940-7347-11e9-816b-07687310a99a", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [ { @@ -450,7 +450,7 @@ }, "id": "39dfc8d0-28cf-11ea-ba6c-49a884eb104f", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [], "type": "visualization", @@ -542,7 +542,7 @@ }, "id": "1f3f00c0-28d1-11ea-ba6c-49a884eb104f", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [], "type": "visualization", @@ -642,7 +642,7 @@ }, "id": "915bcd50-28d1-11ea-ba6c-49a884eb104f", "migrationVersion": { - "visualization": "7.4.2" + "visualization": "7.3.0" }, "references": [], "type": "visualization", @@ -650,5 +650,5 @@ "version": "WzI2OTIsM10=" } ], - "version": "7.5.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-rds-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-rds-overview.json index 5d8633eb2e1..367104574b6 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-rds-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-rds-overview.json @@ -32,7 +32,7 @@ "panelIndex": "1", "panelRefName": "panel_0", "title": "Database Connections", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -48,7 +48,7 @@ "panelIndex": "3", "panelRefName": "panel_1", "title": "Insert Latency in Milliseconds", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -64,7 +64,7 @@ "panelIndex": "4", "panelRefName": "panel_2", "title": "Select Latency in Milliseconds", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -80,7 +80,7 @@ "panelIndex": "5", "panelRefName": "panel_3", "title": "Transaction Blocked", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -93,7 +93,7 @@ }, "panelIndex": "6", "panelRefName": "panel_4", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -109,7 +109,7 @@ "panelIndex": "7", "panelRefName": "panel_5", "title": "Insert Throughput in Count/Second", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -125,7 +125,7 @@ "panelIndex": "8", "panelRefName": "panel_6", "title": "Select Throughput in Count/Second", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -141,7 +141,7 @@ "panelIndex": "132653bc-2669-4e8c-b536-06c680e9acf0", "panelRefName": "panel_7", "title": "Disk Queue Depth", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -843,5 +843,5 @@ "version": "WzExNTk1LDhd" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-s3-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-s3-overview.json index d69c483c42a..5701193ce16 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-s3-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-s3-overview.json @@ -29,7 +29,7 @@ }, "panelIndex": "1", "panelRefName": "panel_0", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -42,7 +42,7 @@ }, "panelIndex": "2", "panelRefName": "panel_1", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -55,7 +55,7 @@ }, "panelIndex": "3", "panelRefName": "panel_2", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -68,7 +68,7 @@ }, "panelIndex": "4", "panelRefName": "panel_3", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -81,7 +81,7 @@ }, "panelIndex": "5", "panelRefName": "panel_4", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -94,7 +94,7 @@ }, "panelIndex": "6", "panelRefName": "panel_5", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -107,7 +107,7 @@ }, "panelIndex": "7", "panelRefName": "panel_6", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -713,5 +713,5 @@ "version": "Wzc0NDAsN10=" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-sns-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-sns-overview.json index ea5cf1fe0be..e3d9af42885 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-sns-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-sns-overview.json @@ -55,7 +55,7 @@ }, "panelIndex": "3b9b0cee-b175-4268-8c5b-4ce869a09caf", "panelRefName": "panel_0", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -71,7 +71,7 @@ "panelIndex": "5f0d72c5-0f28-449f-9c93-3b4074f068f7", "panelRefName": "panel_1", "title": "SNS Messages and Notifications", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": {}, @@ -84,7 +84,7 @@ }, "panelIndex": "5a9d5f2f-b075-4892-8188-c6e808a1163d", "panelRefName": "panel_2", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -100,7 +100,7 @@ "panelIndex": "c6d5a54d-61a4-470b-8769-c5b6d6ab6c0f", "panelRefName": "panel_3", "title": "SNS Publish Size", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -116,7 +116,7 @@ "panelIndex": "0684c25d-34e8-425e-9069-dd8364e6325b", "panelRefName": "panel_4", "title": "SNS Notifications Filtered Out", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -132,7 +132,7 @@ "panelIndex": "72e987da-9a49-4dd4-99c4-4acbc49a0e0b", "panelRefName": "panel_5", "title": "SNS Notifications Filtered Out Invalid Attributes", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -148,7 +148,7 @@ "panelIndex": "923bd4cd-d8fe-47b5-afcf-577bf2c5987c", "panelRefName": "panel_6", "title": "SNS Notifications Filtered Out No Message Attributes", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -164,7 +164,7 @@ "panelIndex": "f176153f-4588-42f9-a7bb-3015909d5610", "panelRefName": "panel_7", "title": "SNS Notifications Failed to Redrive to DLQ", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -180,7 +180,7 @@ "panelIndex": "f3c5915b-6848-4950-afca-53653d13d6af", "panelRefName": "panel_8", "title": "SNS SMS Success Rate", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -196,7 +196,7 @@ "panelIndex": "3b3cc747-b57c-44e0-a18c-77155072bee4", "panelRefName": "panel_9", "title": "SNS Notifications Redriven To DLQ", - "version": "7.4.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -212,7 +212,7 @@ "panelIndex": "ee130150-c1de-465b-8a8e-013f466528bf", "panelRefName": "panel_10", "title": "SNS SMS Month To Date Spent USD", - "version": "7.4.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -1122,5 +1122,5 @@ "version": "WzU1MywxXQ==" } ], - "version": "7.4.0" + "version": "7.3.0" } diff --git a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-usage-overview.json b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-usage-overview.json index da51dceb5cf..2f96fae244b 100644 --- a/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-usage-overview.json +++ b/x-pack/metricbeat/module/aws/_meta/kibana/7/dashboard/Metricbeat-aws-usage-overview.json @@ -32,7 +32,7 @@ "panelIndex": "2ea7bd59-d748-4e4a-889d-f7e2ca1cfe36", "panelRefName": "panel_0", "title": "Region Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -48,7 +48,7 @@ "panelIndex": "00c2b1f6-3367-4b6f-ac01-7e48b76c262a", "panelRefName": "panel_1", "title": "Usage Resource Count", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -64,7 +64,7 @@ "panelIndex": "fecfe5d4-ef1c-4f38-954a-a2506d72bc5b", "panelRefName": "panel_2", "title": "Usage API Call Count", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -80,7 +80,7 @@ "panelIndex": "69ce7461-36ad-4e7c-b541-c6a1601bf089", "panelRefName": "panel_3", "title": "AWS Account Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -96,7 +96,7 @@ "panelIndex": "62e86407-6ae3-47d3-9136-dd61bdf3267a", "panelRefName": "panel_4", "title": "AWS Service Filter", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -112,7 +112,7 @@ "panelIndex": "196a044c-5c20-4417-8aa0-f60fc502e46c", "panelRefName": "panel_5", "title": "Usage Resource Count Per Service", - "version": "7.5.0" + "version": "7.3.0" }, { "embeddableConfig": { @@ -128,7 +128,7 @@ "panelIndex": "022941b7-01a1-4570-86e9-d03451d4e102", "panelRefName": "panel_6", "title": "Usage API Call Count Per Service", - "version": "7.5.0" + "version": "7.3.0" } ], "timeRestore": false, @@ -819,5 +819,5 @@ "version": "WzU4OSw0XQ==" } ], - "version": "7.5.0" + "version": "7.3.0" } From d0a80a2aa29c46e469c8659d9f43ffd8dae7aac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 21 Jan 2020 11:18:39 +0100 Subject: [PATCH 25/37] Use github.com/godror/godror instead of goracle.v2 (#15683) From the README of goracle: > Goracle is deprecated because of naming (trademark) issues. From now on we are using github.com/godror/godror instead. --- NOTICE.txt | 504 +++++++------- .../godror/godror}/CHANGELOG.md | 99 ++- .../godror/godror}/LICENSE.md | 19 +- .../godror/godror}/NOTES.md | 0 .../godror/godror}/README.md | 62 +- .../godror/godror}/conn.go | 257 +++++-- .../godror/godror/contrib/free.db/cwallet.sso | Bin 0 -> 6733 bytes .../godror/godror/contrib/free.db/env.sh | 5 + .../godror/godror/contrib/free.db/ewallet.p12 | Bin 0 -> 6688 bytes .../godror/contrib/free.db/keystore.jks | Bin 0 -> 3241 bytes .../godror/contrib/free.db/ojdbc.properties | 1 + .../godror/godror/contrib/free.db/sqlnet.ora | 2 + .../godror/contrib/free.db/tnsnames.ora | 6 + .../godror/contrib/free.db/truststore.jks | Bin 0 -> 3335 bytes .../contrib/oracle-instant-client/Dockerfile | 14 + .../contrib/oracle-instant-client/README.md | 0 .../godror}/contrib/oracle-xe-18c/Dockerfile | 0 .../godror}/contrib/oracle-xe-18c/README.md | 0 .../godror/godror}/data.go | 213 +++++- .../godror/godror}/drv.go | 372 +++++++--- vendor/github.com/godror/godror/drv_posix.go | 11 + vendor/github.com/godror/godror/go.mod | 12 + vendor/github.com/godror/godror/go.sum | 14 + .../godror/godror}/lob.go | 60 +- .../godror/godror}/obj.go | 272 +++++--- .../godror/godror}/odpi/CONTRIBUTING.md | 0 .../godror/godror}/odpi/LICENSE.md | 1 - .../godror/godror}/odpi/README.md | 3 +- .../godror/godror}/odpi/embed/README.md | 1 - .../godror/godror}/odpi/embed/dpi.c | 2 +- .../godror/godror}/odpi/include/dpi.h | 65 +- .../godror/godror}/odpi/src/dpiConn.c | 249 ++++--- .../godror/godror}/odpi/src/dpiContext.c | 43 +- .../godror/godror}/odpi/src/dpiData.c | 83 ++- .../godror/godror}/odpi/src/dpiDebug.c | 1 - .../godror/godror}/odpi/src/dpiDeqOptions.c | 9 +- .../godror/godror}/odpi/src/dpiEnqOptions.c | 5 +- .../godror/godror}/odpi/src/dpiEnv.c | 107 ++- .../godror/godror}/odpi/src/dpiError.c | 214 +++--- .../godror}/odpi/src/dpiErrorMessages.h | 5 +- .../godror/godror}/odpi/src/dpiGen.c | 18 +- .../godror/godror}/odpi/src/dpiGlobal.c | 1 - .../godror/godror}/odpi/src/dpiHandleList.c | 3 +- .../godror/godror}/odpi/src/dpiHandlePool.c | 9 +- .../godror/godror}/odpi/src/dpiImpl.h | 182 ++++- .../godror/godror}/odpi/src/dpiLob.c | 38 +- .../godror/godror}/odpi/src/dpiMsgProps.c | 185 +++-- .../godror/godror}/odpi/src/dpiObject.c | 168 +++-- .../godror/godror}/odpi/src/dpiObjectAttr.c | 3 +- .../godror/godror}/odpi/src/dpiObjectType.c | 5 +- .../godror/godror}/odpi/src/dpiOci.c | 653 +++++++++++++----- .../godror/godror}/odpi/src/dpiOracleType.c | 10 +- .../godror/godror}/odpi/src/dpiPool.c | 22 +- .../godror/godror/odpi/src/dpiQueue.c | 560 +++++++++++++++ .../godror/godror}/odpi/src/dpiRowid.c | 4 +- .../godror/godror}/odpi/src/dpiSodaColl.c | 129 +++- .../godror}/odpi/src/dpiSodaCollCursor.c | 3 +- .../godror/godror}/odpi/src/dpiSodaDb.c | 5 +- .../godror/godror}/odpi/src/dpiSodaDoc.c | 3 +- .../godror}/odpi/src/dpiSodaDocCursor.c | 3 +- .../godror/godror}/odpi/src/dpiStmt.c | 133 +++- .../godror/godror}/odpi/src/dpiSubscr.c | 57 +- .../godror/godror}/odpi/src/dpiUtils.c | 3 +- .../godror/godror}/odpi/src/dpiVar.c | 52 +- .../godror/godror}/orahlp.go | 66 +- vendor/github.com/godror/godror/queue.go | 639 +++++++++++++++++ .../godror/godror}/rows.go | 70 +- vendor/github.com/godror/godror/sid/sid.go | 531 ++++++++++++++ .../godror/godror}/stmt.go | 289 +++++--- .../godror/godror}/subscr.c | 0 .../godror/godror}/subscr.go | 32 +- .../godror/godror}/version.go | 10 +- vendor/golang.org/x/xerrors/LICENSE | 27 + vendor/golang.org/x/xerrors/PATENTS | 22 + vendor/golang.org/x/xerrors/README | 2 + vendor/golang.org/x/xerrors/adaptor.go | 193 ++++++ vendor/golang.org/x/xerrors/codereview.cfg | 1 + vendor/golang.org/x/xerrors/doc.go | 22 + vendor/golang.org/x/xerrors/errors.go | 33 + vendor/golang.org/x/xerrors/fmt.go | 187 +++++ vendor/golang.org/x/xerrors/format.go | 34 + vendor/golang.org/x/xerrors/frame.go | 56 ++ vendor/golang.org/x/xerrors/go.mod | 3 + .../golang.org/x/xerrors/internal/internal.go | 8 + vendor/golang.org/x/xerrors/wrap.go | 106 +++ .../contrib/oracle-instant-client/Dockerfile | 24 - vendor/gopkg.in/goracle.v2/drv_10.go | 106 --- vendor/gopkg.in/goracle.v2/drv_posix.go | 21 - vendor/gopkg.in/goracle.v2/go.mod | 10 - vendor/gopkg.in/goracle.v2/go.sum | 14 - vendor/gopkg.in/goracle.v2/stmt_go09.go | 52 -- vendor/gopkg.in/goracle.v2/stmt_go10.go | 78 --- vendor/vendor.json | 51 +- x-pack/metricbeat/module/oracle/connection.go | 6 +- .../oracle/performance/metricset_test.go | 2 +- .../oracle/tablespace/metricset_test.go | 2 +- x-pack/metricbeat/module/oracle/testing.go | 4 +- 97 files changed, 5881 insertions(+), 1780 deletions(-) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/CHANGELOG.md (69%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/LICENSE.md (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/NOTES.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/README.md (72%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/conn.go (74%) create mode 100644 vendor/github.com/godror/godror/contrib/free.db/cwallet.sso create mode 100644 vendor/github.com/godror/godror/contrib/free.db/env.sh create mode 100644 vendor/github.com/godror/godror/contrib/free.db/ewallet.p12 create mode 100644 vendor/github.com/godror/godror/contrib/free.db/keystore.jks create mode 100644 vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties create mode 100644 vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora create mode 100644 vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora create mode 100644 vendor/github.com/godror/godror/contrib/free.db/truststore.jks create mode 100644 vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-instant-client/README.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-xe-18c/Dockerfile (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-xe-18c/README.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/data.go (52%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/drv.go (67%) create mode 100644 vendor/github.com/godror/godror/drv_posix.go create mode 100644 vendor/github.com/godror/godror/go.mod create mode 100644 vendor/github.com/godror/godror/go.sum rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/lob.go (77%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/obj.go (62%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/CONTRIBUTING.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/LICENSE.md (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/README.md (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/embed/README.md (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/embed/dpi.c (98%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/include/dpi.h (96%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiConn.c (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiContext.c (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiData.c (89%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiDebug.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiDeqOptions.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiEnqOptions.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiEnv.c (68%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiError.c (85%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiErrorMessages.h (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiGen.c (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiGlobal.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiHandleList.c (98%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiHandlePool.c (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiImpl.h (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiLob.c (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiMsgProps.c (72%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObject.c (87%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObjectAttr.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObjectType.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiOci.c (85%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiOracleType.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiPool.c (96%) create mode 100644 vendor/github.com/godror/godror/odpi/src/dpiQueue.c rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiRowid.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaColl.c (84%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaCollCursor.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDb.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDoc.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDocCursor.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiStmt.c (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSubscr.c (93%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiUtils.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiVar.c (97%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/orahlp.go (83%) create mode 100644 vendor/github.com/godror/godror/queue.go rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/rows.go (92%) create mode 100644 vendor/github.com/godror/godror/sid/sid.go rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/stmt.go (88%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/subscr.c (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/subscr.go (86%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/version.go (57%) create mode 100644 vendor/golang.org/x/xerrors/LICENSE create mode 100644 vendor/golang.org/x/xerrors/PATENTS create mode 100644 vendor/golang.org/x/xerrors/README create mode 100644 vendor/golang.org/x/xerrors/adaptor.go create mode 100644 vendor/golang.org/x/xerrors/codereview.cfg create mode 100644 vendor/golang.org/x/xerrors/doc.go create mode 100644 vendor/golang.org/x/xerrors/errors.go create mode 100644 vendor/golang.org/x/xerrors/fmt.go create mode 100644 vendor/golang.org/x/xerrors/format.go create mode 100644 vendor/golang.org/x/xerrors/frame.go create mode 100644 vendor/golang.org/x/xerrors/go.mod create mode 100644 vendor/golang.org/x/xerrors/internal/internal.go create mode 100644 vendor/golang.org/x/xerrors/wrap.go delete mode 100644 vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile delete mode 100644 vendor/gopkg.in/goracle.v2/drv_10.go delete mode 100644 vendor/gopkg.in/goracle.v2/drv_posix.go delete mode 100644 vendor/gopkg.in/goracle.v2/go.mod delete mode 100644 vendor/gopkg.in/goracle.v2/go.sum delete mode 100644 vendor/gopkg.in/goracle.v2/stmt_go09.go delete mode 100644 vendor/gopkg.in/goracle.v2/stmt_go10.go diff --git a/NOTICE.txt b/NOTICE.txt index f61138aaf82..08a37d10a5b 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2099,6 +2099,239 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------- +Dependency: github.com/godror/godror +Version: v0.9.0 +Revision: 446a29355d2967f04604e8e015a3343917860adf +License type (autodetected): Apache-2.0 +./vendor/github.com/godror/godror/LICENSE.md: +-------------------------------------------------------------------- +Apache License 2.0 + + +-------------------------------------------------------------------- +Dependency: github.com/godror/godror/odpi +License type (autodetected): UPL-1.0 +./vendor/github.com/godror/godror/odpi/LICENSE.md: +-------------------------------------------------------------------- +Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. + +This program is free software: you can modify it and/or redistribute it under +the terms of: + +(i) the Universal Permissive License v 1.0 or at your option, any + later version (); and/or + +(ii) the Apache License v 2.0. () + + +The Universal Permissive License (UPL), Version 1.0 +=================================================== + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and + +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + one is included with the Software (each a "Larger Work" to which the + Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: + +The above copyright notice and either this complete permission notice or at a +minimum a reference to the UPL must be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Apache License +============== + +Version 2.0, January 2004 + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. **Definitions**. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty + percent (50%) or more of the outstanding shares, or (iii) beneficial + ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, + and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that + is included in or attached to the work (an example is provided in the + Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as + a whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. **Grant of Copyright License.** Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. **Grant of Patent License.** Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or + contributory patent infringement, then any patent licenses granted to You + under this License for that Work shall terminate as of the date such + litigation is filed. + +4. **Redistribution.** You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices + from the Source form of the Work, excluding those notices that do not + pertain to any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of the + Derivative Works, in at least one of the following places: within a + NOTICE text file distributed as part of the Derivative Works; within + the Source form or documentation, if provided along with the Derivative + Works; or, within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents of the + NOTICE file are for informational purposes only and do not modify the + License. You may add Your own attribution notices within Derivative + Works that You distribute, alongside or as an addendum to the NOTICE + text from the Work, provided that such additional attribution notices + cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated + in this License. + +5. **Submission of Contributions.** Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to + the Licensor shall be under the terms and conditions of this License, + without any additional terms or conditions. Notwithstanding the above, + nothing herein shall supersede or modify the terms of any separate license + agreement you may have executed with Licensor regarding such Contributions. + +6. **Trademarks.** This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, except + as required for reasonable and customary use in describing the origin of + the Work and reproducing the content of the NOTICE file. + +7. **Disclaimer of Warranty.** Unless required by applicable law or agreed to + in writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for + determining the appropriateness of using or redistributing the Work and + assume any risks associated with Your exercise of permissions under this + License. + +8. **Limitation of Liability.** In no event and under no legal theory, whether + in tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or + inability to use the Work (including but not limited to damages for loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor has been + advised of the possibility of such damages. + +9. **Accepting Warranty or Additional Liability.** While redistributing the + Work or Derivative Works thereof, You may choose to offer, and charge a fee + for, acceptance of support, warranty, indemnity, or other liability + obligations and/or rights consistent with this License. However, in + accepting such obligations, You may act only on Your own behalf and on Your + sole responsibility, not on behalf of any other Contributor, and only if + You agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + -------------------------------------------------------------------- Dependency: github.com/gofrs/flock Revision: 5135e617513b1e6e205a3a89b042249dee6730c8 @@ -6127,10 +6360,44 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------- +Dependency: golang.org/x/xerrors +Revision: 9bdfabe68543c54f90421aeb9a60ef8061b5b544 +License type (autodetected): BSD-3-Clause +./vendor/golang.org/x/xerrors/LICENSE: +-------------------------------------------------------------------- +Copyright (c) 2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -------------------------------------------------------------------- Dependency: google.golang.org/api -Version: v0.14.0 -Revision: 8a410c21381766a810817fd6200fce8838ecb277 +Version: v0.7.0 +Revision: 02490b97dff7cfde1995bd77de808fd27053bc87 License type (autodetected): BSD-3-Clause ./vendor/google.golang.org/api/LICENSE: -------------------------------------------------------------------- @@ -6252,239 +6519,6 @@ License type (autodetected): Apache-2.0 Apache License 2.0 --------------------------------------------------------------------- -Dependency: gopkg.in/goracle.v2 -Revision: 3222d7159b45fce95150f06a57e1bcc2868108d3 -License type (autodetected): Apache-2.0 -./vendor/gopkg.in/goracle.v2/LICENSE.md: --------------------------------------------------------------------- -Apache License 2.0 - - --------------------------------------------------------------------- -Dependency: gopkg.in/goracle.v2/odpi -License type (autodetected): UPL-1.0 -./vendor/gopkg.in/goracle.v2/odpi/LICENSE.md: --------------------------------------------------------------------- -Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. - -This program is free software: you can modify it and/or redistribute it under -the terms of: - -(i) the Universal Permissive License v 1.0 or at your option, any - later version (); and/or - -(ii) the Apache License v 2.0. () - - -The Universal Permissive License (UPL), Version 1.0 -=================================================== - -Subject to the condition set forth below, permission is hereby granted to any -person obtaining a copy of this software, associated documentation and/or data -(collectively the "Software"), free of charge and under any and all copyright -rights in the Software, and any and all patent rights owned or freely -licensable by each licensor hereunder covering either (i) the unmodified -Software as contributed to or provided by such licensor, or (ii) the Larger -Works (as defined below), to deal in both - -(a) the Software, and - -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - one is included with the Software (each a "Larger Work" to which the - Software is contributed by such licensors), - -without restriction, including without limitation the rights to copy, create -derivative works of, display, perform, and distribute the Software and make, -use, sell, offer for sale, import, export, have made, and have sold the -Software and the Larger Work(s), and to sublicense the foregoing rights on -either these or other terms. - -This license is subject to the following condition: - -The above copyright notice and either this complete permission notice or at a -minimum a reference to the UPL must be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Apache License -============== - -Version 2.0, January 2004 - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. **Definitions**. - - "License" shall mean the terms and conditions for use, reproduction, and - distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by the - copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all other - entities that control, are controlled by, or are under common control with - that entity. For the purposes of this definition, "control" means (i) the - power, direct or indirect, to cause the direction or management of such - entity, whether by contract or otherwise, or (ii) ownership of fifty - percent (50%) or more of the outstanding shares, or (iii) beneficial - ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity exercising - permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation source, - and configuration files. - - "Object" form shall mean any form resulting from mechanical transformation - or translation of a Source form, including but not limited to compiled - object code, generated documentation, and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or Object form, - made available under the License, as indicated by a copyright notice that - is included in or attached to the work (an example is provided in the - Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object form, - that is based on (or derived from) the Work and for which the editorial - revisions, annotations, elaborations, or other modifications represent, as - a whole, an original work of authorship. For the purposes of this License, - Derivative Works shall not include works that remain separable from, or - merely link (or bind by name) to the interfaces of, the Work and Derivative - Works thereof. - - "Contribution" shall mean any work of authorship, including the original - version of the Work and any modifications or additions to that Work or - Derivative Works thereof, that is intentionally submitted to Licensor for - inclusion in the Work by the copyright owner or by an individual or Legal - Entity authorized to submit on behalf of the copyright owner. For the - purposes of this definition, "submitted" means any form of electronic, - verbal, or written communication sent to the Licensor or its - representatives, including but not limited to communication on electronic - mailing lists, source code control systems, and issue tracking systems that - are managed by, or on behalf of, the Licensor for the purpose of discussing - and improving the Work, but excluding communication that is conspicuously - marked or otherwise designated in writing by the copyright owner as "Not a - Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity on - behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. **Grant of Copyright License.** Subject to the terms and conditions of this - License, each Contributor hereby grants to You a perpetual, worldwide, - non-exclusive, no-charge, royalty-free, irrevocable copyright license to - reproduce, prepare Derivative Works of, publicly display, publicly perform, - sublicense, and distribute the Work and such Derivative Works in Source or - Object form. - -3. **Grant of Patent License.** Subject to the terms and conditions of this - License, each Contributor hereby grants to You a perpetual, worldwide, - non-exclusive, no-charge, royalty-free, irrevocable (except as stated in - this section) patent license to make, have made, use, offer to sell, sell, - import, and otherwise transfer the Work, where such license applies only to - those patent claims licensable by such Contributor that are necessarily - infringed by their Contribution(s) alone or by combination of their - Contribution(s) with the Work to which such Contribution(s) was submitted. - If You institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work or a - Contribution incorporated within the Work constitutes direct or - contributory patent infringement, then any patent licenses granted to You - under this License for that Work shall terminate as of the date such - litigation is filed. - -4. **Redistribution.** You may reproduce and distribute copies of the Work or - Derivative Works thereof in any medium, with or without modifications, and - in Source or Object form, provided that You meet the following conditions: - - 1. You must give any other recipients of the Work or Derivative Works a - copy of this License; and - - 2. You must cause any modified files to carry prominent notices stating - that You changed the files; and - - 3. You must retain, in the Source form of any Derivative Works that You - distribute, all copyright, patent, trademark, and attribution notices - from the Source form of the Work, excluding those notices that do not - pertain to any part of the Derivative Works; and - - 4. If the Work includes a "NOTICE" text file as part of its distribution, - then any Derivative Works that You distribute must include a readable - copy of the attribution notices contained within such NOTICE file, - excluding those notices that do not pertain to any part of the - Derivative Works, in at least one of the following places: within a - NOTICE text file distributed as part of the Derivative Works; within - the Source form or documentation, if provided along with the Derivative - Works; or, within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents of the - NOTICE file are for informational purposes only and do not modify the - License. You may add Your own attribution notices within Derivative - Works that You distribute, alongside or as an addendum to the NOTICE - text from the Work, provided that such additional attribution notices - cannot be construed as modifying the License. - - You may add Your own copyright statement to Your modifications and may - provide additional or different license terms and conditions for use, - reproduction, or distribution of Your modifications, or for any such - Derivative Works as a whole, provided Your use, reproduction, and - distribution of the Work otherwise complies with the conditions stated - in this License. - -5. **Submission of Contributions.** Unless You explicitly state otherwise, any - Contribution intentionally submitted for inclusion in the Work by You to - the Licensor shall be under the terms and conditions of this License, - without any additional terms or conditions. Notwithstanding the above, - nothing herein shall supersede or modify the terms of any separate license - agreement you may have executed with Licensor regarding such Contributions. - -6. **Trademarks.** This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, except - as required for reasonable and customary use in describing the origin of - the Work and reproducing the content of the NOTICE file. - -7. **Disclaimer of Warranty.** Unless required by applicable law or agreed to - in writing, Licensor provides the Work (and each Contributor provides its - Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied, including, without limitation, any - warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or - FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for - determining the appropriateness of using or redistributing the Work and - assume any risks associated with Your exercise of permissions under this - License. - -8. **Limitation of Liability.** In no event and under no legal theory, whether - in tort (including negligence), contract, or otherwise, unless required by - applicable law (such as deliberate and grossly negligent acts) or agreed to - in writing, shall any Contributor be liable to You for damages, including - any direct, indirect, special, incidental, or consequential damages of any - character arising as a result of this License or out of the use or - inability to use the Work (including but not limited to damages for loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor has been - advised of the possibility of such damages. - -9. **Accepting Warranty or Additional Liability.** While redistributing the - Work or Derivative Works thereof, You may choose to offer, and charge a fee - for, acceptance of support, warranty, indemnity, or other liability - obligations and/or rights consistent with this License. However, in - accepting such obligations, You may act only on Your own behalf and on Your - sole responsibility, not on behalf of any other Contributor, and only if - You agree to indemnify, defend, and hold each Contributor harmless for any - liability incurred by, or claims asserted against, such Contributor by - reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - - -------------------------------------------------------------------- Dependency: gopkg.in/inf.v0 Revision: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 diff --git a/vendor/gopkg.in/goracle.v2/CHANGELOG.md b/vendor/github.com/godror/godror/CHANGELOG.md similarity index 69% rename from vendor/gopkg.in/goracle.v2/CHANGELOG.md rename to vendor/github.com/godror/godror/CHANGELOG.md index 7dd02ae08e3..0541bbe23b5 100644 --- a/vendor/gopkg.in/goracle.v2/CHANGELOG.md +++ b/vendor/github.com/godror/godror/CHANGELOG.md @@ -5,6 +5,102 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +## [2.24.0] +### Changed +- License: SPDX-License-Identifier: UPL-1.0 OR APL-2.0 + +## [2.23.5] +### Changed +- ODPI-C v3.3.0 + +## [2.23.2] +### Changed +- Close statement (and dpiStmt) on Break/bad conn. + +## [2.23.0] +### Added +- Conn.Timezone() returns the connection's timezone +- allow setting the timezone with Timezone ConnectionParam. +- Support to change password with NewPassword ConnectionParams. + +### Changed +- set DefaultEnqOptions and DefaultDeqOptions in NewQueue. +- make ConnectionParams.WaitTimeout, SessionMaxLifeTime, SessionTimeout be time.Duration. + +## [2.21.3] - 2019-10-03 +### Added +- Export Queue.PayloadObjectType +- Queue.SetEnqOptions, Queue.SetDeqOptions, Queue.SetDeqCorrelation + +## [2.21.1] - 2019-10-02 +### Changed +- Really close the connection if it's bad. For #194. +- ODPI-C v3.2.2 +- de-embed conn from Queue. + +## [2.20.1] - 2019-09-05 +### Added +- AsOraErr function + +### Changed +- Object.reset set attributes to null. +- Use golang.org/x/xerrors instead of github.com/pkg/errors. +- ObjectType.Close became unexported. + +## [2.20.0] - 2019-09-04 +### Added +- ObjectType cache in connection. +- Queue support with Objects. + +### Changed +- ObjectType.Close became unexported. +- Change Object Set/Get +- use golang.org/x/xerrors instead of github.com/pkg/errors. + +## [2.19.0] - 2019-08-15 +### Changed +- Require Context for getConn and thus in ClientVersion, ServerVersion, GetObjectType, DriverConn functions. + +## [2.18.5] - 2019-08-14 +### Changed +- Remove log.Println left in... + +## [2.18.4] - 2019-08-14 +### Changed +- Timezone detection: DBTIMEZONE is plain wrong, parse from SYSTIMESTAMP. + +## [2.18.3] - 2019-08-13 +### Changed +- GetObjectType uppercases the name by default. +- Upgrade to ODPI-C v3.2.1 + +## [2.18.2] - 2019-07-23 +### Changed +- Force copying of bytes (garbage appears Out with RAW). + +## [2.18.0] - 2019-07-16 +### Added +- Setable pool session timeouts. + +## [2.16.4] - 2019-06-26 +### Changed +- Fix bool input (#166). +- Allow region name from DBTIMEZONE, not just offset. + +## [2.16.2] - 2019-05-27 +### Changed +- Make Query AUTOCOMMIT like Exec - it's needed to release Rows for "FOR UPDATE". + +## [2.16.1] - 2019-05-27 +### Added +- Data.SetNull +- Expose dpiConn_newVar + +## [2.16.0] - 2019-05-17 +### Changed +- NumberAsString new option for #159. ## [2.15.3] - 2019-05-16 ### Changed @@ -70,7 +166,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Use ODPI-C v3.1.1 ### Added -- Make goracle.drv implement driver.DriverContext with OpenConnector. +- Make godror.drv implement driver.DriverContext with OpenConnector. ## [2.12.2] - 2019-02-15 ### Changed @@ -213,4 +309,3 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - initialize context / load lib only on first Open, to allow import without Oracle Client installed - use golangci-lint - diff --git a/vendor/gopkg.in/goracle.v2/LICENSE.md b/vendor/github.com/godror/godror/LICENSE.md similarity index 95% rename from vendor/gopkg.in/goracle.v2/LICENSE.md rename to vendor/github.com/godror/godror/LICENSE.md index f634025b67c..7ca5c6c439f 100644 --- a/vendor/gopkg.in/goracle.v2/LICENSE.md +++ b/vendor/github.com/godror/godror/LICENSE.md @@ -1,19 +1,12 @@ -goracle +godror ======= -Copyright 2017 Tamás Gulácsi +Copyright 2017, 2018, 2019 Tamás Gulácsi -Licensed 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. +You can use either the + Apache License, Version 2.0 (APL-2.0), +or the + Universal Permissive License, Version 1.0 (UPL-1.0). ODPI-C ====== diff --git a/vendor/gopkg.in/goracle.v2/NOTES.md b/vendor/github.com/godror/godror/NOTES.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/NOTES.md rename to vendor/github.com/godror/godror/NOTES.md diff --git a/vendor/gopkg.in/goracle.v2/README.md b/vendor/github.com/godror/godror/README.md similarity index 72% rename from vendor/gopkg.in/goracle.v2/README.md rename to vendor/github.com/godror/godror/README.md index 8673ff1a789..97697086919 100644 --- a/vendor/gopkg.in/goracle.v2/README.md +++ b/vendor/github.com/godror/godror/README.md @@ -1,25 +1,29 @@ -[![Build Status](https://travis-ci.org/go-goracle/goracle.svg?branch=v2)](https://travis-ci.org/go-goracle/goracle) -[![GoDoc](https://godoc.org/gopkg.in/goracle.v2?status.svg)](http://godoc.org/gopkg.in/goracle.v2) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-goracle/goracle)](https://goreportcard.com/report/github.com/go-goracle/goracle) -[![codecov](https://codecov.io/gh/go-goracle/goracle/branch/master/graph/badge.svg)](https://codecov.io/gh/go-goracle/goracle) +[![Travis](https://travis-ci.org/godror/godror.svg?branch=v2)](https://travis-ci.org/godror/godror) +[![CircleCI](https://circleci.com/gh/godror/godror.svg?style=svg)](https://circleci.com/gh/godror/godror) +[![GoDoc](https://godoc.org/github.com/godror/godror?status.svg)](http://godoc.org/github.com/godror/godror) +[![Go Report Card](https://goreportcard.com/badge/github.com/godror/godror)](https://goreportcard.com/report/github.com/godror/godror) +[![codecov](https://codecov.io/gh/godror/godror/branch/master/graph/badge.svg)](https://codecov.io/gh/godror/godror) -# goracle +# Go DRiver for ORacle -[goracle](driver.go) is a package which is a +[godror](https://godoc.org/pkg/github.com/godror/godror) is a package which is a [database/sql/driver.Driver](http://golang.org/pkg/database/sql/driver/#Driver) for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wrapper, [ODPI-C](https://www.github.com/oracle/odpi). At least Go 1.11 is required! +Although an Oracle client is NOT required for compiling, it is at run time. +One can download it from https://www.oracle.com/database/technologies/instant-client/downloads.html + ## Connect -In `sql.Open("goracle", connString)`, you can provide the classic "user/passw@service_name" +In `sql.Open("godror", connString)`, you can provide the classic "user/passw@service_name" as connString, or an URL like "oracle://user:passw@service_name". You can provide all possible options with `ConnectionParams`. Watch out the `ConnectionParams.String()` does redact the password -(for security, to avoid logging it - see https://github.com/go-goracle/goracle/issues/79). +(for security, to avoid logging it - see https://github.com/godror/godror/issues/79). So use `ConnectionParams.StringWithPassword()`. More advanced configurations can be set with a connection string such as: @@ -29,22 +33,22 @@ A configuration like this is how you would add functionality such as load balanc described in parenthesis above can also be set in the `SID` field of `ConnectionParams`. For other possible connection strings, see https://oracle.github.io/node-oracledb/doc/api.html#connectionstrings -and https://docs.oracle.com/en/database/oracle/oracle-database/12.2/netag/configuring-naming-methods.html#GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE . +and https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE . TL;DR; the short form is `username@[//]host[:port][/service_name][:server][/instance_name]`, the long form is `(DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=host)(PORT=port)) (CONNECT_DATA= (SERVICE_NAME=service_name) (SERVER=server) (INSTANCE_NAME=instance_name)))`. To use heterogeneous pools, set `heterogeneousPool=1` and provide the username/password through -`goracle.ContextWithUserPassw`. +`godror.ContextWithUserPassw`. ## Rationale With Go 1.9, driver-specific things are not needed, everything (I need) can be achieved with the standard _database/sql_ library. Even calling stored procedures with OUT parameters, or sending/retrieving PL/SQL array types - just give a -`goracle.PlSQLArrays` Option within the parameters of `Exec`! +`godror.PlSQLArrays` Option within the parameters of `Exec`! -The array size of the returned PL/SQL arrays can be set with `goracle.ArraySize(2000)` +The array size of the returned PL/SQL arrays can be set with `godror.ArraySize(2000)` * the default is 1024. @@ -56,7 +60,7 @@ Correctness and simplicity is more important than speed, but the underlying ODPI helps a lot with the lower levels, so the performance is not bad. Queries are prefetched (256 rows by default, can be changed by adding a -`goracle.FetchRowCount(1000)` argument to the call of Query), +`godror.FetchRowCount(1000)` argument to the call of Query), but you can speed up INSERT/UPDATE/DELETE statements by providing all the subsequent parameters at once, by putting each param's subsequent elements in a separate slice: @@ -72,28 +76,28 @@ do ## Logging -Goracle uses `github.com/go-kit/kit/log`'s concept of a `Log` function. -Either set `goracle.Log` to a logging function globally, +godror uses `github.com/go-kit/kit/log`'s concept of a `Log` function. +Either set `godror.Log` to a logging function globally, or (better) set the logger in the Context of ExecContext or QueryContext: - db.QueryContext(goracle.ContextWithLog(ctx, logger.Log), qry) + db.QueryContext(godror.ContextWithLog(ctx, logger.Log), qry) ## Tracing To set ClientIdentifier, ClientInfo, Module, Action and DbOp on the session, -to be seen in the Database by the Admin, set goracle.TraceTag on the Context: +to be seen in the Database by the Admin, set godror.TraceTag on the Context: - db.QueryContext(goracle.ContextWithTraceTag(goracle.TraceTag{ + db.QueryContext(godror.ContextWithTraceTag(godror.TraceTag{ Module: "processing", Action: "first", }), qry) ## Extras -To use the goracle-specific functions, you'll need a `*goracle.conn`. -That's what `goracle.DriverConn` is for! +To use the godror-specific functions, you'll need a `*godror.conn`. +That's what `godror.DriverConn` is for! See [z_qrcn_test.go](./z_qrcn_test.go) for using that to reach -[NewSubscription](https://godoc.org/gopkg.in/goracle.v2#Subscription). +[NewSubscription](https://godoc.org/github.com/godror/godror#Subscription). ### Calling stored procedures Use `ExecContext` and mark each OUT parameter with `sql.Out`. @@ -101,7 +105,7 @@ Use `ExecContext` and mark each OUT parameter with `sql.Out`. ### Using cursors returned by stored procedures Use `ExecContext` and an `interface{}` or a `database/sql/driver.Rows` as the `sql.Out` destination, then either use the `driver.Rows` interface, -or transform it into a regular `*sql.Rows` with `goracle.WrapRows`, +or transform it into a regular `*sql.Rows` with `godror.WrapRows`, or (since Go 1.12) just Scan into `*sql.Rows`. For examples, see Anthony Tuininga's @@ -124,7 +128,7 @@ Just use plain old `string` ! ### NUMBER -`NUMBER`s are transferred as `goracle.Number` (which is a `string`) to Go under the hood. +`NUMBER`s are transferred as `godror.Number` (which is a `string`) to Go under the hood. This ensures that we don't lose any precision (Oracle's NUMBER has 38 decimal digits), and `sql.Scan` will hide this and `Scan` into your `int64`, `float64` or `string`, as you wish. @@ -158,11 +162,11 @@ See #121. Just - go get gopkg.in/goracle.v2 + go get github.com/godror/godror Or if you prefer `dep` - dep ensure -add gopkg.in/goracle.v2 + dep ensure -add github.com/godror/godror and you're ready to go! @@ -173,14 +177,14 @@ Note that Windows may need some newer gcc (mingw-w64 with gcc 7.2.0). Just as with other Go projects, you don't want to change the import paths, but you can hack on the library in place, just set up different remotes: - cd $GOPATH.src/gopkg.in/goracle.v2 - git remote add upstream https://github.com/go-goracle/goracle.git + cd $GOPATH.src/github.com/godror/godror + git remote add upstream https://github.com/godror/godror.git git fetch upstream git checkout -b master upstream/master git checkout -f master git pull upstream master - git remote add fork git@github.com:mygithubacc/goracle + git remote add fork git@github.com:mygithubacc/godror git checkout -b newfeature upstream/master Change, experiment as you wish, then @@ -188,7 +192,7 @@ Change, experiment as you wish, then git commit -m 'my great changes' *.go git push fork newfeature -and you're ready to send a GitHub Pull Request from `github.com/mygithubacc/goracle`, `newfeature` branch. +and you're ready to send a GitHub Pull Request from `github.com/mygithubacc/godror`, `newfeature` branch. ### pre-commit diff --git a/vendor/gopkg.in/goracle.v2/conn.go b/vendor/github.com/godror/godror/conn.go similarity index 74% rename from vendor/gopkg.in/goracle.v2/conn.go rename to vendor/github.com/godror/godror/conn.go index e5a9bb6c3a2..f1476349729 100644 --- a/vendor/gopkg.in/goracle.v2/conn.go +++ b/vendor/github.com/godror/godror/conn.go @@ -1,19 +1,9 @@ // Copyright 2019 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -22,16 +12,18 @@ package goracle import "C" import ( + "bytes" "context" "database/sql" "database/sql/driver" "io" + "strconv" "strings" "sync" "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) const getConnection = "--GET_CONNECTION--" @@ -40,14 +32,16 @@ const wrapResultset = "--WRAP_RESULTSET--" // The maximum capacity is limited to (2^32 / sizeof(dpiData))-1 to remain compatible // with 32-bit platforms. The size of a `C.dpiData` is 32 Byte on a 64-bit system, `C.dpiSubscrMessageTable` is 40 bytes. // So this is 2^25. -// See https://github.com/go-goracle/goracle/issues/73#issuecomment-401281714 -const maxArraySize = (1<<30)/C.sizeof_dpiSubscrMessageTable - 1 +// See https://github.com/go-godror/godror/issues/73#issuecomment-401281714 +const maxArraySize = (1<<32)/C.sizeof_dpiSubscrMessageTable - 1 var _ = driver.Conn((*conn)(nil)) var _ = driver.ConnBeginTx((*conn)(nil)) var _ = driver.ConnPrepareContext((*conn)(nil)) var _ = driver.Pinger((*conn)(nil)) +//var _ = driver.ExecerContext((*conn)(nil)) + type conn struct { connParams ConnectionParams currentTT TraceTag @@ -61,6 +55,7 @@ type conn struct { newSession bool timeZone *time.Location tzOffSecs int + objTypes map[string]ObjectType } func (c *conn) getError() error { @@ -77,7 +72,7 @@ func (c *conn) Break() error { Log("msg", "Break", "dpiConn", c.dpiConn) } if C.dpiConn_breakExecution(c.dpiConn) == C.DPI_FAILURE { - return maybeBadConn(errors.Wrap(c.getError(), "Break")) + return maybeBadConn(errors.Errorf("Break: %w", c.getError()), c) } return nil } @@ -102,7 +97,7 @@ func (c *conn) Ping(ctx context.Context) error { defer close(done) failure := C.dpiConn_ping(c.dpiConn) == C.DPI_FAILURE if failure { - done <- maybeBadConn(errors.Wrap(c.getError(), "Ping")) + done <- maybeBadConn(errors.Errorf("Ping: %w", c.getError()), c) return } done <- nil @@ -118,6 +113,7 @@ func (c *conn) Ping(ctx context.Context) error { return err default: _ = c.Break() + c.close(true) return driver.ErrBadConn } } @@ -142,28 +138,49 @@ func (c *conn) Close() error { } c.Lock() defer c.Unlock() + return c.close(true) +} + +func (c *conn) close(doNotReuse bool) error { + if c == nil { + return nil + } c.setTraceTag(TraceTag{}) - dpiConn := c.dpiConn - c.dpiConn = nil + dpiConn, objTypes := c.dpiConn, c.objTypes + c.dpiConn, c.objTypes = nil, nil if dpiConn == nil { return nil } + defer C.dpiConn_release(dpiConn) + + seen := make(map[string]struct{}, len(objTypes)) + for _, o := range objTypes { + nm := o.FullName() + if _, seen := seen[nm]; seen { + continue + } + seen[nm] = struct{}{} + o.close() + } + if !doNotReuse { + return nil + } + // Just to be sure, break anything in progress. done := make(chan struct{}) go func() { select { case <-done: case <-time.After(10 * time.Second): + if Log != nil { + Log("msg", "TIMEOUT releasing connection") + } C.dpiConn_breakExecution(dpiConn) } }() - rc := C.dpiConn_release(dpiConn) + C.dpiConn_close(dpiConn, C.DPI_MODE_CONN_CLOSE_DROP, nil, 0) close(done) - var err error - if rc == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Close")) - } - return err + return nil } // Begin starts and returns a new transaction. @@ -210,7 +227,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e case sql.LevelSerializable: todo.Level = trLS default: - return nil, errors.Errorf("%v isolation level is not supported", sql.IsolationLevel(opts.Isolation)) + return nil, errors.Errorf("isolation level is not supported: %s", sql.IsolationLevel(opts.Isolation)) } if todo != c.tranParams { @@ -229,7 +246,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e stmt.Close() } if err != nil { - return nil, maybeBadConn(errors.Wrap(err, qry)) + return nil, maybeBadConn(errors.Errorf("%s: %w", qry, err), c) } } c.tranParams = todo @@ -288,7 +305,7 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e if C.dpiConn_prepareStmt(c.dpiConn, 0, cSQL, C.uint32_t(len(query)), nil, 0, (**C.dpiStmt)(unsafe.Pointer(&dpiStmt)), ) == C.DPI_FAILURE { - return nil, maybeBadConn(errors.Wrap(c.getError(), "Prepare: "+query)) + return nil, maybeBadConn(errors.Errorf("Prepare: %s: %w", query, c.getError()), c) } return &statement{conn: c, dpiStmt: dpiStmt, query: query}, nil } @@ -307,12 +324,12 @@ func (c *conn) endTran(isCommit bool) error { //msg := "Commit" if isCommit { if C.dpiConn_commit(c.dpiConn) == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Commit")) + err = maybeBadConn(errors.Errorf("Commit: %w", c.getError()), c) } } else { //msg = "Rollback" if C.dpiConn_rollback(c.dpiConn) == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Rollback")) + err = maybeBadConn(errors.Errorf("Rollback: %w", c.getError()), c) } } c.Unlock() @@ -350,7 +367,7 @@ func (c *conn) newVar(vi varInfo) (*C.dpiVar, []C.dpiData, error) { isArray, vi.ObjectType, &v, &dataArr, ) == C.DPI_FAILURE { - return nil, nil, errors.Wrapf(c.getError(), "newVar(typ=%d, natTyp=%d, sliceLen=%d, bufSize=%d)", vi.Typ, vi.NatTyp, vi.SliceLen, vi.BufSize) + return nil, nil, errors.Errorf("newVar(typ=%d, natTyp=%d, sliceLen=%d, bufSize=%d): %w", vi.Typ, vi.NatTyp, vi.SliceLen, vi.BufSize, c.getError()) } // https://github.com/golang/go/wiki/cgo#Turning_C_arrays_into_Go_slices /* @@ -380,59 +397,142 @@ func (c *conn) init() error { var release *C.char var releaseLen C.uint32_t if C.dpiConn_getServerVersion(c.dpiConn, &release, &releaseLen, &v) == C.DPI_FAILURE { - return errors.Wrap(c.getError(), "getServerVersion") + if c.connParams.IsPrelim { + return nil + } + return errors.Errorf("getServerVersion: %w", c.getError()) } c.Server.set(&v) - c.Server.ServerRelease = C.GoStringN(release, C.int(releaseLen)) + c.Server.ServerRelease = string(bytes.Replace( + ((*[maxArraySize]byte)(unsafe.Pointer(release)))[:releaseLen:releaseLen], + []byte{'\n'}, []byte{';', ' '}, -1)) } - if c.timeZone != nil { + if c.timeZone != nil && (c.timeZone != time.Local || c.tzOffSecs != 0) { return nil } c.timeZone = time.Local - _, c.tzOffSecs = (time.Time{}).In(c.timeZone).Zone() + _, c.tzOffSecs = time.Now().In(c.timeZone).Zone() + if Log != nil { + Log("tz", c.timeZone, "offSecs", c.tzOffSecs) + } - const qry = "SELECT DBTIMEZONE FROM DUAL" + // DBTIMEZONE is useless, false, and misdirecting! + // https://stackoverflow.com/questions/52531137/sysdate-and-dbtimezone-different-in-oracle-database + const qry = "SELECT DBTIMEZONE, LTRIM(REGEXP_SUBSTR(TO_CHAR(SYSTIMESTAMP), ' [^ ]+$')) FROM DUAL" ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() st, err := c.PrepareContext(ctx, qry) if err != nil { - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } defer st.Close() - rows, err := st.Query([]driver.Value{}) + rows, err := st.Query(nil) //lint:ignore SA1019 - it's hard to use QueryContext here if err != nil { - return errors.Wrap(err, qry) + if Log != nil { + Log("qry", qry, "error", err) + } + return nil } defer rows.Close() - var timezone string - vals := []driver.Value{timezone} - for { - if err = rows.Next(vals); err != nil { - if err == io.EOF { - break + var dbTZ, timezone string + vals := []driver.Value{dbTZ, timezone} + if err = rows.Next(vals); err != nil && err != io.EOF { + return errors.Errorf("%s: %w", qry, err) + } + dbTZ = vals[0].(string) + timezone = vals[1].(string) + + tz, off, err := calculateTZ(dbTZ, timezone) + if Log != nil { + Log("timezone", timezone, "tz", tz, "offSecs", off) + } + if err != nil || tz == nil { + return err + } + c.timeZone, c.tzOffSecs = tz, off + + return nil +} + +func calculateTZ(dbTZ, timezone string) (*time.Location, int, error) { + if Log != nil { + Log("dbTZ", dbTZ, "timezone", timezone) + } + var tz *time.Location + now := time.Now() + _, localOff := time.Now().Local().Zone() + off := localOff + var ok bool + var err error + if dbTZ != "" && strings.Contains(dbTZ, "/") { + tz, err = time.LoadLocation(dbTZ) + if ok = err == nil; ok { + if tz == time.Local { + return tz, off, nil } - return errors.Wrap(err, qry) + _, off = now.In(tz).Zone() + } else if Log != nil { + Log("LoadLocation", dbTZ, "error", err) } - timezone = strings.TrimSpace(vals[0].(string)) + } + if !ok { if timezone != "" { - break + if off, err = parseTZ(timezone); err != nil { + return tz, off, errors.Errorf("%s: %w", timezone, err) + } + } else if off, err = parseTZ(dbTZ); err != nil { + return tz, off, errors.Errorf("%s: %w", dbTZ, err) } } - if timezone == "" { - return errors.New("empty DBTIMEZONE") + // This is dangerous, but I just cannot get whether the DB time zone + // setting has DST or not - DBTIMEZONE returns just a fixed offset. + if off != localOff && tz == nil { + tz = time.FixedZone(timezone, off) + } + return tz, off, nil +} +func parseTZ(s string) (int, error) { + s = strings.TrimSpace(s) + if s == "" { + return 0, io.EOF + } + if s == "Z" || s == "UTC" { + return 0, nil } - if off, err := parseTZ(timezone); err != nil { - return errors.Wrap(err, timezone) + var tz int + var ok bool + if i := strings.IndexByte(s, ':'); i >= 0 { + if i64, err := strconv.ParseInt(s[i+1:], 10, 6); err != nil { + return tz, errors.Errorf("%s: %w", s, err) + } else { + tz = int(i64 * 60) + } + s = s[:i] + ok = true + } + if !ok { + if i := strings.IndexByte(s, '/'); i >= 0 { + targetLoc, err := time.LoadLocation(s) + if err != nil { + return tz, errors.Errorf("%s: %w", s, err) + } + + _, localOffset := time.Now().In(targetLoc).Zone() + + tz = localOffset + return tz, nil + } + } + if i64, err := strconv.ParseInt(s, 10, 5); err != nil { + return tz, errors.Errorf("%s: %w", s, err) } else { - // This is dangerous, but I just cannot get whether the DB time zone - // setting has DST or not - DBTIMEZONE returns just a fixed offset. - if _, localOff := time.Now().Local().Zone(); localOff != off { - c.tzOffSecs = off - c.timeZone = time.FixedZone(timezone, c.tzOffSecs) + if i64 < 0 { + tz = -tz } + tz += int(i64 * 3600) } - return nil + return tz, nil } func (c *conn) setCallTimeout(ctx context.Context) { @@ -447,21 +547,34 @@ func (c *conn) setCallTimeout(ctx context.Context) { C.dpiConn_setCallTimeout(c.dpiConn, ms) } -func maybeBadConn(err error) error { +// maybeBadConn checks whether the error is because of a bad connection, and returns driver.ErrBadConn, +// as database/sql requires. +// +// Also in this case, iff c != nil, closes it. +func maybeBadConn(err error, c *conn) error { if err == nil { return nil } - root := errors.Cause(err) - if root == driver.ErrBadConn { - return root + cl := func() {} + if c != nil { + cl = func() { + if Log != nil { + Log("msg", "maybeBadConn close", "conn", c) + } + c.close(true) + } } - if cd, ok := root.(interface { - Code() int - }); ok { + if errors.Is(err, driver.ErrBadConn) { + cl() + return driver.ErrBadConn + } + var cd interface{ Code() int } + if errors.As(err, &cd) { // Yes, this is copied from rana/ora, but I've put it there, so it's mine. @tgulacsi switch cd.Code() { case 0: if strings.Contains(err.Error(), " DPI-1002: ") { + cl() return driver.ErrBadConn } // cases by experience: @@ -500,6 +613,7 @@ func maybeBadConn(err error) error { 27146, // post/wait initialization failed 28511, // lost RPC connection 56600: // an illegal OCI function call was issued + cl() return driver.ErrBadConn } } @@ -542,7 +656,7 @@ func (c *conn) setTraceTag(tt TraceTag) error { C.free(unsafe.Pointer(s)) } if rc == C.DPI_FAILURE { - return errors.Wrap(c.getError(), nm) + return errors.Errorf("%s: %w", nm, c.getError()) } } c.currentTT = tt @@ -592,7 +706,7 @@ func (c *conn) ensureContextUser(ctx context.Context) error { } if c.dpiConn != nil { - if err := c.Close(); err != nil { + if err := c.close(false); err != nil { return driver.ErrBadConn } } @@ -625,7 +739,7 @@ const ( // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/database-startup-and-shutdown.html#GUID-44B24F65-8C24-4DF3-8FBF-B896A4D6F3F3 func (c *conn) Startup(mode StartupMode) error { if C.dpiConn_startupDatabase(c.dpiConn, C.dpiStartupMode(mode)) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "startup(%v)", mode) + return errors.Errorf("startup(%v): %w", mode, c.getError()) } return nil } @@ -654,7 +768,12 @@ const ( // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/database-startup-and-shutdown.html#GUID-44B24F65-8C24-4DF3-8FBF-B896A4D6F3F3 func (c *conn) Shutdown(mode ShutdownMode) error { if C.dpiConn_shutdownDatabase(c.dpiConn, C.dpiShutdownMode(mode)) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "shutdown(%v)", mode) + return errors.Errorf("shutdown(%v): %w", mode, c.getError()) } return nil } + +// Timezone returns the connection's timezone. +func (c *conn) Timezone() *time.Location { + return c.timeZone +} diff --git a/vendor/github.com/godror/godror/contrib/free.db/cwallet.sso b/vendor/github.com/godror/godror/contrib/free.db/cwallet.sso new file mode 100644 index 0000000000000000000000000000000000000000..c9eeffc2ffed3f7b333ef773cd5b77090a13f97b GIT binary patch literal 6733 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/free.db/keystore.jks b/vendor/github.com/godror/godror/contrib/free.db/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..1923759914e9ef2ac4e5be310afded0e521bb038 GIT binary patch literal 3241 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties b/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties new file mode 100644 index 00000000000..9fc350ca425 --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties @@ -0,0 +1 @@ +oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=${TNS_ADMIN}))) \ No newline at end of file diff --git a/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora b/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora new file mode 100644 index 00000000000..260f677fcde --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora @@ -0,0 +1,2 @@ +WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin"))) +SSL_SERVER_DN_MATCH=yes \ No newline at end of file diff --git a/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora b/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora new file mode 100644 index 00000000000..1b10c58ee0a --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora @@ -0,0 +1,6 @@ +free_high = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_high.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + +free_low = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_low.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + +free_medium = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_medium.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + diff --git a/vendor/github.com/godror/godror/contrib/free.db/truststore.jks b/vendor/github.com/godror/godror/contrib/free.db/truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..55faa40478b570ffb11e9c5dd949d9acdcd45f16 GIT binary patch literal 3335 zcmdT`X;f3!8qFmk%ww1Y(J-h85^h2;3{D{+Gg6{}l>%uJ1k8X*Froq>TB;%lQUz3y zL1a?U0uOmsBVvuT0*^wlrXUbS0R^nYf{4%?P@f&vYTuu(_3m0(C*L{eyZgJ}-DlrD zH#Rp0gTa)bAADi7pt9D}Vt2+;=^P%K8$-dNxpZm*hYk&#J#-G5N`b)u=IIO05isR2 zj1%YrgCX)jA>u1g2tQB+R|1rjbb+^}&sg6j+&xT6=lFGelMQMi)ojze)26flKtmY@ zQm`7J8WO$@fkY{7BV!Fglp;_^X?j4wBn7Y!i;7(W8Y`wXP`Z3RAM?H@43*8qqQPZ~ zB{<6XLxvZF{W*n!4ra4?Xc7@zW~_yE1RX(VEDnUOPmQ&3ABSMT-zs4hxMC4!*#{i5 zHxY*>FSdld*b)d%2v~mnkbp7_E(CO7(7d{m5CCAkHDOr+&9_0rETNa67VAWKk8hTUfx<`S}mdA?F{iyt+@8soGCY;!!b9jaHT(TE|f=ha}xB`WP0S)ozw1;4&0aTT3zi??iY55dBQKX zMaoUr&-KnicqW+k5wN)@hTFDkxjk;)=n{dsIvJjRt=qHhPAgQGx?7pi~Ha3Uwp|)Q6gCjsk#rger)H z1|w za>cS0!UQxD7{DI}IfZokUyFWGDl;={$^CkL=eCde2OTnqe*nyCL%-h-SogAjCA){4 zdfbccjH&<3ZvbJz@RKp`T^Yzdeu1pkR%J^ca@n%%U>Pesuf%%glQ+dw8inxVCp)%-b5}Omx=1_RCY!>>j z^2u~Yv^_U=CyP#lln!eQ8Y=Fkg3=DA)A(#Q4NZ<=bLd?`o5PCz zt?(|0q%-J<194cqBM$dYB(W~=o0O4ZhTg-FSC=W zW-`TVw)&abEg!r%lqW5a?bTIFZMW(taSW#fvtmLXl@aJ=1+&xg_%=Jb_{{~)$=0FK zS>DyEmdT_eAi}Vx@bJiJZ`O2yoMjt-?YU>}l2koB89tGJAf=&3uQGdJ(Dcc+i{(Qd ztu%qhtJwo`O?rQ;2s1aEaQgP=H_SIYeYzmVzoYPiTx4<`xT=X4nh&aG$xSasdacVJ znz((ggKc&`^s=qVp$z@IEz5zDCE#nFnmAie&3OL0mVaZ=CLQ}EV+Bc%v;EC72^z_F zemZF77l$e2X0oNYWm!f4dt(pD z)T-MlNXm~bhhOE#a6=5DEA`rH;ww~xTC*GGQq#q?FIUCga^%g$;p(3+wN_+N9 z)SKC}Wi5jJbj$Mo2aO>}hpLFEcK>52_4^ z+?!+6Fjs+05`>NwSu`$1Ae*E+*E~pHS!GO${3htQ>w;XEer$ktF1iYi!d3i<^MThv z8c_>rMD9E1qv|#glI6bnN^wG5>-KE1@5fzM{>PjTxE71WDr^sQL5JEAiavz@g!%fb z11NJF)Z;v?INwzoS`}1sT!Ww0T2eNy-+pQbpoYE&RYu467cM)QG~Vc4sw(ZN-KXh-q^J0Pw)`98>FOKf zHurfc`}XE<|00GJZiVv`1>PL~l=&!L#Mc$g0>6Cmpu$5p3|E<8BIzu-;U!xYCqL~t z?V}o%-W^%*dPr1Ua&-8hm-4c9R-d}@w zm6)hnYHc#>XLsnPeUn5yCvRRJ_Wf1n*?qjHd8@1S8Xm`-V}z@4137nceoAo2^=a!M15Fxx+OGIfWU%9qPlN zSeQrSvKS7JgtepA{4x7W?eeiJJRoUprPJcRT+G4 ze_cc5DGF+;oP3rC=wG^f_)Z=^GDCgcoe{~&lgx*bKuuJcY(%1)-+s@Wmoj{*RA}}q D;Lhu) literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile b/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile new file mode 100644 index 00000000000..45af9abff4b --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile @@ -0,0 +1,14 @@ +FROM debian:testing + +LABEL maintainer="t.gulacsi@unosoft.hu" + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y libaio1 wget unzip + +RUN wget -O /tmp/instantclient-basic-linux-x64.zip https://download.oracle.com/otn_software/linux/instantclient/193000/instantclient-basic-linux.x64-19.3.0.0.0dbru.zip + +RUN mkdir -p /usr/lib/oracle && unzip /tmp/instantclient-basic-linux-x64.zip -d /usr/lib/oracle + +RUN ldconfig -v /usr/lib/oracle/instantclient_19_3 +RUN ldd /usr/lib/oracle/instantclient_19_3/libclntsh.so diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/README.md b/vendor/github.com/godror/godror/contrib/oracle-instant-client/README.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/README.md rename to vendor/github.com/godror/godror/contrib/oracle-instant-client/README.md diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/Dockerfile b/vendor/github.com/godror/godror/contrib/oracle-xe-18c/Dockerfile similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/Dockerfile rename to vendor/github.com/godror/godror/contrib/oracle-xe-18c/Dockerfile diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/README.md b/vendor/github.com/godror/godror/contrib/oracle-xe-18c/README.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/README.md rename to vendor/github.com/godror/godror/contrib/oracle-xe-18c/README.md diff --git a/vendor/gopkg.in/goracle.v2/data.go b/vendor/github.com/godror/godror/data.go similarity index 52% rename from vendor/gopkg.in/goracle.v2/data.go rename to vendor/github.com/godror/godror/data.go index 4feb4308970..1d78c8abbae 100644 --- a/vendor/gopkg.in/goracle.v2/data.go +++ b/vendor/github.com/godror/godror/data.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -21,10 +11,14 @@ package goracle */ import "C" import ( + "database/sql" "database/sql/driver" "fmt" + "reflect" "time" "unsafe" + + errors "golang.org/x/xerrors" ) // Data holds the data to/from Oracle. @@ -34,11 +28,35 @@ type Data struct { NativeTypeNum C.dpiNativeTypeNum } +var ErrNotSupported = errors.New("not supported") + +// NewData creates a new Data structure for the given type, populated with the given type. +func NewData(v interface{}) (*Data, error) { + if v == nil { + return nil, errors.Errorf("%s: %w", "nil type", ErrNotSupported) + } + data := Data{dpiData: &C.dpiData{isNull: 1}} + return &data, data.Set(v) +} + // IsNull returns whether the data is null. func (d *Data) IsNull() bool { + // Use of C.dpiData_getIsNull(d.dpiData) would be safer, + // but ODPI-C 3.1.4 just returns dpiData->isNull, so do the same + // without calling CGO. return d == nil || d.dpiData == nil || d.dpiData.isNull == 1 } +// SetNull sets the value of the data to be the null value. +func (d *Data) SetNull() { + if !d.IsNull() { + // Maybe C.dpiData_setNull(d.dpiData) would be safer, but as we don't use C.dpiData_getIsNull, + // and those functions (at least in ODPI-C 3.1.4) just operate on data->isNull directly, + // don't use CGO if possible. + d.dpiData.isNull = 1 + } +} + // GetBool returns the bool data. func (d *Data) GetBool() bool { return !d.IsNull() && C.dpiData_getBool(d.dpiData) == 1 @@ -59,6 +77,9 @@ func (d *Data) GetBytes() []byte { return nil } b := C.dpiData_getBytes(d.dpiData) + if b.ptr == nil || b.length == 0 { + return nil + } return ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length] } @@ -155,7 +176,14 @@ func (d *Data) GetLob() *Lob { return &Lob{Reader: &dpiLobReader{dpiLob: C.dpiData_getLOB(d.dpiData)}} } +// SetLob sets Lob to the data. +func (d *Data) SetLob(lob *DirectLob) { + C.dpiData_setLOB(d.dpiData, lob.dpiLob) +} + // GetObject gets Object from data. +// +// As with all Objects, you MUST call Close on it when not needed anymore! func (d *Data) GetObject() *Object { if d == nil || d.dpiData == nil { panic("null") @@ -168,6 +196,9 @@ func (d *Data) GetObject() *Object { if o == nil { return nil } + if C.dpiObject_addRef(o) == C.DPI_FAILURE { + panic(d.ObjectType.getError()) + } obj := &Object{dpiObject: o, ObjectType: d.ObjectType} obj.init() return obj @@ -265,11 +296,168 @@ func (d *Data) Get() interface{} { } } +// Set the data. +func (d *Data) Set(v interface{}) error { + if v == nil { + return errors.Errorf("%s: %w", "nil type", ErrNotSupported) + } + if d.dpiData == nil { + d.dpiData = &C.dpiData{isNull: 1} + } + switch x := v.(type) { + case int32: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INT64 + d.SetInt64(int64(x)) + case int64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INT64 + d.SetInt64(x) + case uint64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_UINT64 + d.SetUint64(x) + case float32: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_FLOAT + d.SetFloat32(x) + case float64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_DOUBLE + d.SetFloat64(x) + case string: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BYTES + d.SetBytes([]byte(x)) + case []byte: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BYTES + d.SetBytes(x) + case time.Time: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_TIMESTAMP + d.SetTime(x) + case time.Duration: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INTERVAL_DS + d.SetIntervalDS(x) + case IntervalYM: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INTERVAL_YM + d.SetIntervalYM(x) + case *DirectLob: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_LOB + d.SetLob(x) + case *Object: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_OBJECT + d.ObjectType = x.ObjectType + d.SetObject(x) + //case *stmt: + //d.NativeTypeNum = C.DPI_NATIVE_TYPE_STMT + //d.SetStmt(x) + case bool: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BOOLEAN + d.SetBool(x) + //case rowid: + //d.NativeTypeNum = C.DPI_NATIVE_TYPE_ROWID + //d.SetRowid(x) + default: + return errors.Errorf("%T: %w", ErrNotSupported, v) + } + return nil +} + // IsObject returns whether the data contains an Object or not. func (d *Data) IsObject() bool { return d.NativeTypeNum == C.DPI_NATIVE_TYPE_OBJECT } +// NewData returns Data for input parameters on Object/ObjectCollection. +func (c *conn) NewData(baseType interface{}, sliceLen, bufSize int) ([]*Data, error) { + if c == nil || c.dpiConn == nil { + return nil, errors.New("connection is nil") + } + + vi, err := newVarInfo(baseType, sliceLen, bufSize) + if err != nil { + return nil, err + } + + _, dpiData, err := c.newVar(vi) + if err != nil { + return nil, err + } + + data := make([]*Data, sliceLen) + for i := 0; i < sliceLen; i++ { + data[i] = &Data{dpiData: &dpiData[i], NativeTypeNum: vi.NatTyp} + } + + return data, nil +} + +func newVarInfo(baseType interface{}, sliceLen, bufSize int) (varInfo, error) { + var vi varInfo + + switch v := baseType.(type) { + case Lob, []Lob: + vi.NatTyp = C.DPI_NATIVE_TYPE_LOB + var isClob bool + switch v := v.(type) { + case Lob: + isClob = v.IsClob + case []Lob: + isClob = len(v) > 0 && v[0].IsClob + } + if isClob { + vi.Typ = C.DPI_ORACLE_TYPE_CLOB + } else { + vi.Typ = C.DPI_ORACLE_TYPE_BLOB + } + case Number, []Number: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_BYTES + case int, []int, int64, []int64, sql.NullInt64, []sql.NullInt64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_INT64 + case int32, []int32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_INT, C.DPI_NATIVE_TYPE_INT64 + case uint, []uint, uint64, []uint64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_UINT64 + case uint32, []uint32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_UINT, C.DPI_NATIVE_TYPE_UINT64 + case float32, []float32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_FLOAT, C.DPI_NATIVE_TYPE_FLOAT + case float64, []float64, sql.NullFloat64, []sql.NullFloat64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_DOUBLE, C.DPI_NATIVE_TYPE_DOUBLE + case bool, []bool: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_BOOLEAN, C.DPI_NATIVE_TYPE_BOOLEAN + case []byte, [][]byte: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_RAW, C.DPI_NATIVE_TYPE_BYTES + switch v := v.(type) { + case []byte: + bufSize = len(v) + case [][]byte: + for _, b := range v { + if n := len(b); n > bufSize { + bufSize = n + } + } + } + case string, []string, nil: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_VARCHAR, C.DPI_NATIVE_TYPE_BYTES + bufSize = 32767 + case time.Time, []time.Time: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_DATE, C.DPI_NATIVE_TYPE_TIMESTAMP + case userType, []userType: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + switch v := v.(type) { + case userType: + vi.ObjectType = v.ObjectRef().ObjectType.dpiObjectType + case []userType: + if len(v) > 0 { + vi.ObjectType = v[0].ObjectRef().ObjectType.dpiObjectType + } + } + default: + return vi, errors.Errorf("unknown type %T", v) + } + + vi.IsPLSArray = reflect.TypeOf(baseType).Kind() == reflect.Slice + vi.SliceLen = sliceLen + vi.BufSize = bufSize + + return vi, nil +} + func (d *Data) reset() { d.NativeTypeNum = 0 d.ObjectType = ObjectType{} @@ -278,4 +466,5 @@ func (d *Data) reset() { } else { d.SetBytes(nil) } + d.dpiData.isNull = 1 } diff --git a/vendor/gopkg.in/goracle.v2/drv.go b/vendor/github.com/godror/godror/drv.go similarity index 67% rename from vendor/gopkg.in/goracle.v2/drv.go rename to vendor/github.com/godror/godror/drv.go index 89cee453dff..8ad65fd4c58 100644 --- a/vendor/gopkg.in/goracle.v2/drv.go +++ b/vendor/github.com/godror/godror/drv.go @@ -1,21 +1,11 @@ // Copyright 2019 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -// Package goracle is a database/sql/driver for Oracle DB. +// Package godror is a database/sql/driver for Oracle DB. // -// The connection string for the sql.Open("goracle", connString) call can be +// The connection string for the sql.Open("godror", connString) call can be // the simple // login/password@sid [AS SYSDBA|AS SYSOPER] // @@ -31,7 +21,12 @@ // standaloneConnection=0& \ // enableEvents=0& \ // heterogeneousPool=0& \ -// prelim=0 +// prelim=0& \ +// poolWaitTimeout=5m& \ +// poolSessionMaxLifetime=1h& \ +// poolSessionTimeout=30s& \ +// timezone=Local& \ +// newPassword= // // These are the defaults. Many advocate that a static session pool (min=max, incr=0) // is better, with 1-10 sessions per CPU thread. @@ -41,7 +36,9 @@ // If you specify connectionClass, that'll reuse the same session pool // without the connectionClass, but will specify it on each session acquire. // Thus you can cluster the session pool with classes, or use POOLED for DRCP. -package goracle +// +// For what can be used as "sid", see https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/configuring-naming-methods.html#GUID-E5358DEA-D619-4B7B-A799-3D2F802500F1 +package godror /* #cgo CFLAGS: -I./odpi/include -I./odpi/src -I./odpi/embed @@ -68,7 +65,7 @@ import ( "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) const ( @@ -84,9 +81,13 @@ const ( DpiMajorVersion = C.DPI_MAJOR_VERSION // DpiMinorVersion is the wanted minor version of the underlying ODPI-C library. DpiMinorVersion = C.DPI_MINOR_VERSION + // DpiPatchLevel is the patch level version of the underlying ODPI-C library + DpiPatchLevel = C.DPI_PATCH_LEVEL + // DpiVersionNumber is the underlying ODPI-C version as one number (Major * 10000 + Minor * 100 + Patch) + DpiVersionNumber = C.DPI_VERSION_NUMBER // DriverName is set on the connection to be seen in the DB - DriverName = "gopkg.in/goracle.v2 : " + Version + DriverName = "github.com/godror/godror : " + Version // DefaultPoolMinSessions specifies the default value for minSessions for pool creation. DefaultPoolMinSessions = 1 @@ -95,10 +96,16 @@ const ( // DefaultPoolIncrement specifies the default value for increment for pool creation. DefaultPoolIncrement = 1 // DefaultConnectionClass is the default connectionClass - DefaultConnectionClass = "GORACLE" + DefaultConnectionClass = "GODROR" // NoConnectionPoolingConnectionClass is a special connection class name to indicate no connection pooling. // It is the same as setting standaloneConnection=1 NoConnectionPoolingConnectionClass = "NO-CONNECTION-POOLING" + // DefaultSessionTimeout is the seconds before idle pool sessions get evicted + DefaultSessionTimeout = 5 * time.Minute + // DefaultWaitTimeout is the milliseconds to wait for a session to become available + DefaultWaitTimeout = 30 * time.Second + // DefaultMaxLifeTime is the maximum time in seconds till a pooled session may exist + DefaultMaxLifeTime = 1 * time.Hour ) // Number as string @@ -307,7 +314,7 @@ var defaultDrv *drv func init() { defaultDrv = newDrv() - sql.Register("goracle", defaultDrv) + sql.Register("godror", defaultDrv) } func newDrv() *drv { @@ -347,7 +354,7 @@ func (d *drv) init() error { var v C.dpiVersionInfo if C.dpiContext_getClientVersion(d.dpiContext, &v) == C.DPI_FAILURE { - return errors.Wrap(d.getError(), "getClientVersion") + return errors.Errorf("%s: %w", "getClientVersion", d.getError()) } d.clientVersion.set(&v) return nil @@ -362,7 +369,7 @@ func (d *drv) Open(connString string) (driver.Conn, error) { } conn, err := d.openConn(P) - return conn, maybeBadConn(err) + return conn, maybeBadConn(err, conn) } func (d *drv) ClientVersion() (VersionInfo, error) { @@ -374,7 +381,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { return nil, err } - c := conn{drv: d, connParams: P} + c := conn{drv: d, connParams: P, timeZone: time.Local} connString := P.String() defer func() { @@ -400,15 +407,16 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { authMode |= elt.Mode } } - if P.IsPrelim { - // The shared memory may not exist when Oracle is shut down. + P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass + if P.IsPrelim || P.StandaloneConnection { + // Prelim: the shared memory may not exist when Oracle is shut down. P.ConnClass = "" } extAuth := C.int(b2i(P.Username == "" && P.Password == "")) var connCreateParams C.dpiConnCreateParams if C.dpiContext_initConnCreateParams(d.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initConnCreateParams") + return nil, errors.Errorf("initConnCreateParams: %w", d.getError()) } connCreateParams.authMode = authMode connCreateParams.externalAuth = extAuth @@ -424,21 +432,25 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { d.mu.Unlock() if dp != nil { //Proxy authenticated connections to database will be provided by methods with context + c.mu.Lock() c.Client, c.Server = d.clientVersion, dp.serverVersion c.timeZone, c.tzOffSecs = dp.timeZone, dp.tzOffSecs + c.mu.Unlock() if err := c.acquireConn("", ""); err != nil { return nil, err } err := c.init() if err == nil { + c.mu.Lock() dp.serverVersion = c.Server dp.timeZone, dp.tzOffSecs = c.timeZone, c.tzOffSecs + c.mu.Unlock() } return &c, err } } - var cUserName, cPassword *C.char + var cUserName, cPassword, cNewPassword *C.char if !(P.Username == "" && P.Password == "") { cUserName, cPassword = C.CString(P.Username), C.CString(P.Password) } @@ -453,6 +465,9 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { C.free(unsafe.Pointer(cUserName)) C.free(unsafe.Pointer(cPassword)) } + if cNewPassword != nil { + C.free(unsafe.Pointer(cNewPassword)) + } if cSid != nil { C.free(unsafe.Pointer(cSid)) } @@ -462,7 +477,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { }() var commonCreateParams C.dpiCommonCreateParams if C.dpiContext_initCommonCreateParams(d.dpiContext, &commonCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initCommonCreateParams") + return nil, errors.Errorf("initCommonCreateParams: %w", d.getError()) } commonCreateParams.createMode = C.DPI_MODE_CREATE_DEFAULT | C.DPI_MODE_CREATE_THREADED if P.EnableEvents { @@ -474,6 +489,11 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { commonCreateParams.driverNameLength = C.uint32_t(len(DriverName)) if P.IsSysDBA || P.IsSysOper || P.IsSysASM || P.IsPrelim || P.StandaloneConnection { + if P.NewPassword != "" { + cNewPassword = C.CString(P.NewPassword) + connCreateParams.newPassword = cNewPassword + connCreateParams.newPasswordLength = C.uint32_t(len(P.NewPassword)) + } dc := C.malloc(C.sizeof_void) if Log != nil { Log("C", "dpiConn_create", "params", P.String(), "common", commonCreateParams, "conn", connCreateParams) @@ -488,7 +508,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { (**C.dpiConn)(unsafe.Pointer(&dc)), ) == C.DPI_FAILURE { C.free(unsafe.Pointer(dc)) - return nil, errors.Wrapf(d.getError(), "username=%q sid=%q params=%+v", P.Username, P.SID, connCreateParams) + return nil, errors.Errorf("username=%q sid=%q params=%+v: %w", P.Username, P.SID, connCreateParams, d.getError()) } c.dpiConn = (*C.dpiConn)(dc) c.currentUser = P.Username @@ -498,25 +518,42 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { } var poolCreateParams C.dpiPoolCreateParams if C.dpiContext_initPoolCreateParams(d.dpiContext, &poolCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initPoolCreateParams") + return nil, errors.Errorf("initPoolCreateParams: %w", d.getError()) + } + poolCreateParams.minSessions = DefaultPoolMinSessions + if P.MinSessions >= 0 { + poolCreateParams.minSessions = C.uint32_t(P.MinSessions) + } + poolCreateParams.maxSessions = DefaultPoolMaxSessions + if P.MaxSessions > 0 { + poolCreateParams.maxSessions = C.uint32_t(P.MaxSessions) + } + poolCreateParams.sessionIncrement = DefaultPoolIncrement + if P.PoolIncrement > 0 { + poolCreateParams.sessionIncrement = C.uint32_t(P.PoolIncrement) } - poolCreateParams.minSessions = C.uint32_t(P.MinSessions) - poolCreateParams.maxSessions = C.uint32_t(P.MaxSessions) - poolCreateParams.sessionIncrement = C.uint32_t(P.PoolIncrement) if extAuth == 1 || P.HeterogeneousPool { poolCreateParams.homogeneous = 0 } poolCreateParams.externalAuth = extAuth poolCreateParams.getMode = C.DPI_MODE_POOL_GET_TIMEDWAIT - poolCreateParams.timeout = 300 // seconds before idle pool sessions got evicted - poolCreateParams.waitTimeout = 3 * 1000 // milliseconds to wait for a session become available - poolCreateParams.maxLifetimeSession = 3600 // maximum time in seconds till a pooled session may exist + poolCreateParams.timeout = C.uint32_t(DefaultSessionTimeout / time.Second) + if P.SessionTimeout > time.Second { + poolCreateParams.timeout = C.uint32_t(P.SessionTimeout / time.Second) // seconds before idle pool sessions get evicted + } + poolCreateParams.waitTimeout = C.uint32_t(DefaultWaitTimeout / time.Millisecond) + if P.WaitTimeout > time.Millisecond { + poolCreateParams.waitTimeout = C.uint32_t(P.WaitTimeout / time.Millisecond) // milliseconds to wait for a session to become available + } + poolCreateParams.maxLifetimeSession = C.uint32_t(DefaultMaxLifeTime / time.Second) + if P.MaxLifeTime > 0 { + poolCreateParams.maxLifetimeSession = C.uint32_t(P.MaxLifeTime / time.Second) // maximum time in seconds till a pooled session may exist + } var dp *C.dpiPool if Log != nil { - Log("C", "dpiPool_create", "username", P.Username, "sid", P.SID, "common", commonCreateParams, "pool", poolCreateParams) + Log("C", "dpiPool_create", "username", P.Username, "conn", connString, "sid", P.SID, "common", commonCreateParams, "pool", fmt.Sprintf("%#v", poolCreateParams)) } - //fmt.Println("POOL create", connString) if C.dpiPool_create( d.dpiContext, cUserName, C.uint32_t(len(P.Username)), @@ -526,7 +563,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { &poolCreateParams, (**C.dpiPool)(unsafe.Pointer(&dp)), ) == C.DPI_FAILURE { - return nil, errors.Wrapf(d.getError(), "params=%s extAuth=%v", P.String(), extAuth) + return nil, errors.Errorf("params=%s extAuth=%v: %w", P.String(), extAuth, d.getError()) } C.dpiPool_setStmtCacheSize(dp, 40) d.mu.Lock() @@ -539,7 +576,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { func (c *conn) acquireConn(user, pass string) error { var connCreateParams C.dpiConnCreateParams if C.dpiContext_initConnCreateParams(c.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return errors.Wrap(c.getError(), "initConnCreateParams") + return errors.Errorf("initConnCreateParams: %w", "", c.getError()) } dc := C.malloc(C.sizeof_void) @@ -572,18 +609,22 @@ func (c *conn) acquireConn(user, pass string) error { (**C.dpiConn)(unsafe.Pointer(&dc)), ) == C.DPI_FAILURE { C.free(unsafe.Pointer(dc)) - return errors.Wrapf(c.getError(), "acquirePoolConnection") + return errors.Errorf("acquirePoolConnection: %w", c.getError()) } + c.mu.Lock() c.dpiConn = (*C.dpiConn)(dc) c.currentUser = user c.newSession = connCreateParams.outNewSession == 1 c.Client, c.Server = c.drv.clientVersion, pool.serverVersion c.timeZone, c.tzOffSecs = pool.timeZone, pool.tzOffSecs + c.mu.Unlock() err := c.init() if err == nil { + c.mu.Lock() pool.serverVersion = c.Server pool.timeZone, pool.tzOffSecs = c.timeZone, c.tzOffSecs + c.mu.Unlock() } return err @@ -593,12 +634,16 @@ func (c *conn) acquireConn(user, pass string) error { // You can use ConnectionParams{...}.StringWithPassword() // as a connection string in sql.Open. type ConnectionParams struct { - Username, Password, SID, ConnClass string - MinSessions, MaxSessions, PoolIncrement int - IsSysDBA, IsSysOper, IsSysASM, IsPrelim bool - HeterogeneousPool bool - StandaloneConnection bool - EnableEvents bool + Username, Password, SID, ConnClass string + // NewPassword is used iff StandaloneConnection is true! + NewPassword string + MinSessions, MaxSessions, PoolIncrement int + WaitTimeout, MaxLifeTime, SessionTimeout time.Duration + IsSysDBA, IsSysOper, IsSysASM, IsPrelim bool + HeterogeneousPool bool + StandaloneConnection bool + EnableEvents bool + Timezone *time.Location } // String returns the string representation of ConnectionParams. @@ -624,47 +669,74 @@ func (P ConnectionParams) string(class, withPassword bool) string { if i := strings.IndexByte(host, '/'); i >= 0 { host, path = host[:i], host[i:] } - cc := "" - if class { - cc = fmt.Sprintf("connectionClass=%s&", url.QueryEscape(P.ConnClass)) + q := make(url.Values, 32) + s := P.ConnClass + if !class { + s = "" } - // params should be sorted lexicographically + q.Add("connectionClass", s) + password := P.Password - if !withPassword { + if withPassword { + q.Add("newPassword", P.NewPassword) + } else { hsh := fnv.New64() io.WriteString(hsh, P.Password) password = "SECRET-" + base64.URLEncoding.EncodeToString(hsh.Sum(nil)) + if P.NewPassword != "" { + hsh.Reset() + io.WriteString(hsh, P.NewPassword) + q.Add("newPassword", "SECRET-"+base64.URLEncoding.EncodeToString(hsh.Sum(nil))) + } + } + s = "" + if P.Timezone != nil { + s = P.Timezone.String() } + q.Add("timezone", s) + B := func(b bool) string { + if b { + return "1" + } + return "0" + } + q.Add("poolMinSessions", strconv.Itoa(P.MinSessions)) + q.Add("poolMaxSessions", strconv.Itoa(P.MaxSessions)) + q.Add("poolIncrement", strconv.Itoa(P.PoolIncrement)) + q.Add("sysdba", B(P.IsSysDBA)) + q.Add("sysoper", B(P.IsSysOper)) + q.Add("sysasm", B(P.IsSysASM)) + q.Add("standaloneConnection", B(P.StandaloneConnection)) + q.Add("enableEvents", B(P.EnableEvents)) + q.Add("heterogeneousPool", B(P.HeterogeneousPool)) + q.Add("prelim", B(P.IsPrelim)) + q.Add("poolWaitTimeout", P.WaitTimeout.String()) + q.Add("poolSessionMaxLifetime", P.MaxLifeTime.String()) + q.Add("poolSessionTimeout", P.SessionTimeout.String()) return (&url.URL{ - Scheme: "oracle", - User: url.UserPassword(P.Username, password), - Host: host, - Path: path, - RawQuery: cc + - fmt.Sprintf("poolIncrement=%d&poolMaxSessions=%d&poolMinSessions=%d&"+ - "sysdba=%d&sysoper=%d&sysasm=%d&"+ - "standaloneConnection=%d&enableEvents=%d&"+ - "heterogeneousPool=%d&prelim=%d", - P.PoolIncrement, P.MaxSessions, P.MinSessions, - b2i(P.IsSysDBA), b2i(P.IsSysOper), b2i(P.IsSysASM), - b2i(P.StandaloneConnection), b2i(P.EnableEvents), - b2i(P.HeterogeneousPool), b2i(P.IsPrelim), - ), + Scheme: "oracle", + User: url.UserPassword(P.Username, password), + Host: host, + Path: path, + RawQuery: q.Encode(), }).String() } // ParseConnString parses the given connection string into a struct. func ParseConnString(connString string) (ConnectionParams, error) { P := ConnectionParams{ - MinSessions: DefaultPoolMinSessions, - MaxSessions: DefaultPoolMaxSessions, - PoolIncrement: DefaultPoolIncrement, - ConnClass: DefaultConnectionClass, + MinSessions: DefaultPoolMinSessions, + MaxSessions: DefaultPoolMaxSessions, + PoolIncrement: DefaultPoolIncrement, + ConnClass: DefaultConnectionClass, + MaxLifeTime: DefaultMaxLifeTime, + WaitTimeout: DefaultWaitTimeout, + SessionTimeout: DefaultSessionTimeout, } if !strings.HasPrefix(connString, "oracle://") { i := strings.IndexByte(connString, '/') if i < 0 { - return P, errors.Errorf("no '/' in connection string") + return P, errors.New("no '/' in connection string") } P.Username, connString = connString[:i], connString[i+1:] @@ -692,13 +764,18 @@ func ParseConnString(connString string) (ConnectionParams, error) { } u, err := url.Parse(connString) if err != nil { - return P, errors.Wrap(err, connString) + return P, errors.Errorf("%s: %w", connString, err) } if usr := u.User; usr != nil { P.Username = usr.Username() P.Password, _ = usr.Password() } P.SID = u.Hostname() + // IPv6 literal address brackets are removed by u.Hostname, + // so we have to put them back + if strings.HasPrefix(u.Host, "[") && !strings.Contains(P.SID[1:], "]") { + P.SID = "[" + P.SID + "]" + } if u.Port() != "" { P.SID += ":" + u.Port() } @@ -724,10 +801,27 @@ func ParseConnString(connString string) (ConnectionParams, error) { } { *task.Dest = q.Get(task.Key) == "1" } + if tz := q.Get("timezone"); tz != "" { + if tz == "local" { + P.Timezone = time.Local + } else if strings.Contains(tz, "/") { + if P.Timezone, err = time.LoadLocation(tz); err != nil { + return P, errors.Errorf("%s: %w", tz, err) + } + } else if off, err := parseTZ(tz); err == nil { + P.Timezone = time.FixedZone(tz, off) + } else { + return P, errors.Errorf("%s: %w", tz, err) + } + } + P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass if P.IsPrelim { P.ConnClass = "" } + if P.StandaloneConnection { + P.NewPassword = q.Get("newPassword") + } for _, task := range []struct { Dest *int @@ -744,7 +838,36 @@ func ParseConnString(connString string) (ConnectionParams, error) { var err error *task.Dest, err = strconv.Atoi(s) if err != nil { - return P, errors.Wrap(err, task.Key+"="+s) + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + } + for _, task := range []struct { + Dest *time.Duration + Key string + }{ + {&P.SessionTimeout, "poolSessionTimeout"}, + {&P.WaitTimeout, "poolWaitTimeout"}, + {&P.MaxLifeTime, "poolSessionMaxLifetime"}, + } { + s := q.Get(task.Key) + if s == "" { + continue + } + var err error + *task.Dest, err = time.ParseDuration(s) + if err != nil { + if !strings.Contains(err.Error(), "time: missing unit in duration") { + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + i, err := strconv.Atoi(s) + if err != nil { + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + base := time.Second + if task.Key == "poolWaitTimeout" { + base = time.Millisecond + } + *task.Dest = time.Duration(i) * base } } if P.MinSessions > P.MaxSessions { @@ -755,7 +878,6 @@ func ParseConnString(connString string) (ConnectionParams, error) { } else if P.PoolIncrement < 1 { P.PoolIncrement = 1 } - return P, nil } @@ -765,6 +887,13 @@ type OraErr struct { code int } +// AsOraErr returns the underlying *OraErr and whether it succeeded. +func AsOraErr(err error) (*OraErr, bool) { + var oerr *OraErr + ok := errors.As(err, &oerr) + return oerr, ok +} + var _ = error((*OraErr)(nil)) // Code returns the OraErr's error code. @@ -867,7 +996,7 @@ func timeZoneFor(hourOffset, minuteOffset C.int8_t) *time.Location { type ctxKey string -const logCtxKey = ctxKey("goracle.Log") +const logCtxKey = ctxKey("godror.Log") type logFunc func(...interface{}) error @@ -883,30 +1012,83 @@ func ContextWithLog(ctx context.Context, logF func(...interface{}) error) contex return context.WithValue(ctx, logCtxKey, logF) } -func parseTZ(s string) (int, error) { - s = strings.TrimSpace(s) - if s == "" { - return 0, io.EOF +var _ = driver.Connector((*connector)(nil)) + +type connector struct { + ConnectionParams + *drv + onInit func(driver.Conn) error +} + +// OpenConnector must parse the name in the same format that Driver.Open +// parses the name parameter. +func (d *drv) OpenConnector(name string) (driver.Connector, error) { + P, err := ParseConnString(name) + if err != nil { + return nil, err } - if s == "Z" || s == "UTC" { - return 0, nil + + return connector{ConnectionParams: P, drv: d}, nil +} + +// Connect returns a connection to the database. +// Connect may return a cached connection (one previously +// closed), but doing so is unnecessary; the sql package +// maintains a pool of idle connections for efficient re-use. +// +// The provided context.Context is for dialing purposes only +// (see net.DialContext) and should not be stored or used for +// other purposes. +// +// The returned connection is only used by one goroutine at a +// time. +func (c connector) Connect(context.Context) (driver.Conn, error) { + conn, err := c.drv.openConn(c.ConnectionParams) + if err != nil || c.onInit == nil || !conn.newSession { + return conn, err + } + if err = c.onInit(conn); err != nil { + conn.close(true) + return nil, err } - var tz int - if i := strings.IndexByte(s, ':'); i >= 0 { - if i64, err := strconv.ParseInt(s[i+1:], 10, 6); err != nil { - return tz, errors.Wrap(err, s) - } else { - tz = int(i64) - } - s = s[:i] + return conn, nil +} + +// Driver returns the underlying Driver of the Connector, +// mainly to maintain compatibility with the Driver method +// on sql.DB. +func (c connector) Driver() driver.Driver { return c.drv } + +// NewConnector returns a driver.Connector to be used with sql.OpenDB, +// which calls the given onInit if the connection is new. +// +// For an example, see NewSessionIniter. +func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { + cxr, err := defaultDrv.OpenConnector(name) + if err != nil { + return nil, err } - if i64, err := strconv.ParseInt(s, 10, 5); err != nil { - return tz, errors.Wrap(err, s) - } else { - if i64 < 0 { - tz = -tz + cx := cxr.(connector) + cx.onInit = onInit + return cx, err +} + +// NewSessionIniter returns a function suitable for use in NewConnector as onInit, +// which calls "ALTER SESSION SET =''" for each element of the given map. +func NewSessionIniter(m map[string]string) func(driver.Conn) error { + return func(cx driver.Conn) error { + for k, v := range m { + qry := fmt.Sprintf("ALTER SESSION SET %s = q'(%s)'", k, strings.Replace(v, "'", "''", -1)) + st, err := cx.Prepare(qry) + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + _, err = st.Exec(nil) //lint:ignore SA1019 it's hard to use ExecContext here + st.Close() + if err != nil { + return err + } } - tz += int(i64 * 3600) + return nil } - return tz, nil } diff --git a/vendor/github.com/godror/godror/drv_posix.go b/vendor/github.com/godror/godror/drv_posix.go new file mode 100644 index 00000000000..c88fa6ec60c --- /dev/null +++ b/vendor/github.com/godror/godror/drv_posix.go @@ -0,0 +1,11 @@ +// +build !windows + +// Copyright 2017 Tamás Gulácsi +// +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 + +package godror + +// #cgo LDFLAGS: -ldl -lpthread +import "C" diff --git a/vendor/github.com/godror/godror/go.mod b/vendor/github.com/godror/godror/go.mod new file mode 100644 index 00000000000..d7c794d6705 --- /dev/null +++ b/vendor/github.com/godror/godror/go.mod @@ -0,0 +1,12 @@ +module github.com/godror/godror + +go 1.12 + +require ( + github.com/go-kit/kit v0.9.0 + github.com/go-logfmt/logfmt v0.4.0 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/google/go-cmp v0.3.1 + golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 +) diff --git a/vendor/github.com/godror/godror/go.sum b/vendor/github.com/godror/godror/go.sum new file mode 100644 index 00000000000..2456fcd618c --- /dev/null +++ b/vendor/github.com/godror/godror/go.sum @@ -0,0 +1,14 @@ +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/gopkg.in/goracle.v2/lob.go b/vendor/github.com/godror/godror/lob.go similarity index 77% rename from vendor/gopkg.in/goracle.v2/lob.go rename to vendor/github.com/godror/godror/lob.go index 567dbaa843d..a914462d464 100644 --- a/vendor/gopkg.in/goracle.v2/lob.go +++ b/vendor/github.com/godror/godror/lob.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include "dpiImpl.h" @@ -25,7 +15,7 @@ import ( "unicode/utf8" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // Lob is for reading/writing a LOB. @@ -98,7 +88,9 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { if dlr.sizePlusOne == 0 { // never read size before if C.dpiLob_getSize(dlr.dpiLob, &dlr.sizePlusOne) == C.DPI_FAILURE { - return 0, errors.Wrap(dlr.getError(), "getSize") + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil + return 0, errors.Errorf("getSize: %w", dlr.getError()) } dlr.sizePlusOne++ } @@ -108,12 +100,14 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { return 0, io.EOF } if C.dpiLob_readBytes(dlr.dpiLob, dlr.offset+1, n, (*C.char)(unsafe.Pointer(&p[0])), &n) == C.DPI_FAILURE { + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil err := dlr.getError() if dlr.finished = err.(interface{ Code() int }).Code() == 1403; dlr.finished { dlr.offset += n return int(n), io.EOF } - return int(n), errors.Wrapf(err, "lob=%p offset=%d n=%d", dlr.dpiLob, dlr.offset, len(p)) + return int(n), errors.Errorf("lob=%p offset=%d n=%d: %w", dlr.dpiLob, dlr.offset, len(p), err) } //fmt.Printf("read %d\n", n) if dlr.IsClob { @@ -123,6 +117,9 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { } var err error if n == 0 || dlr.offset+1 >= dlr.sizePlusOne { + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil + dlr.finished = true err = io.EOF } return int(n), err @@ -141,14 +138,14 @@ func (dlw *dpiLobWriter) Write(p []byte) (int, error) { if !dlw.opened { //fmt.Printf("open %p\n", lob) if C.dpiLob_openResource(lob) == C.DPI_FAILURE { - return 0, errors.Wrapf(dlw.getError(), "openResources(%p)", lob) + return 0, errors.Errorf("openResources(%p): %w", lob, dlw.getError()) } dlw.opened = true } n := C.uint64_t(len(p)) if C.dpiLob_writeBytes(lob, dlw.offset+1, (*C.char)(unsafe.Pointer(&p[0])), n) == C.DPI_FAILURE { - err := errors.Wrapf(dlw.getError(), "writeBytes(%p, offset=%d, data=%d)", lob, dlw.offset, n) + err := errors.Errorf("writeBytes(%p, offset=%d, data=%d): %w", lob, dlw.offset, n, dlw.getError()) dlw.dpiLob = nil C.dpiLob_closeResource(lob) return 0, err @@ -171,7 +168,7 @@ func (dlw *dpiLobWriter) Close() error { if ec, ok := err.(interface{ Code() int }); ok && !dlw.opened && ec.Code() == 22289 { // cannot perform %s operation on an unopened file or LOB return nil } - return errors.Wrapf(err, "closeResource(%p)", lob) + return errors.Errorf("closeResource(%p): %w", lob, err) } return nil } @@ -186,6 +183,19 @@ type DirectLob struct { var _ = io.ReaderAt((*DirectLob)(nil)) var _ = io.WriterAt((*DirectLob)(nil)) +// NewTempLob returns a temporary LOB as DirectLob. +func (c *conn) NewTempLob(isClob bool) (*DirectLob, error) { + typ := C.uint(C.DPI_ORACLE_TYPE_BLOB) + if isClob { + typ = C.DPI_ORACLE_TYPE_CLOB + } + lob := DirectLob{conn: c} + if C.dpiConn_newTempLob(c.dpiConn, typ, &lob.dpiLob) == C.DPI_FAILURE { + return nil, errors.Errorf("newTempLob: %w", c.getError()) + } + return &lob, nil +} + // Close the Lob. func (dl *DirectLob) Close() error { if !dl.opened { @@ -193,7 +203,7 @@ func (dl *DirectLob) Close() error { } dl.opened = false if C.dpiLob_closeResource(dl.dpiLob) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "closeResource") + return errors.Errorf("closeResource: %w", dl.conn.getError()) } return nil } @@ -202,7 +212,7 @@ func (dl *DirectLob) Close() error { func (dl *DirectLob) Size() (int64, error) { var n C.uint64_t if C.dpiLob_getSize(dl.dpiLob, &n) == C.DPI_FAILURE { - return int64(n), errors.Wrap(dl.conn.getError(), "getSize") + return int64(n), errors.Errorf("getSize: %w", dl.conn.getError()) } return int64(n), nil } @@ -210,7 +220,7 @@ func (dl *DirectLob) Size() (int64, error) { // Trim the LOB to the given size. func (dl *DirectLob) Trim(size int64) error { if C.dpiLob_trim(dl.dpiLob, C.uint64_t(size)) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "trim") + return errors.Errorf("trim: %w", dl.conn.getError()) } return nil } @@ -219,7 +229,7 @@ func (dl *DirectLob) Trim(size int64) error { // The LOB is cleared first. func (dl *DirectLob) Set(p []byte) error { if C.dpiLob_setFromBytes(dl.dpiLob, (*C.char)(unsafe.Pointer(&p[0])), C.uint64_t(len(p))) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "setFromBytes") + return errors.Errorf("setFromBytes: %w", dl.conn.getError()) } return nil } @@ -228,7 +238,7 @@ func (dl *DirectLob) Set(p []byte) error { func (dl *DirectLob) ReadAt(p []byte, offset int64) (int, error) { n := C.uint64_t(len(p)) if C.dpiLob_readBytes(dl.dpiLob, C.uint64_t(offset)+1, n, (*C.char)(unsafe.Pointer(&p[0])), &n) == C.DPI_FAILURE { - return int(n), errors.Wrap(dl.conn.getError(), "readBytes") + return int(n), errors.Errorf("readBytes: %w", dl.conn.getError()) } return int(n), nil } @@ -238,14 +248,14 @@ func (dl *DirectLob) WriteAt(p []byte, offset int64) (int, error) { if !dl.opened { //fmt.Printf("open %p\n", lob) if C.dpiLob_openResource(dl.dpiLob) == C.DPI_FAILURE { - return 0, errors.Wrapf(dl.conn.getError(), "openResources(%p)", dl.dpiLob) + return 0, errors.Errorf("openResources(%p): %w", dl.dpiLob, dl.conn.getError()) } dl.opened = true } n := C.uint64_t(len(p)) if C.dpiLob_writeBytes(dl.dpiLob, C.uint64_t(offset)+1, (*C.char)(unsafe.Pointer(&p[0])), n) == C.DPI_FAILURE { - return int(n), errors.Wrap(dl.conn.getError(), "writeBytes") + return int(n), errors.Errorf("writeBytes: %w", dl.conn.getError()) } return int(n), nil } diff --git a/vendor/gopkg.in/goracle.v2/obj.go b/vendor/github.com/godror/godror/obj.go similarity index 62% rename from vendor/gopkg.in/goracle.v2/obj.go rename to vendor/github.com/godror/godror/obj.go index e8f97afcfd9..a5d35505420 100644 --- a/vendor/gopkg.in/goracle.v2/obj.go +++ b/vendor/github.com/godror/godror/obj.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -21,23 +11,25 @@ package goracle */ import "C" import ( + "context" "fmt" "reflect" + "strings" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) var _ = fmt.Printf // Object represents a dpiObject. type Object struct { - scratch Data ObjectType + scratch Data dpiObject *C.dpiObject } -func (O *Object) getError() error { return O.drv.getError() } +func (O *Object) getError() error { return O.conn.getError() } // ErrNoSuchKey is the error for missing key in lookup. var ErrNoSuchKey = errors.New("no such key") @@ -49,33 +41,35 @@ func (O *Object) GetAttribute(data *Data, name string) error { } attr, ok := O.Attributes[name] if !ok { - return errors.Wrap(ErrNoSuchKey, name) + return errors.Errorf("%s: %w", name, ErrNoSuchKey) } data.reset() + if data.dpiData == nil { + data.dpiData = &C.dpiData{isNull: 0} + } data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType - wasNull := data.dpiData == nil // the maximum length of that buffer must be supplied // in the value.asBytes.length attribute before calling this function. if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { - var a [22]byte - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), 22) + var a [39]byte + C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(len(a))) } + //fmt.Printf("getAttributeValue(%p, %p, %d, %+v)\n", O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) if C.dpiObject_getAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - if wasNull { - C.free(unsafe.Pointer(data.dpiData)) - data.dpiData = nil - } - return errors.Wrapf(O.getError(), "getAttributeValue(obj=%+v, attr=%+v, typ=%d)", O, attr.dpiObjectAttr, data.NativeTypeNum) + return errors.Errorf("getAttributeValue(%q, obj=%+v, attr=%+v, typ=%d): %w", name, O, attr.dpiObjectAttr, data.NativeTypeNum, O.getError()) } //fmt.Printf("getAttributeValue(%p, %q=%p, %d, %+v)\n", O.dpiObject, attr.Name, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) return nil } -// SetAttribute sets the i-th attribute with data. +// SetAttribute sets the named attribute with data. func (O *Object) SetAttribute(name string, data *Data) error { + if !strings.Contains(name, `"`) { + name = strings.ToUpper(name) + } attr := O.Attributes[name] if data.NativeTypeNum == 0 { data.NativeTypeNum = attr.NativeTypeNum @@ -87,7 +81,18 @@ func (O *Object) SetAttribute(name string, data *Data) error { return nil } -// ResetAttributes prepare all atributes for use the object as IN parameter +// Set is a convenience function to set the named attribute with the given value. +func (O *Object) Set(name string, v interface{}) error { + if data, ok := v.(*Data); ok { + return O.SetAttribute(name, data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.SetAttribute(name, &O.scratch) +} + +// ResetAttributes prepare all attributes for use the object as IN parameter func (O *Object) ResetAttributes() error { var data Data for _, attr := range O.Attributes { @@ -95,8 +100,8 @@ func (O *Object) ResetAttributes() error { data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { - var a [22]byte - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), 22) + a := make([]byte, attr.Precision) + C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(attr.Precision)) } if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { return O.getError() @@ -131,15 +136,25 @@ func (O *Object) ObjectRef() *Object { return O } +// Collection returns &ObjectCollection{Object: O} iff the Object is a collection. +// Otherwise it returns nil. +func (O *Object) Collection() *ObjectCollection { + if O.ObjectType.CollectionOf == nil { + return nil + } + return &ObjectCollection{Object: O} +} + // Close releases a reference to the object. func (O *Object) Close() error { - if O.dpiObject == nil { + obj := O.dpiObject + O.dpiObject = nil + if obj == nil { return nil } - if rc := C.dpiObject_release(O.dpiObject); rc == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "error on close object") + if C.dpiObject_release(obj) == C.DPI_FAILURE { + return errors.Errorf("error on close object: %w", O.getError()) } - O.dpiObject = nil return nil } @@ -157,7 +172,6 @@ var ErrNotExist = errors.New("not exist") // AsSlice retrieves the collection into a slice. func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { - var data Data var dr reflect.Value needsInit := dest == nil if !needsInit { @@ -165,12 +179,12 @@ func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { } for i, err := O.First(); err == nil; i, err = O.Next(i) { if O.CollectionOf.NativeTypeNum == C.DPI_NATIVE_TYPE_OBJECT { - data.ObjectType = *O.CollectionOf + O.scratch.ObjectType = *O.CollectionOf } - if err = O.Get(&data, i); err != nil { + if err = O.GetItem(&O.scratch, i); err != nil { return dest, err } - vr := reflect.ValueOf(data.Get()) + vr := reflect.ValueOf(O.scratch.Get()) if needsInit { needsInit = false length, lengthErr := O.Len() @@ -184,31 +198,53 @@ func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { return dr.Interface(), nil } -// Append data to the collection. -func (O *ObjectCollection) Append(data *Data) error { +// AppendData to the collection. +func (O *ObjectCollection) AppendData(data *Data) error { if C.dpiObject_appendElement(O.dpiObject, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "append(%d)", data.NativeTypeNum) + return errors.Errorf("append(%d): %w", data.NativeTypeNum, O.getError()) } return nil } +// Append v to the collection. +func (O *ObjectCollection) Append(v interface{}) error { + if data, ok := v.(*Data); ok { + return O.AppendData(data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.AppendData(&O.scratch) +} + +// AppendObject adds an Object to the collection. +func (O *ObjectCollection) AppendObject(obj *Object) error { + O.scratch = Data{ + ObjectType: obj.ObjectType, + NativeTypeNum: C.DPI_NATIVE_TYPE_OBJECT, + dpiData: &C.dpiData{isNull: 1}, + } + O.scratch.SetObject(obj) + return O.Append(&O.scratch) +} + // Delete i-th element of the collection. func (O *ObjectCollection) Delete(i int) error { if C.dpiObject_deleteElementByIndex(O.dpiObject, C.int32_t(i)) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "delete(%d)", i) + return errors.Errorf("delete(%d): %w", i, O.getError()) } return nil } -// Get the i-th element of the collection into data. -func (O *ObjectCollection) Get(data *Data, i int) error { +// GetItem gets the i-th element of the collection into data. +func (O *ObjectCollection) GetItem(data *Data, i int) error { if data == nil { panic("data cannot be nil") } idx := C.int32_t(i) var exists C.int if C.dpiObject_getElementExistsByIndex(O.dpiObject, idx, &exists) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "exists(%d)", idx) + return errors.Errorf("exists(%d): %w", idx, O.getError()) } if exists == 0 { return ErrNotExist @@ -217,25 +253,43 @@ func (O *ObjectCollection) Get(data *Data, i int) error { data.NativeTypeNum = O.CollectionOf.NativeTypeNum data.ObjectType = *O.CollectionOf if C.dpiObject_getElementValueByIndex(O.dpiObject, idx, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "get(%d[%d])", idx, data.NativeTypeNum) + return errors.Errorf("get(%d[%d]): %w", idx, data.NativeTypeNum, O.getError()) } return nil } -// Set the i-th element of the collection with data. -func (O *ObjectCollection) Set(i int, data *Data) error { +// Get the i-th element of the collection. +func (O *ObjectCollection) Get(i int) (interface{}, error) { + var data Data + err := O.GetItem(&data, i) + return data.Get(), err +} + +// SetItem sets the i-th element of the collection with data. +func (O *ObjectCollection) SetItem(i int, data *Data) error { if C.dpiObject_setElementValueByIndex(O.dpiObject, C.int32_t(i), data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "set(%d[%d])", i, data.NativeTypeNum) + return errors.Errorf("set(%d[%d]): %w", i, data.NativeTypeNum, O.getError()) } return nil } +// Set the i-th element of the collection with value. +func (O *ObjectCollection) Set(i int, v interface{}) error { + if data, ok := v.(*Data); ok { + return O.SetItem(i, data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.SetItem(i, &O.scratch) +} + // First returns the first element's index of the collection. func (O *ObjectCollection) First() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getFirstIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "first") + return 0, errors.Errorf("first: %w", O.getError()) } if exists == 1 { return int(idx), nil @@ -248,7 +302,7 @@ func (O *ObjectCollection) Last() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getLastIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "last") + return 0, errors.Errorf("last: %w", O.getError()) } if exists == 1 { return int(idx), nil @@ -261,7 +315,7 @@ func (O *ObjectCollection) Next(i int) (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getNextIndex(O.dpiObject, C.int32_t(i), &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrapf(O.getError(), "next(%d)", i) + return 0, errors.Errorf("next(%d): %w", i, O.getError()) } if exists == 1 { return int(idx), nil @@ -273,7 +327,7 @@ func (O *ObjectCollection) Next(i int) (int, error) { func (O *ObjectCollection) Len() (int, error) { var size C.int32_t if C.dpiObject_getSize(O.dpiObject, &size) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "len") + return 0, errors.Errorf("len: %w", O.getError()) } return int(size), nil } @@ -288,12 +342,13 @@ func (O *ObjectCollection) Trim(n int) error { // ObjectType holds type info of an Object. type ObjectType struct { + dpiObjectType *C.dpiObjectType + conn *conn + Schema, Name string DBSize, ClientSizeInBytes, CharSize int CollectionOf *ObjectType Attributes map[string]ObjectAttribute - dpiObjectType *C.dpiObjectType - drv *drv OracleTypeNum C.dpiOracleTypeNum NativeTypeNum C.dpiNativeTypeNum Precision int16 @@ -301,7 +356,14 @@ type ObjectType struct { FsPrecision uint8 } -func (t ObjectType) getError() error { return t.drv.getError() } +func (t ObjectType) getError() error { return t.conn.getError() } + +func (t ObjectType) String() string { + if t.Schema == "" { + return t.Name + } + return t.Schema + "." + t.Name +} // FullName returns the object's name with the schame prepended. func (t ObjectType) FullName() string { @@ -312,66 +374,103 @@ func (t ObjectType) FullName() string { } // GetObjectType returns the ObjectType of a name. +// +// The name is uppercased! Because here Oracle seems to be case-sensitive. +// To leave it as is, enclose it in "-s! func (c *conn) GetObjectType(name string) (ObjectType, error) { + c.mu.Lock() + defer c.mu.Unlock() + if !strings.Contains(name, "\"") { + name = strings.ToUpper(name) + } + if o, ok := c.objTypes[name]; ok { + return o, nil + } cName := C.CString(name) defer func() { C.free(unsafe.Pointer(cName)) }() objType := (*C.dpiObjectType)(C.malloc(C.sizeof_void)) if C.dpiConn_getObjectType(c.dpiConn, cName, C.uint32_t(len(name)), &objType) == C.DPI_FAILURE { C.free(unsafe.Pointer(objType)) - return ObjectType{}, errors.Wrapf(c.getError(), "getObjectType(%q) conn=%p", name, c.dpiConn) + return ObjectType{}, errors.Errorf("getObjectType(%q) conn=%p: %w", name, c.dpiConn, c.getError()) + } + t := ObjectType{conn: c, dpiObjectType: objType} + err := t.init() + if err == nil { + c.objTypes[name] = t } - t := ObjectType{drv: c.drv, dpiObjectType: objType} - return t, t.init() + return t, err } // NewObject returns a new Object with ObjectType type. +// +// As with all Objects, you MUST call Close on it when not needed anymore! func (t ObjectType) NewObject() (*Object, error) { obj := (*C.dpiObject)(C.malloc(C.sizeof_void)) if C.dpiObjectType_createObject(t.dpiObjectType, &obj) == C.DPI_FAILURE { C.free(unsafe.Pointer(obj)) return nil, t.getError() } - return &Object{ObjectType: t, dpiObject: obj}, nil + O := &Object{ObjectType: t, dpiObject: obj} + // https://github.com/oracle/odpi/issues/112#issuecomment-524479532 + return O, O.ResetAttributes() +} + +// NewCollection returns a new Collection object with ObjectType type. +// If the ObjectType is not a Collection, it returns ErrNotCollection error. +func (t ObjectType) NewCollection() (*ObjectCollection, error) { + if t.CollectionOf == nil { + return nil, ErrNotCollection + } + O, err := t.NewObject() + if err != nil { + return nil, err + } + return &ObjectCollection{Object: O}, nil } // Close releases a reference to the object type. -func (t *ObjectType) Close() error { +func (t *ObjectType) close() error { + if t == nil { + return nil + } + attributes, d := t.Attributes, t.dpiObjectType + t.Attributes, t.dpiObjectType = nil, nil - for _, attr := range t.Attributes { + for _, attr := range attributes { err := attr.Close() if err != nil { return err } } - t.Attributes = nil - d := t.dpiObjectType - t.dpiObjectType = nil if d == nil { return nil } - if rc := C.dpiObjectType_release(d); rc == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "error on close object type") + if C.dpiObjectType_release(d) == C.DPI_FAILURE { + return errors.Errorf("error on close object type: %w", t.getError()) } return nil } -func wrapObject(d *drv, objectType *C.dpiObjectType, object *C.dpiObject) (*Object, error) { +func wrapObject(c *conn, objectType *C.dpiObjectType, object *C.dpiObject) (*Object, error) { if objectType == nil { return nil, errors.New("objectType is nil") } + if C.dpiObject_addRef(object) == C.DPI_FAILURE { + return nil, c.getError() + } o := &Object{ - ObjectType: ObjectType{dpiObjectType: objectType, drv: d}, + ObjectType: ObjectType{dpiObjectType: objectType, conn: c}, dpiObject: object, } return o, o.init() } func (t *ObjectType) init() error { - if t.drv == nil { - panic("drv is nil") + if t.conn == nil { + panic("conn is nil") } if t.Name != "" && t.Attributes != nil { return nil @@ -381,15 +480,18 @@ func (t *ObjectType) init() error { } var info C.dpiObjectTypeInfo if C.dpiObjectType_getInfo(t.dpiObjectType, &info) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.getInfo", t) + return errors.Errorf("%v.getInfo: %w", t, t.getError()) } t.Schema = C.GoStringN(info.schema, C.int(info.schemaLength)) t.Name = C.GoStringN(info.name, C.int(info.nameLength)) t.CollectionOf = nil - numAttributes := int(info.numAttributes) + if t.conn.objTypes == nil { + t.conn.objTypes = make(map[string]ObjectType) + } + numAttributes := int(info.numAttributes) if info.isCollection == 1 { - t.CollectionOf = &ObjectType{drv: t.drv} + t.CollectionOf = &ObjectType{conn: t.conn} if err := t.CollectionOf.fromDataTypeInfo(info.elementTypeInfo); err != nil { return err } @@ -400,6 +502,7 @@ func (t *ObjectType) init() error { } if numAttributes == 0 { t.Attributes = map[string]ObjectAttribute{} + t.conn.objTypes[t.FullName()] = *t return nil } t.Attributes = make(map[string]ObjectAttribute, numAttributes) @@ -408,18 +511,18 @@ func (t *ObjectType) init() error { C.uint16_t(len(attrs)), (**C.dpiObjectAttr)(unsafe.Pointer(&attrs[0])), ) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.getAttributes", t) + return errors.Errorf("%v.getAttributes: %w", t, t.getError()) } for i, attr := range attrs { var attrInfo C.dpiObjectAttrInfo if C.dpiObjectAttr_getInfo(attr, &attrInfo) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.attr_getInfo", attr) + return errors.Errorf("%v.attr_getInfo: %w", attr, t.getError()) } if Log != nil { Log("i", i, "attrInfo", attrInfo) } typ := attrInfo.typeInfo - sub, err := objectTypeFromDataTypeInfo(t.drv, typ) + sub, err := objectTypeFromDataTypeInfo(t.conn, typ) if err != nil { return err } @@ -431,6 +534,7 @@ func (t *ObjectType) init() error { //fmt.Printf("%d=%q. typ=%+v sub=%+v\n", i, objAttr.Name, typ, sub) t.Attributes[objAttr.Name] = objAttr } + t.conn.objTypes[t.FullName()] = *t return nil } @@ -447,14 +551,14 @@ func (t *ObjectType) fromDataTypeInfo(typ C.dpiDataTypeInfo) error { t.FsPrecision = uint8(typ.fsPrecision) return t.init() } -func objectTypeFromDataTypeInfo(drv *drv, typ C.dpiDataTypeInfo) (ObjectType, error) { - if drv == nil { - panic("drv nil") +func objectTypeFromDataTypeInfo(conn *conn, typ C.dpiDataTypeInfo) (ObjectType, error) { + if conn == nil { + panic("conn is nil") } if typ.oracleTypeNum == 0 { panic("typ is nil") } - t := ObjectType{drv: drv} + t := ObjectType{conn: conn} err := t.fromDataTypeInfo(typ) return t, err } @@ -469,11 +573,11 @@ type ObjectAttribute struct { // Close the ObjectAttribute. func (A ObjectAttribute) Close() error { attr := A.dpiObjectAttr + A.dpiObjectAttr = nil + if attr == nil { return nil } - - A.dpiObjectAttr = nil if C.dpiObjectAttr_release(attr) == C.DPI_FAILURE { return A.getError() } @@ -481,10 +585,10 @@ func (A ObjectAttribute) Close() error { } // GetObjectType returns the ObjectType for the name. -func GetObjectType(ex Execer, typeName string) (ObjectType, error) { - c, err := getConn(ex) +func GetObjectType(ctx context.Context, ex Execer, typeName string) (ObjectType, error) { + c, err := getConn(ctx, ex) if err != nil { - return ObjectType{}, errors.WithMessage(err, "getConn for "+typeName) + return ObjectType{}, errors.Errorf("getConn for %s: %w", typeName, err) } return c.GetObjectType(typeName) } diff --git a/vendor/gopkg.in/goracle.v2/odpi/CONTRIBUTING.md b/vendor/github.com/godror/godror/odpi/CONTRIBUTING.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/odpi/CONTRIBUTING.md rename to vendor/github.com/godror/godror/odpi/CONTRIBUTING.md diff --git a/vendor/gopkg.in/goracle.v2/odpi/LICENSE.md b/vendor/github.com/godror/godror/odpi/LICENSE.md similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/LICENSE.md rename to vendor/github.com/godror/godror/odpi/LICENSE.md index 20b6fc956fa..cb344b76c16 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/LICENSE.md +++ b/vendor/github.com/godror/godror/odpi/LICENSE.md @@ -215,4 +215,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - diff --git a/vendor/gopkg.in/goracle.v2/odpi/README.md b/vendor/github.com/godror/godror/odpi/README.md similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/README.md rename to vendor/github.com/godror/godror/odpi/README.md index a8e1decf845..fa911cc2130 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/README.md +++ b/vendor/github.com/godror/godror/odpi/README.md @@ -1,4 +1,4 @@ -# ODPI-C version 3.1 +# ODPI-C version 3.3 Oracle Database Programming Interface for C (ODPI-C) is an open source library of C code that simplifies access to Oracle Database for applications written in @@ -48,6 +48,7 @@ Third-party Drivers: * [ruby-ODPI ](https://github.com/kubo/ruby-odpi) Ruby Interface. * [rust-oracle ](https://github.com/kubo/rust-oracle) Driver for Rust. * [Oracle.jl](https://github.com/felipenoris/Oracle.jl) Driver for Julia. +* [oranif](https://github.com/K2InformaticsGmbH/oranif) Driver for Erlang. ## License diff --git a/vendor/gopkg.in/goracle.v2/odpi/embed/README.md b/vendor/github.com/godror/godror/odpi/embed/README.md similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/embed/README.md rename to vendor/github.com/godror/godror/odpi/embed/README.md index 5dc0fb5ca15..dfe0b4524c0 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/embed/README.md +++ b/vendor/github.com/godror/godror/odpi/embed/README.md @@ -1,4 +1,3 @@ This directory contains the file dpi.c which can be used to embed ODPI-C within your project without having to manage the individual files that make up the library. The files can also be compiled independently if that is preferred. - diff --git a/vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c b/vendor/github.com/godror/godror/odpi/embed/dpi.c similarity index 98% rename from vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c rename to vendor/github.com/godror/godror/odpi/embed/dpi.c index e47f3f21460..7d0c6dc83bb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c +++ b/vendor/github.com/godror/godror/odpi/embed/dpi.c @@ -37,6 +37,7 @@ #include "../src/dpiOci.c" #include "../src/dpiOracleType.c" #include "../src/dpiPool.c" +#include "../src/dpiQueue.c" #include "../src/dpiRowid.c" #include "../src/dpiSodaColl.c" #include "../src/dpiSodaCollCursor.c" @@ -47,4 +48,3 @@ #include "../src/dpiSubscr.c" #include "../src/dpiUtils.c" #include "../src/dpiVar.c" - diff --git a/vendor/gopkg.in/goracle.v2/odpi/include/dpi.h b/vendor/github.com/godror/godror/odpi/include/dpi.h similarity index 96% rename from vendor/gopkg.in/goracle.v2/odpi/include/dpi.h rename to vendor/github.com/godror/godror/odpi/include/dpi.h index 8606774900c..58b3a2d5867 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/include/dpi.h +++ b/vendor/github.com/godror/godror/odpi/include/dpi.h @@ -44,8 +44,8 @@ // define ODPI-C version information #define DPI_MAJOR_VERSION 3 -#define DPI_MINOR_VERSION 1 -#define DPI_PATCH_LEVEL 4 +#define DPI_MINOR_VERSION 3 +#define DPI_PATCH_LEVEL 0 #define DPI_VERSION_SUFFIX #define DPI_STR_HELPER(x) #x @@ -152,7 +152,6 @@ typedef uint32_t dpiEventType; #define DPI_EVENT_STARTUP 1 #define DPI_EVENT_SHUTDOWN 2 #define DPI_EVENT_SHUTDOWN_ANY 3 -#define DPI_EVENT_DROP_DB 4 #define DPI_EVENT_DEREG 5 #define DPI_EVENT_OBJCHANGE 6 #define DPI_EVENT_QUERYCHANGE 7 @@ -414,6 +413,7 @@ typedef struct dpiObjectAttrInfo dpiObjectAttrInfo; typedef struct dpiObjectTypeInfo dpiObjectTypeInfo; typedef struct dpiPoolCreateParams dpiPoolCreateParams; typedef struct dpiQueryInfo dpiQueryInfo; +typedef struct dpiQueue dpiQueue; typedef struct dpiShardingKeyColumn dpiShardingKeyColumn; typedef struct dpiSodaColl dpiSodaColl; typedef struct dpiSodaCollNames dpiSodaCollNames; @@ -571,6 +571,7 @@ struct dpiPoolCreateParams { uint32_t maxLifetimeSession; const char *plsqlFixupCallback; uint32_t plsqlFixupCallbackLength; + uint32_t maxSessionsPerShard; }; // structure used for transferring query metadata from ODPI-C @@ -642,6 +643,8 @@ struct dpiSubscrCreateParams { uint8_t groupingClass; uint32_t groupingValue; uint8_t groupingType; + uint64_t outRegId; + int clientInitiated; }; // structure used for transferring messages in subscription callbacks @@ -836,6 +839,10 @@ int dpiConn_newEnqOptions(dpiConn *conn, dpiEnqOptions **options); // create a new message properties object and return it int dpiConn_newMsgProps(dpiConn *conn, dpiMsgProps **props); +// create a new AQ queue +int dpiConn_newQueue(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue); + // create a new temporary LOB int dpiConn_newTempLob(dpiConn *conn, dpiOracleTypeNum lobType, dpiLob **lob); @@ -1202,10 +1209,18 @@ int dpiMsgProps_getExceptionQ(dpiMsgProps *props, const char **value, // return the number of seconds until the message expires int dpiMsgProps_getExpiration(dpiMsgProps *props, int32_t *value); +// return the message id for the message (after enqueuing or dequeuing) +int dpiMsgProps_getMsgId(dpiMsgProps *props, const char **value, + uint32_t *valueLength); + // return the original message id for the message int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, uint32_t *valueLength); +// return the payload of the message (object or bytes) +int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj, + const char **value, uint32_t *valueLength); + // return the priority of the message int dpiMsgProps_getPriority(dpiMsgProps *props, int32_t *value); @@ -1233,6 +1248,13 @@ int dpiMsgProps_setExpiration(dpiMsgProps *props, int32_t value); int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, uint32_t valueLength); +// set the payload of the message (as a series of bytes) +int dpiMsgProps_setPayloadBytes(dpiMsgProps *props, const char *value, + uint32_t valueLength); + +// set the payload of the message (as an object) +int dpiMsgProps_setPayloadObject(dpiMsgProps *props, dpiObject *obj); + // set the priority of the message int dpiMsgProps_setPriority(dpiMsgProps *props, int32_t value); @@ -1398,6 +1420,35 @@ int dpiPool_setTimeout(dpiPool *pool, uint32_t value); int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value); +//----------------------------------------------------------------------------- +// AQ Queue Methods (dpiQueue) +//----------------------------------------------------------------------------- + +// add a reference to the queue +int dpiQueue_addRef(dpiQueue *queue); + +// dequeue multiple messages from the queue +int dpiQueue_deqMany(dpiQueue *queue, uint32_t *numProps, dpiMsgProps **props); + +// dequeue a single message from the queue +int dpiQueue_deqOne(dpiQueue *queue, dpiMsgProps **props); + +// enqueue multiple message to the queue +int dpiQueue_enqMany(dpiQueue *queue, uint32_t numProps, dpiMsgProps **props); + +// enqueue a single message to the queue +int dpiQueue_enqOne(dpiQueue *queue, dpiMsgProps *props); + +// get a reference to the dequeue options associated with the queue +int dpiQueue_getDeqOptions(dpiQueue *queue, dpiDeqOptions **options); + +// get a reference to the enqueue options associated with the queue +int dpiQueue_getEnqOptions(dpiQueue *queue, dpiEnqOptions **options); + +// release a reference to the queue +int dpiQueue_release(dpiQueue *queue); + + //----------------------------------------------------------------------------- // SODA Collection Methods (dpiSodaColl) //----------------------------------------------------------------------------- @@ -1440,6 +1491,10 @@ int dpiSodaColl_getMetadata(dpiSodaColl *coll, const char **value, int dpiSodaColl_getName(dpiSodaColl *coll, const char **value, uint32_t *valueLength); +// insert multiple documents into the SODA collection +int dpiSodaColl_insertMany(dpiSodaColl *coll, uint32_t numDocs, + dpiSodaDoc **docs, uint32_t flags, dpiSodaDoc **insertedDocs); + // insert a document into the SODA collection int dpiSodaColl_insertOne(dpiSodaColl *coll, dpiSodaDoc *doc, uint32_t flags, dpiSodaDoc **insertedDoc); @@ -1644,6 +1699,9 @@ int dpiStmt_getImplicitResult(dpiStmt *stmt, dpiStmt **implicitResult); // return information about the statement int dpiStmt_getInfo(dpiStmt *stmt, dpiStmtInfo *info); +// get the rowid of the last row affected by a DML statement +int dpiStmt_getLastRowid(dpiStmt *stmt, dpiRowid **rowid); + // get the number of query columns (zero implies the statement is not a query) int dpiStmt_getNumQueryColumns(dpiStmt *stmt, uint32_t *numQueryColumns); @@ -1754,4 +1812,3 @@ int dpiVar_setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt); int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements); #endif - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c b/vendor/github.com/godror/godror/odpi/src/dpiConn.c similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c rename to vendor/github.com/godror/godror/odpi/src/dpiConn.c index e1c8edbe841..faa5dc5266b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiConn.c @@ -37,8 +37,7 @@ static int dpiConn__getSession(dpiConn *conn, uint32_t mode, static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, uint32_t handleType, const char *userName, uint32_t userNameLength, const char *password, uint32_t passwordLength, - const dpiConnCreateParams *params, void **shardingKey, - void **superShardingKey, dpiError *error); + const dpiConnCreateParams *params, dpiError *error); static int dpiConn__setShardingKey(dpiConn *conn, void **shardingKey, void *handle, uint32_t handleType, uint32_t attribute, const char *action, dpiShardingKeyColumn *columns, uint8_t numColumns, @@ -65,23 +64,6 @@ static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle, return DPI_FAILURE; } - // allocate a new service context handle which will use the new environment - // handle independent of the original service context handle - conn->handle = NULL; - if (dpiOci__handleAlloc(conn->env->handle, &conn->handle, - DPI_OCI_HTYPE_SVCCTX, "allocate service context handle", - error) < 0) - return DPI_FAILURE; - - // set these handles on the newly created service context - if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX, conn->serverHandle, - 0, DPI_OCI_ATTR_SERVER, "set server handle", error) < 0) - return DPI_FAILURE; - if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX, - conn->sessionHandle, 0, DPI_OCI_ATTR_SESSION, "set session handle", - error) < 0) - return DPI_FAILURE; - return DPI_SUCCESS; } @@ -93,7 +75,7 @@ static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle, //----------------------------------------------------------------------------- static int dpiConn__check(dpiConn *conn, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(conn, DPI_HTYPE_CONN, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(conn, DPI_HTYPE_CONN, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(conn, error); } @@ -224,8 +206,6 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, // handle connections created with an external handle if (conn->externalHandle) { - if (conn->handle) - dpiOci__handleFree(conn->handle, DPI_OCI_HTYPE_SVCCTX); conn->sessionHandle = NULL; // handle standalone connections @@ -254,7 +234,8 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, // update last time used (if the session isn't going to be dropped) // clear last time used (if the session is going to be dropped) - if (conn->sessionHandle) { + // do nothing, however, if not using a pool or the pool is being closed + if (conn->sessionHandle && conn->pool && conn->pool->handle) { // get the pointer from the context associated with the session lastTimeUsed = NULL; @@ -315,9 +296,20 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, conn->sessionHandle = NULL; } - conn->handle = NULL; conn->serverHandle = NULL; + + // destroy sharding and super sharding key descriptors, if applicable + if (conn->shardingKey) { + dpiOci__descriptorFree(conn->shardingKey, DPI_OCI_DTYPE_SHARDING_KEY); + conn->shardingKey = NULL; + } + if (conn->superShardingKey) { + dpiOci__descriptorFree(conn->superShardingKey, + DPI_OCI_DTYPE_SHARDING_KEY); + conn->superShardingKey = NULL; + } + return DPI_SUCCESS; } @@ -333,6 +325,8 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, const dpiCommonCreateParams *commonParams, dpiConnCreateParams *createParams, dpiError *error) { + void *envHandle = NULL; + // allocate handle lists for statements, LOBs and objects if (dpiHandleList__create(&conn->openStmts, error) < 0) return DPI_FAILURE; @@ -341,8 +335,29 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, if (dpiHandleList__create(&conn->objects, error) < 0) return DPI_FAILURE; + // if an external service context handle is provided, acquire the + // environment handle from it; need a temporary environment handle in order + // to do so + if (createParams->externalHandle) { + error->env = conn->env; + if (dpiOci__envNlsCreate(&conn->env->handle, DPI_OCI_DEFAULT, 0, 0, + error) < 0) + return DPI_FAILURE; + if (dpiOci__handleAlloc(conn->env->handle, &error->handle, + DPI_OCI_HTYPE_ERROR, "allocate temp OCI error", error) < 0) + return DPI_FAILURE; + if (dpiOci__attrGet(createParams->externalHandle, DPI_OCI_HTYPE_SVCCTX, + &envHandle, NULL, DPI_OCI_ATTR_ENV, "get env handle", + error) < 0) + return DPI_FAILURE; + dpiOci__handleFree(conn->env->handle, DPI_OCI_HTYPE_ENV); + error->handle = NULL; + conn->env->handle = NULL; + } + // initialize environment (for non-pooled connections) - if (!pool && dpiEnv__init(conn->env, context, commonParams, error) < 0) + if (!pool && dpiEnv__init(conn->env, context, commonParams, envHandle, + error) < 0) return DPI_FAILURE; // if a handle is specified, use it @@ -416,7 +431,7 @@ static int dpiConn__createStandalone(dpiConn *conn, const char *userName, // populate attributes on the session handle if (dpiConn__setAttributesFromCreateParams(conn, conn->sessionHandle, DPI_OCI_HTYPE_SESSION, userName, userNameLength, password, - passwordLength, createParams, NULL, NULL, error) < 0) + passwordLength, createParams, error) < 0) return DPI_FAILURE; // set the session handle on the service context handle @@ -505,11 +520,16 @@ static int dpiConn__get(dpiConn *conn, const char *userName, const char *connectString, uint32_t connectStringLength, dpiConnCreateParams *createParams, dpiPool *pool, dpiError *error) { - void *shardingKey = NULL, *superShardingKey = NULL; int externalAuth, status; void *authInfo; uint32_t mode; + // clear pointers if length is 0 + if (userNameLength == 0) + userName = NULL; + if (passwordLength == 0) + password = NULL; + // set things up for the call to acquire a session if (pool) { dpiGen__setRefCount(pool, error, 1); @@ -547,8 +567,7 @@ static int dpiConn__get(dpiConn *conn, const char *userName, // set attributes for create parameters if (dpiConn__setAttributesFromCreateParams(conn, authInfo, DPI_OCI_HTYPE_AUTHINFO, userName, userNameLength, password, - passwordLength, createParams, &shardingKey, &superShardingKey, - error) < 0) { + passwordLength, createParams, error) < 0) { dpiOci__handleFree(authInfo, DPI_OCI_HTYPE_AUTHINFO); return DPI_FAILURE; } @@ -556,13 +575,6 @@ static int dpiConn__get(dpiConn *conn, const char *userName, // get a session from the pool status = dpiConn__getSession(conn, mode, connectString, connectStringLength, createParams, authInfo, error); - if (status == DPI_SUCCESS && pool) { - if (shardingKey) - dpiOci__descriptorFree(shardingKey, DPI_OCI_DTYPE_SHARDING_KEY); - if (superShardingKey) - dpiOci__descriptorFree(superShardingKey, - DPI_OCI_DTYPE_SHARDING_KEY); - } dpiOci__handleFree(authInfo, DPI_OCI_HTYPE_AUTHINFO); if (status < 0) return status; @@ -630,6 +642,19 @@ static int dpiConn__getHandles(dpiConn *conn, dpiError *error) } +//----------------------------------------------------------------------------- +// dpiConn__getRawTDO() [INTERNAL] +// Internal method used for ensuring that the RAW TDO has been cached on the +//connection. +//----------------------------------------------------------------------------- +int dpiConn__getRawTDO(dpiConn *conn, dpiError *error) +{ + if (conn->rawTDO) + return DPI_SUCCESS; + return dpiOci__typeByName(conn, "SYS", 3, "RAW", 3, &conn->rawTDO, error); +} + + //----------------------------------------------------------------------------- // dpiConn__getServerCharset() [INTERNAL] // Internal method used for retrieving the server character set. This is used @@ -850,8 +875,7 @@ static int dpiConn__setAppContext(void *handle, uint32_t handleType, static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, uint32_t handleType, const char *userName, uint32_t userNameLength, const char *password, uint32_t passwordLength, - const dpiConnCreateParams *params, void **shardingKey, - void **superShardingKey, dpiError *error) + const dpiConnCreateParams *params, dpiError *error) { uint32_t purity; @@ -882,17 +906,20 @@ static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, // set sharding key and super sharding key parameters if (params->shardingKeyColumns && params->numShardingKeyColumns > 0) { - if (dpiConn__setShardingKey(conn, shardingKey, handle, handleType, - DPI_OCI_ATTR_SHARDING_KEY, "set sharding key", + if (dpiConn__setShardingKey(conn, &conn->shardingKey, handle, + handleType, DPI_OCI_ATTR_SHARDING_KEY, "set sharding key", params->shardingKeyColumns, params->numShardingKeyColumns, error) < 0) return DPI_FAILURE; } if (params->superShardingKeyColumns && params->numSuperShardingKeyColumns > 0) { - if (dpiConn__setShardingKey(conn, superShardingKey, handle, handleType, - DPI_OCI_ATTR_SUPER_SHARDING_KEY, "set super sharding key", - params->superShardingKeyColumns, + if (params->numShardingKeyColumns == 0) + return dpiError__set(error, "ensure sharding key", + DPI_ERR_MISSING_SHARDING_KEY); + if (dpiConn__setShardingKey(conn, &conn->superShardingKey, handle, + handleType, DPI_OCI_ATTR_SUPER_SHARDING_KEY, + "set super sharding key", params->superShardingKeyColumns, params->numSuperShardingKeyColumns, error) < 0) return DPI_FAILURE; } @@ -995,13 +1022,14 @@ static int dpiConn__setShardingKey(dpiConn *conn, void **shardingKey, static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, dpiShardingKeyColumn *column, dpiError *error) { + dpiShardingOciDate shardingDateValue; + uint32_t colLen = 0, descType = 0; const dpiOracleType *oracleType; dpiOciNumber numberValue; + int convertOk, status; dpiOciDate dateValue; - uint32_t colLen = 0; void *col = NULL; uint16_t colType; - int convertOk; oracleType = dpiOracleType__getFromNum(column->oracleTypeNum, error); if (!oracleType) @@ -1044,14 +1072,61 @@ static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, } break; case DPI_ORACLE_TYPE_DATE: - col = &dateValue; - colLen = sizeof(dateValue); - colType = DPI_SQLT_DAT; if (column->nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { if (dpiDataBuffer__toOracleDate(&column->value, &dateValue) < 0) return DPI_FAILURE; convertOk = 1; + } else if (column->nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + if (dpiDataBuffer__toOracleDateFromDouble(&column->value, + conn->env, error, &dateValue) < 0) + return DPI_FAILURE; + convertOk = 1; + } + + // for sharding only, the type must be SQLT_DAT, which uses a + // different format for storing the date values + if (convertOk) { + col = &shardingDateValue; + colLen = sizeof(shardingDateValue); + colType = DPI_SQLT_DAT; + shardingDateValue.century = + ((uint8_t) (dateValue.year / 100)) + 100; + shardingDateValue.year = (dateValue.year % 100) + 100; + shardingDateValue.month = dateValue.month; + shardingDateValue.day = dateValue.day; + shardingDateValue.hour = dateValue.hour + 1; + shardingDateValue.minute = dateValue.minute + 1; + shardingDateValue.second = dateValue.second + 1; + } + break; + case DPI_ORACLE_TYPE_TIMESTAMP: + case DPI_ORACLE_TYPE_TIMESTAMP_TZ: + case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: + colLen = sizeof(void*); + colType = DPI_SQLT_TIMESTAMP; + if (column->nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { + descType = DPI_OCI_DTYPE_TIMESTAMP; + if (dpiOci__descriptorAlloc(conn->env->handle, &col, descType, + "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestamp(&column->value, conn->env, + error, col, 0) < 0) { + dpiOci__descriptorFree(col, descType); + return DPI_FAILURE; + } + convertOk = 1; + } else if (column->nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + descType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + if (dpiOci__descriptorAlloc(conn->env->handle, &col, descType, + "alloc LTZ timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestampFromDouble(&column->value, + conn->env, error, col) < 0) { + dpiOci__descriptorFree(col, descType); + return DPI_FAILURE; + } + convertOk = 1; } break; default: @@ -1060,8 +1135,11 @@ static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, if (!convertOk) return dpiError__set(error, "check type", DPI_ERR_NOT_SUPPORTED); - return dpiOci__shardingKeyColumnAdd(shardingKey, col, colLen, colType, + status = dpiOci__shardingKeyColumnAdd(shardingKey, col, colLen, colType, error); + if (descType) + dpiOci__descriptorFree(col, descType); + return status; } @@ -1282,7 +1360,7 @@ int dpiConn_create(const dpiContext *context, const char *userName, int status; // validate parameters - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, conn) @@ -1347,8 +1425,6 @@ int dpiConn_create(const dpiContext *context, const char *userName, dpiError__set(&error, "check pool", DPI_ERR_NOT_CONNECTED); return dpiGen__endPublicFn(context, DPI_FAILURE, &error); } - if (dpiEnv__initError(createParams->pool->env, &error) < 0) - return dpiGen__endPublicFn(context, DPI_FAILURE, &error); status = dpiPool__acquireConnection(createParams->pool, userName, userNameLength, password, passwordLength, createParams, conn, &error); @@ -1366,8 +1442,7 @@ int dpiConn_create(const dpiContext *context, const char *userName, } *conn = tempConn; - dpiHandlePool__release(tempConn->env->errorHandles, error.handle, &error); - error.handle = NULL; + dpiHandlePool__release(tempConn->env->errorHandles, &error.handle); return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -1404,7 +1479,6 @@ int dpiConn_deqObject(dpiConn *conn, const char *queueName, uint32_t queueNameLength, dpiDeqOptions *options, dpiMsgProps *props, dpiObject *payload, const char **msgId, uint32_t *msgIdLength) { - void *ociMsgId = NULL; dpiError error; // validate parameters @@ -1426,19 +1500,15 @@ int dpiConn_deqObject(dpiConn *conn, const char *queueName, // dequeue message if (dpiOci__aqDeq(conn, queueName, options->handle, props->handle, payload->type->tdo, &payload->instance, &payload->indicator, - &ociMsgId, &error) < 0) { + &props->msgIdRaw, &error) < 0) { if (error.buffer->code == 25228) { - if (ociMsgId) - dpiOci__rawResize(conn->env->handle, &ociMsgId, 0, &error); *msgId = NULL; *msgIdLength = 0; return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); } - if (dpiMsgProps__extractMsgId(props, ociMsgId, msgId, msgIdLength, - &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + dpiMsgProps__extractMsgId(props, msgId, msgIdLength); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1451,7 +1521,6 @@ int dpiConn_enqObject(dpiConn *conn, const char *queueName, uint32_t queueNameLength, dpiEnqOptions *options, dpiMsgProps *props, dpiObject *payload, const char **msgId, uint32_t *msgIdLength) { - void *ociMsgId = NULL; dpiError error; // validate parameters @@ -1473,11 +1542,9 @@ int dpiConn_enqObject(dpiConn *conn, const char *queueName, // enqueue message if (dpiOci__aqEnq(conn, queueName, options->handle, props->handle, payload->type->tdo, &payload->instance, &payload->indicator, - &ociMsgId, &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - if (dpiMsgProps__extractMsgId(props, ociMsgId, msgId, msgIdLength, - &error) < 0) + &props->msgIdRaw, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + dpiMsgProps__extractMsgId(props, msgId, msgIdLength); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1682,15 +1749,15 @@ int dpiConn_getServerVersion(dpiConn *conn, const char **releaseString, // validate parameters if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(conn, releaseString) - DPI_CHECK_PTR_NOT_NULL(conn, releaseStringLength) DPI_CHECK_PTR_NOT_NULL(conn, versionInfo) // get server version if (dpiConn__getServerVersion(conn, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - *releaseString = conn->releaseString; - *releaseStringLength = conn->releaseStringLength; + if (releaseString) + *releaseString = conn->releaseString; + if (releaseStringLength) + *releaseStringLength = conn->releaseStringLength; memcpy(versionInfo, &conn->versionInfo, sizeof(dpiVersionInfo)); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1806,22 +1873,34 @@ int dpiConn_newTempLob(dpiConn *conn, dpiOracleTypeNum lobType, dpiLob **lob) //----------------------------------------------------------------------------- int dpiConn_newMsgProps(dpiConn *conn, dpiMsgProps **props) { - dpiMsgProps *tempProps; dpiError error; + int status; if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(conn, props) - if (dpiGen__allocate(DPI_HTYPE_MSG_PROPS, conn->env, (void**) &tempProps, - &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - if (dpiMsgProps__create(tempProps, conn, &error) < 0) { - dpiMsgProps__free(tempProps, &error); - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - } + status = dpiMsgProps__allocate(conn, props, &error); + return dpiGen__endPublicFn(conn, status, &error); +} - *props = tempProps; - return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); + +//----------------------------------------------------------------------------- +// dpiConn_newQueue() [PUBLIC] +// Create a new AQ queue object and return it. +//----------------------------------------------------------------------------- +int dpiConn_newQueue(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue) +{ + dpiError error; + int status; + + if (dpiConn__check(conn, __func__, &error) < 0) + return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + DPI_CHECK_PTR_AND_LENGTH(conn, name) + DPI_CHECK_PTR_NOT_NULL(conn, queue) + status = dpiQueue__allocate(conn, name, nameLength, payloadType, queue, + &error); + return dpiGen__endPublicFn(conn, status, &error); } @@ -2148,6 +2227,7 @@ int dpiConn_subscribe(dpiConn *conn, dpiSubscrCreateParams *params, int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr) { dpiError error; + int status; if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); @@ -2155,12 +2235,15 @@ int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr) &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); if (subscr->registered) { - if (dpiOci__subscriptionUnRegister(conn, subscr, &error) < 0) + dpiMutex__acquire(subscr->mutex); + status = dpiOci__subscriptionUnRegister(conn, subscr, &error); + if (status == DPI_SUCCESS) + subscr->registered = 0; + dpiMutex__release(subscr->mutex); + if (status < 0) return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error); - subscr->registered = 0; } dpiGen__setRefCount(subscr, &error, -1); return dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c b/vendor/github.com/godror/godror/odpi/src/dpiContext.c similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c rename to vendor/github.com/godror/godror/odpi/src/dpiContext.c index 315afe32ea9..e9adb18a33e 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiContext.c @@ -156,7 +156,7 @@ int dpiContext_destroy(dpiContext *context) char message[80]; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); dpiUtils__clearMemory(&context->checkInt, sizeof(context->checkInt)); @@ -181,7 +181,7 @@ int dpiContext_getClientVersion(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, versionInfo) @@ -214,7 +214,7 @@ int dpiContext_initCommonCreateParams(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) @@ -233,7 +233,7 @@ int dpiContext_initConnCreateParams(const dpiContext *context, dpiConnCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) @@ -259,17 +259,22 @@ int dpiContext_initPoolCreateParams(const dpiContext *context, dpiPoolCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) - // size changed in version 3.1; can be dropped once version 4 released - if (context->dpiMinorVersion > 0) + // size changed in versions 3.1 and 3.3 + // changes can be dropped once version 4 released + if (context->dpiMinorVersion > 2) { dpiContext__initPoolCreateParams(params); - else { + } else { dpiContext__initPoolCreateParams(&localParams); - memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v30)); + if (context->dpiMinorVersion > 0) { + memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v32)); + } else { + memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v30)); + } } return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -284,7 +289,7 @@ int dpiContext_initSodaOperOptions(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, options) @@ -300,13 +305,25 @@ int dpiContext_initSodaOperOptions(const dpiContext *context, int dpiContext_initSubscrCreateParams(const dpiContext *context, dpiSubscrCreateParams *params) { + dpiSubscrCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) - dpiContext__initSubscrCreateParams(params); + + // size changed in versions 3.2 and 3.3 + // changes can be dropped once version 4 released + if (context->dpiMinorVersion > 2) { + dpiContext__initSubscrCreateParams(params); + } else { + dpiContext__initSubscrCreateParams(&localParams); + if (context->dpiMinorVersion > 1) { + memcpy(params, &localParams, sizeof(dpiSubscrCreateParams__v32)); + } else { + memcpy(params, &localParams, sizeof(dpiSubscrCreateParams__v30)); + } + } return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c b/vendor/github.com/godror/godror/odpi/src/dpiData.c similarity index 89% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c rename to vendor/github.com/godror/godror/odpi/src/dpiData.c index dc669f4bc7f..57d3faac309 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiData.c @@ -46,6 +46,36 @@ int dpiDataBuffer__fromOracleDate(dpiDataBuffer *data, } +//----------------------------------------------------------------------------- +// dpiDataBuffer__fromOracleDateAsDouble() [INTERNAL] +// Populate the data from an dpiOciDate structure as a double value (number +// of milliseconds since January 1, 1970). +//----------------------------------------------------------------------------- +int dpiDataBuffer__fromOracleDateAsDouble(dpiDataBuffer *data, + dpiEnv *env, dpiError *error, dpiOciDate *oracleValue) +{ + void *timestamp; + int status; + + // allocate and populate a timestamp with the value of the date + if (dpiOci__descriptorAlloc(env->handle, ×tamp, + DPI_OCI_DTYPE_TIMESTAMP_LTZ, "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiOci__dateTimeConstruct(env->handle, timestamp, oracleValue->year, + oracleValue->month, oracleValue->day, oracleValue->hour, + oracleValue->minute, oracleValue->second, 0, NULL, 0, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + + // now calculate the number of milliseconds since January 1, 1970 + status = dpiDataBuffer__fromOracleTimestampAsDouble(data, env, error, + timestamp); + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return status; +} + + //----------------------------------------------------------------------------- // dpiDataBuffer__fromOracleIntervalDS() [INTERNAL] // Populate the data from an OCIInterval structure (days/seconds). @@ -305,6 +335,58 @@ int dpiDataBuffer__toOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue) } +//----------------------------------------------------------------------------- +// dpiDataBuffer__toOracleDateFromDouble() [INTERNAL] +// Populate the data in an dpiOciDate structure given a double (number of +// milliseconds since January 1, 1970). +//----------------------------------------------------------------------------- +int dpiDataBuffer__toOracleDateFromDouble(dpiDataBuffer *data, dpiEnv *env, + dpiError *error, dpiOciDate *oracleValue) +{ + void *timestamp, *timestampLTZ; + uint32_t fsecond; + + // allocate a descriptor to acquire a timestamp + if (dpiOci__descriptorAlloc(env->handle, ×tampLTZ, + DPI_OCI_DTYPE_TIMESTAMP_LTZ, "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestampFromDouble(data, env, error, + timestampLTZ) < 0) { + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + + // allocate a plain timestamp and convert to it + if (dpiOci__descriptorAlloc(env->handle, ×tamp, + DPI_OCI_DTYPE_TIMESTAMP, "alloc plain timestamp", error) < 0) { + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + if (dpiOci__dateTimeConvert(env->handle, timestampLTZ, timestamp, + error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + + // populate date structure + if (dpiOci__dateTimeGetDate(env->handle, timestamp, &oracleValue->year, + &oracleValue->month, &oracleValue->day, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_FAILURE; + } + if (dpiOci__dateTimeGetTime(env->handle, timestamp, &oracleValue->hour, + &oracleValue->minute, &oracleValue->second, &fsecond, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_FAILURE; + } + + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiDataBuffer__toOracleIntervalDS() [INTERNAL] // Populate the data in an OCIInterval structure (days/seconds). @@ -815,4 +897,3 @@ void dpiData_setUint64(dpiData *data, uint64_t value) data->isNull = 0; data->value.asUint64 = value; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c b/vendor/github.com/godror/godror/odpi/src/dpiDebug.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c rename to vendor/github.com/godror/godror/odpi/src/dpiDebug.c index 6188d7d84a7..28b8776475f 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiDebug.c @@ -181,4 +181,3 @@ void dpiDebug__print(const char *format, ...) (void) vfprintf(dpiDebugStream, formatWithPrefix, varArgs); va_end(varArgs); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c b/vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c rename to vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c index 309eb05e5a6..35cb84727ae 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c @@ -60,7 +60,7 @@ static int dpiDeqOptions__getAttrValue(dpiDeqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -82,7 +82,7 @@ static int dpiDeqOptions__setAttrValue(dpiDeqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -162,7 +162,7 @@ int dpiDeqOptions_getMsgId(dpiDeqOptions *options, const char **value, dpiError error; void *rawValue; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -309,7 +309,7 @@ int dpiDeqOptions_setMsgId(dpiDeqOptions *options, const char *value, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -367,4 +367,3 @@ int dpiDeqOptions_setWait(dpiDeqOptions *options, uint32_t value) return dpiDeqOptions__setAttrValue(options, DPI_OCI_ATTR_WAIT, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c b/vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c rename to vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c index 8b073188c33..24bf60a3229 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c @@ -60,7 +60,7 @@ static int dpiEnqOptions__getAttrValue(dpiEnqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -82,7 +82,7 @@ static int dpiEnqOptions__setAttrValue(dpiEnqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -171,4 +171,3 @@ int dpiEnqOptions_setVisibility(dpiEnqOptions *options, dpiVisibility value) return dpiEnqOptions__setAttrValue(options, DPI_OCI_ATTR_VISIBILITY, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c b/vendor/github.com/godror/godror/odpi/src/dpiEnv.c similarity index 68% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c rename to vendor/github.com/godror/godror/odpi/src/dpiEnv.c index e7dff7730a2..c1a2c3f7d61 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiEnv.c @@ -24,7 +24,7 @@ void dpiEnv__free(dpiEnv *env, dpiError *error) { if (env->threaded) dpiMutex__destroy(env->mutex); - if (env->handle) { + if (env->handle && !env->externalHandle) { dpiOci__handleFree(env->handle, DPI_OCI_HTYPE_ENV); env->handle = NULL; } @@ -67,52 +67,68 @@ int dpiEnv__getEncodingInfo(dpiEnv *env, dpiEncodingInfo *info) //----------------------------------------------------------------------------- // dpiEnv__init() [INTERNAL] -// Initialize the environment structure by creating the OCI environment and -// populating information about the environment. +// Initialize the environment structure. If an external handle is provided it +// is used directly; otherwise, a new OCI environment handle is created. In +// either case, information about the environment is stored for later use. //----------------------------------------------------------------------------- int dpiEnv__init(dpiEnv *env, const dpiContext *context, - const dpiCommonCreateParams *params, dpiError *error) + const dpiCommonCreateParams *params, void *externalHandle, + dpiError *error) { char timezoneBuffer[20]; size_t timezoneLength; - // lookup encoding - if (params->encoding && dpiGlobal__lookupCharSet(params->encoding, - &env->charsetId, error) < 0) - return DPI_FAILURE; + // store context and version information + env->context = context; + env->versionInfo = context->versionInfo; - // check for identical encoding before performing lookup - if (params->nencoding && params->encoding && - strcmp(params->nencoding, params->encoding) == 0) - env->ncharsetId = env->charsetId; - else if (params->nencoding && dpiGlobal__lookupCharSet(params->nencoding, - &env->ncharsetId, error) < 0) - return DPI_FAILURE; + // an external handle is available, use it directly + if (externalHandle) { + env->handle = externalHandle; + env->externalHandle = 1; - // both charsetId and ncharsetId must be zero or both must be non-zero - // use NLS routine to look up missing value, if needed - if (env->charsetId && !env->ncharsetId) { - if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_NCHARSET_ID, - &env->ncharsetId, error) < 0) - return DPI_FAILURE; - } else if (!env->charsetId && env->ncharsetId) { - if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_CHARSET_ID, + // otherwise, lookup encodings + } else { + + // lookup encoding + if (params->encoding && dpiGlobal__lookupCharSet(params->encoding, &env->charsetId, error) < 0) return DPI_FAILURE; - } - // create the new environment handle - env->context = context; - env->versionInfo = context->versionInfo; - if (dpiOci__envNlsCreate(&env->handle, params->createMode | DPI_OCI_OBJECT, - env->charsetId, env->ncharsetId, error) < 0) - return DPI_FAILURE; + // check for identical encoding before performing lookup of national + // character set encoding + if (params->nencoding && params->encoding && + strcmp(params->nencoding, params->encoding) == 0) + env->ncharsetId = env->charsetId; + else if (params->nencoding && + dpiGlobal__lookupCharSet(params->nencoding, + &env->ncharsetId, error) < 0) + return DPI_FAILURE; + + // both charsetId and ncharsetId must be zero or both must be non-zero + // use NLS routine to look up missing value, if needed + if (env->charsetId && !env->ncharsetId) { + if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_NCHARSET_ID, + &env->ncharsetId, error) < 0) + return DPI_FAILURE; + } else if (!env->charsetId && env->ncharsetId) { + if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_CHARSET_ID, + &env->charsetId, error) < 0) + return DPI_FAILURE; + } + + // create new environment handle + if (dpiOci__envNlsCreate(&env->handle, + params->createMode | DPI_OCI_OBJECT, + env->charsetId, env->ncharsetId, error) < 0) + return DPI_FAILURE; + + } - // create the error handle pool and acquire the first error handle + // create the error handle pool if (dpiHandlePool__create(&env->errorHandles, error) < 0) return DPI_FAILURE; - if (dpiEnv__initError(env, error) < 0) - return DPI_FAILURE; + error->env = env; // if threaded, create mutex for reference counts if (params->createMode & DPI_OCI_THREADED) @@ -162,28 +178,3 @@ int dpiEnv__init(dpiEnv *env, const dpiContext *context, return DPI_SUCCESS; } - - -//----------------------------------------------------------------------------- -// dpiEnv__initError() [INTERNAL] -// Retrieve the OCI error handle to use for error handling, from a pool of -// error handles common to the environment handle. The environment that was -// used to create the error handle is stored in the error structure so that -// the encoding and character set can be retrieved in the event of an OCI -// error (which uses the CHAR encoding of the environment). -//----------------------------------------------------------------------------- -int dpiEnv__initError(dpiEnv *env, dpiError *error) -{ - error->env = env; - if (dpiHandlePool__acquire(env->errorHandles, &error->handle, error) < 0) - return DPI_FAILURE; - - if (!error->handle) { - if (dpiOci__handleAlloc(env->handle, &error->handle, - DPI_OCI_HTYPE_ERROR, "allocate OCI error", error) < 0) - return DPI_FAILURE; - } - - return DPI_SUCCESS; -} - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c b/vendor/github.com/godror/godror/odpi/src/dpiError.c similarity index 85% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c rename to vendor/github.com/godror/godror/odpi/src/dpiError.c index c76070562cb..aac57b92f18 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiError.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. // This program is free software: you can modify it and/or redistribute it // under the terms of: // @@ -18,21 +18,125 @@ #include "dpiErrorMessages.h" //----------------------------------------------------------------------------- -// dpiError__check() [INTERNAL] -// Checks to see if the status of the last call resulted in an error -// condition. If so, the error is populated. Note that trailing newlines and -// spaces are truncated from the message if they exist. If the connection is -// not NULL a check is made to see if the connection is no longer viable. +// dpiError__getInfo() [INTERNAL] +// Get the error state from the error structure. Returns DPI_FAILURE as a +// convenience to the caller. +//----------------------------------------------------------------------------- +int dpiError__getInfo(dpiError *error, dpiErrorInfo *info) +{ + if (!info) + return DPI_FAILURE; + info->code = error->buffer->code; + info->offset = error->buffer->offset; + info->message = error->buffer->message; + info->messageLength = error->buffer->messageLength; + info->fnName = error->buffer->fnName; + info->action = error->buffer->action; + info->isRecoverable = error->buffer->isRecoverable; + info->encoding = error->buffer->encoding; + switch(info->code) { + case 12154: // TNS:could not resolve the connect identifier specified + info->sqlState = "42S02"; + break; + case 22: // invalid session ID; access denied + case 378: // buffer pools cannot be created as specified + case 602: // Internal programming exception + case 603: // ORACLE server session terminated by fatal error + case 604: // error occurred at recursive SQL level + case 609: // could not attach to incoming connection + case 1012: // not logged on + case 1033: // ORACLE initialization or shutdown in progress + case 1041: // internal error. hostdef extension doesn't exist + case 1043: // user side memory corruption + case 1089: // immediate shutdown or close in progress + case 1090: // shutdown in progress + case 1092: // ORACLE instance terminated. Disconnection forced + case 3113: // end-of-file on communication channel + case 3114: // not connected to ORACLE + case 3122: // attempt to close ORACLE-side window on user side + case 3135: // connection lost contact + case 12153: // TNS:not connected + case 27146: // post/wait initialization failed + case 28511: // lost RPC connection to heterogeneous remote agent + info->sqlState = "01002"; + break; + default: + if (error->buffer->code == 0 && + error->buffer->errorNum == (dpiErrorNum) 0) + info->sqlState = "00000"; + else info->sqlState = "HY000"; + break; + } + return DPI_FAILURE; +} + + +//----------------------------------------------------------------------------- +// dpiError__initHandle() [INTERNAL] +// Retrieve the OCI error handle to use for error handling, from a pool of +// error handles common to the environment handle stored on the error. This +// environment also controls the encoding of OCI errors (which uses the CHAR +// encoding of the environment). +//----------------------------------------------------------------------------- +int dpiError__initHandle(dpiError *error) +{ + if (dpiHandlePool__acquire(error->env->errorHandles, &error->handle, + error) < 0) + return DPI_FAILURE; + if (!error->handle) { + if (dpiOci__handleAlloc(error->env->handle, &error->handle, + DPI_OCI_HTYPE_ERROR, "allocate OCI error", error) < 0) + return DPI_FAILURE; + } + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiError__set() [INTERNAL] +// Set the error buffer to the specified DPI error. Returns DPI_FAILURE as a +// convenience to the caller. +//----------------------------------------------------------------------------- +int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum, + ...) +{ + va_list varArgs; + + if (error) { + error->buffer->code = 0; + error->buffer->isRecoverable = 0; + error->buffer->offset = 0; + strcpy(error->buffer->encoding, DPI_CHARSET_NAME_UTF8); + error->buffer->action = action; + error->buffer->errorNum = errorNum; + va_start(varArgs, errorNum); + error->buffer->messageLength = + (uint32_t) vsnprintf(error->buffer->message, + sizeof(error->buffer->message), + dpiErrorMessages[errorNum - DPI_ERR_NO_ERR], varArgs); + va_end(varArgs); + if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS) + dpiDebug__print("internal error %.*s (%s / %s)\n", + error->buffer->messageLength, error->buffer->message, + error->buffer->fnName, action); + } + return DPI_FAILURE; +} + + +//----------------------------------------------------------------------------- +// dpiError__setFromOCI() [INTERNAL] +// Called when an OCI error has occurred and sets the error structure with +// the contents of that error. Note that trailing newlines and spaces are +// truncated from the message if they exist. If the connection is not NULL a +// check is made to see if the connection is no longer viable. The value +// DPI_FAILURE is returned as a convenience to the caller. //----------------------------------------------------------------------------- -int dpiError__check(dpiError *error, int status, dpiConn *conn, +int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn, const char *action) { uint32_t callTimeout; - // no error has taken place - if (status == DPI_OCI_SUCCESS || status == DPI_OCI_SUCCESS_WITH_INFO) - return DPI_SUCCESS; - // special error cases if (status == DPI_OCI_INVALID_HANDLE) return dpiError__set(error, action, DPI_ERR_INVALID_HANDLE, "OCI"); @@ -98,6 +202,7 @@ int dpiError__check(dpiError *error, int status, dpiConn *conn, conn->deadSession = 1; break; case 3136: // inbound connection timed out + case 3156: // OCI call timed out case 12161: // TNS:internal error: partial data received callTimeout = 0; if (conn->env->versionInfo->versionNum >= 18) @@ -115,90 +220,3 @@ int dpiError__check(dpiError *error, int status, dpiConn *conn, return DPI_FAILURE; } - - -//----------------------------------------------------------------------------- -// dpiError__getInfo() [INTERNAL] -// Get the error state from the error structure. Returns DPI_FAILURE as a -// convenience to the caller. -//----------------------------------------------------------------------------- -int dpiError__getInfo(dpiError *error, dpiErrorInfo *info) -{ - if (!info) - return DPI_FAILURE; - info->code = error->buffer->code; - info->offset = error->buffer->offset; - info->message = error->buffer->message; - info->messageLength = error->buffer->messageLength; - info->fnName = error->buffer->fnName; - info->action = error->buffer->action; - info->isRecoverable = error->buffer->isRecoverable; - info->encoding = error->buffer->encoding; - switch(info->code) { - case 12154: // TNS:could not resolve the connect identifier specified - info->sqlState = "42S02"; - break; - case 22: // invalid session ID; access denied - case 378: // buffer pools cannot be created as specified - case 602: // Internal programming exception - case 603: // ORACLE server session terminated by fatal error - case 604: // error occurred at recursive SQL level - case 609: // could not attach to incoming connection - case 1012: // not logged on - case 1033: // ORACLE initialization or shutdown in progress - case 1041: // internal error. hostdef extension doesn't exist - case 1043: // user side memory corruption - case 1089: // immediate shutdown or close in progress - case 1090: // shutdown in progress - case 1092: // ORACLE instance terminated. Disconnection forced - case 3113: // end-of-file on communication channel - case 3114: // not connected to ORACLE - case 3122: // attempt to close ORACLE-side window on user side - case 3135: // connection lost contact - case 12153: // TNS:not connected - case 27146: // post/wait initialization failed - case 28511: // lost RPC connection to heterogeneous remote agent - info->sqlState = "01002"; - break; - default: - if (error->buffer->code == 0 && - error->buffer->errorNum == (dpiErrorNum) 0) - info->sqlState = "00000"; - else info->sqlState = "HY000"; - break; - } - return DPI_FAILURE; -} - - -//----------------------------------------------------------------------------- -// dpiError__set() [INTERNAL] -// Set the error buffer to the specified DPI error. Returns DPI_FAILURE as a -// convenience to the caller. -//----------------------------------------------------------------------------- -int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum, - ...) -{ - va_list varArgs; - - if (error) { - error->buffer->code = 0; - error->buffer->isRecoverable = 0; - error->buffer->offset = 0; - strcpy(error->buffer->encoding, DPI_CHARSET_NAME_UTF8); - error->buffer->action = action; - error->buffer->errorNum = errorNum; - va_start(varArgs, errorNum); - error->buffer->messageLength = - (uint32_t) vsnprintf(error->buffer->message, - sizeof(error->buffer->message), - dpiErrorMessages[errorNum - DPI_ERR_NO_ERR], varArgs); - va_end(varArgs); - if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS) - dpiDebug__print("internal error %.*s (%s / %s)\n", - error->buffer->messageLength, error->buffer->message, - error->buffer->fnName, action); - } - return DPI_FAILURE; -} - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h b/vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h rename to vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h index fd87de21279..1de52a2b17b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h +++ b/vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h @@ -83,5 +83,8 @@ static const char* const dpiErrorMessages[DPI_ERR_MAX - DPI_ERR_NO_ERR] = { "DPI-1067: call timeout of %u ms exceeded with ORA-%d", // DPI_ERR_CALL_TIMEOUT "DPI-1068: SODA cursor was already closed", // DPI_ERR_SODA_CURSOR_CLOSED "DPI-1069: proxy user name must be enclosed in [] when using external authentication", // DPI_ERR_EXT_AUTH_INVALID_PROXY + "DPI-1070: no payload provided in message properties", // DPI_ERR_QUEUE_NO_PAYLOAD + "DPI-1071: payload type in message properties must match the payload type of the queue", // DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE + "DPI-1072: the Oracle Client library version is unsupported", // DPI_ERR_ORACLE_CLIENT_UNSUPPORTED + "DPI-1073: sharding key is required when specifying a super sharding key", // DPI_ERR_MISSING_SHARDING_KEY }; - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c b/vendor/github.com/godror/godror/odpi/src/dpiGen.c similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c rename to vendor/github.com/godror/godror/odpi/src/dpiGen.c index e6b65b9a65b..f671adf2a21 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiGen.c @@ -133,6 +133,12 @@ static const dpiTypeDef dpiAllTypeDefs[DPI_HTYPE_MAX - DPI_HTYPE_NONE - 1] = { sizeof(dpiSodaDocCursor), // size of structure 0x80ceb83b, // check integer (dpiTypeFreeProc) dpiSodaDocCursor__free + }, + { + "dpiQueue", // name + sizeof(dpiQueue), // size of structure + 0x54904ba2, // check integer + (dpiTypeFreeProc) dpiQueue__free } }; @@ -145,7 +151,7 @@ int dpiGen__addRef(void *ptr, dpiHandleTypeNum typeNum, const char *fnName) { dpiError error; - if (dpiGen__startPublicFn(ptr, typeNum, fnName, 0, &error) < 0) + if (dpiGen__startPublicFn(ptr, typeNum, fnName, &error) < 0) return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error); dpiGen__setRefCount(ptr, &error, 1); return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error); @@ -218,7 +224,7 @@ int dpiGen__endPublicFn(const void *ptr, int returnValue, dpiError *error) dpiDebug__print("fn end %s(%p) -> %d\n", error->buffer->fnName, ptr, returnValue); if (error->handle) - dpiHandlePool__release(error->env->errorHandles, error->handle, error); + dpiHandlePool__release(error->env->errorHandles, &error->handle); return returnValue; } @@ -235,7 +241,7 @@ int dpiGen__release(void *ptr, dpiHandleTypeNum typeNum, const char *fnName) { dpiError error; - if (dpiGen__startPublicFn(ptr, typeNum, fnName, 1, &error) < 0) + if (dpiGen__startPublicFn(ptr, typeNum, fnName, &error) < 0) return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error); dpiGen__setRefCount(ptr, &error, -1); return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error); @@ -286,7 +292,7 @@ void dpiGen__setRefCount(void *ptr, dpiError *error, int increment) // all subsequent calls. //----------------------------------------------------------------------------- int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, - const char *fnName, int needErrorHandle, dpiError *error) + const char *fnName, dpiError *error) { dpiBaseType *value = (dpiBaseType*) ptr; @@ -296,8 +302,6 @@ int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, return DPI_FAILURE; if (dpiGen__checkHandle(ptr, typeNum, "check main handle", error) < 0) return DPI_FAILURE; - if (needErrorHandle && dpiEnv__initError(value->env, error) < 0) - return DPI_FAILURE; + error->env = value->env; return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c b/vendor/github.com/godror/godror/odpi/src/dpiGlobal.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c rename to vendor/github.com/godror/godror/odpi/src/dpiGlobal.c index c57dd557848..6599d870421 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiGlobal.c @@ -289,4 +289,3 @@ int dpiGlobal__lookupEncoding(uint16_t charsetId, char *encoding, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c b/vendor/github.com/godror/godror/odpi/src/dpiHandleList.c similarity index 98% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c rename to vendor/github.com/godror/godror/odpi/src/dpiHandleList.c index 920a2c628fe..2f3864067bb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiHandleList.c @@ -43,7 +43,7 @@ int dpiHandleList__addHandle(dpiHandleList *list, void *handle, list->handles = tempHandles; list->numSlots = numSlots; *slotNum = list->numUsedSlots++; - list->currentPos = list->numUsedSlots + 1; + list->currentPos = list->numUsedSlots; } else { for (i = 0; i < list->numSlots; i++) { if (!list->handles[list->currentPos]) @@ -114,4 +114,3 @@ void dpiHandleList__removeHandle(dpiHandleList *list, uint32_t slotNum) list->numUsedSlots--; dpiMutex__release(list->mutex); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c b/vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c rename to vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c index aab33c86f2f..456f094f136 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c @@ -105,14 +105,15 @@ void dpiHandlePool__free(dpiHandlePool *pool) // dpiHandlePool__release() [INTERNAL] // Release a handle back to the pool. No checks are performed on the handle // that is being returned to the pool; It will simply be placed back in the -// pool. +// pool. The handle is then NULLed in order to avoid multiple attempts to +// release the handle back to the pool. //----------------------------------------------------------------------------- -void dpiHandlePool__release(dpiHandlePool *pool, void *handle, dpiError *error) +void dpiHandlePool__release(dpiHandlePool *pool, void **handle) { dpiMutex__acquire(pool->mutex); - pool->handles[pool->releasePos++] = handle; + pool->handles[pool->releasePos++] = *handle; + *handle = NULL; if (pool->releasePos == pool->numSlots) pool->releasePos = 0; dpiMutex__release(pool->mutex); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h b/vendor/github.com/godror/godror/odpi/src/dpiImpl.h similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h rename to vendor/github.com/godror/godror/odpi/src/dpiImpl.h index 101846dc1da..ec2ede13955 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h +++ b/vendor/github.com/godror/godror/odpi/src/dpiImpl.h @@ -153,6 +153,7 @@ extern unsigned long dpiDebugLevel; // define values used for getting/setting OCI attributes #define DPI_OCI_ATTR_DATA_SIZE 1 #define DPI_OCI_ATTR_DATA_TYPE 2 +#define DPI_OCI_ATTR_ENV 5 #define DPI_OCI_ATTR_PRECISION 5 #define DPI_OCI_ATTR_SCALE 6 #define DPI_OCI_ATTR_NAME 4 @@ -165,6 +166,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_ROW_COUNT 9 #define DPI_OCI_ATTR_PREFETCH_ROWS 11 #define DPI_OCI_ATTR_PARAM_COUNT 18 +#define DPI_OCI_ATTR_ROWID 19 #define DPI_OCI_ATTR_USERNAME 22 #define DPI_OCI_ATTR_PASSWORD 23 #define DPI_OCI_ATTR_STMT_TYPE 24 @@ -219,6 +221,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_NUM_TYPE_ATTRS 228 #define DPI_OCI_ATTR_SUBSCR_CQ_QOSFLAGS 229 #define DPI_OCI_ATTR_LIST_TYPE_ATTRS 229 +#define DPI_OCI_ATTR_SUBSCR_CQ_REGID 230 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_CLASS 231 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_VALUE 232 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_TYPE 233 @@ -263,6 +266,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_CONNECTION_CLASS 425 #define DPI_OCI_ATTR_PURITY 426 #define DPI_OCI_ATTR_RECEIVE_TIMEOUT 436 +#define DPI_OCI_ATTR_LOBPREFETCH_LENGTH 440 #define DPI_OCI_ATTR_SUBSCR_IPADDR 452 #define DPI_OCI_ATTR_UB8_ROW_COUNT 457 #define DPI_OCI_ATTR_SPOOL_AUTH 460 @@ -294,6 +298,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_SODA_SKIP 577 #define DPI_OCI_ATTR_SODA_LIMIT 578 #define DPI_OCI_ATTR_SODA_DOC_COUNT 593 +#define DPI_OCI_ATTR_SPOOL_MAX_PER_SHARD 602 // define OCI object type constants #define DPI_OCI_OTYPE_NAME 1 @@ -335,6 +340,11 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_TYPECODE_SMALLINT 246 #define DPI_SQLT_REC 250 #define DPI_SQLT_BOL 252 +#define DPI_OCI_TYPECODE_ROWID 262 +#define DPI_OCI_TYPECODE_LONG 263 +#define DPI_OCI_TYPECODE_LONG_RAW 264 +#define DPI_OCI_TYPECODE_BINARY_INTEGER 265 +#define DPI_OCI_TYPECODE_PLS_INTEGER 266 // define session pool constants #define DPI_OCI_SPD_FORCE 0x0001 @@ -428,6 +438,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_SODA_COLL_CREATE_MAP 0x00010000 #define DPI_OCI_SODA_INDEX_DROP_FORCE 0x00010000 #define DPI_OCI_TRANS_TWOPHASE 0x01000000 +#define DPI_OCI_SECURE_NOTIFICATION 0x20000000 //----------------------------------------------------------------------------- // Macros @@ -519,6 +530,10 @@ typedef enum { DPI_ERR_CALL_TIMEOUT, DPI_ERR_SODA_CURSOR_CLOSED, DPI_ERR_EXT_AUTH_INVALID_PROXY, + DPI_ERR_QUEUE_NO_PAYLOAD, + DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE, + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED, + DPI_ERR_MISSING_SHARDING_KEY, DPI_ERR_MAX } dpiErrorNum; @@ -544,6 +559,7 @@ typedef enum { DPI_HTYPE_SODA_DB, DPI_HTYPE_SODA_DOC, DPI_HTYPE_SODA_DOC_CURSOR, + DPI_HTYPE_QUEUE, DPI_HTYPE_MAX } dpiHandleTypeNum; @@ -587,6 +603,25 @@ typedef struct { uint32_t maxLifetimeSession; } dpiPoolCreateParams__v30; +// structure used for creating pools (3.2) +typedef struct { + uint32_t minSessions; + uint32_t maxSessions; + uint32_t sessionIncrement; + int pingInterval; + int pingTimeout; + int homogeneous; + int externalAuth; + dpiPoolGetMode getMode; + const char *outPoolName; + uint32_t outPoolNameLength; + uint32_t timeout; + uint32_t waitTimeout; + uint32_t maxLifetimeSession; + const char *plsqlFixupCallback; + uint32_t plsqlFixupCallbackLength; +} dpiPoolCreateParams__v32; + // structure used for creating connections (3.0) typedef struct { dpiAuthMode authMode; @@ -612,6 +647,49 @@ typedef struct { uint8_t numSuperShardingKeyColumns; } dpiConnCreateParams__v30; +// structure used for creating subscriptions (3.0 and 3.1) +typedef struct { + dpiSubscrNamespace subscrNamespace; + dpiSubscrProtocol protocol; + dpiSubscrQOS qos; + dpiOpCode operations; + uint32_t portNumber; + uint32_t timeout; + const char *name; + uint32_t nameLength; + dpiSubscrCallback callback; + void *callbackContext; + const char *recipientName; + uint32_t recipientNameLength; + const char *ipAddress; + uint32_t ipAddressLength; + uint8_t groupingClass; + uint32_t groupingValue; + uint8_t groupingType; +} dpiSubscrCreateParams__v30; + +// structure used for creating subscriptions (3.2) +typedef struct { + dpiSubscrNamespace subscrNamespace; + dpiSubscrProtocol protocol; + dpiSubscrQOS qos; + dpiOpCode operations; + uint32_t portNumber; + uint32_t timeout; + const char *name; + uint32_t nameLength; + dpiSubscrCallback callback; + void *callbackContext; + const char *recipientName; + uint32_t recipientNameLength; + const char *ipAddress; + uint32_t ipAddressLength; + uint8_t groupingClass; + uint32_t groupingValue; + uint8_t groupingType; + uint64_t outRegId; +} dpiSubscrCreateParams__v32; + //----------------------------------------------------------------------------- // OCI type definitions @@ -632,6 +710,17 @@ typedef struct { uint8_t second; } dpiOciDate; +// alternative representation of OCI Date type used for sharding +typedef struct { + uint8_t century; + uint8_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; +} dpiShardingOciDate; + // representation of OCI XID type (two-phase commit) typedef struct { long formatID; @@ -707,6 +796,7 @@ typedef struct { void *baseDate; // midnight, January 1, 1970 int threaded; // threaded mode enabled? int events; // events mode enabled? + int externalHandle; // external handle? } dpiEnv; // used to manage all errors that take place in the library; the implementation @@ -816,6 +906,7 @@ typedef union { char *asBytes; float *asFloat; double *asDouble; + int32_t *asInt32; int64_t *asInt64; uint64_t *asUint64; dpiOciNumber *asNumber; @@ -836,6 +927,7 @@ typedef union { // buffers to Oracle when values are being transferred to or from the Oracle // database typedef union { + int32_t asInt32; int64_t asInt64; uint64_t asUint64; float asFloat; @@ -869,6 +961,18 @@ typedef struct { dpiOracleData data; // Oracle data buffers (internal only) } dpiVarBuffer; +// represents memory areas used for enqueuing and dequeuing messages from +// queues +typedef struct { + uint32_t numElements; // number of elements in next arrays + dpiMsgProps **props; // array of dpiMsgProps handles + void **handles; // array of OCI msg prop handles + void **instances; // array of instances + void **indicators; // array of indicators + int16_t *rawIndicators; // array of indicators (RAW queues) + void **msgIds; // array of OCI message ids +} dpiQueueBuffer; + //----------------------------------------------------------------------------- // External implementation type definitions @@ -900,8 +1004,11 @@ struct dpiConn { void *handle; // OCI service context handle void *serverHandle; // OCI server handle void *sessionHandle; // OCI session handle + void *shardingKey; // OCI sharding key descriptor + void *superShardingKey; // OCI supper sharding key descriptor const char *releaseString; // cached release string or NULL uint32_t releaseStringLength; // cached release string length or 0 + void *rawTDO; // cached RAW TDO dpiVersionInfo versionInfo; // Oracle database version info uint32_t commitMode; // commit mode (for two-phase commits) uint16_t charsetId; // database character set ID @@ -932,6 +1039,7 @@ struct dpiStmt { dpiConn *conn; // connection which created this uint32_t openSlotNum; // slot in connection handle list void *handle; // OCI statement handle + dpiStmt *parentStmt; // parent statement (implicit results) uint32_t fetchArraySize; // rows to fetch each time uint32_t bufferRowCount; // number of rows in fetch buffers uint32_t bufferRowIndex; // index into buffers for current row @@ -946,6 +1054,7 @@ struct dpiStmt { uint64_t rowCount; // rows affected or rows fetched so far uint64_t bufferMinRow; // row num of first row in buffers uint16_t statementType; // type of statement + dpiRowid *lastRowid; // rowid of last affected row int isOwned; // owned by structure? int hasRowsToFetch; // potentially more rows to fetch? int scrollable; // scrollable cursor? @@ -1047,10 +1156,12 @@ struct dpiSubscr { dpiType_HEAD dpiConn *conn; // connection which created this void *handle; // OCI subscription handle + dpiMutexType mutex; // enables thread safety dpiSubscrNamespace subscrNamespace; // OCI namespace dpiSubscrQOS qos; // quality of service flags dpiSubscrCallback callback; // callback when event is propagated void *callbackContext; // context pointer for callback + int clientInitiated; // client initiated? int registered; // registered with database? }; @@ -1072,15 +1183,16 @@ struct dpiEnqOptions { void *handle; // OCI enqueue options handle }; -// represents the available properties for message when using advanced queuing +// represents the available properties for messages when using advanced queuing // and is exposed publicly as a handle of type DPI_HTYPE_MSG_PROPS; the // implementation for this is found in the file dpiMsgProps.c struct dpiMsgProps { dpiType_HEAD dpiConn *conn; // connection which created this void *handle; // OCI message properties handle - char *buffer; // latest message ID en/dequeued - uint32_t bufferLength; // size of allocated buffer + dpiObject *payloadObj; // payload (object) + void *payloadRaw; // payload (RAW) + void *msgIdRaw; // message ID (RAW) }; // represents SODA collections and is exposed publicly as a handle of type @@ -1129,6 +1241,19 @@ struct dpiSodaDocCursor { void *handle; // OCI SODA document cursor handle }; +// represents a queue used in AQ (advanced queuing) and is exposed publicly as +// a handle of type DPI_HTYPE_QUEUE; the implementation for this is found in +// the file dpiQueue.c +struct dpiQueue { + dpiType_HEAD + dpiConn *conn; // connection which created this + const char *name; // name of the queue (NULL-terminated) + dpiObjectType *payloadType; // object type (for object payloads) + dpiDeqOptions *deqOptions; // dequeue options + dpiEnqOptions *enqOptions; // enqueue options + dpiQueueBuffer buffer; // buffer area +}; + //----------------------------------------------------------------------------- // definition of internal dpiContext methods @@ -1145,6 +1270,8 @@ void dpiContext__initSubscrCreateParams(dpiSubscrCreateParams *params); //----------------------------------------------------------------------------- int dpiDataBuffer__fromOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue); +int dpiDataBuffer__fromOracleDateAsDouble(dpiDataBuffer *data, + dpiEnv *env, dpiError *error, dpiOciDate *oracleValue); int dpiDataBuffer__fromOracleIntervalDS(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__fromOracleIntervalYM(dpiDataBuffer *data, dpiEnv *env, @@ -1162,6 +1289,8 @@ int dpiDataBuffer__fromOracleTimestamp(dpiDataBuffer *data, dpiEnv *env, int dpiDataBuffer__fromOracleTimestampAsDouble(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue); +int dpiDataBuffer__toOracleDateFromDouble(dpiDataBuffer *data, dpiEnv *env, + dpiError *error, dpiOciDate *oracleValue); int dpiDataBuffer__toOracleIntervalDS(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleIntervalYM(dpiDataBuffer *data, dpiEnv *env, @@ -1185,19 +1314,20 @@ int dpiDataBuffer__toOracleTimestampFromDouble(dpiDataBuffer *data, //----------------------------------------------------------------------------- void dpiEnv__free(dpiEnv *env, dpiError *error); int dpiEnv__init(dpiEnv *env, const dpiContext *context, - const dpiCommonCreateParams *params, dpiError *error); + const dpiCommonCreateParams *params, void *externalHandle, + dpiError *error); int dpiEnv__getEncodingInfo(dpiEnv *env, dpiEncodingInfo *info); -int dpiEnv__initError(dpiEnv *env, dpiError *error); //----------------------------------------------------------------------------- // definition of internal dpiError methods //----------------------------------------------------------------------------- -int dpiError__check(dpiError *error, int status, dpiConn *conn, - const char *action); int dpiError__getInfo(dpiError *error, dpiErrorInfo *info); +int dpiError__initHandle(dpiError *error); int dpiError__set(dpiError *error, const char *context, dpiErrorNum errorNum, ...); +int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn, + const char *action); //----------------------------------------------------------------------------- @@ -1212,7 +1342,7 @@ int dpiGen__endPublicFn(const void *ptr, int returnValue, dpiError *error); int dpiGen__release(void *ptr, dpiHandleTypeNum typeNum, const char *fnName); void dpiGen__setRefCount(void *ptr, dpiError *error, int increment); int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, - const char *fnName, int needErrorHandle, dpiError *error); + const char *fnName, dpiError *error); //----------------------------------------------------------------------------- @@ -1245,6 +1375,7 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, const dpiCommonCreateParams *commonParams, dpiConnCreateParams *createParams, dpiError *error); void dpiConn__free(dpiConn *conn, dpiError *error); +int dpiConn__getRawTDO(dpiConn *conn, dpiError *error); int dpiConn__getServerVersion(dpiConn *conn, dpiError *error); @@ -1408,15 +1539,28 @@ int dpiSodaDocCursor__allocate(dpiSodaColl *coll, void *handle, void dpiSodaDocCursor__free(dpiSodaDocCursor *cursor, dpiError *error); +//----------------------------------------------------------------------------- +// definition of internal dpiQueue methods +//----------------------------------------------------------------------------- +int dpiQueue__allocate(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue, dpiError *error); +void dpiQueue__free(dpiQueue *queue, dpiError *error); + + //----------------------------------------------------------------------------- // definition of internal dpiOci methods //----------------------------------------------------------------------------- int dpiOci__aqDeq(dpiConn *conn, const char *queueName, void *options, void *msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); +int dpiOci__aqDeqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); int dpiOci__aqEnq(dpiConn *conn, const char *queueName, void *options, void *msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); +int dpiOci__aqEnqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error); int dpiOci__arrayDescriptorAlloc(void *envHandle, void **handle, uint32_t handleType, uint32_t arraySize, dpiError *error); int dpiOci__arrayDescriptorFree(void **handle, uint32_t handleType); @@ -1456,6 +1600,8 @@ int dpiOci__dateTimeConstruct(void *envHandle, void *handle, int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t fsecond, const char *tz, size_t tzLength, dpiError *error); +int dpiOci__dateTimeConvert(void *envHandle, void *inDate, void *outDate, + dpiError *error); int dpiOci__dateTimeGetDate(void *envHandle, void *handle, int16_t *year, uint8_t *month, uint8_t *day, dpiError *error); int dpiOci__dateTimeGetTime(void *envHandle, void *handle, uint8_t *hour, @@ -1546,7 +1692,8 @@ int dpiOci__numberToInt(void *number, void *value, unsigned int valueLength, int dpiOci__numberToReal(double *value, void *number, dpiError *error); int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, void *sourceIndicator, dpiError *error); -int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error); +int dpiOci__objectFree(void *envHandle, void *data, int checkError, + dpiError *error); int dpiOci__objectGetAttr(dpiObject *obj, dpiObjectAttr *attr, int16_t *scalarValueIndicator, void **valueIndicator, void **value, void **tdo, dpiError *error); @@ -1599,7 +1746,7 @@ int dpiOci__sodaBulkInsert(dpiSodaColl *coll, void **documents, uint32_t numDocuments, void *outputOptions, uint32_t mode, dpiError *error); int dpiOci__sodaBulkInsertAndGet(dpiSodaColl *coll, void **documents, - uint32_t *numDocuments, void *outputOptions, uint32_t mode, + uint32_t numDocuments, void *outputOptions, uint32_t mode, dpiError *error); int dpiOci__sodaCollCreateWithMetadata(dpiSodaDb *db, const char *name, uint32_t nameLength, const char *metadata, uint32_t metadataLength, @@ -1662,7 +1809,7 @@ int dpiOci__stringPtr(void *envHandle, void *handle, char **ptr); int dpiOci__stringResize(void *envHandle, void **handle, uint32_t newSize, dpiError *error); int dpiOci__stringSize(void *envHandle, void *handle, uint32_t *size); -int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, +int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, uint32_t mode, dpiError *error); int dpiOci__subscriptionUnRegister(dpiConn *conn, dpiSubscr *subscr, dpiError *error); @@ -1690,14 +1837,17 @@ int dpiOci__transRollback(dpiConn *conn, int checkError, dpiError *error); int dpiOci__transStart(dpiConn *conn, dpiError *error); int dpiOci__typeByFullName(dpiConn *conn, const char *name, uint32_t nameLength, void **tdo, dpiError *error); +int dpiOci__typeByName(dpiConn *conn, const char *schema, + uint32_t schemaLength, const char *name, uint32_t nameLength, + void **tdo, dpiError *error); //----------------------------------------------------------------------------- // definition of internal dpiMsgProps methods //----------------------------------------------------------------------------- -int dpiMsgProps__create(dpiMsgProps *props, dpiConn *conn, dpiError *error); -int dpiMsgProps__extractMsgId(dpiMsgProps *props, void *ociRaw, - const char **msgId, uint32_t *msgIdLength, dpiError *error); +int dpiMsgProps__allocate(dpiConn *conn, dpiMsgProps **props, dpiError *error); +void dpiMsgProps__extractMsgId(dpiMsgProps *props, const char **msgId, + uint32_t *msgIdLength); void dpiMsgProps__free(dpiMsgProps *props, dpiError *error); @@ -1708,8 +1858,7 @@ int dpiHandlePool__acquire(dpiHandlePool *pool, void **handle, dpiError *error); int dpiHandlePool__create(dpiHandlePool **pool, dpiError *error); void dpiHandlePool__free(dpiHandlePool *pool); -void dpiHandlePool__release(dpiHandlePool *pool, void *handle, - dpiError *error); +void dpiHandlePool__release(dpiHandlePool *pool, void **handle); //----------------------------------------------------------------------------- @@ -1754,4 +1903,3 @@ void dpiDebug__initialize(void); void dpiDebug__print(const char *format, ...); #endif - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c b/vendor/github.com/godror/godror/odpi/src/dpiLob.c similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c rename to vendor/github.com/godror/godror/odpi/src/dpiLob.c index 310953fc674..55dfcebad6e 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiLob.c @@ -53,10 +53,9 @@ int dpiLob__allocate(dpiConn *conn, const dpiOracleType *type, dpiLob **lob, // dpiLob__check() [INTERNAL] // Check that the LOB is valid and get an error handle for subsequent calls. //----------------------------------------------------------------------------- -static int dpiLob__check(dpiLob *lob, const char *fnName, int needErrorHandle, - dpiError *error) +static int dpiLob__check(dpiLob *lob, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(lob, DPI_HTYPE_LOB, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(lob, DPI_HTYPE_LOB, fnName, error) < 0) return DPI_FAILURE; if (!lob->locator) return dpiError__set(error, "check closed", DPI_ERR_LOB_CLOSED); @@ -210,7 +209,7 @@ int dpiLob_close(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiLob__close(lob, 1, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -226,7 +225,7 @@ int dpiLob_closeResource(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobClose(lob, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -242,7 +241,7 @@ int dpiLob_copy(dpiLob *lob, dpiLob **copiedLob) dpiLob *tempLob; dpiError error; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, copiedLob) if (dpiLob__allocate(lob->conn, lob->type, &tempLob, &error) < 0) @@ -266,7 +265,7 @@ int dpiLob_getBufferSize(dpiLob *lob, uint64_t sizeInChars, { dpiError error; - if (dpiLob__check(lob, __func__, 0, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, sizeInBytes) if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_CLOB) @@ -287,7 +286,7 @@ int dpiLob_getChunkSize(dpiLob *lob, uint32_t *size) dpiError error; int status; - if (dpiLob__check(lob, __func__, 0, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, size) status = dpiOci__lobGetChunkSize(lob, size, &error); @@ -307,7 +306,7 @@ int dpiLob_getDirectoryAndFileName(dpiLob *lob, const char **directoryAlias, dpiError error; // validate parameters - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, directoryAlias) DPI_CHECK_PTR_NOT_NULL(lob, directoryAliasLength) @@ -344,7 +343,7 @@ int dpiLob_getFileExists(dpiLob *lob, int *exists) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, exists) status = dpiOci__lobFileExists(lob, exists, &error); @@ -361,7 +360,7 @@ int dpiLob_getIsResourceOpen(dpiLob *lob, int *isOpen) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, isOpen) status = dpiOci__lobIsOpen(lob, isOpen, &error); @@ -378,7 +377,7 @@ int dpiLob_getSize(dpiLob *lob, uint64_t *size) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, size) status = dpiOci__lobGetLength2(lob, size, &error); @@ -395,7 +394,7 @@ int dpiLob_openResource(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobOpen(lob, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -412,7 +411,7 @@ int dpiLob_readBytes(dpiLob *lob, uint64_t offset, uint64_t amount, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, value) DPI_CHECK_PTR_NOT_NULL(lob, valueLength) @@ -443,7 +442,7 @@ int dpiLob_setDirectoryAndFileName(dpiLob *lob, const char *directoryAlias, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, directoryAlias) DPI_CHECK_PTR_NOT_NULL(lob, fileName) @@ -463,9 +462,9 @@ int dpiLob_setFromBytes(dpiLob *lob, const char *value, uint64_t valueLength) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(lob, value) + DPI_CHECK_PTR_AND_LENGTH(lob, value) status = dpiLob__setFromBytes(lob, value, valueLength, &error); return dpiGen__endPublicFn(lob, status, &error); } @@ -480,7 +479,7 @@ int dpiLob_trim(dpiLob *lob, uint64_t newSize) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobTrim2(lob, newSize, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -497,10 +496,9 @@ int dpiLob_writeBytes(dpiLob *lob, uint64_t offset, const char *value, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, value) status = dpiOci__lobWrite2(lob, offset, value, valueLength, &error); return dpiGen__endPublicFn(lob, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c b/vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c similarity index 72% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c rename to vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c index 24260897b19..518d2e7d20b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. // This program is free software: you can modify it and/or redistribute it // under the terms of: // @@ -17,45 +17,40 @@ #include "dpiImpl.h" //----------------------------------------------------------------------------- -// dpiMsgProps__create() [INTERNAL] -// Create a new subscription structure and return it. In case of error NULL -// is returned. +// dpiMsgProps__allocate() [INTERNAL] +// Create a new message properties structure and return it. In case of error +// NULL is returned. //----------------------------------------------------------------------------- -int dpiMsgProps__create(dpiMsgProps *options, dpiConn *conn, dpiError *error) +int dpiMsgProps__allocate(dpiConn *conn, dpiMsgProps **props, dpiError *error) { + dpiMsgProps *tempProps; + + if (dpiGen__allocate(DPI_HTYPE_MSG_PROPS, conn->env, (void**) &tempProps, + error) < 0) + return DPI_FAILURE; dpiGen__setRefCount(conn, error, 1); - options->conn = conn; - return dpiOci__descriptorAlloc(conn->env->handle, &options->handle, - DPI_OCI_DTYPE_AQMSG_PROPERTIES, "allocate descriptor", error); + tempProps->conn = conn; + if (dpiOci__descriptorAlloc(conn->env->handle, &tempProps->handle, + DPI_OCI_DTYPE_AQMSG_PROPERTIES, "allocate descriptor", + error) < 0) { + dpiMsgProps__free(tempProps, error); + return DPI_FAILURE; + } + + *props = tempProps; + return DPI_SUCCESS; } //----------------------------------------------------------------------------- // dpiMsgProps__extractMsgId() [INTERNAL] -// Extract bytes from the OCIRaw value containing the message id and store -// them in allocated memory on the message properties instance. Then resize the -// OCIRaw value so the memory can be reclaimed. +// Extract bytes from the OCIRaw value containing the message id. //----------------------------------------------------------------------------- -int dpiMsgProps__extractMsgId(dpiMsgProps *props, void *ociRaw, - const char **msgId, uint32_t *msgIdLength, dpiError *error) +void dpiMsgProps__extractMsgId(dpiMsgProps *props, const char **msgId, + uint32_t *msgIdLength) { - const char *rawPtr; - - dpiOci__rawPtr(props->env->handle, ociRaw, (void**) &rawPtr); - dpiOci__rawSize(props->env->handle, ociRaw, msgIdLength); - if (*msgIdLength > props->bufferLength) { - if (props->buffer) { - dpiUtils__freeMemory(props->buffer); - props->buffer = NULL; - } - if (dpiUtils__allocateMemory(1, *msgIdLength, 0, - "allocate msgid buffer", (void**) &props->buffer, error) < 0) - return DPI_FAILURE; - } - memcpy(props->buffer, rawPtr, *msgIdLength); - *msgId = props->buffer; - dpiOci__rawResize(props->env->handle, &ociRaw, 0, error); - return DPI_SUCCESS; + dpiOci__rawPtr(props->env->handle, props->msgIdRaw, (void**) msgId); + dpiOci__rawSize(props->env->handle, props->msgIdRaw, msgIdLength); } @@ -69,14 +64,22 @@ void dpiMsgProps__free(dpiMsgProps *props, dpiError *error) dpiOci__descriptorFree(props->handle, DPI_OCI_DTYPE_AQMSG_PROPERTIES); props->handle = NULL; } + if (props->payloadObj) { + dpiGen__setRefCount(props->payloadObj, error, -1); + props->payloadObj = NULL; + } + if (props->payloadRaw) { + dpiOci__rawResize(props->env->handle, &props->payloadRaw, 0, error); + props->payloadRaw = NULL; + } + if (props->msgIdRaw) { + dpiOci__rawResize(props->env->handle, &props->msgIdRaw, 0, error); + props->msgIdRaw = NULL; + } if (props->conn) { dpiGen__setRefCount(props->conn, error, -1); props->conn = NULL; } - if (props->buffer) { - dpiUtils__freeMemory(props->buffer); - props->buffer = NULL; - } dpiUtils__freeMemory(props); } @@ -91,8 +94,7 @@ static int dpiMsgProps__getAttrValue(dpiMsgProps *props, uint32_t attribute, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, 1, - &error) < 0) + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) DPI_CHECK_PTR_NOT_NULL(props, valueLength) @@ -112,8 +114,7 @@ static int dpiMsgProps__setAttrValue(dpiMsgProps *props, uint32_t attribute, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, 1, - &error) < 0) + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) status = dpiOci__attrSet(props->handle, DPI_OCI_DTYPE_AQMSG_PROPERTIES, @@ -181,7 +182,7 @@ int dpiMsgProps_getEnqTime(dpiMsgProps *props, dpiTimestamp *value) dpiOciDate ociValue; dpiError error; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -240,6 +241,32 @@ int dpiMsgProps_getNumAttempts(dpiMsgProps *props, int32_t *value) } +//----------------------------------------------------------------------------- +// dpiMsgProps_getMsgId() [PUBLIC] +// Return the message id for the message (available after enqueuing or +// dequeuing a message). +//----------------------------------------------------------------------------- +int dpiMsgProps_getMsgId(dpiMsgProps *props, const char **value, + uint32_t *valueLength) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(props, value) + DPI_CHECK_PTR_NOT_NULL(props, valueLength) + if (!props->msgIdRaw) { + *value = NULL; + *valueLength = 0; + } else { + dpiOci__rawPtr(props->env->handle, props->msgIdRaw, (void**) value); + dpiOci__rawSize(props->env->handle, props->msgIdRaw, valueLength); + } + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_getOriginalMsgId() [PUBLIC] // Return the original message id for the message. @@ -250,7 +277,7 @@ int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, dpiError error; void *rawValue; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -265,6 +292,36 @@ int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, } +//----------------------------------------------------------------------------- +// dpiMsgProps_getPayload() [PUBLIC] +// Get the payload for the message (as an object or a series of bytes). +//----------------------------------------------------------------------------- +int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj, + const char **value, uint32_t *valueLength) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (obj) + *obj = props->payloadObj; + if (value && valueLength) { + if (props->payloadRaw) { + dpiOci__rawPtr(props->env->handle, props->payloadRaw, + (void**) value); + dpiOci__rawSize(props->env->handle, props->payloadRaw, + valueLength); + } else { + *value = NULL; + *valueLength = 0; + } + } + + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_getPriority() [PUBLIC] // Return the priority of the message. @@ -359,7 +416,7 @@ int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -374,6 +431,51 @@ int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, } +//----------------------------------------------------------------------------- +// dpiMsgProps_setPayloadBytes() [PUBLIC] +// Set the payload for the message (as a series of bytes). +//----------------------------------------------------------------------------- +int dpiMsgProps_setPayloadBytes(dpiMsgProps *props, const char *value, + uint32_t valueLength) +{ + dpiError error; + int status; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(props, value) + if (props->payloadRaw) { + dpiOci__rawResize(props->env->handle, &props->payloadRaw, 0, &error); + props->payloadRaw = NULL; + } + status = dpiOci__rawAssignBytes(props->env->handle, value, valueLength, + &props->payloadRaw, &error); + return dpiGen__endPublicFn(props, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiMsgProps_setPayloadObject() [PUBLIC] +// Set the payload for the message (as an object). +//----------------------------------------------------------------------------- +int dpiMsgProps_setPayloadObject(dpiMsgProps *props, dpiObject *obj) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (dpiGen__checkHandle(obj, DPI_HTYPE_OBJECT, "check object", &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (props->payloadObj) + dpiGen__setRefCount(props->payloadObj, &error, -1); + dpiGen__setRefCount(obj, &error, 1); + props->payloadObj = obj; + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_setPriority() [PUBLIC] // Set the priority of the message. @@ -383,4 +485,3 @@ int dpiMsgProps_setPriority(dpiMsgProps *props, int32_t value) return dpiMsgProps__setAttrValue(props, DPI_OCI_ATTR_PRIORITY, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c b/vendor/github.com/godror/godror/odpi/src/dpiObject.c similarity index 87% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c rename to vendor/github.com/godror/godror/odpi/src/dpiObject.c index 001789ddf5a..338c68aeeda 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObject.c @@ -16,6 +16,10 @@ #include "dpiImpl.h" +// forward declarations of internal functions only used in this file +int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error); + + //----------------------------------------------------------------------------- // dpiObject__allocate() [INTERNAL] // Allocate and initialize an object structure. @@ -66,7 +70,7 @@ int dpiObject__allocate(dpiObjectType *objType, void *instance, static int dpiObject__check(dpiObject *obj, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(obj, DPI_HTYPE_OBJECT, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(obj, DPI_HTYPE_OBJECT, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(obj->type->conn, error); } @@ -94,7 +98,8 @@ static int dpiObject__checkIsCollection(dpiObject *obj, const char *fnName, // Clear the Oracle value after use. //----------------------------------------------------------------------------- static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error, - dpiOracleDataBuffer *buffer, dpiOracleTypeNum oracleTypeNum) + dpiOracleDataBuffer *buffer, dpiLob *lob, + dpiOracleTypeNum oracleTypeNum) { switch (oracleTypeNum) { case DPI_ORACLE_TYPE_CHAR: @@ -129,12 +134,9 @@ static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error, case DPI_ORACLE_TYPE_NCLOB: case DPI_ORACLE_TYPE_BLOB: case DPI_ORACLE_TYPE_BFILE: - if (buffer->asLobLocator) { - dpiOci__lobFreeTemporary(obj->type->conn, buffer->asLobLocator, - 0, error); - dpiOci__descriptorFree(buffer->asLobLocator, - DPI_OCI_DTYPE_LOB); - } + if (lob) + dpiGen__setRefCount(lob, error, -1); + break; default: break; }; @@ -171,7 +173,7 @@ int dpiObject__close(dpiObject *obj, int checkError, dpiError *error) // flag; again, this must be done while holding the lock (if in threaded // mode) in order to avoid race conditions! if (obj->instance && !obj->dependsOnObj) { - if (dpiOci__objectFree(obj, checkError, error) < 0) { + if (dpiObject__closeHelper(obj, checkError, error) < 0) { if (obj->env->threaded) dpiMutex__acquire(obj->env->mutex); obj->closing = 0; @@ -179,17 +181,33 @@ int dpiObject__close(dpiObject *obj, int checkError, dpiError *error) dpiMutex__release(obj->env->mutex); return DPI_FAILURE; } - if (!obj->type->conn->closing) - dpiHandleList__removeHandle(obj->type->conn->objects, - obj->openSlotNum); - obj->instance = NULL; - obj->indicator = NULL; } return DPI_SUCCESS; } +//----------------------------------------------------------------------------- +// dpiObject__closeHelper() [INTERNAL] +// Helper function for closing an object. +//----------------------------------------------------------------------------- +int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error) +{ + if (dpiOci__objectFree(obj->env->handle, obj->instance, checkError, + error) < 0) + return DPI_FAILURE; + obj->instance = NULL; + if (obj->freeIndicator && dpiOci__objectFree(obj->env->handle, + obj->indicator, checkError, error) < 0) + return DPI_FAILURE; + obj->indicator = NULL; + if (!obj->type->conn->closing) + dpiHandleList__removeHandle(obj->type->conn->objects, + obj->openSlotNum); + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiObject__free() [INTERNAL] // Free the memory for an object. @@ -260,9 +278,10 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, } break; case DPI_ORACLE_TYPE_NATIVE_INT: - if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) - return dpiDataBuffer__fromOracleNumberAsInteger(&data->value, - error, value->asNumber); + if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) { + data->value.asInt64 = *value->asInt32; + return DPI_SUCCESS; + } break; case DPI_ORACLE_TYPE_NATIVE_FLOAT: if (nativeTypeNum == DPI_NATIVE_TYPE_FLOAT) { @@ -294,17 +313,26 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleDate(&data->value, value->asDate); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleDateAsDouble(&data->value, + obj->env, error, value->asDate); break; case DPI_ORACLE_TYPE_TIMESTAMP: if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleTimestamp(&data->value, obj->env, error, *value->asTimestamp, 0); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value, + obj->env, error, *value->asTimestamp); break; case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleTimestamp(&data->value, obj->env, error, *value->asTimestamp, 1); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value, + obj->env, error, *value->asTimestamp); break; case DPI_ORACLE_TYPE_OBJECT: if (typeInfo->objectType && @@ -366,8 +394,8 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, //----------------------------------------------------------------------------- static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, const dpiDataTypeInfo *dataTypeInfo, dpiOracleDataBuffer *buffer, - void **ociValue, int16_t *valueIndicator, void **objectIndicator, - dpiNativeTypeNum nativeTypeNum, dpiData *data) + dpiLob **lob, void **ociValue, int16_t *valueIndicator, + void **objectIndicator, dpiNativeTypeNum nativeTypeNum, dpiData *data) { dpiOracleTypeNum valueOracleTypeNum; uint32_t handleType; @@ -413,6 +441,12 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, } break; case DPI_ORACLE_TYPE_NATIVE_INT: + if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) { + buffer->asInt32 = (int32_t) data->value.asInt64; + *ociValue = &buffer->asInt32; + return DPI_SUCCESS; + } + break; case DPI_ORACLE_TYPE_NUMBER: *ociValue = &buffer->asNumber; if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) @@ -448,25 +482,35 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__toOracleDate(&data->value, &buffer->asDate); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__toOracleDateFromDouble(&data->value, + obj->env, error, &buffer->asDate); break; case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: buffer->asTimestamp = NULL; - if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { - if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP) + if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP || + nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_LTZ || + nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + handleType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + } else if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP) { handleType = DPI_OCI_DTYPE_TIMESTAMP; - else if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_TZ) + } else { handleType = DPI_OCI_DTYPE_TIMESTAMP_TZ; - else handleType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + } if (dpiOci__descriptorAlloc(obj->env->handle, &buffer->asTimestamp, handleType, "allocate timestamp", error) < 0) return DPI_FAILURE; *ociValue = buffer->asTimestamp; - return dpiDataBuffer__toOracleTimestamp(&data->value, obj->env, - error, buffer->asTimestamp, - (valueOracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP)); + if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) + return dpiDataBuffer__toOracleTimestamp(&data->value, + obj->env, error, buffer->asTimestamp, + (valueOracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP)); + return dpiDataBuffer__toOracleTimestampFromDouble(&data->value, + obj->env, error, buffer->asTimestamp); } break; case DPI_ORACLE_TYPE_OBJECT: @@ -503,21 +547,15 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, return DPI_SUCCESS; } else if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) { const dpiOracleType *lobType; - dpiLob *tempLob; lobType = dpiOracleType__getFromNum(valueOracleTypeNum, error); - if (dpiLob__allocate(obj->type->conn, lobType, &tempLob, - error) < 0) + if (dpiLob__allocate(obj->type->conn, lobType, lob, error) < 0) return DPI_FAILURE; bytes = &data->value.asBytes; - if (dpiLob__setFromBytes(tempLob, bytes->ptr, bytes->length, - error) < 0) { - dpiLob__free(tempLob, error); + if (dpiLob__setFromBytes(*lob, bytes->ptr, bytes->length, + error) < 0) return DPI_FAILURE; - } - buffer->asLobLocator = tempLob->locator; - *ociValue = tempLob->locator; - tempLob->locator = NULL; - dpiLob__free(tempLob, error); + buffer->asLobLocator = (*lob)->locator; + *ociValue = (*lob)->locator; return DPI_SUCCESS; } break; @@ -550,6 +588,7 @@ int dpiObject_appendElement(dpiObject *obj, dpiNativeTypeNum nativeTypeNum, { dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; void *indicator; dpiError error; void *ociValue; @@ -558,15 +597,16 @@ int dpiObject_appendElement(dpiObject *obj, dpiNativeTypeNum nativeTypeNum, if (dpiObject__checkIsCollection(obj, __func__, &error) < 0) return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(obj, data) - if (dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, - &valueBuffer, &ociValue, &scalarValueIndicator, - (void**) &indicator, nativeTypeNum, data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); - if (!indicator) - indicator = &scalarValueIndicator; - status = dpiOci__collAppend(obj->type->conn, ociValue, indicator, - obj->instance, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + (void**) &indicator, nativeTypeNum, data); + if (status == DPI_SUCCESS) { + if (!indicator) + indicator = &scalarValueIndicator; + status = dpiOci__collAppend(obj->type->conn, ociValue, indicator, + obj->instance, &error); + } + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, obj->type->elementTypeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -836,6 +876,7 @@ int dpiObject_setAttributeValue(dpiObject *obj, dpiObjectAttr *attr, void *valueIndicator, *ociValue; dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; dpiError error; int status; @@ -861,15 +902,15 @@ int dpiObject_setAttributeValue(dpiObject *obj, dpiObjectAttr *attr, } // convert to input data format - if (dpiObject__toOracleValue(obj, &error, &attr->typeInfo, &valueBuffer, - &ociValue, &scalarValueIndicator, &valueIndicator, nativeTypeNum, - data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); + status = dpiObject__toOracleValue(obj, &error, &attr->typeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + &valueIndicator, nativeTypeNum, data); // set attribute value - status = dpiOci__objectSetAttr(obj, attr, scalarValueIndicator, - valueIndicator, ociValue, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + if (status == DPI_SUCCESS) + status = dpiOci__objectSetAttr(obj, attr, scalarValueIndicator, + valueIndicator, ociValue, &error); + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, attr->typeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -884,6 +925,7 @@ int dpiObject_setElementValueByIndex(dpiObject *obj, int32_t index, { dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; void *indicator; dpiError error; void *ociValue; @@ -892,15 +934,16 @@ int dpiObject_setElementValueByIndex(dpiObject *obj, int32_t index, if (dpiObject__checkIsCollection(obj, __func__, &error) < 0) return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(obj, data) - if (dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, - &valueBuffer, &ociValue, &scalarValueIndicator, - (void**) &indicator, nativeTypeNum, data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); - if (!indicator) - indicator = &scalarValueIndicator; - status = dpiOci__collAssignElem(obj->type->conn, index, ociValue, - indicator, obj->instance, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + (void**) &indicator, nativeTypeNum, data); + if (status == DPI_SUCCESS) { + if (!indicator) + indicator = &scalarValueIndicator; + status = dpiOci__collAssignElem(obj->type->conn, index, ociValue, + indicator, obj->instance, &error); + } + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, obj->type->elementTypeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -921,4 +964,3 @@ int dpiObject_trim(dpiObject *obj, uint32_t numToTrim) &error); return dpiGen__endPublicFn(obj, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c b/vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c rename to vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c index 573abc68217..45d623ef573 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c @@ -93,7 +93,7 @@ int dpiObjectAttr_getInfo(dpiObjectAttr *attr, dpiObjectAttrInfo *info) { dpiError error; - if (dpiGen__startPublicFn(attr, DPI_HTYPE_OBJECT_ATTR, __func__, 0, + if (dpiGen__startPublicFn(attr, DPI_HTYPE_OBJECT_ATTR, __func__, &error) < 0) return dpiGen__endPublicFn(attr, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(attr, info) @@ -112,4 +112,3 @@ int dpiObjectAttr_release(dpiObjectAttr *attr) { return dpiGen__release(attr, DPI_HTYPE_OBJECT_ATTR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c b/vendor/github.com/godror/godror/odpi/src/dpiObjectType.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c rename to vendor/github.com/godror/godror/odpi/src/dpiObjectType.c index 9030b397839..fbb2cf240c8 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObjectType.c @@ -57,7 +57,7 @@ int dpiObjectType__allocate(dpiConn *conn, void *param, static int dpiObjectType__check(dpiObjectType *objType, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, fnName, 1, + if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(objType->conn, error); @@ -319,7 +319,7 @@ int dpiObjectType_getInfo(dpiObjectType *objType, dpiObjectTypeInfo *info) { dpiError error; - if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, __func__, 0, + if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, __func__, &error) < 0) return dpiGen__endPublicFn(objType, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(objType, info) @@ -342,4 +342,3 @@ int dpiObjectType_release(dpiObjectType *objType) { return dpiGen__release(objType, DPI_HTYPE_OBJECT_TYPE, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c b/vendor/github.com/godror/godror/odpi/src/dpiOci.c similarity index 85% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c rename to vendor/github.com/godror/godror/odpi/src/dpiOci.c index 2ad76c688d5..c731324cb48 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiOci.c @@ -35,14 +35,35 @@ static void *dpiOci__reallocMem(void *unused, void *ptr, size_t newSize); error) < 0) \ return DPI_FAILURE; +// macro to ensure that an error handle is available +#define DPI_OCI_ENSURE_ERROR_HANDLE(error) \ + if (!error->handle && dpiError__initHandle(error) < 0) \ + return DPI_FAILURE; + +// macros to simplify code for checking results of OCI calls +#define DPI_OCI_ERROR_OCCURRED(status) \ + (status != DPI_OCI_SUCCESS && status != DPI_OCI_SUCCESS_WITH_INFO) +#define DPI_OCI_CHECK_AND_RETURN(error, status, conn, action) \ + if (DPI_OCI_ERROR_OCCURRED(status)) \ + return dpiError__setFromOCI(error, status, conn, action); \ + return DPI_SUCCESS; + // typedefs for all OCI functions used by ODPI-C typedef int (*dpiOciFnType__aqDeq)(void *svchp, void *errhp, const char *queue_name, void *deqopt, void *msgprop, void *payload_tdo, void **payload, void **payload_ind, void **msgid, uint32_t flags); +typedef int (*dpiOciFnType__aqDeqArray)(void *svchp, void *errhp, + const char *queue_name, void *deqopt, uint32_t *iters, void **msgprop, + void *payload_tdo, void **payload, void **payload_ind, void **msgid, + void *ctxp, void *deqcbfp, uint32_t flags); typedef int (*dpiOciFnType__aqEnq)(void *svchp, void *errhp, const char *queue_name, void *enqopt, void *msgprop, void *payload_tdo, void **payload, void **payload_ind, void **msgid, uint32_t flags); +typedef int (*dpiOciFnType__aqEnqArray)(void *svchp, void *errhp, + const char *queue_name, void *enqopt, uint32_t *iters, void **msgprop, + void *payload_tdo, void **payload, void **payload_ind, void **msgid, + void *ctxp, void *enqcbfp, uint32_t flags); typedef int (*dpiOciFnType__arrayDescriptorAlloc)(const void *parenth, void **descpp, const uint32_t type, uint32_t array_size, const size_t xtramem_sz, void **usrmempp); @@ -99,6 +120,8 @@ typedef int (*dpiOciFnType__dateTimeConstruct)(void *hndl, void *err, void *datetime, int16_t yr, uint8_t mnth, uint8_t dy, uint8_t hr, uint8_t mm, uint8_t ss, uint32_t fsec, const char *tz, size_t tzLength); +typedef int (*dpiOciFnType__dateTimeConvert)(void *hndl, void *err, + void *indate, void *outdate); typedef int (*dpiOciFnType__dateTimeGetDate)(void *hndl, void *err, const void *date, int16_t *yr, uint8_t *mnth, uint8_t *dy); typedef int (*dpiOciFnType__dateTimeGetTime)(void *hndl, void *err, @@ -283,6 +306,12 @@ typedef int (*dpiOciFnType__sessionRelease)(void *svchp, void *errhp, typedef int (*dpiOciFnType__shardingKeyColumnAdd)(void *shardingKey, void *errhp, void *col, uint32_t colLen, uint16_t colType, uint32_t mode); +typedef int (*dpiOciFnType__sodaBulkInsert)(void *svchp, + void *collection, void **documentarray, uint32_t arraylen, + void *opoptns, void *errhp, uint32_t mode); +typedef int (*dpiOciFnType__sodaBulkInsertAndGet)(void *svchp, + void *collection, void **documentarray, uint32_t arraylen, + void *opoptns, void *errhp, uint32_t mode); typedef int (*dpiOciFnType__sodaCollCreateWithMetadata)(void *svchp, const char *collname, uint32_t collnamelen, const char *metadata, uint32_t metadatalen, void **collection, void *errhp, uint32_t mode); @@ -389,6 +418,10 @@ typedef int (*dpiOciFnType__typeByFullName)(void *env, void *err, uint32_t full_type_name_length, const char *version_name, uint32_t version_name_length, uint16_t pin_duration, int get_option, void **tdo); +typedef int (*dpiOciFnType__typeByName)(void *env, void *err, const void *svc, + const char *schema_name, uint32_t s_length, const char *type_name, + uint32_t t_length, const char *version_name, uint32_t v_length, + uint16_t pin_duration, int get_option, void **tdo); // library handle for dynamically loaded OCI library @@ -400,16 +433,18 @@ static const char *dpiOciLibNames[] = { "oci.dll", #elif __APPLE__ "libclntsh.dylib", + "libclntsh.dylib.19.1", "libclntsh.dylib.18.1", "libclntsh.dylib.12.1", "libclntsh.dylib.11.1", - "libclntsh.dylib.19.1", + "libclntsh.dylib.20.1", #else "libclntsh.so", + "libclntsh.so.19.1", "libclntsh.so.18.1", "libclntsh.so.12.1", "libclntsh.so.11.1", - "libclntsh.so.19.1", + "libclntsh.so.20.1", #endif NULL }; @@ -429,7 +464,9 @@ static dpiVersionInfo dpiOciLibVersionInfo; // all OCI symbols used by ODPI-C static struct { dpiOciFnType__aqDeq fnAqDeq; + dpiOciFnType__aqDeqArray fnAqDeqArray; dpiOciFnType__aqEnq fnAqEnq; + dpiOciFnType__aqEnqArray fnAqEnqArray; dpiOciFnType__arrayDescriptorAlloc fnArrayDescriptorAlloc; dpiOciFnType__arrayDescriptorFree fnArrayDescriptorFree; dpiOciFnType__attrGet fnAttrGet; @@ -450,6 +487,7 @@ static struct { dpiOciFnType__contextGetValue fnContextGetValue; dpiOciFnType__contextSetValue fnContextSetValue; dpiOciFnType__dateTimeConstruct fnDateTimeConstruct; + dpiOciFnType__dateTimeConvert fnDateTimeConvert; dpiOciFnType__dateTimeGetDate fnDateTimeGetDate; dpiOciFnType__dateTimeGetTime fnDateTimeGetTime; dpiOciFnType__dateTimeGetTimeZoneOffset fnDateTimeGetTimeZoneOffset; @@ -526,6 +564,8 @@ static struct { dpiOciFnType__sessionRelease fnSessionRelease; dpiOciFnType__shardingKeyColumnAdd fnShardingKeyColumnAdd; dpiOciFnType__stmtExecute fnStmtExecute; + dpiOciFnType__sodaBulkInsert fnSodaBulkInsert; + dpiOciFnType__sodaBulkInsertAndGet fnSodaBulkInsertAndGet; dpiOciFnType__sodaCollCreateWithMetadata fnSodaCollCreateWithMetadata; dpiOciFnType__sodaCollDrop fnSodaCollDrop; dpiOciFnType__sodaCollGetNext fnSodaCollGetNext; @@ -572,6 +612,7 @@ static struct { dpiOciFnType__transRollback fnTransRollback; dpiOciFnType__transStart fnTransStart; dpiOciFnType__typeByFullName fnTypeByFullName; + dpiOciFnType__typeByName fnTypeByName; } dpiOciSymbols; @@ -580,7 +621,7 @@ static struct { // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void *dpiOci__allocateMem(void *unused, size_t size) +static void *dpiOci__allocateMem(UNUSED void *unused, size_t size) { void *ptr; @@ -601,10 +642,30 @@ int dpiOci__aqDeq(dpiConn *conn, const char *queueName, void *options, int status; DPI_OCI_LOAD_SYMBOL("OCIAQDeq", dpiOciSymbols.fnAqDeq) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAqDeq)(conn->handle, error->handle, queueName, options, msgProps, payloadType, payload, payloadInd, msgId, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "dequeue message"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "dequeue message"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__aqDeqArray() [INTERNAL] +// Wrapper for OCIAQDeqArray(). +//----------------------------------------------------------------------------- +int dpiOci__aqDeqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIAQDeqArray", dpiOciSymbols.fnAqDeqArray) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnAqDeqArray)(conn->handle, error->handle, + queueName, options, numIters, msgProps, payloadType, payload, + payloadInd, msgId, NULL, NULL, DPI_OCI_DEFAULT); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "dequeue messages"); } @@ -619,10 +680,30 @@ int dpiOci__aqEnq(dpiConn *conn, const char *queueName, void *options, int status; DPI_OCI_LOAD_SYMBOL("OCIAQEnq", dpiOciSymbols.fnAqEnq) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAqEnq)(conn->handle, error->handle, queueName, options, msgProps, payloadType, payload, payloadInd, msgId, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "enqueue message"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "enqueue message"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__aqEnqArray() [INTERNAL] +// Wrapper for OCIAQEnqArray(). +//----------------------------------------------------------------------------- +int dpiOci__aqEnqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIAQEnqArray", dpiOciSymbols.fnAqEnqArray) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnAqEnqArray)(conn->handle, error->handle, + queueName, options, numIters, msgProps, payloadType, payload, + payloadInd, msgId, NULL, NULL, DPI_OCI_DEFAULT); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "enqueue messages"); } @@ -639,7 +720,7 @@ int dpiOci__arrayDescriptorAlloc(void *envHandle, void **handle, dpiOciSymbols.fnArrayDescriptorAlloc) status = (*dpiOciSymbols.fnArrayDescriptorAlloc)(envHandle, handle, handleType, arraySize, 0, NULL); - return dpiError__check(error, status, NULL, "allocate descriptors"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "allocate descriptors"); } @@ -672,11 +753,12 @@ int dpiOci__attrGet(const void *handle, uint32_t handleType, void *ptr, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAttrGet)(handle, handleType, ptr, size, attribute, error->handle); - if (action) - return dpiError__check(error, status, NULL, action); - return DPI_SUCCESS; + if (!action) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -689,11 +771,12 @@ int dpiOci__attrSet(void *handle, uint32_t handleType, void *ptr, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAttrSet)(handle, handleType, ptr, size, attribute, error->handle); - if (action) - return dpiError__check(error, status, NULL, action); - return DPI_SUCCESS; + if (!action) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -707,6 +790,7 @@ int dpiOci__bindByName(dpiStmt *stmt, void **bindHandle, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByName", dpiOciSymbols.fnBindByName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByName)(stmt->handle, bindHandle, error->handle, name, nameLength, (dynamicBind) ? NULL : var->buffer.data.asRaw, @@ -719,7 +803,7 @@ int dpiOci__bindByName(dpiStmt *stmt, void **bindHandle, const char *name, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by name"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by name"); } @@ -733,6 +817,7 @@ int dpiOci__bindByName2(dpiStmt *stmt, void **bindHandle, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByName2", dpiOciSymbols.fnBindByName2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByName2)(stmt->handle, bindHandle, error->handle, name, nameLength, (dynamicBind) ? NULL : var->buffer.data.asRaw, @@ -745,7 +830,7 @@ int dpiOci__bindByName2(dpiStmt *stmt, void **bindHandle, const char *name, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by name"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by name"); } @@ -759,6 +844,7 @@ int dpiOci__bindByPos(dpiStmt *stmt, void **bindHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByPos", dpiOciSymbols.fnBindByPos) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByPos)(stmt->handle, bindHandle, error->handle, pos, (dynamicBind) ? NULL : var->buffer.data.asRaw, (var->isDynamic) ? INT_MAX : (int32_t) var->sizeInBytes, @@ -770,7 +856,7 @@ int dpiOci__bindByPos(dpiStmt *stmt, void **bindHandle, uint32_t pos, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by position"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by position"); } @@ -784,6 +870,7 @@ int dpiOci__bindByPos2(dpiStmt *stmt, void **bindHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByPos2", dpiOciSymbols.fnBindByPos2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByPos2)(stmt->handle, bindHandle, error->handle, pos, (dynamicBind) ? NULL : var->buffer.data.asRaw, (var->isDynamic) ? INT_MAX : var->sizeInBytes, @@ -795,7 +882,7 @@ int dpiOci__bindByPos2(dpiStmt *stmt, void **bindHandle, uint32_t pos, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by position"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by position"); } @@ -808,10 +895,11 @@ int dpiOci__bindDynamic(dpiVar *var, void *bindHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBindDynamic", dpiOciSymbols.fnBindDynamic) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindDynamic)(bindHandle, error->handle, var, (void*) dpiVar__inBindCallback, var, (void*) dpiVar__outBindCallback); - return dpiError__check(error, status, var->conn, "bind dynamic"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "bind dynamic"); } @@ -824,10 +912,11 @@ int dpiOci__bindObject(dpiVar *var, void *bindHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBindObject", dpiOciSymbols.fnBindObject) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindObject)(bindHandle, error->handle, var->objectType->tdo, (void**) var->buffer.data.asRaw, 0, var->buffer.objectIndicator, 0); - return dpiError__check(error, status, var->conn, "bind object"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "bind object"); } @@ -840,8 +929,9 @@ int dpiOci__break(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBreak", dpiOciSymbols.fnBreak) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBreak)(conn->handle, error->handle); - return dpiError__check(error, status, conn, "break execution"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "break execution"); } @@ -866,9 +956,10 @@ int dpiOci__collAppend(dpiConn *conn, const void *elem, const void *elemInd, int status; DPI_OCI_LOAD_SYMBOL("OCICollAppend", dpiOciSymbols.fnCollAppend) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollAppend)(conn->env->handle, error->handle, elem, elemInd, coll); - return dpiError__check(error, status, conn, "append element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "append element"); } @@ -882,9 +973,10 @@ int dpiOci__collAssignElem(dpiConn *conn, int32_t index, const void *elem, int status; DPI_OCI_LOAD_SYMBOL("OCICollAssignElem", dpiOciSymbols.fnCollAssignElem) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollAssignElem)(conn->env->handle, error->handle, index, elem, elemInd, coll); - return dpiError__check(error, status, conn, "assign element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "assign element"); } @@ -898,9 +990,10 @@ int dpiOci__collGetElem(dpiConn *conn, void *coll, int32_t index, int *exists, int status; DPI_OCI_LOAD_SYMBOL("OCICollGetElem", dpiOciSymbols.fnCollGetElem) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollGetElem)(conn->env->handle, error->handle, coll, index, exists, elem, elemInd); - return dpiError__check(error, status, conn, "get element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get element"); } @@ -913,9 +1006,10 @@ int dpiOci__collSize(dpiConn *conn, void *coll, int32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCICollSize", dpiOciSymbols.fnCollSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollSize)(conn->env->handle, error->handle, coll, size); - return dpiError__check(error, status, conn, "get size"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get size"); } @@ -929,9 +1023,10 @@ int dpiOci__collTrim(dpiConn *conn, uint32_t numToTrim, void *coll, int status; DPI_OCI_LOAD_SYMBOL("OCICollTrim", dpiOciSymbols.fnCollTrim) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollTrim)(conn->env->handle, error->handle, (int32_t) numToTrim, coll); - return dpiError__check(error, status, conn, "trim"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "trim"); } @@ -945,11 +1040,12 @@ int dpiOci__contextGetValue(dpiConn *conn, const char *key, uint32_t keyLength, int status; DPI_OCI_LOAD_SYMBOL("OCIContextGetValue", dpiOciSymbols.fnContextGetValue) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnContextGetValue)(conn->sessionHandle, error->handle, key, (uint8_t) keyLength, value); - if (checkError) - return dpiError__check(error, status, conn, "get context value"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get context value"); } @@ -963,12 +1059,13 @@ int dpiOci__contextSetValue(dpiConn *conn, const char *key, uint32_t keyLength, int status; DPI_OCI_LOAD_SYMBOL("OCIContextSetValue", dpiOciSymbols.fnContextSetValue) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnContextSetValue)(conn->sessionHandle, error->handle, DPI_OCI_DURATION_SESSION, key, (uint8_t) keyLength, value); - if (checkError) - return dpiError__check(error, status, conn, "set context value"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "set context value"); } @@ -985,10 +1082,28 @@ int dpiOci__dateTimeConstruct(void *envHandle, void *handle, int16_t year, DPI_OCI_LOAD_SYMBOL("OCIDateTimeConstruct", dpiOciSymbols.fnDateTimeConstruct) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeConstruct)(envHandle, error->handle, handle, year, month, day, hour, minute, second, fsecond, tz, tzLength); - return dpiError__check(error, status, NULL, "construct date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "construct date"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__dateTimeConvert() [INTERNAL] +// Wrapper for OCIDateTimeConvert(). +//----------------------------------------------------------------------------- +int dpiOci__dateTimeConvert(void *envHandle, void *inDate, void *outDate, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIDateTimeConvert", dpiOciSymbols.fnDateTimeConvert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnDateTimeConvert)(envHandle, error->handle, + inDate, outDate); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "convert date"); } @@ -1002,9 +1117,10 @@ int dpiOci__dateTimeGetDate(void *envHandle, void *handle, int16_t *year, int status; DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetDate", dpiOciSymbols.fnDateTimeGetDate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetDate)(envHandle, error->handle, handle, year, month, day); - return dpiError__check(error, status, NULL, "get date portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get date portion"); } @@ -1018,9 +1134,10 @@ int dpiOci__dateTimeGetTime(void *envHandle, void *handle, uint8_t *hour, int status; DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetTime", dpiOciSymbols.fnDateTimeGetTime) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetTime)(envHandle, error->handle, handle, hour, minute, second, fsecond); - return dpiError__check(error, status, NULL, "get time portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get time portion"); } @@ -1035,9 +1152,10 @@ int dpiOci__dateTimeGetTimeZoneOffset(void *envHandle, void *handle, DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetTimeZoneOffset", dpiOciSymbols.fnDateTimeGetTimeZoneOffset) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetTimeZoneOffset)(envHandle, error->handle, handle, tzHourOffset, tzMinuteOffset); - return dpiError__check(error, status, NULL, "get time zone portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get time zone portion"); } @@ -1052,9 +1170,10 @@ int dpiOci__dateTimeIntervalAdd(void *envHandle, void *handle, void *interval, DPI_OCI_LOAD_SYMBOL("OCIDateTimeIntervalAdd", dpiOciSymbols.fnDateTimeIntervalAdd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeIntervalAdd)(envHandle, error->handle, handle, interval, outHandle); - return dpiError__check(error, status, NULL, "add interval to date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "add interval to date"); } @@ -1069,9 +1188,10 @@ int dpiOci__dateTimeSubtract(void *envHandle, void *handle1, void *handle2, DPI_OCI_LOAD_SYMBOL("OCIDateTimeSubtract", dpiOciSymbols.fnDateTimeSubtract) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeSubtract)(envHandle, error->handle, handle1, handle2, interval); - return dpiError__check(error, status, NULL, "subtract date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "subtract date"); } @@ -1084,9 +1204,10 @@ int dpiOci__dbShutdown(dpiConn *conn, uint32_t mode, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDBShutdown", dpiOciSymbols.fnDbShutdown) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDbShutdown)(conn->handle, error->handle, NULL, mode); - return dpiError__check(error, status, NULL, "shutdown database"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "shutdown database"); } @@ -1099,9 +1220,10 @@ int dpiOci__dbStartup(dpiConn *conn, uint32_t mode, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDBStartup", dpiOciSymbols.fnDbStartup) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDbStartup)(conn->handle, error->handle, NULL, DPI_OCI_DEFAULT, mode); - return dpiError__check(error, status, NULL, "startup database"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "startup database"); } @@ -1115,6 +1237,7 @@ int dpiOci__defineByPos(dpiStmt *stmt, void **defineHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIDefineByPos", dpiOciSymbols.fnDefineByPos) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineByPos)(stmt->handle, defineHandle, error->handle, pos, (var->isDynamic) ? NULL : var->buffer.data.asRaw, @@ -1124,7 +1247,7 @@ int dpiOci__defineByPos(dpiStmt *stmt, void **defineHandle, uint32_t pos, (var->isDynamic) ? NULL : var->buffer.actualLength16, (var->isDynamic) ? NULL : var->buffer.returnCode, (var->isDynamic) ? DPI_OCI_DYNAMIC_FETCH : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "define"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "define"); } @@ -1138,6 +1261,7 @@ int dpiOci__defineByPos2(dpiStmt *stmt, void **defineHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIDefineByPos2", dpiOciSymbols.fnDefineByPos2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineByPos2)(stmt->handle, defineHandle, error->handle, pos, (var->isDynamic) ? NULL : var->buffer.data.asRaw, @@ -1147,7 +1271,7 @@ int dpiOci__defineByPos2(dpiStmt *stmt, void **defineHandle, uint32_t pos, (var->isDynamic) ? NULL : var->buffer.actualLength32, (var->isDynamic) ? NULL : var->buffer.returnCode, (var->isDynamic) ? DPI_OCI_DYNAMIC_FETCH : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "define"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "define"); } @@ -1160,9 +1284,10 @@ int dpiOci__defineDynamic(dpiVar *var, void *defineHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDefineDynamic", dpiOciSymbols.fnDefineDynamic) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineDynamic)(defineHandle, error->handle, var, (void*) dpiVar__defineCallback); - return dpiError__check(error, status, var->conn, "define dynamic"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "define dynamic"); } @@ -1175,10 +1300,11 @@ int dpiOci__defineObject(dpiVar *var, void *defineHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDefineObject", dpiOciSymbols.fnDefineObject) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineObject)(defineHandle, error->handle, var->objectType->tdo, (void**) var->buffer.data.asRaw, 0, var->buffer.objectIndicator, 0); - return dpiError__check(error, status, var->conn, "define object"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "define object"); } @@ -1192,9 +1318,10 @@ int dpiOci__describeAny(dpiConn *conn, void *obj, uint32_t objLength, int status; DPI_OCI_LOAD_SYMBOL("OCIDescribeAny", dpiOciSymbols.fnDescribeAny) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDescribeAny)(conn->handle, error->handle, obj, objLength, objType, 0, DPI_OCI_PTYPE_TYPE, describeHandle); - return dpiError__check(error, status, conn, "describe type"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "describe type"); } @@ -1210,7 +1337,7 @@ int dpiOci__descriptorAlloc(void *envHandle, void **handle, DPI_OCI_LOAD_SYMBOL("OCIDescriptorAlloc", dpiOciSymbols.fnDescriptorAlloc) status = (*dpiOciSymbols.fnDescriptorAlloc)(envHandle, handle, handleType, 0, NULL); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -1314,7 +1441,7 @@ int dpiOci__errorGet(void *handle, uint32_t handleType, uint16_t charsetId, // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void dpiOci__freeMem(void *unused, void *ptr) +static void dpiOci__freeMem(UNUSED void *unused, void *ptr) { char message[40]; @@ -1338,7 +1465,7 @@ int dpiOci__handleAlloc(void *envHandle, void **handle, uint32_t handleType, NULL); if (handleType == DPI_OCI_HTYPE_ERROR && status != DPI_OCI_SUCCESS) return dpiError__set(error, action, DPI_ERR_NO_MEMORY); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -1372,9 +1499,10 @@ int dpiOci__intervalGetDaySecond(void *envHandle, int32_t *day, int32_t *hour, DPI_OCI_LOAD_SYMBOL("OCIIntervalGetDaySecond", dpiOciSymbols.fnIntervalGetDaySecond) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalGetDaySecond)(envHandle, error->handle, day, hour, minute, second, fsecond, interval); - return dpiError__check(error, status, NULL, "get interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get interval components"); } @@ -1389,9 +1517,10 @@ int dpiOci__intervalGetYearMonth(void *envHandle, int32_t *year, DPI_OCI_LOAD_SYMBOL("OCIIntervalGetYearMonth", dpiOciSymbols.fnIntervalGetYearMonth) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalGetYearMonth)(envHandle, error->handle, year, month, interval); - return dpiError__check(error, status, NULL, "get interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get interval components"); } @@ -1407,9 +1536,10 @@ int dpiOci__intervalSetDaySecond(void *envHandle, int32_t day, int32_t hour, DPI_OCI_LOAD_SYMBOL("OCIIntervalSetDaySecond", dpiOciSymbols.fnIntervalSetDaySecond) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalSetDaySecond)(envHandle, error->handle, day, hour, minute, second, fsecond, interval); - return dpiError__check(error, status, NULL, "set interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "set interval components"); } @@ -1424,9 +1554,10 @@ int dpiOci__intervalSetYearMonth(void *envHandle, int32_t year, int32_t month, DPI_OCI_LOAD_SYMBOL("OCIIntervalSetYearMonth", dpiOciSymbols.fnIntervalSetYearMonth) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalSetYearMonth)(envHandle, error->handle, year, month, interval); - return dpiError__check(error, status, NULL, "set interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "set interval components"); } @@ -1713,13 +1844,17 @@ static int dpiOci__loadLibValidate(dpiError *error) // determine the OCI client version information if (dpiOci__loadSymbol("OCIClientVersion", (void**) &dpiOciSymbols.fnClientVersion, NULL) < 0) - return dpiError__set(error, "check Oracle Client version", - DPI_ERR_ORACLE_CLIENT_TOO_OLD, 0, 0, 11, 2); + return dpiError__set(error, "load symbol OCIClientVersion", + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED); + memset(&dpiOciLibVersionInfo, 0, sizeof(dpiOciLibVersionInfo)); (*dpiOciSymbols.fnClientVersion)(&dpiOciLibVersionInfo.versionNum, &dpiOciLibVersionInfo.releaseNum, &dpiOciLibVersionInfo.updateNum, &dpiOciLibVersionInfo.portReleaseNum, &dpiOciLibVersionInfo.portUpdateNum); + if (dpiOciLibVersionInfo.versionNum == 0) + return dpiError__set(error, "get OCI client version", + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED); dpiOciLibVersionInfo.fullVersionNum = (uint32_t) DPI_ORACLE_VERSION_TO_NUMBER(dpiOciLibVersionInfo.versionNum, dpiOciLibVersionInfo.releaseNum, @@ -1785,9 +1920,10 @@ int dpiOci__lobClose(dpiLob *lob, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobClose", dpiOciSymbols.fnLobClose) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobClose)(lob->conn->handle, error->handle, lob->locator); - return dpiError__check(error, status, lob->conn, "close LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "close LOB"); } @@ -1802,13 +1938,14 @@ int dpiOci__lobCreateTemporary(dpiLob *lob, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCILobCreateTemporary", dpiOciSymbols.fnLobCreateTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_BLOB) lobType = DPI_OCI_TEMP_BLOB; else lobType = DPI_OCI_TEMP_CLOB; status = (*dpiOciSymbols.fnLobCreateTemporary)(lob->conn->handle, error->handle, lob->locator, DPI_OCI_DEFAULT, lob->type->charsetForm, lobType, 1, DPI_OCI_DURATION_SESSION); - return dpiError__check(error, status, lob->conn, "create temporary LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "create temporary LOB"); } @@ -1821,9 +1958,10 @@ int dpiOci__lobFileExists(dpiLob *lob, int *exists, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobFileExists", dpiOciSymbols.fnLobFileExists) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileExists)(lob->conn->handle, error->handle, lob->locator, exists); - return dpiError__check(error, status, lob->conn, "get file exists"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get file exists"); } @@ -1838,9 +1976,10 @@ int dpiOci__lobFileGetName(dpiLob *lob, char *dirAlias, int status; DPI_OCI_LOAD_SYMBOL("OCILobFileGetName", dpiOciSymbols.fnLobFileGetName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileGetName)(lob->env->handle, error->handle, lob->locator, dirAlias, dirAliasLength, name, nameLength); - return dpiError__check(error, status, lob->conn, "get LOB file name"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get LOB file name"); } @@ -1855,9 +1994,10 @@ int dpiOci__lobFileSetName(dpiLob *lob, const char *dirAlias, int status; DPI_OCI_LOAD_SYMBOL("OCILobFileSetName", dpiOciSymbols.fnLobFileSetName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileSetName)(lob->env->handle, error->handle, &lob->locator, dirAlias, dirAliasLength, name, nameLength); - return dpiError__check(error, status, lob->conn, "set LOB file name"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "set LOB file name"); } @@ -1872,11 +2012,12 @@ int dpiOci__lobFreeTemporary(dpiConn *conn, void *lobLocator, int checkError, DPI_OCI_LOAD_SYMBOL("OCILobFreeTemporary", dpiOciSymbols.fnLobFreeTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFreeTemporary)(conn->handle, error->handle, lobLocator); - if (checkError) - return dpiError__check(error, status, conn, "free temporary LOB"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "free temporary LOB"); } @@ -1889,9 +2030,10 @@ int dpiOci__lobGetChunkSize(dpiLob *lob, uint32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobGetChunkSize", dpiOciSymbols.fnLobGetChunkSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobGetChunkSize)(lob->conn->handle, error->handle, lob->locator, size); - return dpiError__check(error, status, lob->conn, "get chunk size"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get chunk size"); } @@ -1904,9 +2046,10 @@ int dpiOci__lobGetLength2(dpiLob *lob, uint64_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobGetLength2", dpiOciSymbols.fnLobGetLength2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobGetLength2)(lob->conn->handle, error->handle, lob->locator, size); - return dpiError__check(error, status, lob->conn, "get length"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get length"); } @@ -1919,9 +2062,10 @@ int dpiOci__lobIsOpen(dpiLob *lob, int *isOpen, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobIsOpen", dpiOciSymbols.fnLobIsOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobIsOpen)(lob->conn->handle, error->handle, lob->locator, isOpen); - return dpiError__check(error, status, lob->conn, "check is open"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "check is open"); } @@ -1936,11 +2080,12 @@ int dpiOci__lobIsTemporary(dpiLob *lob, int *isTemporary, int checkError, *isTemporary = 0; DPI_OCI_LOAD_SYMBOL("OCILobIsTemporary", dpiOciSymbols.fnLobIsTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobIsTemporary)(lob->env->handle, error->handle, lob->locator, isTemporary); - if (checkError) - return dpiError__check(error, status, lob->conn, "check is temporary"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "check is temporary"); } @@ -1954,9 +2099,10 @@ int dpiOci__lobLocatorAssign(dpiLob *lob, void **copiedHandle, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCILobLocatorAssign", dpiOciSymbols.fnLobLocatorAssign) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobLocatorAssign)(lob->conn->handle, error->handle, lob->locator, copiedHandle); - return dpiError__check(error, status, lob->conn, "assign locator"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "assign locator"); } @@ -1970,11 +2116,12 @@ int dpiOci__lobOpen(dpiLob *lob, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobOpen", dpiOciSymbols.fnLobOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) mode = (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_BFILE) ? DPI_OCI_LOB_READONLY : DPI_OCI_LOB_READWRITE; status = (*dpiOciSymbols.fnLobOpen)(lob->conn->handle, error->handle, lob->locator, mode); - return dpiError__check(error, status, lob->conn, "close LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "close LOB"); } @@ -1990,13 +2137,14 @@ int dpiOci__lobRead2(dpiLob *lob, uint64_t offset, uint64_t *amountInBytes, int status; DPI_OCI_LOAD_SYMBOL("OCILobRead2", dpiOciSymbols.fnLobRead2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) charsetId = (lob->type->charsetForm == DPI_SQLCS_NCHAR) ? lob->env->ncharsetId : lob->env->charsetId; status = (*dpiOciSymbols.fnLobRead2)(lob->conn->handle, error->handle, lob->locator, amountInBytes, amountInChars, offset, buffer, bufferLength, DPI_OCI_ONE_PIECE, NULL, NULL, charsetId, lob->type->charsetForm); - return dpiError__check(error, status, lob->conn, "read from LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "read from LOB"); } @@ -2009,11 +2157,12 @@ int dpiOci__lobTrim2(dpiLob *lob, uint64_t newLength, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobTrim2", dpiOciSymbols.fnLobTrim2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobTrim2)(lob->conn->handle, error->handle, lob->locator, newLength); if (status == DPI_OCI_INVALID_HANDLE) return dpiOci__lobCreateTemporary(lob, error); - return dpiError__check(error, status, lob->conn, "trim LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "trim LOB"); } @@ -2029,13 +2178,14 @@ int dpiOci__lobWrite2(dpiLob *lob, uint64_t offset, const char *value, int status; DPI_OCI_LOAD_SYMBOL("OCILobWrite2", dpiOciSymbols.fnLobWrite2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) charsetId = (lob->type->charsetForm == DPI_SQLCS_NCHAR) ? lob->env->ncharsetId : lob->env->charsetId; status = (*dpiOciSymbols.fnLobWrite2)(lob->conn->handle, error->handle, lob->locator, &lengthInBytes, &lengthInChars, offset, (void*) value, valueLength, DPI_OCI_ONE_PIECE, NULL, NULL, charsetId, lob->type->charsetForm); - return dpiError__check(error, status, lob->conn, "write to LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "write to LOB"); } @@ -2050,11 +2200,12 @@ int dpiOci__memoryAlloc(dpiConn *conn, void **ptr, uint32_t size, *ptr = NULL; DPI_OCI_LOAD_SYMBOL("OCIMemoryAlloc", dpiOciSymbols.fnMemoryAlloc) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnMemoryAlloc)(conn->sessionHandle, error->handle, ptr, DPI_OCI_DURATION_SESSION, size, DPI_OCI_MEMORY_CLEARED); - if (checkError) - return dpiError__check(error, status, conn, "allocate memory"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "allocate memory"); } @@ -2065,6 +2216,7 @@ int dpiOci__memoryAlloc(dpiConn *conn, void **ptr, uint32_t size, int dpiOci__memoryFree(dpiConn *conn, void *ptr, dpiError *error) { DPI_OCI_LOAD_SYMBOL("OCIMemoryFree", dpiOciSymbols.fnMemoryFree) + DPI_OCI_ENSURE_ERROR_HANDLE(error) (*dpiOciSymbols.fnMemoryFree)(conn->sessionHandle, error->handle, ptr); return DPI_SUCCESS; } @@ -2083,10 +2235,11 @@ int dpiOci__nlsCharSetConvert(void *envHandle, uint16_t destCharsetId, DPI_OCI_LOAD_SYMBOL("OCINlsCharSetConvert", dpiOciSymbols.fnNlsCharSetConvert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNlsCharSetConvert)(envHandle, error->handle, destCharsetId, dest, destLength, sourceCharsetId, source, sourceLength, resultSize); - return dpiError__check(error, status, NULL, "convert text"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "convert text"); } @@ -2169,9 +2322,10 @@ int dpiOci__nlsNumericInfoGet(void *envHandle, int32_t *value, uint16_t item, DPI_OCI_LOAD_SYMBOL("OCINlsNumericInfoGet", dpiOciSymbols.fnNlsNumericInfoGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNlsNumericInfoGet)(envHandle, error->handle, value, item); - return dpiError__check(error, status, NULL, "get NLS info"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get NLS info"); } @@ -2185,9 +2339,10 @@ int dpiOci__numberFromInt(const void *value, unsigned int valueLength, int status; DPI_OCI_LOAD_SYMBOL("OCINumberFromInt", dpiOciSymbols.fnNumberFromInt) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberFromInt)(error->handle, value, valueLength, flags, number); - return dpiError__check(error, status, NULL, "number from integer"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number from integer"); } @@ -2200,9 +2355,10 @@ int dpiOci__numberFromReal(const double value, void *number, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCINumberFromReal", dpiOciSymbols.fnNumberFromReal) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberFromReal)(error->handle, &value, sizeof(double), number); - return dpiError__check(error, status, NULL, "number from real"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number from real"); } @@ -2216,9 +2372,10 @@ int dpiOci__numberToInt(void *number, void *value, unsigned int valueLength, int status; DPI_OCI_LOAD_SYMBOL("OCINumberToInt", dpiOciSymbols.fnNumberToInt) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberToInt)(error->handle, number, valueLength, flags, value); - return dpiError__check(error, status, NULL, "number to integer"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number to integer"); } @@ -2231,9 +2388,10 @@ int dpiOci__numberToReal(double *value, void *number, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCINumberToReal", dpiOciSymbols.fnNumberToReal) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberToReal)(error->handle, number, sizeof(double), value); - return dpiError__check(error, status, NULL, "number to real"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number to real"); } @@ -2247,11 +2405,12 @@ int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectCopy", dpiOciSymbols.fnObjectCopy) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectCopy)(obj->env->handle, error->handle, obj->type->conn->handle, sourceInstance, sourceIndicator, obj->instance, obj->indicator, obj->type->tdo, DPI_OCI_DURATION_SESSION, DPI_OCI_DEFAULT); - return dpiError__check(error, status, obj->type->conn, "copy object"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "copy object"); } @@ -2259,15 +2418,18 @@ int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, // dpiOci__objectFree() [INTERNAL] // Wrapper for OCIObjectFree(). //----------------------------------------------------------------------------- -int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error) +int dpiOci__objectFree(void *envHandle, void *data, int checkError, + dpiError *error) { int status; DPI_OCI_LOAD_SYMBOL("OCIObjectFree", dpiOciSymbols.fnObjectFree) - status = (*dpiOciSymbols.fnObjectFree)(obj->env->handle, error->handle, - obj->instance, DPI_OCI_DEFAULT); - if (checkError && dpiError__check(error, status, obj->type->conn, - "free instance") < 0) { + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnObjectFree)(envHandle, error->handle, data, + DPI_OCI_DEFAULT); + if (checkError && DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, NULL, "free instance"); + // during the attempt to free, PL/SQL records fail with error // "ORA-21602: operation does not support the specified typecode", but // a subsequent attempt will yield error "OCI-21500: internal error @@ -2277,13 +2439,6 @@ int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error) return DPI_SUCCESS; return DPI_FAILURE; } - if (obj->freeIndicator) { - status = (*dpiOciSymbols.fnObjectFree)(obj->env->handle, error->handle, - obj->indicator, DPI_OCI_DEFAULT); - if (checkError && dpiError__check(error, status, obj->type->conn, - "free indicator") < 0) - return DPI_FAILURE; - } return DPI_SUCCESS; } @@ -2299,11 +2454,12 @@ int dpiOci__objectGetAttr(dpiObject *obj, dpiObjectAttr *attr, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectGetAttr", dpiOciSymbols.fnObjectGetAttr) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectGetAttr)(obj->env->handle, error->handle, obj->instance, obj->indicator, obj->type->tdo, &attr->name, &attr->nameLength, 1, 0, 0, scalarValueIndicator, valueIndicator, value, tdo); - return dpiError__check(error, status, obj->type->conn, "get attribute"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get attribute"); } @@ -2316,9 +2472,10 @@ int dpiOci__objectGetInd(dpiObject *obj, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIObjectGetInd", dpiOciSymbols.fnObjectGetInd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectGetInd)(obj->env->handle, error->handle, obj->instance, &obj->indicator); - return dpiError__check(error, status, obj->type->conn, "get indicator"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get indicator"); } @@ -2331,10 +2488,11 @@ int dpiOci__objectNew(dpiObject *obj, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIObjectNew", dpiOciSymbols.fnObjectNew) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectNew)(obj->env->handle, error->handle, obj->type->conn->handle, obj->type->typeCode, obj->type->tdo, NULL, DPI_OCI_DURATION_SESSION, 1, &obj->instance); - return dpiError__check(error, status, obj->type->conn, "create object"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "create object"); } @@ -2348,10 +2506,11 @@ int dpiOci__objectPin(void *envHandle, void *objRef, void **obj, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectPin", dpiOciSymbols.fnObjectPin) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectPin)(envHandle, error->handle, objRef, NULL, DPI_OCI_PIN_ANY, DPI_OCI_DURATION_SESSION, DPI_OCI_LOCK_NONE, obj); - return dpiError__check(error, status, NULL, "pin reference"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "pin reference"); } @@ -2366,11 +2525,12 @@ int dpiOci__objectSetAttr(dpiObject *obj, dpiObjectAttr *attr, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectSetAttr", dpiOciSymbols.fnObjectSetAttr) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectSetAttr)(obj->env->handle, error->handle, obj->instance, obj->indicator, obj->type->tdo, &attr->name, &attr->nameLength, 1, NULL, 0, scalarValueIndicator, valueIndicator, value); - return dpiError__check(error, status, obj->type->conn, "set attribute"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "set attribute"); } @@ -2386,10 +2546,11 @@ int dpiOci__passwordChange(dpiConn *conn, const char *userName, int status; DPI_OCI_LOAD_SYMBOL("OCIPasswordChange", dpiOciSymbols.fnPasswordChange) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnPasswordChange)(conn->handle, error->handle, userName, userNameLength, oldPassword, oldPasswordLength, newPassword, newPasswordLength, mode); - return dpiError__check(error, status, conn, "change password"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "change password"); } @@ -2403,9 +2564,10 @@ int dpiOci__paramGet(const void *handle, uint32_t handleType, void **parameter, int status; DPI_OCI_LOAD_SYMBOL("OCIParamGet", dpiOciSymbols.fnParamGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnParamGet)(handle, handleType, error->handle, parameter, pos); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -2418,17 +2580,21 @@ int dpiOci__ping(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIPing", dpiOciSymbols.fnPing) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnPing)(conn->handle, error->handle, DPI_OCI_DEFAULT); - status = dpiError__check(error, status, conn, "ping"); + if (DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, conn, "ping"); - // attempting to ping a database earlier than 10g will result in error - // ORA-1010: invalid OCI operation, but that implies a successful ping - // so ignore that error and treat it as a successful operation - if (status < 0 && error->buffer->code == 1010) - return DPI_SUCCESS; + // attempting to ping a database earlier than 10g will result in error + // ORA-1010: invalid OCI operation, but that implies a successful ping + // so ignore that error and treat it as a successful operation + if (error->buffer->code == 1010) + return DPI_SUCCESS; + return DPI_FAILURE; + } - return status; + return DPI_SUCCESS; } @@ -2442,9 +2608,10 @@ int dpiOci__rawAssignBytes(void *envHandle, const char *value, int status; DPI_OCI_LOAD_SYMBOL("OCIRawAssignBytes", dpiOciSymbols.fnRawAssignBytes) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnRawAssignBytes)(envHandle, error->handle, value, valueLength, handle); - return dpiError__check(error, status, NULL, "assign bytes to raw"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "assign bytes to raw"); } @@ -2472,9 +2639,10 @@ int dpiOci__rawResize(void *envHandle, void **handle, uint32_t newSize, int status; DPI_OCI_LOAD_SYMBOL("OCIRawResize", dpiOciSymbols.fnRawResize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnRawResize)(envHandle, error->handle, newSize, handle); - return dpiError__check(error, status, NULL, "resize raw"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "resize raw"); } @@ -2497,7 +2665,7 @@ int dpiOci__rawSize(void *envHandle, void *handle, uint32_t *size) // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void *dpiOci__reallocMem(void *unused, void *ptr, size_t newSize) +static void *dpiOci__reallocMem(UNUSED void *unused, void *ptr, size_t newSize) { char message[80]; void *newPtr; @@ -2520,12 +2688,13 @@ int dpiOci__rowidToChar(dpiRowid *rowid, char *buffer, uint16_t *bufferSize, int status; DPI_OCI_LOAD_SYMBOL("OCIRowidToChar", dpiOciSymbols.fnRowidToChar) + DPI_OCI_ENSURE_ERROR_HANDLE(error) origSize = *bufferSize; status = (*dpiOciSymbols.fnRowidToChar)(rowid->handle, buffer, bufferSize, error->handle); if (origSize == 0) return DPI_SUCCESS; - return dpiError__check(error, status, NULL, "get rowid as string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get rowid as string"); } @@ -2539,9 +2708,10 @@ int dpiOci__serverAttach(dpiConn *conn, const char *connectString, int status; DPI_OCI_LOAD_SYMBOL("OCIServerAttach", dpiOciSymbols.fnServerAttach) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnServerAttach)(conn->serverHandle, error->handle, connectString, (int32_t) connectStringLength, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "server attach"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "server attach"); } @@ -2554,11 +2724,12 @@ int dpiOci__serverDetach(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIServerDetach", dpiOciSymbols.fnServerDetach) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnServerDetach)(conn->serverHandle, error->handle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "detatch from server"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "detatch from server"); } @@ -2571,6 +2742,7 @@ int dpiOci__serverRelease(dpiConn *conn, char *buffer, uint32_t bufferSize, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) if (conn->env->versionInfo->versionNum < 18) { DPI_OCI_LOAD_SYMBOL("OCIServerRelease", dpiOciSymbols.fnServerRelease) status = (*dpiOciSymbols.fnServerRelease)(conn->handle, error->handle, @@ -2582,7 +2754,7 @@ int dpiOci__serverRelease(dpiConn *conn, char *buffer, uint32_t bufferSize, buffer, bufferSize, DPI_OCI_HTYPE_SVCCTX, version, DPI_OCI_DEFAULT); } - return dpiError__check(error, status, conn, "get server version"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get server version"); } @@ -2596,9 +2768,10 @@ int dpiOci__sessionBegin(dpiConn *conn, uint32_t credentialType, int status; DPI_OCI_LOAD_SYMBOL("OCISessionBegin", dpiOciSymbols.fnSessionBegin) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionBegin)(conn->handle, error->handle, conn->sessionHandle, credentialType, mode); - return dpiError__check(error, status, conn, "begin session"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "begin session"); } @@ -2611,11 +2784,12 @@ int dpiOci__sessionEnd(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCISessionEnd", dpiOciSymbols.fnSessionEnd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionEnd)(conn->handle, error->handle, conn->sessionHandle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "end session"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "end session"); } @@ -2631,10 +2805,11 @@ int dpiOci__sessionGet(void *envHandle, void **handle, void *authInfo, int status; DPI_OCI_LOAD_SYMBOL("OCISessionGet", dpiOciSymbols.fnSessionGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionGet)(envHandle, error->handle, handle, authInfo, connectString, connectStringLength, tag, tagLength, outTag, outTagLength, found, mode); - return dpiError__check(error, status, NULL, "get session"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get session"); } @@ -2652,12 +2827,13 @@ int dpiOci__sessionPoolCreate(dpiPool *pool, const char *connectString, DPI_OCI_LOAD_SYMBOL("OCISessionPoolCreate", dpiOciSymbols.fnSessionPoolCreate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionPoolCreate)(pool->env->handle, error->handle, pool->handle, (char**) &pool->name, &pool->nameLength, connectString, connectStringLength, minSessions, maxSessions, sessionIncrement, userName, userNameLength, password, passwordLength, mode); - return dpiError__check(error, status, NULL, "create pool"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "create pool"); } @@ -2673,6 +2849,7 @@ int dpiOci__sessionPoolDestroy(dpiPool *pool, uint32_t mode, int checkError, DPI_OCI_LOAD_SYMBOL("OCISessionPoolDestroy", dpiOciSymbols.fnSessionPoolDestroy) + DPI_OCI_ENSURE_ERROR_HANDLE(error) // clear the pool handle immediately so that no further attempts are made // to use the pool while the pool is being closed; if the pool close fails, @@ -2681,10 +2858,9 @@ int dpiOci__sessionPoolDestroy(dpiPool *pool, uint32_t mode, int checkError, pool->handle = NULL; status = (*dpiOciSymbols.fnSessionPoolDestroy)(handle, error->handle, mode); - if (checkError && - dpiError__check(error, status, NULL, "destroy pool") < 0) { + if (checkError && DPI_OCI_ERROR_OCCURRED(status)) { pool->handle = handle; - return DPI_FAILURE; + return dpiError__setFromOCI(error, status, NULL, "destroy pool"); } dpiOci__handleFree(handle, DPI_OCI_HTYPE_SPOOL); return DPI_SUCCESS; @@ -2701,11 +2877,12 @@ int dpiOci__sessionRelease(dpiConn *conn, const char *tag, uint32_t tagLength, int status; DPI_OCI_LOAD_SYMBOL("OCISessionRelease", dpiOciSymbols.fnSessionRelease) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionRelease)(conn->handle, error->handle, tag, tagLength, mode); - if (checkError) - return dpiError__check(error, status, conn, "release session"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "release session"); } @@ -2720,9 +2897,51 @@ int dpiOci__shardingKeyColumnAdd(void *shardingKey, void *col, uint32_t colLen, DPI_OCI_LOAD_SYMBOL("OCIShardingKeyColumnAdd", dpiOciSymbols.fnShardingKeyColumnAdd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnShardingKeyColumnAdd)(shardingKey, error->handle, col, colLen, colType, DPI_OCI_DEFAULT); - return dpiError__check(error, status, NULL, "add sharding column"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "add sharding column"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__sodaBulkInsert() [INTERNAL] +// Wrapper for OCISodaBulkInsert(). +//----------------------------------------------------------------------------- +int dpiOci__sodaBulkInsert(dpiSodaColl *coll, void **documents, + uint32_t numDocuments, void *outputOptions, uint32_t mode, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCISodaBulkInsert", dpiOciSymbols.fnSodaBulkInsert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnSodaBulkInsert)(coll->db->conn->handle, + coll->handle, documents, numDocuments, outputOptions, + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "insert multiple documents"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__sodaBulkInsertAndGet() [INTERNAL] +// Wrapper for OCISodaBulkInsert(). +//----------------------------------------------------------------------------- +int dpiOci__sodaBulkInsertAndGet(dpiSodaColl *coll, void **documents, + uint32_t numDocuments, void *outputOptions, uint32_t mode, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCISodaBulkInsertAndGet", + dpiOciSymbols.fnSodaBulkInsertAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnSodaBulkInsertAndGet)(coll->db->conn->handle, + coll->handle, documents, numDocuments, outputOptions, + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "insert (and get) multiple documents"); } @@ -2738,10 +2957,12 @@ int dpiOci__sodaCollCreateWithMetadata(dpiSodaDb *db, const char *name, DPI_OCI_LOAD_SYMBOL("OCISodaCollCreateWithMetadata", dpiOciSymbols.fnSodaCollCreateWithMetadata) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollCreateWithMetadata)(db->conn->handle, name, nameLength, metadata, metadataLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, "create SODA collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, + "create SODA collection"); } @@ -2755,9 +2976,10 @@ int dpiOci__sodaCollDrop(dpiSodaColl *coll, int *isDropped, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollDrop", dpiOciSymbols.fnSodaCollDrop) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollDrop)(coll->db->conn->handle, coll->handle, isDropped, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "drop SODA collection"); } @@ -2772,13 +2994,14 @@ int dpiOci__sodaCollGetNext(dpiConn *conn, void *cursorHandle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollGetNext", dpiOciSymbols.fnSodaCollGetNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollGetNext)(conn->handle, cursorHandle, collectionHandle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *collectionHandle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, conn, "get next collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get next collection"); } @@ -2793,9 +3016,10 @@ int dpiOci__sodaCollList(dpiSodaDb *db, const char *startingName, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollList", dpiOciSymbols.fnSodaCollList) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollList)(db->conn->handle, startingName, startingNameLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, "get SODA collection cursor"); } @@ -2810,9 +3034,10 @@ int dpiOci__sodaCollOpen(dpiSodaDb *db, const char *name, uint32_t nameLength, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollOpen", dpiOciSymbols.fnSodaCollOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollOpen)(db->conn->handle, name, nameLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, "open SODA collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, "open SODA collection"); } @@ -2827,9 +3052,11 @@ int dpiOci__sodaDataGuideGet(dpiSodaColl *coll, void **handle, uint32_t mode, DPI_OCI_LOAD_SYMBOL("OCISodaDataGuideGet", dpiOciSymbols.fnSodaDataGuideGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDataGuideGet)(coll->db->conn->handle, coll->handle, DPI_OCI_DEFAULT, handle, error->handle, mode); - if (dpiError__check(error, status, coll->db->conn, "get data guide") < 0) { + if (DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, coll->db->conn, "get data guide"); if (error->buffer->code != 24801) return DPI_FAILURE; *handle = NULL; @@ -2848,9 +3075,10 @@ int dpiOci__sodaDocCount(dpiSodaColl *coll, void *options, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaDocCount", dpiOciSymbols.fnSodaDocCount) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDocCount)(coll->db->conn->handle, coll->handle, options, count, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "get document count"); } @@ -2865,13 +3093,14 @@ int dpiOci__sodaDocGetNext(dpiSodaDocCursor *cursor, void **handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaDocGetNext", dpiOciSymbols.fnSodaDocGetNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDocGetNext)(cursor->coll->db->conn->handle, cursor->handle, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, cursor->coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, cursor->coll->db->conn, "get next document"); } @@ -2886,13 +3115,14 @@ int dpiOci__sodaFind(dpiSodaColl *coll, const void *options, uint32_t flags, int status; DPI_OCI_LOAD_SYMBOL("OCISodaFind", dpiOciSymbols.fnSodaFind) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaFind)(coll->db->conn->handle, coll->handle, options, flags, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "find SODA documents"); } @@ -2907,13 +3137,15 @@ int dpiOci__sodaFindOne(dpiSodaColl *coll, const void *options, uint32_t flags, int status; DPI_OCI_LOAD_SYMBOL("OCISodaFindOne", dpiOciSymbols.fnSodaFindOne) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaFindOne)(coll->db->conn->handle, coll->handle, options, flags, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, coll->db->conn, "get SODA document"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "get SODA document"); } @@ -2927,9 +3159,10 @@ int dpiOci__sodaIndexCreate(dpiSodaColl *coll, const char *indexSpec, int status; DPI_OCI_LOAD_SYMBOL("OCISodaIndexCreate", dpiOciSymbols.fnSodaIndexCreate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaIndexCreate)(coll->db->conn->handle, coll->handle, indexSpec, indexSpecLength, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, "create index"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "create index"); } @@ -2943,9 +3176,10 @@ int dpiOci__sodaIndexDrop(dpiSodaColl *coll, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCISodaIndexDrop", dpiOciSymbols.fnSodaIndexDrop) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaIndexDrop)(coll->db->conn->handle, name, nameLength, isDropped, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, "drop index"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "drop index"); } @@ -2959,9 +3193,10 @@ int dpiOci__sodaInsert(dpiSodaColl *coll, void *handle, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaInsert", dpiOciSymbols.fnSodaInsert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaInsert)(coll->db->conn->handle, coll->handle, handle, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "insert SODA document"); } @@ -2977,9 +3212,10 @@ int dpiOci__sodaInsertAndGet(dpiSodaColl *coll, void **handle, uint32_t mode, DPI_OCI_LOAD_SYMBOL("OCISodaInsertAndGet", dpiOciSymbols.fnSodaInsertAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaInsertAndGet)(coll->db->conn->handle, coll->handle, handle, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "insert and get SODA document"); } @@ -2994,10 +3230,12 @@ int dpiOci__sodaOperKeysSet(const dpiSodaOperOptions *options, void *handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaOperKeysSet", dpiOciSymbols.fnSodaOperKeysSet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaOperKeysSet)(handle, options->keys, options->keyLengths, options->numKeys, error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, NULL, "set operation options keys"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, + "set operation options keys"); } @@ -3011,9 +3249,10 @@ int dpiOci__sodaRemove(dpiSodaColl *coll, void *options, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaRemove", dpiOciSymbols.fnSodaRemove) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaRemove)(coll->db->conn->handle, coll->handle, options, count, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "remove documents from SODA collection"); } @@ -3028,9 +3267,10 @@ int dpiOci__sodaReplOne(dpiSodaColl *coll, const void *options, void *handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaReplOne", dpiOciSymbols.fnSodaReplOne) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaReplOne)(coll->db->conn->handle, coll->handle, options, handle, isReplaced, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "replace SODA document"); } @@ -3046,9 +3286,10 @@ int dpiOci__sodaReplOneAndGet(dpiSodaColl *coll, const void *options, DPI_OCI_LOAD_SYMBOL("OCISodaReplOneAndGet", dpiOciSymbols.fnSodaReplOneAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaReplOneAndGet)(coll->db->conn->handle, coll->handle, options, handle, isReplaced, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "replace and get SODA document"); } @@ -3063,9 +3304,10 @@ int dpiOci__stmtExecute(dpiStmt *stmt, uint32_t numIters, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtExecute", dpiOciSymbols.fnStmtExecute) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtExecute)(stmt->conn->handle, stmt->handle, error->handle, numIters, 0, 0, 0, mode); - return dpiError__check(error, status, stmt->conn, "execute"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "execute"); } @@ -3079,13 +3321,16 @@ int dpiOci__stmtFetch2(dpiStmt *stmt, uint32_t numRows, uint16_t fetchMode, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtFetch2", dpiOciSymbols.fnStmtFetch2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtFetch2)(stmt->handle, error->handle, numRows, fetchMode, offset, DPI_OCI_DEFAULT); - if (status == DPI_OCI_NO_DATA || fetchMode == DPI_MODE_FETCH_LAST) + if (status == DPI_OCI_NO_DATA || fetchMode == DPI_MODE_FETCH_LAST) { stmt->hasRowsToFetch = 0; - else if (dpiError__check(error, status, stmt->conn, "fetch") < 0) - return DPI_FAILURE; - else stmt->hasRowsToFetch = 1; + } else if (DPI_OCI_ERROR_OCCURRED(status)) { + return dpiError__setFromOCI(error, status, stmt->conn, "fetch"); + } else { + stmt->hasRowsToFetch = 1; + } return DPI_SUCCESS; } @@ -3102,6 +3347,7 @@ int dpiOci__stmtGetBindInfo(dpiStmt *stmt, uint32_t size, uint32_t startLoc, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtGetBindInfo", dpiOciSymbols.fnStmtGetBindInfo) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtGetBindInfo)(stmt->handle, error->handle, size, startLoc, numFound, names, nameLengths, indNames, indNameLengths, isDuplicate, bindHandles); @@ -3109,7 +3355,7 @@ int dpiOci__stmtGetBindInfo(dpiStmt *stmt, uint32_t size, uint32_t startLoc, *numFound = 0; return DPI_SUCCESS; } - return dpiError__check(error, status, stmt->conn, "get bind info"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "get bind info"); } @@ -3124,13 +3370,14 @@ int dpiOci__stmtGetNextResult(dpiStmt *stmt, void **handle, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCIStmtGetNextResult", dpiOciSymbols.fnStmtGetNextResult) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtGetNextResult)(stmt->handle, error->handle, handle, &returnType, DPI_OCI_DEFAULT); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, stmt->conn, "get next result"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "get next result"); } @@ -3144,12 +3391,13 @@ int dpiOci__stmtPrepare2(dpiStmt *stmt, const char *sql, uint32_t sqlLength, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtPrepare2", dpiOciSymbols.fnStmtPrepare2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtPrepare2)(stmt->conn->handle, &stmt->handle, error->handle, sql, sqlLength, tag, tagLength, DPI_OCI_NTV_SYNTAX, DPI_OCI_DEFAULT); - if (dpiError__check(error, status, stmt->conn, "prepare SQL") < 0) { + if (DPI_OCI_ERROR_OCCURRED(status)) { stmt->handle = NULL; - return DPI_FAILURE; + return dpiError__setFromOCI(error, status, stmt->conn, "prepare SQL"); } return DPI_SUCCESS; @@ -3178,11 +3426,12 @@ int dpiOci__stmtRelease(dpiStmt *stmt, const char *tag, uint32_t tagLength, } DPI_OCI_LOAD_SYMBOL("OCIStmtRelease", dpiOciSymbols.fnStmtRelease) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtRelease)(stmt->handle, error->handle, tag, tagLength, mode); - if (checkError) - return dpiError__check(error, status, stmt->conn, "release statement"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "release statement"); } @@ -3197,9 +3446,10 @@ int dpiOci__stringAssignText(void *envHandle, const char *value, DPI_OCI_LOAD_SYMBOL("OCIStringAssignText", dpiOciSymbols.fnStringAssignText) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStringAssignText)(envHandle, error->handle, value, valueLength, handle); - return dpiError__check(error, status, NULL, "assign to string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "assign to string"); } @@ -3227,9 +3477,10 @@ int dpiOci__stringResize(void *envHandle, void **handle, uint32_t newSize, int status; DPI_OCI_LOAD_SYMBOL("OCIStringResize", dpiOciSymbols.fnStringResize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStringResize)(envHandle, error->handle, newSize, handle); - return dpiError__check(error, status, NULL, "resize string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "resize string"); } @@ -3251,15 +3502,17 @@ int dpiOci__stringSize(void *envHandle, void *handle, uint32_t *size) // dpiOci__subscriptionRegister() [INTERNAL] // Wrapper for OCISubscriptionRegister(). //----------------------------------------------------------------------------- -int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, dpiError *error) +int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, uint32_t mode, + dpiError *error) { int status; DPI_OCI_LOAD_SYMBOL("OCISubscriptionRegister", dpiOciSymbols.fnSubscriptionRegister) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSubscriptionRegister)(conn->handle, handle, 1, - error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "register"); + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "register"); } @@ -3270,13 +3523,17 @@ int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, dpiError *error) int dpiOci__subscriptionUnRegister(dpiConn *conn, dpiSubscr *subscr, dpiError *error) { + uint32_t mode; int status; DPI_OCI_LOAD_SYMBOL("OCISubscriptionUnRegister", dpiOciSymbols.fnSubscriptionUnRegister) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + mode = (subscr->clientInitiated) ? DPI_OCI_SECURE_NOTIFICATION : + DPI_OCI_DEFAULT; status = (*dpiOciSymbols.fnSubscriptionUnRegister)(conn->handle, - subscr->handle, error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "unregister"); + subscr->handle, error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "unregister"); } @@ -3289,9 +3546,10 @@ int dpiOci__tableDelete(dpiObject *obj, int32_t index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableDelete", dpiOciSymbols.fnTableDelete) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableDelete)(obj->env->handle, error->handle, index, obj->instance); - return dpiError__check(error, status, obj->type->conn, "delete element"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "delete element"); } @@ -3305,9 +3563,11 @@ int dpiOci__tableExists(dpiObject *obj, int32_t index, int *exists, int status; DPI_OCI_LOAD_SYMBOL("OCITableExists", dpiOciSymbols.fnTableExists) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableExists)(obj->env->handle, error->handle, obj->instance, index, exists); - return dpiError__check(error, status, obj->type->conn, "get index exists"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, + "get index exists"); } @@ -3320,9 +3580,11 @@ int dpiOci__tableFirst(dpiObject *obj, int32_t *index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableFirst", dpiOciSymbols.fnTableFirst) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableFirst)(obj->env->handle, error->handle, obj->instance, index); - return dpiError__check(error, status, obj->type->conn, "get first index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, + "get first index"); } @@ -3335,9 +3597,10 @@ int dpiOci__tableLast(dpiObject *obj, int32_t *index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableLast", dpiOciSymbols.fnTableLast) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableLast)(obj->env->handle, error->handle, obj->instance, index); - return dpiError__check(error, status, obj->type->conn, "get last index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get last index"); } @@ -3351,9 +3614,10 @@ int dpiOci__tableNext(dpiObject *obj, int32_t index, int32_t *nextIndex, int status; DPI_OCI_LOAD_SYMBOL("OCITableNext", dpiOciSymbols.fnTableNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableNext)(obj->env->handle, error->handle, index, obj->instance, nextIndex, exists); - return dpiError__check(error, status, obj->type->conn, "get next index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get next index"); } @@ -3367,9 +3631,10 @@ int dpiOci__tablePrev(dpiObject *obj, int32_t index, int32_t *prevIndex, int status; DPI_OCI_LOAD_SYMBOL("OCITablePrev", dpiOciSymbols.fnTablePrev) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTablePrev)(obj->env->handle, error->handle, index, obj->instance, prevIndex, exists); - return dpiError__check(error, status, obj->type->conn, "get prev index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get prev index"); } @@ -3382,9 +3647,10 @@ int dpiOci__tableSize(dpiObject *obj, int32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableSize", dpiOciSymbols.fnTableSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableSize)(obj->env->handle, error->handle, obj->instance, size); - return dpiError__check(error, status, obj->type->conn, "get size"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get size"); } @@ -3431,7 +3697,7 @@ int dpiOci__threadKeyInit(void *envHandle, void *errorHandle, void **key, DPI_OCI_LOAD_SYMBOL("OCIThreadKeyInit", dpiOciSymbols.fnThreadKeyInit) status = (*dpiOciSymbols.fnThreadKeyInit)(envHandle, errorHandle, key, destroyFunc); - return dpiError__check(error, status, NULL, "initialize thread key"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "initialize thread key"); } @@ -3462,9 +3728,10 @@ int dpiOci__transCommit(dpiConn *conn, uint32_t flags, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransCommit", dpiOciSymbols.fnTransCommit) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransCommit)(conn->handle, error->handle, flags); - return dpiError__check(error, status, conn, "commit"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "commit"); } @@ -3477,10 +3744,11 @@ int dpiOci__transPrepare(dpiConn *conn, int *commitNeeded, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransPrepare", dpiOciSymbols.fnTransPrepare) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransPrepare)(conn->handle, error->handle, DPI_OCI_DEFAULT); *commitNeeded = (status == DPI_OCI_SUCCESS); - return dpiError__check(error, status, conn, "prepare transaction"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "prepare transaction"); } @@ -3493,11 +3761,12 @@ int dpiOci__transRollback(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransRollback", dpiOciSymbols.fnTransRollback) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransRollback)(conn->handle, error->handle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "rollback"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "rollback"); } @@ -3510,9 +3779,29 @@ int dpiOci__transStart(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransStart", dpiOciSymbols.fnTransStart) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransStart)(conn->handle, error->handle, 0, DPI_OCI_TRANS_NEW); - return dpiError__check(error, status, conn, "start transaction"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "start transaction"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__typeByName() [INTERNAL] +// Wrapper for OCITypeByName(). +//----------------------------------------------------------------------------- +int dpiOci__typeByName(dpiConn *conn, const char *schema, + uint32_t schemaLength, const char *name, uint32_t nameLength, + void **tdo, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCITypeByName", dpiOciSymbols.fnTypeByName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnTypeByName)(conn->env->handle, error->handle, + conn->handle, schema, schemaLength, name, nameLength, NULL, 0, + DPI_OCI_DURATION_SESSION, DPI_OCI_TYPEGET_ALL, tdo); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get type by name"); } @@ -3526,9 +3815,9 @@ int dpiOci__typeByFullName(dpiConn *conn, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCITypeByFullName", dpiOciSymbols.fnTypeByFullName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTypeByFullName)(conn->env->handle, error->handle, conn->handle, name, nameLength, NULL, 0, DPI_OCI_DURATION_SESSION, DPI_OCI_TYPEGET_ALL, tdo); - return dpiError__check(error, status, conn, "get type by full name"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get type by full name"); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c b/vendor/github.com/godror/godror/odpi/src/dpiOracleType.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c rename to vendor/github.com/godror/godror/odpi/src/dpiOracleType.c index 7397d8f5253..ee307a7d995 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiOracleType.c @@ -298,12 +298,14 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, if (charsetForm == DPI_SQLCS_NCHAR) return DPI_ORACLE_TYPE_NVARCHAR; return DPI_ORACLE_TYPE_VARCHAR; + case DPI_SQLT_INT: case DPI_SQLT_FLT: case DPI_SQLT_NUM: case DPI_SQLT_PDN: case DPI_SQLT_VNU: case DPI_SQLT_BFLOAT: case DPI_SQLT_BDOUBLE: + case DPI_OCI_TYPECODE_SMALLINT: return DPI_ORACLE_TYPE_NUMBER; case DPI_SQLT_DAT: case DPI_SQLT_ODT: @@ -315,8 +317,8 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, if (charsetForm == DPI_SQLCS_NCHAR) return DPI_ORACLE_TYPE_NCHAR; return DPI_ORACLE_TYPE_CHAR; - case DPI_SQLT_INT: - case DPI_OCI_TYPECODE_SMALLINT: + case DPI_OCI_TYPECODE_BINARY_INTEGER: + case DPI_OCI_TYPECODE_PLS_INTEGER: return DPI_ORACLE_TYPE_NATIVE_INT; case DPI_SQLT_IBFLOAT: return DPI_ORACLE_TYPE_NATIVE_FLOAT; @@ -344,6 +346,7 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, case DPI_SQLT_BFILE: return DPI_ORACLE_TYPE_BFILE; case DPI_SQLT_RDD: + case DPI_OCI_TYPECODE_ROWID: return DPI_ORACLE_TYPE_ROWID; case DPI_SQLT_RSET: return DPI_ORACLE_TYPE_STMT; @@ -352,8 +355,10 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, case DPI_SQLT_INTERVAL_YM: return DPI_ORACLE_TYPE_INTERVAL_YM; case DPI_SQLT_LNG: + case DPI_OCI_TYPECODE_LONG: return DPI_ORACLE_TYPE_LONG_VARCHAR; case DPI_SQLT_LBI: + case DPI_OCI_TYPECODE_LONG_RAW: return DPI_ORACLE_TYPE_LONG_RAW; } return (dpiOracleTypeNum) 0; @@ -497,4 +502,3 @@ int dpiOracleType__populateTypeInfo(dpiConn *conn, void *handle, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c b/vendor/github.com/godror/godror/odpi/src/dpiPool.c similarity index 96% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c rename to vendor/github.com/godror/godror/odpi/src/dpiPool.c index 9d237767163..58f21e5efc9 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiPool.c @@ -30,6 +30,7 @@ int dpiPool__acquireConnection(dpiPool *pool, const char *userName, if (dpiGen__allocate(DPI_HTYPE_CONN, pool->env, (void**) &tempConn, error) < 0) return DPI_FAILURE; + error->env = pool->env; // create the connection if (dpiConn__create(tempConn, pool->env->context, userName, userNameLength, @@ -52,7 +53,7 @@ int dpiPool__acquireConnection(dpiPool *pool, const char *userName, static int dpiPool__checkConnected(dpiPool *pool, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(pool, DPI_HTYPE_POOL, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(pool, DPI_HTYPE_POOL, fnName, error) < 0) return DPI_FAILURE; if (!pool->handle) return dpiError__set(error, "check pool", DPI_ERR_NOT_CONNECTED); @@ -158,6 +159,17 @@ static int dpiPool__create(dpiPool *pool, const char *userName, return DPI_FAILURE; } + // set the maximum number of sessions per shard (valid in 18.3 and higher) + if (pool->env->versionInfo->versionNum > 18 || + (pool->env->versionInfo->versionNum == 18 && + pool->env->versionInfo->releaseNum >= 3)) { + if (dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, (void*) + &createParams->maxSessionsPerShard, 0, + DPI_OCI_ATTR_SPOOL_MAX_PER_SHARD, + "set max sessions per shard", error) < 0) + return DPI_FAILURE; + } + // set reamining attributes directly pool->homogeneous = createParams->homogeneous; pool->externalAuth = createParams->externalAuth; @@ -359,7 +371,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, dpiError error; // validate parameters - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_AND_LENGTH(context, userName) @@ -387,7 +399,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, return dpiGen__endPublicFn(context, DPI_FAILURE, &error); // initialize environment - if (dpiEnv__init(tempPool->env, context, commonParams, &error) < 0) { + if (dpiEnv__init(tempPool->env, context, commonParams, NULL, &error) < 0) { dpiPool__free(tempPool, &error); return dpiGen__endPublicFn(context, DPI_FAILURE, &error); } @@ -403,8 +415,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, createParams->outPoolName = tempPool->name; createParams->outPoolNameLength = tempPool->nameLength; *pool = tempPool; - dpiHandlePool__release(tempPool->env->errorHandles, error.handle, &error); - error.handle = NULL; + dpiHandlePool__release(tempPool->env->errorHandles, &error.handle); return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -573,4 +584,3 @@ int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value) return dpiPool__setAttributeUint(pool, DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT, value, __func__); } - diff --git a/vendor/github.com/godror/godror/odpi/src/dpiQueue.c b/vendor/github.com/godror/godror/odpi/src/dpiQueue.c new file mode 100644 index 00000000000..9c2f39a9a82 --- /dev/null +++ b/vendor/github.com/godror/godror/odpi/src/dpiQueue.c @@ -0,0 +1,560 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +// This program is free software: you can modify it and/or redistribute it +// under the terms of: +// +// (i) the Universal Permissive License v 1.0 or at your option, any +// later version (http://oss.oracle.com/licenses/upl); and/or +// +// (ii) the Apache License v 2.0. (http://www.apache.org/licenses/LICENSE-2.0) +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// dpiQueue.c +// Implementation of AQ queues. +//----------------------------------------------------------------------------- + +#include "dpiImpl.h" + +// forward declarations of internal functions only used in this file +static int dpiQueue__allocateBuffer(dpiQueue *queue, uint32_t numElements, + dpiError *error); +static int dpiQueue__deq(dpiQueue *queue, uint32_t *numProps, + dpiMsgProps **props, dpiError *error); +static void dpiQueue__freeBuffer(dpiQueue *queue, dpiError *error); +static int dpiQueue__getPayloadTDO(dpiQueue *queue, void **tdo, + dpiError *error); + + +//----------------------------------------------------------------------------- +// dpiQueue__allocate() [INTERNAL] +// Allocate and initialize a queue. +//----------------------------------------------------------------------------- +int dpiQueue__allocate(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue, dpiError *error) +{ + dpiQueue *tempQueue; + char *buffer; + + // allocate handle; store reference to the connection that created it + if (dpiGen__allocate(DPI_HTYPE_QUEUE, conn->env, (void**) &tempQueue, + error) < 0) + return DPI_FAILURE; + dpiGen__setRefCount(conn, error, 1); + tempQueue->conn = conn; + + // store payload type, which is either an object type or NULL (meaning that + // RAW payloads are being enqueued and dequeued) + if (payloadType) { + dpiGen__setRefCount(payloadType, error, 1); + tempQueue->payloadType = payloadType; + } + + // allocate space for the name of the queue; OCI requires a NULL-terminated + // string so allocate enough space to store the NULL terminator; UTF-16 + // encoded strings are not currently supported + if (dpiUtils__allocateMemory(1, nameLength + 1, 0, "queue name", + (void**) &buffer, error) < 0) { + dpiQueue__free(tempQueue, error); + return DPI_FAILURE; + } + memcpy(buffer, name, nameLength); + buffer[nameLength] = '\0'; + tempQueue->name = buffer; + + *queue = tempQueue; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__allocateBuffer() [INTERNAL] +// Ensure there is enough space in the buffer for the specified number of +// elements. +//----------------------------------------------------------------------------- +static int dpiQueue__allocateBuffer(dpiQueue *queue, uint32_t numElements, + dpiError *error) +{ + dpiQueue__freeBuffer(queue, error); + queue->buffer.numElements = numElements; + if (dpiUtils__allocateMemory(numElements, sizeof(dpiMsgProps*), 1, + "allocate msg props array", (void**) &queue->buffer.props, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI handles array", (void**) &queue->buffer.handles, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI instances array", (void**) &queue->buffer.instances, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI indicators array", + (void**) &queue->buffer.indicators, error) < 0) + return DPI_FAILURE; + if (!queue->payloadType) { + if (dpiUtils__allocateMemory(numElements, sizeof(int16_t), 1, + "allocate OCI raw indicators array", + (void**) &queue->buffer.rawIndicators, error) < 0) + return DPI_FAILURE; + } + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate message ids array", (void**) &queue->buffer.msgIds, + error) < 0) + return DPI_FAILURE; + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__check() [INTERNAL] +// Determine if the queue is available to use. +//----------------------------------------------------------------------------- +static int dpiQueue__check(dpiQueue *queue, const char *fnName, + dpiError *error) +{ + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, fnName, error) < 0) + return DPI_FAILURE; + if (!queue->conn->handle || queue->conn->closing) + return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__createDeqOptions() [INTERNAL] +// Create the dequeue options object that will be used for performing +// dequeues against the queue. +//----------------------------------------------------------------------------- +static int dpiQueue__createDeqOptions(dpiQueue *queue, dpiError *error) +{ + dpiDeqOptions *tempOptions; + + if (dpiGen__allocate(DPI_HTYPE_DEQ_OPTIONS, queue->env, + (void**) &tempOptions, error) < 0) + return DPI_FAILURE; + if (dpiDeqOptions__create(tempOptions, queue->conn, error) < 0) { + dpiDeqOptions__free(tempOptions, error); + return DPI_FAILURE; + } + + queue->deqOptions = tempOptions; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__createEnqOptions() [INTERNAL] +// Create the dequeue options object that will be used for performing +// dequeues against the queue. +//----------------------------------------------------------------------------- +static int dpiQueue__createEnqOptions(dpiQueue *queue, dpiError *error) +{ + dpiEnqOptions *tempOptions; + + if (dpiGen__allocate(DPI_HTYPE_ENQ_OPTIONS, queue->env, + (void**) &tempOptions, error) < 0) + return DPI_FAILURE; + if (dpiEnqOptions__create(tempOptions, queue->conn, error) < 0) { + dpiEnqOptions__free(tempOptions, error); + return DPI_FAILURE; + } + + queue->enqOptions = tempOptions; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__deq() [INTERNAL] +// Perform a dequeue of up to the specified number of properties. +//----------------------------------------------------------------------------- +static int dpiQueue__deq(dpiQueue *queue, uint32_t *numProps, + dpiMsgProps **props, dpiError *error) +{ + dpiMsgProps *prop; + void *payloadTDO; + uint32_t i; + + // create dequeue options, if necessary + if (!queue->deqOptions && dpiQueue__createDeqOptions(queue, error) < 0) + return DPI_FAILURE; + + // allocate buffer, if necessary + if (queue->buffer.numElements < *numProps && + dpiQueue__allocateBuffer(queue, *numProps, error) < 0) + return DPI_FAILURE; + + // populate buffer + for (i = 0; i < *numProps; i++) { + prop = queue->buffer.props[i]; + + // create new message properties, if applicable + if (!prop) { + if (dpiMsgProps__allocate(queue->conn, &prop, error) < 0) + return DPI_FAILURE; + queue->buffer.props[i] = prop; + } + + // create payload object, if applicable + if (queue->payloadType && !prop->payloadObj && + dpiObject__allocate(queue->payloadType, NULL, NULL, NULL, + &prop->payloadObj, error) < 0) + return DPI_FAILURE; + + // set OCI arrays + queue->buffer.handles[i] = prop->handle; + if (queue->payloadType) { + queue->buffer.instances[i] = prop->payloadObj->instance; + queue->buffer.indicators[i] = prop->payloadObj->indicator; + } else { + queue->buffer.instances[i] = prop->payloadRaw; + queue->buffer.indicators[i] = &queue->buffer.rawIndicators[i]; + } + queue->buffer.msgIds[i] = prop->msgIdRaw; + + } + + // perform dequeue + if (dpiQueue__getPayloadTDO(queue, &payloadTDO, error) < 0) + return DPI_FAILURE; + if (dpiOci__aqDeqArray(queue->conn, queue->name, queue->deqOptions->handle, + numProps, queue->buffer.handles, payloadTDO, + queue->buffer.instances, queue->buffer.indicators, + queue->buffer.msgIds, error) < 0) { + if (error->buffer->code != 25228) + return DPI_FAILURE; + error->buffer->offset = (uint16_t) *numProps; + } + + // transfer message properties to destination array + for (i = 0; i < *numProps; i++) { + props[i] = queue->buffer.props[i]; + queue->buffer.props[i] = NULL; + if (!queue->payloadType) + props[i]->payloadRaw = queue->buffer.instances[i]; + props[i]->msgIdRaw = queue->buffer.msgIds[i]; + } + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__enq() [INTERNAL] +// Perform an enqueue of the specified properties. +//----------------------------------------------------------------------------- +static int dpiQueue__enq(dpiQueue *queue, uint32_t numProps, + dpiMsgProps **props, dpiError *error) +{ + void *payloadTDO; + uint32_t i; + + // if no messages are being enqueued, nothing to do! + if (numProps == 0) + return DPI_SUCCESS; + + // create enqueue options, if necessary + if (!queue->enqOptions && dpiQueue__createEnqOptions(queue, error) < 0) + return DPI_FAILURE; + + // allocate buffer, if necessary + if (queue->buffer.numElements < numProps && + dpiQueue__allocateBuffer(queue, numProps, error) < 0) + return DPI_FAILURE; + + // populate buffer + for (i = 0; i < numProps; i++) { + + // perform checks + if (!props[i]->payloadObj && !props[i]->payloadRaw) + return dpiError__set(error, "check payload", + DPI_ERR_QUEUE_NO_PAYLOAD); + if ((queue->payloadType && !props[i]->payloadObj) || + (!queue->payloadType && props[i]->payloadObj)) + return dpiError__set(error, "check payload", + DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE); + if (queue->payloadType && props[i]->payloadObj && + queue->payloadType->tdo != props[i]->payloadObj->type->tdo) + return dpiError__set(error, "check payload", + DPI_ERR_WRONG_TYPE, + props[i]->payloadObj->type->schemaLength, + props[i]->payloadObj->type->schema, + props[i]->payloadObj->type->nameLength, + props[i]->payloadObj->type->name, + queue->payloadType->schemaLength, + queue->payloadType->schema, + queue->payloadType->nameLength, + queue->payloadType->name); + + // set OCI arrays + queue->buffer.handles[i] = props[i]->handle; + if (queue->payloadType) { + queue->buffer.instances[i] = props[i]->payloadObj->instance; + queue->buffer.indicators[i] = props[i]->payloadObj->indicator; + } else { + queue->buffer.instances[i] = props[i]->payloadRaw; + queue->buffer.indicators[i] = &queue->buffer.rawIndicators[i]; + } + queue->buffer.msgIds[i] = props[i]->msgIdRaw; + + } + + // perform enqueue + if (dpiQueue__getPayloadTDO(queue, &payloadTDO, error) < 0) + return DPI_FAILURE; + if (numProps == 1) { + if (dpiOci__aqEnq(queue->conn, queue->name, queue->enqOptions->handle, + queue->buffer.handles[0], payloadTDO, queue->buffer.instances, + queue->buffer.indicators, queue->buffer.msgIds, error) < 0) + return DPI_FAILURE; + } else { + if (dpiOci__aqEnqArray(queue->conn, queue->name, + queue->enqOptions->handle, &numProps, queue->buffer.handles, + payloadTDO, queue->buffer.instances, queue->buffer.indicators, + queue->buffer.msgIds, error) < 0) { + error->buffer->offset = (uint16_t) numProps; + return DPI_FAILURE; + } + } + + // transfer message ids back to message properties + for (i = 0; i < numProps; i++) + props[i]->msgIdRaw = queue->buffer.msgIds[i]; + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__free() [INTERNAL] +// Free the memory for a queue. +//----------------------------------------------------------------------------- +void dpiQueue__free(dpiQueue *queue, dpiError *error) +{ + if (queue->conn) { + dpiGen__setRefCount(queue->conn, error, -1); + queue->conn = NULL; + } + if (queue->payloadType) { + dpiGen__setRefCount(queue->payloadType, error, -1); + queue->payloadType = NULL; + } + if (queue->name) { + dpiUtils__freeMemory((void*) queue->name); + queue->name = NULL; + } + if (queue->deqOptions) { + dpiGen__setRefCount(queue->deqOptions, error, -1); + queue->deqOptions = NULL; + } + if (queue->enqOptions) { + dpiGen__setRefCount(queue->enqOptions, error, -1); + queue->enqOptions = NULL; + } + dpiQueue__freeBuffer(queue, error); + dpiUtils__freeMemory(queue); +} + + +//----------------------------------------------------------------------------- +// dpiQueue__freeBuffer() [INTERNAL] +// Free the memory areas in the queue buffer. +//----------------------------------------------------------------------------- +static void dpiQueue__freeBuffer(dpiQueue *queue, dpiError *error) +{ + dpiQueueBuffer *buffer = &queue->buffer; + uint32_t i; + + if (buffer->props) { + for (i = 0; i < buffer->numElements; i++) { + if (buffer->props[i]) { + dpiGen__setRefCount(buffer->props[i], error, -1); + buffer->props[i] = NULL; + } + } + dpiUtils__freeMemory(buffer->props); + buffer->props = NULL; + } + if (buffer->handles) { + dpiUtils__freeMemory(buffer->handles); + buffer->handles = NULL; + } + if (buffer->instances) { + dpiUtils__freeMemory(buffer->instances); + buffer->instances = NULL; + } + if (buffer->indicators) { + dpiUtils__freeMemory(buffer->indicators); + buffer->indicators = NULL; + } + if (buffer->rawIndicators) { + dpiUtils__freeMemory(buffer->rawIndicators); + buffer->rawIndicators = NULL; + } + if (buffer->msgIds) { + dpiUtils__freeMemory(buffer->msgIds); + buffer->msgIds = NULL; + } +} + + +//----------------------------------------------------------------------------- +// dpiQueue__getPayloadTDO() [INTERNAL] +// Acquire the TDO to use for the payload. This will either be the TDO of the +// object type (if one was specified when the queue was created) or it will be +// the RAW TDO cached on the connection. +//----------------------------------------------------------------------------- +static int dpiQueue__getPayloadTDO(dpiQueue *queue, void **tdo, + dpiError *error) +{ + if (queue->payloadType) { + *tdo = queue->payloadType->tdo; + } else { + if (dpiConn__getRawTDO(queue->conn, error) < 0) + return DPI_FAILURE; + *tdo = queue->conn->rawTDO; + } + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue_addRef() [PUBLIC] +// Add a reference to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_addRef(dpiQueue *queue) +{ + return dpiGen__addRef(queue, DPI_HTYPE_QUEUE, __func__); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_deqMany() [PUBLIC] +// Dequeue multiple messages from the queue. +//----------------------------------------------------------------------------- +int dpiQueue_deqMany(dpiQueue *queue, uint32_t *numProps, dpiMsgProps **props) +{ + dpiError error; + int status; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, numProps) + DPI_CHECK_PTR_NOT_NULL(queue, props) + status = dpiQueue__deq(queue, numProps, props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_deqOne() [PUBLIC] +// Dequeue a single message from the queue. +//----------------------------------------------------------------------------- +int dpiQueue_deqOne(dpiQueue *queue, dpiMsgProps **props) +{ + uint32_t numProps = 1; + dpiError error; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, props) + if (dpiQueue__deq(queue, &numProps, props, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + if (numProps == 0) + *props = NULL; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_enqMany() [PUBLIC] +// Enqueue multiple message to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_enqMany(dpiQueue *queue, uint32_t numProps, dpiMsgProps **props) +{ + dpiError error; + uint32_t i; + int status; + + // validate parameters + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, props) + for (i = 0; i < numProps; i++) { + if (dpiGen__checkHandle(props[i], DPI_HTYPE_MSG_PROPS, + "check message properties", &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + } + status = dpiQueue__enq(queue, numProps, props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_enqOne() [PUBLIC] +// Enqueue a single message to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_enqOne(dpiQueue *queue, dpiMsgProps *props) +{ + dpiError error; + int status; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + if (dpiGen__checkHandle(props, DPI_HTYPE_MSG_PROPS, + "check message properties", &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + status = dpiQueue__enq(queue, 1, &props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_getDeqOptions() [PUBLIC] +// Return the dequeue options associated with the queue. If no dequeue +// options are currently associated with the queue, create them first. +//----------------------------------------------------------------------------- +int dpiQueue_getDeqOptions(dpiQueue *queue, dpiDeqOptions **options) +{ + dpiError error; + + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, __func__, &error) < 0) + return DPI_FAILURE; + DPI_CHECK_PTR_NOT_NULL(queue, options) + if (!queue->deqOptions && dpiQueue__createDeqOptions(queue, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + *options = queue->deqOptions; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_getEnqOptions() [PUBLIC] +// Return the enqueue options associated with the queue. If no enqueue +// options are currently associated with the queue, create them first. +//----------------------------------------------------------------------------- +int dpiQueue_getEnqOptions(dpiQueue *queue, dpiEnqOptions **options) +{ + dpiError error; + + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, __func__, &error) < 0) + return DPI_FAILURE; + DPI_CHECK_PTR_NOT_NULL(queue, options) + if (!queue->enqOptions && dpiQueue__createEnqOptions(queue, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + *options = queue->enqOptions; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_release() [PUBLIC] +// Release a reference to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_release(dpiQueue *queue) +{ + return dpiGen__release(queue, DPI_HTYPE_QUEUE, __func__); +} diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c b/vendor/github.com/godror/godror/odpi/src/dpiRowid.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c rename to vendor/github.com/godror/godror/odpi/src/dpiRowid.c index f3de644deba..9bda49e7cd1 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiRowid.c @@ -78,8 +78,7 @@ int dpiRowid_getStringValue(dpiRowid *rowid, const char **value, dpiError error; uint16_t i; - if (dpiGen__startPublicFn(rowid, DPI_HTYPE_ROWID, __func__, 1, - &error) < 0) + if (dpiGen__startPublicFn(rowid, DPI_HTYPE_ROWID, __func__, &error) < 0) return dpiGen__endPublicFn(rowid, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(rowid, value) DPI_CHECK_PTR_NOT_NULL(rowid, valueLength) @@ -133,4 +132,3 @@ int dpiRowid_release(dpiRowid *rowid) { return dpiGen__release(rowid, DPI_HTYPE_ROWID, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c similarity index 84% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c index a874e4b3f7e..b0a0ded7c34 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c @@ -57,7 +57,7 @@ int dpiSodaColl__allocate(dpiSodaDb *db, void *handle, dpiSodaColl **coll, static int dpiSodaColl__check(dpiSodaColl *coll, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(coll, DPI_HTYPE_SODA_COLL, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(coll, DPI_HTYPE_SODA_COLL, fnName, error) < 0) return DPI_FAILURE; if (!coll->db->conn->handle || coll->db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -255,6 +255,85 @@ static int dpiSodaColl__getDocCount(dpiSodaColl *coll, } +//----------------------------------------------------------------------------- +// dpiSodaColl__insertMany() [INTERNAL] +// Insert multiple documents into the collection and return handles to the +// newly created documents, if desired. +//----------------------------------------------------------------------------- +static int dpiSodaColl__insertMany(dpiSodaColl *coll, uint32_t numDocs, + void **docHandles, uint32_t flags, dpiSodaDoc **insertedDocs, + dpiError *error) +{ + void *optionsHandle; + uint32_t i, j, mode; + uint64_t docCount; + int status; + + // create OCI output options handle + if (dpiOci__handleAlloc(coll->env->handle, &optionsHandle, + DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS, + "allocate SODA output options handle", error) < 0) + return DPI_FAILURE; + + // determine mode to pass + mode = DPI_OCI_DEFAULT; + if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT) + mode |= DPI_OCI_SODA_ATOMIC_COMMIT; + + // perform actual bulk insert + if (insertedDocs) { + status = dpiOci__sodaBulkInsertAndGet(coll, docHandles, numDocs, + optionsHandle, mode, error); + } else { + status = dpiOci__sodaBulkInsert(coll, docHandles, numDocs, + optionsHandle, mode, error); + } + + // on failure, determine the number of documents that were successfully + // inserted and store that information in the error buffer + if (status < 0) { + dpiOci__attrGet(optionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS, + (void*) &docCount, 0, DPI_OCI_ATTR_SODA_DOC_COUNT, + NULL, error); + error->buffer->offset = (uint16_t) docCount; + } + dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS); + + // on failure, if using the "AndGet" variant, any document handles that + // were created need to be freed + if (insertedDocs && status < 0) { + for (i = 0; i < numDocs; i++) { + if (docHandles[i]) { + dpiOci__handleFree(docHandles[i], DPI_OCI_HTYPE_SODA_DOCUMENT); + docHandles[i] = NULL; + } + } + } + if (status < 0) + return DPI_FAILURE; + + // return document handles, if desired + if (insertedDocs) { + for (i = 0; i < numDocs; i++) { + if (dpiSodaDoc__allocate(coll->db, docHandles[i], &insertedDocs[i], + error) < 0) { + for (j = 0; j < i; j++) { + dpiSodaDoc__free(insertedDocs[j], error); + insertedDocs[j] = NULL; + } + for (j = i; j < numDocs; j++) { + dpiOci__handleFree(docHandles[i], + DPI_OCI_HTYPE_SODA_DOCUMENT); + } + return DPI_FAILURE; + } + } + } + + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiSodaColl__remove() [INTERNAL] // Internal method for removing documents from a collection. @@ -584,6 +663,53 @@ int dpiSodaColl_getName(dpiSodaColl *coll, const char **value, } +//----------------------------------------------------------------------------- +// dpiSodaColl_insertMany() [PUBLIC] +// Insert multiple documents into the collection and return handles to the +// newly created documents, if desired. +//----------------------------------------------------------------------------- +int dpiSodaColl_insertMany(dpiSodaColl *coll, uint32_t numDocs, + dpiSodaDoc **docs, uint32_t flags, dpiSodaDoc **insertedDocs) +{ + void **docHandles; + dpiError error; + uint32_t i; + int status; + + // validate parameters + if (dpiSodaColl__check(coll, __func__, &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(coll, docs) + if (numDocs == 0) { + dpiError__set(&error, "check num documents", DPI_ERR_ARRAY_SIZE_ZERO); + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + } + for (i = 0; i < numDocs; i++) { + if (dpiGen__checkHandle(docs[i], DPI_HTYPE_SODA_DOC, "check document", + &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + } + + // bulk insert is only supported with Oracle Client 18.5+ + if (dpiUtils__checkClientVersion(coll->env->versionInfo, 18, 5, + &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + + // create and populate array to hold document handles + if (dpiUtils__allocateMemory(numDocs, sizeof(void*), 1, + "allocate document handles", (void**) &docHandles, &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + for (i = 0; i < numDocs; i++) + docHandles[i] = docs[i]->handle; + + // perform bulk insert + status = dpiSodaColl__insertMany(coll, numDocs, docHandles, flags, + insertedDocs, &error); + dpiUtils__freeMemory(docHandles); + return dpiGen__endPublicFn(coll, status, &error); +} + + //----------------------------------------------------------------------------- // dpiSodaColl_insertOne() [PUBLIC] // Insert a document into the collection and return a handle to the newly @@ -684,4 +810,3 @@ int dpiSodaColl_replaceOne(dpiSodaColl *coll, replacedDoc, &error); return dpiGen__endPublicFn(coll, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c index 2356b7b9cf9..f4e91a427cb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c @@ -43,7 +43,7 @@ int dpiSodaCollCursor__allocate(dpiSodaDb *db, void *handle, static int dpiSodaCollCursor__check(dpiSodaCollCursor *cursor, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_COLL_CURSOR, fnName, 1, + if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_COLL_CURSOR, fnName, error) < 0) return DPI_FAILURE; if (!cursor->handle) @@ -142,4 +142,3 @@ int dpiSodaCollCursor_release(dpiSodaCollCursor *cursor) { return dpiGen__release(cursor, DPI_HTYPE_SODA_COLL_CURSOR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c index f6c5cacaf30..0e1605a3507 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c @@ -23,7 +23,7 @@ static int dpiSodaDb__checkConnected(dpiSodaDb *db, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(db, DPI_HTYPE_SODA_DB, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(db, DPI_HTYPE_SODA_DB, fnName, error) < 0) return DPI_FAILURE; if (!db->conn->handle || db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -201,7 +201,7 @@ int dpiSodaDb_createCollection(dpiSodaDb *db, const char *name, //----------------------------------------------------------------------------- int dpiSodaDb_createDocument(dpiSodaDb *db, const char *key, uint32_t keyLength, const char *content, uint32_t contentLength, - const char *mediaType, uint32_t mediaTypeLength, uint32_t flags, + const char *mediaType, uint32_t mediaTypeLength, UNUSED uint32_t flags, dpiSodaDoc **doc) { int detectEncoding; @@ -429,4 +429,3 @@ int dpiSodaDb_release(dpiSodaDb *db) { return dpiGen__release(db, DPI_HTYPE_SODA_DB, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c index 1b144ee7a6a..b009e33a44a 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c @@ -43,7 +43,7 @@ int dpiSodaDoc__allocate(dpiSodaDb *db, void *handle, dpiSodaDoc **doc, static int dpiSodaDoc__check(dpiSodaDoc *doc, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(doc, DPI_HTYPE_SODA_DOC, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(doc, DPI_HTYPE_SODA_DOC, fnName, error) < 0) return DPI_FAILURE; if (!doc->db->conn->handle || doc->db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -229,4 +229,3 @@ int dpiSodaDoc_release(dpiSodaDoc *doc) { return dpiGen__release(doc, DPI_HTYPE_SODA_DOC, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c index a7d7999b43b..9bfd2bdbeea 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c @@ -43,7 +43,7 @@ int dpiSodaDocCursor__allocate(dpiSodaColl *coll, void *handle, static int dpiSodaDocCursor__check(dpiSodaDocCursor *cursor, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_DOC_CURSOR, fnName, 1, + if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_DOC_CURSOR, fnName, error) < 0) return DPI_FAILURE; if (!cursor->handle) @@ -142,4 +142,3 @@ int dpiSodaDocCursor_release(dpiSodaDocCursor *cursor) { return dpiGen__release(cursor, DPI_HTYPE_SODA_DOC_CURSOR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c b/vendor/github.com/godror/godror/odpi/src/dpiStmt.c similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c rename to vendor/github.com/godror/godror/odpi/src/dpiStmt.c index 6cfd01fa187..cd3520b93b0 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiStmt.c @@ -212,9 +212,9 @@ static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, int addReference, //----------------------------------------------------------------------------- static int dpiStmt__check(dpiStmt *stmt, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(stmt, DPI_HTYPE_STMT, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(stmt, DPI_HTYPE_STMT, fnName, error) < 0) return DPI_FAILURE; - if (!stmt->handle) + if (!stmt->handle || (stmt->parentStmt && !stmt->parentStmt->handle)) return dpiError__set(error, "check closed", DPI_ERR_STMT_CLOSED); if (dpiConn__checkConnected(stmt->conn, error) < 0) return DPI_FAILURE; @@ -321,14 +321,19 @@ int dpiStmt__close(dpiStmt *stmt, const char *tag, uint32_t tagLength, dpiStmt__clearBatchErrors(stmt); dpiStmt__clearBindVars(stmt, error); dpiStmt__clearQueryVars(stmt, error); + if (stmt->lastRowid) + dpiGen__setRefCount(stmt->lastRowid, error, -1); if (stmt->handle) { - if (!stmt->conn->deadSession && stmt->conn->handle) { + if (stmt->parentStmt) { + dpiGen__setRefCount(stmt->parentStmt, error, -1); + stmt->parentStmt = NULL; + } else if (!stmt->conn->deadSession && stmt->conn->handle) { if (stmt->isOwned) dpiOci__handleFree(stmt->handle, DPI_OCI_HTYPE_STMT); else status = dpiOci__stmtRelease(stmt, tag, tagLength, propagateErrors, error); } - if (!stmt->conn->closing) + if (!stmt->conn->closing && !stmt->parentStmt) dpiHandleList__removeHandle(stmt->conn->openStmts, stmt->openSlotNum); stmt->handle = NULL; @@ -479,6 +484,7 @@ static int dpiStmt__define(dpiStmt *stmt, uint32_t pos, dpiVar *var, { void *defineHandle = NULL; dpiQueryInfo *queryInfo; + int tempBool; // no need to perform define if variable is unchanged if (stmt->queryVars[pos - 1] == var) @@ -513,6 +519,15 @@ static int dpiStmt__define(dpiStmt *stmt, uint32_t pos, dpiVar *var, return DPI_FAILURE; } + // specify that the LOB length should be prefetched + if (var->nativeTypeNum == DPI_NATIVE_TYPE_LOB) { + tempBool = 1; + if (dpiOci__attrSet(defineHandle, DPI_OCI_HTYPE_DEFINE, + (void*) &tempBool, 0, DPI_OCI_ATTR_LOBPREFETCH_LENGTH, + "set lob prefetch length", error) < 0) + return DPI_FAILURE; + } + // define objects, if applicable if (var->buffer.objectIndicator && dpiOci__defineObject(var, defineHandle, error) < 0) @@ -677,6 +692,10 @@ static int dpiStmt__fetch(dpiStmt *stmt, dpiError *error) void dpiStmt__free(dpiStmt *stmt, dpiError *error) { dpiStmt__close(stmt, NULL, 0, 0, error); + if (stmt->parentStmt) { + dpiGen__setRefCount(stmt->parentStmt, error, -1); + stmt->parentStmt = NULL; + } if (stmt->conn) { dpiGen__setRefCount(stmt->conn, error, -1); stmt->conn = NULL; @@ -753,7 +772,7 @@ static int dpiStmt__getBatchErrors(dpiStmt *stmt, dpiError *error) // get error message localError.buffer = &stmt->batchErrors[i]; localError.handle = batchErrorHandle; - dpiError__check(&localError, DPI_OCI_ERROR, stmt->conn, + dpiError__setFromOCI(&localError, DPI_OCI_ERROR, stmt->conn, "get batch error"); if (error->buffer->errorNum) { overallStatus = DPI_FAILURE; @@ -773,6 +792,42 @@ static int dpiStmt__getBatchErrors(dpiStmt *stmt, dpiError *error) } +//----------------------------------------------------------------------------- +// dpiStmt__getRowCount() [INTERNAL] +// Return the number of rows affected by the last DML executed (for insert, +// update, delete and merge) or the number of rows fetched (for queries). In +// all other cases, 0 is returned. +//----------------------------------------------------------------------------- +static int dpiStmt__getRowCount(dpiStmt *stmt, uint64_t *count, + dpiError *error) +{ + uint32_t rowCount32; + + if (stmt->statementType == DPI_STMT_TYPE_SELECT) + *count = stmt->rowCount; + else if (stmt->statementType != DPI_STMT_TYPE_INSERT && + stmt->statementType != DPI_STMT_TYPE_UPDATE && + stmt->statementType != DPI_STMT_TYPE_DELETE && + stmt->statementType != DPI_STMT_TYPE_MERGE && + stmt->statementType != DPI_STMT_TYPE_CALL && + stmt->statementType != DPI_STMT_TYPE_BEGIN && + stmt->statementType != DPI_STMT_TYPE_DECLARE) { + *count = 0; + } else if (stmt->env->versionInfo->versionNum < 12) { + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, &rowCount32, 0, + DPI_OCI_ATTR_ROW_COUNT, "get row count", error) < 0) + return DPI_FAILURE; + *count = rowCount32; + } else { + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, count, 0, + DPI_OCI_ATTR_UB8_ROW_COUNT, "get row count", error) < 0) + return DPI_FAILURE; + } + + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiStmt__getQueryInfo() [INTERNAL] // Get query information for the position in question. @@ -1484,6 +1539,8 @@ int dpiStmt_getImplicitResult(dpiStmt *stmt, dpiStmt **implicitResult) if (dpiStmt__allocate(stmt->conn, 0, &tempStmt, &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); tempStmt->handle = handle; + dpiGen__setRefCount(stmt, &error, 1); + tempStmt->parentStmt = stmt; if (dpiStmt__createQueryVars(tempStmt, &error) < 0) { dpiStmt__free(tempStmt, &error); return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); @@ -1522,6 +1579,46 @@ int dpiStmt_getInfo(dpiStmt *stmt, dpiStmtInfo *info) } +//----------------------------------------------------------------------------- +// dpiStmt_getLastRowid() [PUBLIC] +// Returns the rowid of the last row that was affected by a DML statement. If +// no rows were affected by the last statement executed or the last statement +// executed was not a DML statement, NULL is returned. +//----------------------------------------------------------------------------- +int dpiStmt_getLastRowid(dpiStmt *stmt, dpiRowid **rowid) +{ + uint64_t rowCount; + dpiError error; + + if (dpiStmt__check(stmt, __func__, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(stmt, rowid) + *rowid = NULL; + if (stmt->statementType == DPI_STMT_TYPE_INSERT || + stmt->statementType == DPI_STMT_TYPE_UPDATE || + stmt->statementType == DPI_STMT_TYPE_DELETE || + stmt->statementType == DPI_STMT_TYPE_MERGE) { + if (dpiStmt__getRowCount(stmt, &rowCount, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + if (rowCount > 0) { + if (stmt->lastRowid) { + dpiGen__setRefCount(stmt->lastRowid, &error, -1); + stmt->lastRowid = NULL; + } + if (dpiRowid__allocate(stmt->conn, &stmt->lastRowid, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, + stmt->lastRowid->handle, 0, DPI_OCI_ATTR_ROWID, + "get last rowid", &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + *rowid = stmt->lastRowid; + } + } + + return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiStmt_getNumQueryColumns() [PUBLIC] // Returns the number of query columns associated with a statement. If the @@ -1612,33 +1709,14 @@ int dpiStmt_getQueryValue(dpiStmt *stmt, uint32_t pos, //----------------------------------------------------------------------------- int dpiStmt_getRowCount(dpiStmt *stmt, uint64_t *count) { - uint32_t rowCount32; dpiError error; + int status; if (dpiStmt__check(stmt, __func__, &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(stmt, count) - if (stmt->statementType == DPI_STMT_TYPE_SELECT) - *count = stmt->rowCount; - else if (stmt->statementType != DPI_STMT_TYPE_INSERT && - stmt->statementType != DPI_STMT_TYPE_UPDATE && - stmt->statementType != DPI_STMT_TYPE_DELETE && - stmt->statementType != DPI_STMT_TYPE_MERGE && - stmt->statementType != DPI_STMT_TYPE_CALL && - stmt->statementType != DPI_STMT_TYPE_BEGIN && - stmt->statementType != DPI_STMT_TYPE_DECLARE) { - *count = 0; - } else if (stmt->env->versionInfo->versionNum < 12) { - if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, &rowCount32, 0, - DPI_OCI_ATTR_ROW_COUNT, "get row count", &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - *count = rowCount32; - } else { - if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, count, 0, - DPI_OCI_ATTR_UB8_ROW_COUNT, "get row count", &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - } - return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); + status = dpiStmt__getRowCount(stmt, count, &error); + return dpiGen__endPublicFn(stmt, status, &error); } @@ -1818,4 +1896,3 @@ int dpiStmt_setFetchArraySize(dpiStmt *stmt, uint32_t arraySize) stmt->fetchArraySize = arraySize; return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c b/vendor/github.com/godror/godror/odpi/src/dpiSubscr.c similarity index 93% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c rename to vendor/github.com/godror/godror/odpi/src/dpiSubscr.c index 55c00168e0d..cf1ed60b2d8 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSubscr.c @@ -40,9 +40,19 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, dpiError error; // ensure that the subscription handle is still valid - if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, __func__, 1, - &error) < 0) + if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, __func__, + &error) < 0) { dpiGen__endPublicFn(subscr, DPI_FAILURE, &error); + return; + } + + // if the subscription is no longer registered, nothing further to do + dpiMutex__acquire(subscr->mutex); + if (!subscr->registered) { + dpiMutex__release(subscr->mutex); + dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); + return; + } // populate message memset(&message, 0, sizeof(message)); @@ -52,11 +62,13 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, } message.registered = subscr->registered; - // invoke user callback + // invoke user callback; temporarily increase reference count to ensure + // that the subscription is not freed during the callback + dpiGen__setRefCount(subscr, &error, 1); (*subscr->callback)(subscr->callbackContext, &message); - - // clean up message dpiSubscr__freeMessage(&message); + dpiMutex__release(subscr->mutex); + dpiGen__setRefCount(subscr, &error, -1); dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); } @@ -68,7 +80,7 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, static int dpiSubscr__check(dpiSubscr *subscr, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, fnName, error) < 0) return DPI_FAILURE; if (!subscr->handle) return dpiError__set(error, "check closed", DPI_ERR_SUBSCR_CLOSED); @@ -84,7 +96,7 @@ static int dpiSubscr__check(dpiSubscr *subscr, const char *fnName, int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, dpiSubscrCreateParams *params, dpiError *error) { - uint32_t qosFlags; + uint32_t qosFlags, mode; int32_t int32Val; int rowids; @@ -95,6 +107,8 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, subscr->callbackContext = params->callbackContext; subscr->subscrNamespace = params->subscrNamespace; subscr->qos = params->qos; + subscr->clientInitiated = params->clientInitiated; + dpiMutex__initialize(subscr->mutex); // create the subscription handle if (dpiOci__handleAlloc(conn->env->handle, &subscr->handle, @@ -222,11 +236,27 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, } - // register the subscription - if (dpiOci__subscriptionRegister(conn, &subscr->handle, error) < 0) + // register the subscription; client initiated subscriptions are only valid + // with 19.4 client and database + mode = DPI_OCI_DEFAULT; + if (params->clientInitiated) { + if (dpiUtils__checkClientVersion(conn->env->versionInfo, 19, 4, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__checkDatabaseVersion(conn, 19, 4, error) < 0) + return DPI_FAILURE; + mode = DPI_OCI_SECURE_NOTIFICATION; + } + if (dpiOci__subscriptionRegister(conn, &subscr->handle, mode, error) < 0) return DPI_FAILURE; subscr->registered = 1; + // acquire the registration id + if (dpiOci__attrGet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION, + ¶ms->outRegId, NULL, DPI_OCI_ATTR_SUBSCR_CQ_REGID, + "get registration id", error) < 0) + return DPI_FAILURE; + return DPI_SUCCESS; } @@ -237,6 +267,7 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, //----------------------------------------------------------------------------- void dpiSubscr__free(dpiSubscr *subscr, dpiError *error) { + dpiMutex__acquire(subscr->mutex); if (subscr->handle) { if (subscr->registered) dpiOci__subscriptionUnRegister(subscr->conn, subscr, error); @@ -247,6 +278,8 @@ void dpiSubscr__free(dpiSubscr *subscr, dpiError *error) dpiGen__setRefCount(subscr->conn, error, -1); subscr->conn = NULL; } + dpiMutex__release(subscr->mutex); + dpiMutex__destroy(subscr->mutex); dpiUtils__freeMemory(subscr); } @@ -615,9 +648,12 @@ static int dpiSubscr__populateQueryChangeMessage(dpiSubscr *subscr, static int dpiSubscr__prepareStmt(dpiSubscr *subscr, dpiStmt *stmt, const char *sql, uint32_t sqlLength, dpiError *error) { - // prepare statement for execution + // prepare statement for execution; only SELECT statements are supported if (dpiStmt__prepare(stmt, sql, sqlLength, NULL, 0, error) < 0) return DPI_FAILURE; + if (stmt->statementType != DPI_STMT_TYPE_SELECT) + return dpiError__set(error, "subscr prepare statement", + DPI_ERR_NOT_SUPPORTED); // fetch array size is set to 1 in order to avoid over allocation since // the query is not really going to be used for fetching rows, just for @@ -675,4 +711,3 @@ int dpiSubscr_release(dpiSubscr *subscr) { return dpiGen__release(subscr, DPI_HTYPE_SUBSCR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c b/vendor/github.com/godror/godror/odpi/src/dpiUtils.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c rename to vendor/github.com/godror/godror/odpi/src/dpiUtils.c index 1aad9118400..0ab09e54487 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiUtils.c @@ -251,7 +251,7 @@ int dpiUtils__parseNumberString(const char *value, uint32_t valueLength, return dpiError__set(error, "no digits in exponent", DPI_ERR_INVALID_NUMBER); exponentDigits[numExponentDigits] = '\0'; - exponent = (int16_t) strtol(exponentDigits, NULL, 0); + exponent = (int16_t) strtol(exponentDigits, NULL, 10); if (exponentIsNegative) exponent = -exponent; *decimalPointIndex += exponent; @@ -399,4 +399,3 @@ int dpiUtils__setAttributesFromCommonCreateParams(void *handle, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c b/vendor/github.com/godror/godror/odpi/src/dpiVar.c similarity index 97% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c rename to vendor/github.com/godror/godror/odpi/src/dpiVar.c index de9db59bc48..d8cde787c64 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiVar.c @@ -226,10 +226,9 @@ static void dpiVar__assignCallbackBuffer(dpiVar *var, dpiVarBuffer *buffer, // Verifies that the array size has not been exceeded. //----------------------------------------------------------------------------- static int dpiVar__checkArraySize(dpiVar *var, uint32_t pos, - const char *fnName, int needErrorHandle, dpiError *error) + const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, fnName, needErrorHandle, - error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, fnName, error) < 0) return DPI_FAILURE; if (pos >= var->buffer.maxArraySize) return dpiError__set(error, "check array size", @@ -629,7 +628,6 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, return DPI_SUCCESS; } - // check for a NULL value; for objects the indicator is elsewhere data = &buffer->externalData[pos]; if (!buffer->objectIndicator) @@ -638,8 +636,17 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, data->isNull = (*((int16_t*) buffer->objectIndicator[pos]) == DPI_OCI_IND_NULL); else data->isNull = 1; - if (data->isNull) + if (data->isNull) { + if (inFetch && var->objectType && var->objectType->isCollection) { + if (dpiOci__objectFree(var->env->handle, + buffer->data.asObject[pos], 1, error) < 0) + return DPI_FAILURE; + if (dpiOci__objectFree(var->env->handle, + buffer->objectIndicator[pos], 1, error) < 0) + return DPI_FAILURE; + } return DPI_SUCCESS; + } // check return code for variable length data if (buffer->returnCode) { @@ -781,8 +788,8 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, // does nothing useful except satisfy OCI requirements. //----------------------------------------------------------------------------- int32_t dpiVar__inBindCallback(dpiVar *var, UNUSED void *bindp, - UNUSED uint32_t iter, uint32_t index, void **bufpp, uint32_t *alenp, - uint8_t *piecep, void **indpp) + UNUSED uint32_t iter, UNUSED uint32_t index, void **bufpp, + uint32_t *alenp, uint8_t *piecep, void **indpp) { dpiDynamicBytes *dynBytes; @@ -1208,7 +1215,8 @@ static int dpiVar__setFromBytes(dpiVar *var, uint32_t pos, const char *value, dynBytes = &var->buffer.dynamicBytes[pos]; if (dpiVar__allocateDynamicBytes(dynBytes, valueLength, error) < 0) return DPI_FAILURE; - memcpy(dynBytes->chunks->ptr, value, valueLength); + if (valueLength > 0) + memcpy(dynBytes->chunks->ptr, value, valueLength); dynBytes->numChunks = 1; dynBytes->chunks->length = valueLength; bytes->ptr = dynBytes->chunks->ptr; @@ -1461,6 +1469,10 @@ int dpiVar__setValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, case DPI_ORACLE_TYPE_NUMBER: return dpiDataBuffer__toOracleNumberFromDouble( &data->value, error, &buffer->data.asNumber[pos]); + case DPI_ORACLE_TYPE_DATE: + return dpiDataBuffer__toOracleDateFromDouble( + &data->value, var->env, error, + &buffer->data.asDate[pos]); case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: @@ -1520,6 +1532,7 @@ static int dpiVar__validateTypes(const dpiOracleType *oracleType, dpiNativeTypeNum nativeTypeNum, dpiError *error) { switch (oracleType->oracleTypeNum) { + case DPI_ORACLE_TYPE_DATE: case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: @@ -1564,7 +1577,7 @@ int dpiVar_copyData(dpiVar *var, uint32_t pos, dpiVar *sourceVar, dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (dpiGen__checkHandle(sourceVar, DPI_HTYPE_VAR, "check source var", &error) < 0) @@ -1594,7 +1607,7 @@ int dpiVar_getNumElementsInArray(dpiVar *var, uint32_t *numElements) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, numElements) if (var->dynBindBuffers) @@ -1618,7 +1631,7 @@ int dpiVar_getReturnedData(dpiVar *var, uint32_t pos, uint32_t *numElements, { dpiError error; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, numElements) DPI_CHECK_PTR_NOT_NULL(var, data) @@ -1642,7 +1655,7 @@ int dpiVar_getSizeInBytes(dpiVar *var, uint32_t *sizeInBytes) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, sizeInBytes) *sizeInBytes = var->sizeInBytes; @@ -1673,9 +1686,9 @@ int dpiVar_setFromBytes(dpiVar *var, uint32_t pos, const char *value, dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(var, value) + DPI_CHECK_PTR_AND_LENGTH(var, value) if (var->nativeTypeNum != DPI_NATIVE_TYPE_BYTES && var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1702,7 +1715,7 @@ int dpiVar_setFromLob(dpiVar *var, uint32_t pos, dpiLob *lob) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1724,7 +1737,7 @@ int dpiVar_setFromObject(dpiVar *var, uint32_t pos, dpiObject *obj) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_OBJECT) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1746,7 +1759,7 @@ int dpiVar_setFromRowid(dpiVar *var, uint32_t pos, dpiRowid *rowid) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_ROWID) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1768,7 +1781,7 @@ int dpiVar_setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_STMT) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1788,7 +1801,7 @@ int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (numElements > var->buffer.maxArraySize) { dpiError__set(&error, "check num elements", @@ -1798,4 +1811,3 @@ int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements) var->buffer.actualArraySize = numElements; return dpiGen__endPublicFn(var, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/orahlp.go b/vendor/github.com/godror/godror/orahlp.go similarity index 83% rename from vendor/gopkg.in/goracle.v2/orahlp.go rename to vendor/github.com/godror/godror/orahlp.go index 6775a4678da..94e1f74828d 100644 --- a/vendor/gopkg.in/goracle.v2/orahlp.go +++ b/vendor/github.com/godror/godror/orahlp.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror import ( "bufio" @@ -24,8 +14,9 @@ import ( "fmt" "io" "sync" + "time" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // QueryColumn is the described column. @@ -52,10 +43,11 @@ type Querier interface { // This can help using unknown-at-compile-time, a.k.a. // dynamic queries. func DescribeQuery(ctx context.Context, db Execer, qry string) ([]QueryColumn, error) { - c, err := getConn(db) + c, err := getConn(ctx, db) if err != nil { return nil, err } + defer c.close(false) stmt, err := c.PrepareContext(ctx, qry) if err != nil { @@ -213,7 +205,10 @@ func MapToSlice(qry string, metParam func(string) interface{}) (string, []interf func EnableDbmsOutput(ctx context.Context, conn Execer) error { qry := "BEGIN DBMS_OUTPUT.enable(1000000); END;" _, err := conn.ExecContext(ctx, qry) - return errors.Wrap(err, qry) + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + return nil } // ReadDbmsOutput copies the DBMS_OUTPUT buffer into the given io.Writer. @@ -224,7 +219,7 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { const qry = `BEGIN DBMS_OUTPUT.get_lines(:1, :2); END;` stmt, err := conn.PrepareContext(ctx, qry) if err != nil { - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } lines := make([]string, maxNumLines) @@ -237,7 +232,7 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { numLines = int64(len(lines)) if _, err = stmt.ExecContext(ctx, params...); err != nil { _ = bw.Flush() - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } for i := 0; i < int(numLines); i++ { _, _ = bw.WriteString(lines[i]) @@ -253,8 +248,8 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { } // ClientVersion returns the VersionInfo from the DB. -func ClientVersion(ex Execer) (VersionInfo, error) { - c, err := getConn(ex) +func ClientVersion(ctx context.Context, ex Execer) (VersionInfo, error) { + c, err := getConn(ctx, ex) if err != nil { return VersionInfo{}, err } @@ -262,8 +257,8 @@ func ClientVersion(ex Execer) (VersionInfo, error) { } // ServerVersion returns the VersionInfo of the client. -func ServerVersion(ex Execer) (VersionInfo, error) { - c, err := getConn(ex) +func ServerVersion(ctx context.Context, ex Execer) (VersionInfo, error) { + c, err := getConn(ctx, ex) if err != nil { return VersionInfo{}, err } @@ -273,32 +268,37 @@ func ServerVersion(ex Execer) (VersionInfo, error) { // Conn is the interface for a connection, to be returned by DriverConn. type Conn interface { driver.Conn + driver.ConnBeginTx + driver.ConnPrepareContext driver.Pinger + Break() error - BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) - PrepareContext(ctx context.Context, query string) (driver.Stmt, error) Commit() error Rollback() error + ClientVersion() (VersionInfo, error) ServerVersion() (VersionInfo, error) GetObjectType(name string) (ObjectType, error) NewSubscription(string, func(Event)) (*Subscription, error) Startup(StartupMode) error Shutdown(ShutdownMode) error + NewData(baseType interface{}, SliceLen, BufSize int) ([]*Data, error) + + Timezone() *time.Location } -// DriverConn returns the *goracle.conn of the database/sql.Conn -func DriverConn(ex Execer) (Conn, error) { - return getConn(ex) +// DriverConn returns the *godror.conn of the database/sql.Conn +func DriverConn(ctx context.Context, ex Execer) (Conn, error) { + return getConn(ctx, ex) } var getConnMu sync.Mutex -func getConn(ex Execer) (*conn, error) { +func getConn(ctx context.Context, ex Execer) (*conn, error) { getConnMu.Lock() defer getConnMu.Unlock() var c interface{} - if _, err := ex.ExecContext(context.Background(), getConnection, sql.Out{Dest: &c}); err != nil { - return nil, errors.Wrap(err, "getConnection") + if _, err := ex.ExecContext(ctx, getConnection, sql.Out{Dest: &c}); err != nil { + return nil, errors.Errorf("getConnection: %w", err) } return c.(*conn), nil } @@ -307,3 +307,11 @@ func getConn(ex Execer) (*conn, error) { func WrapRows(ctx context.Context, q Querier, rset driver.Rows) (*sql.Rows, error) { return q.QueryContext(ctx, wrapResultset, rset) } + +func Timezone(ctx context.Context, ex Execer) (*time.Location, error) { + c, err := getConn(ctx, ex) + if err != nil { + return nil, err + } + return c.Timezone(), nil +} diff --git a/vendor/github.com/godror/godror/queue.go b/vendor/github.com/godror/godror/queue.go new file mode 100644 index 00000000000..01f081452af --- /dev/null +++ b/vendor/github.com/godror/godror/queue.go @@ -0,0 +1,639 @@ +// Copyright 2019 Tamás Gulácsi +// +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 + +package godror + +/* +#include +#include "dpiImpl.h" +*/ +import "C" +import ( + "context" + "sync" + "time" + "unsafe" + + errors "golang.org/x/xerrors" +) + +const MsgIDLength = 16 + +var zeroMsgID [MsgIDLength]byte + +// DefaultEnqOptions is the default set for NewQueue. +var DefaultEnqOptions = EnqOptions{ + Visibility: VisibleImmediate, + DeliveryMode: DeliverPersistent, +} + +// DefaultDeqOptions is the default set for NewQueue. +var DefaultDeqOptions = DeqOptions{ + Mode: DeqRemove, + DeliveryMode: DeliverPersistent, + Navigation: NavFirst, + Visibility: VisibleImmediate, + Wait: 30, +} + +// Queue represents an Oracle Advanced Queue. +type Queue struct { + conn *conn + dpiQueue *C.dpiQueue + PayloadObjectType ObjectType + name string + + mu sync.Mutex + props []*C.dpiMsgProps +} + +// NewQueue creates a new Queue. +// +// WARNING: the connection given to it must not be closed before the Queue is closed! +// So use an sql.Conn for it. +func NewQueue(ctx context.Context, execer Execer, name string, payloadObjectTypeName string) (*Queue, error) { + cx, err := DriverConn(ctx, execer) + if err != nil { + return nil, err + } + Q := Queue{conn: cx.(*conn), name: name} + + var payloadType *C.dpiObjectType + if payloadObjectTypeName != "" { + if Q.PayloadObjectType, err = Q.conn.GetObjectType(payloadObjectTypeName); err != nil { + return nil, err + } else { + payloadType = Q.PayloadObjectType.dpiObjectType + } + } + value := C.CString(name) + if C.dpiConn_newQueue(Q.conn.dpiConn, value, C.uint(len(name)), payloadType, &Q.dpiQueue) == C.DPI_FAILURE { + err = errors.Errorf("newQueue %q: %w", name, Q.conn.drv.getError()) + } + C.free(unsafe.Pointer(value)) + if err != nil { + cx.Close() + return nil, err + } + if err = Q.SetEnqOptions(DefaultEnqOptions); err != nil { + cx.Close() + Q.Close() + return nil, err + } + if err = Q.SetDeqOptions(DefaultDeqOptions); err != nil { + cx.Close() + Q.Close() + return nil, err + } + return &Q, nil +} + +// Close the queue. +func (Q *Queue) Close() error { + c, q := Q.conn, Q.dpiQueue + Q.conn, Q.dpiQueue = nil, nil + if q == nil { + return nil + } + if C.dpiQueue_release(q) == C.DPI_FAILURE { + return errors.Errorf("release: %w", c.getError()) + } + return nil +} + +// Name of the queue. +func (Q *Queue) Name() string { return Q.name } + +// EnqOptions returns the queue's enqueue options in effect. +func (Q *Queue) EnqOptions() (EnqOptions, error) { + var E EnqOptions + var opts *C.dpiEnqOptions + if C.dpiQueue_getEnqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return E, errors.Errorf("getEnqOptions: %w", Q.conn.drv.getError()) + } + err := E.fromOra(Q.conn.drv, opts) + return E, err +} + +// DeqOptions returns the queue's dequeue options in effect. +func (Q *Queue) DeqOptions() (DeqOptions, error) { + var D DeqOptions + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return D, errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + err := D.fromOra(Q.conn.drv, opts) + return D, err +} + +// Dequeues messages into the given slice. +// Returns the number of messages filled in the given slice. +func (Q *Queue) Dequeue(messages []Message) (int, error) { + Q.mu.Lock() + defer Q.mu.Unlock() + var props []*C.dpiMsgProps + if cap(Q.props) >= len(messages) { + props = Q.props[:len(messages)] + } else { + props = make([]*C.dpiMsgProps, len(messages)) + } + Q.props = props + + var ok C.int + num := C.uint(len(props)) + if num == 1 { + ok = C.dpiQueue_deqOne(Q.dpiQueue, &props[0]) + } else { + ok = C.dpiQueue_deqMany(Q.dpiQueue, &num, &props[0]) + } + if ok == C.DPI_FAILURE { + err := Q.conn.getError() + if code := err.(interface{ Code() int }).Code(); code == 3156 { + return 0, context.DeadlineExceeded + } + return 0, errors.Errorf("dequeue: %w", err) + } + var firstErr error + for i, p := range props[:int(num)] { + if err := messages[i].fromOra(Q.conn, p, &Q.PayloadObjectType); err != nil { + if firstErr == nil { + firstErr = err + } + } + C.dpiMsgProps_release(p) + } + return int(num), firstErr +} + +// Enqueue all the messages given. +// +// WARNING: calling this function in parallel on different connections acquired from the same pool may fail due to Oracle bug 29928074. Ensure that this function is not run in parallel, use standalone connections or connections from different pools, or make multiple calls to Queue.enqOne() instead. The function Queue.Dequeue() call is not affected. +func (Q *Queue) Enqueue(messages []Message) error { + Q.mu.Lock() + defer Q.mu.Unlock() + var props []*C.dpiMsgProps + if cap(Q.props) >= len(messages) { + props = Q.props[:len(messages)] + } else { + props = make([]*C.dpiMsgProps, len(messages)) + } + Q.props = props + defer func() { + for _, p := range props { + if p != nil { + C.dpiMsgProps_release(p) + } + } + }() + for i, m := range messages { + if C.dpiConn_newMsgProps(Q.conn.dpiConn, &props[i]) == C.DPI_FAILURE { + return errors.Errorf("newMsgProps: %w", Q.conn.getError()) + } + if err := m.toOra(Q.conn.drv, props[i]); err != nil { + return err + } + } + + var ok C.int + if len(messages) == 1 { + ok = C.dpiQueue_enqOne(Q.dpiQueue, props[0]) + } else { + ok = C.dpiQueue_enqMany(Q.dpiQueue, C.uint(len(props)), &props[0]) + } + if ok == C.DPI_FAILURE { + return errors.Errorf("enqueue %#v: %w", messages, Q.conn.getError()) + } + + return nil +} + +// Message is a message - either received or being sent. +type Message struct { + DeliveryMode DeliveryMode + Enqueued time.Time + Delay, Expiration int32 + Priority, NumAttempts int32 + Correlation, ExceptionQ string + MsgID, OriginalMsgID [16]byte + State MessageState + Raw []byte + Object *Object +} + +func (M *Message) toOra(d *drv, props *C.dpiMsgProps) error { + var firstErr error + OK := func(ok C.int, name string) { + if ok == C.DPI_SUCCESS { + return + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", name, d.getError()) + } + } + if M.Correlation != "" { + value := C.CString(M.Correlation) + OK(C.dpiMsgProps_setCorrelation(props, value, C.uint(len(M.Correlation))), "setCorrelation") + C.free(unsafe.Pointer(value)) + } + + if M.Delay != 0 { + OK(C.dpiMsgProps_setDelay(props, C.int(M.Delay)), "setDelay") + } + + if M.ExceptionQ != "" { + value := C.CString(M.ExceptionQ) + OK(C.dpiMsgProps_setExceptionQ(props, value, C.uint(len(M.ExceptionQ))), "setExceptionQ") + C.free(unsafe.Pointer(value)) + } + + if M.Expiration != 0 { + OK(C.dpiMsgProps_setExpiration(props, C.int(M.Expiration)), "setExpiration") + } + + if M.OriginalMsgID != zeroMsgID { + OK(C.dpiMsgProps_setOriginalMsgId(props, (*C.char)(unsafe.Pointer(&M.OriginalMsgID[0])), MsgIDLength), "setMsgOriginalId") + } + + OK(C.dpiMsgProps_setPriority(props, C.int(M.Priority)), "setPriority") + + if M.Object == nil { + OK(C.dpiMsgProps_setPayloadBytes(props, (*C.char)(unsafe.Pointer(&M.Raw[0])), C.uint(len(M.Raw))), "setPayloadBytes") + } else { + OK(C.dpiMsgProps_setPayloadObject(props, M.Object.dpiObject), "setPayloadObject") + } + + return firstErr +} + +func (M *Message) fromOra(c *conn, props *C.dpiMsgProps, objType *ObjectType) error { + var firstErr error + OK := func(ok C.int, name string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", name, c.getError()) + } + return false + } + M.NumAttempts = 0 + var cint C.int + if OK(C.dpiMsgProps_getNumAttempts(props, &cint), "getNumAttempts") { + M.NumAttempts = int32(cint) + } + var value *C.char + var length C.uint + M.Correlation = "" + if OK(C.dpiMsgProps_getCorrelation(props, &value, &length), "getCorrelation") { + M.Correlation = C.GoStringN(value, C.int(length)) + } + + M.Delay = 0 + if OK(C.dpiMsgProps_getDelay(props, &cint), "getDelay") { + M.Delay = int32(cint) + } + + M.DeliveryMode = DeliverPersistent + var mode C.dpiMessageDeliveryMode + if OK(C.dpiMsgProps_getDeliveryMode(props, &mode), "getDeliveryMode") { + M.DeliveryMode = DeliveryMode(mode) + } + + M.ExceptionQ = "" + if OK(C.dpiMsgProps_getExceptionQ(props, &value, &length), "getExceptionQ") { + M.ExceptionQ = C.GoStringN(value, C.int(length)) + } + + var ts C.dpiTimestamp + M.Enqueued = time.Time{} + if OK(C.dpiMsgProps_getEnqTime(props, &ts), "getEnqTime") { + tz := c.timeZone + if ts.tzHourOffset != 0 || ts.tzMinuteOffset != 0 { + tz = timeZoneFor(ts.tzHourOffset, ts.tzMinuteOffset) + } + if tz == nil { + tz = time.Local + } + M.Enqueued = time.Date( + int(ts.year), time.Month(ts.month), int(ts.day), + int(ts.hour), int(ts.minute), int(ts.second), int(ts.fsecond), + tz, + ) + } + + M.Expiration = 0 + if OK(C.dpiMsgProps_getExpiration(props, &cint), "getExpiration") { + M.Expiration = int32(cint) + } + + M.MsgID = zeroMsgID + if OK(C.dpiMsgProps_getMsgId(props, &value, &length), "getMsgId") { + n := C.int(length) + if n > MsgIDLength { + n = MsgIDLength + } + copy(M.MsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + } + + M.OriginalMsgID = zeroMsgID + if OK(C.dpiMsgProps_getOriginalMsgId(props, &value, &length), "getMsgOriginalId") { + n := C.int(length) + if n > MsgIDLength { + n = MsgIDLength + } + copy(M.OriginalMsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + } + + M.Priority = 0 + if OK(C.dpiMsgProps_getPriority(props, &cint), "getPriority") { + M.Priority = int32(cint) + } + + M.State = 0 + var state C.dpiMessageState + if OK(C.dpiMsgProps_getState(props, &state), "getState") { + M.State = MessageState(state) + } + + M.Raw = nil + M.Object = nil + var obj *C.dpiObject + if OK(C.dpiMsgProps_getPayload(props, &obj, &value, &length), "getPayload") { + if obj == nil { + M.Raw = append(make([]byte, 0, length), ((*[1 << 30]byte)(unsafe.Pointer(value)))[:int(length):int(length)]...) + } else { + if C.dpiObject_addRef(obj) == C.DPI_FAILURE { + return objType.getError() + } + M.Object = &Object{dpiObject: obj, ObjectType: *objType} + } + } + return nil +} + +// EnqOptions are the options used to enqueue a message. +type EnqOptions struct { + Transformation string + Visibility Visibility + DeliveryMode DeliveryMode +} + +func (E *EnqOptions) fromOra(d *drv, opts *C.dpiEnqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + E.DeliveryMode = DeliverPersistent + + var value *C.char + var length C.uint + if OK(C.dpiEnqOptions_getTransformation(opts, &value, &length), "getTransformation") { + E.Transformation = C.GoStringN(value, C.int(length)) + } + + var vis C.dpiVisibility + if OK(C.dpiEnqOptions_getVisibility(opts, &vis), "getVisibility") { + E.Visibility = Visibility(vis) + } + + return firstErr +} + +func (E EnqOptions) toOra(d *drv, opts *C.dpiEnqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + OK(C.dpiEnqOptions_setDeliveryMode(opts, C.dpiMessageDeliveryMode(E.DeliveryMode)), "setDeliveryMode") + cs := C.CString(E.Transformation) + OK(C.dpiEnqOptions_setTransformation(opts, cs, C.uint(len(E.Transformation))), "setTransformation") + C.free(unsafe.Pointer(cs)) + OK(C.dpiEnqOptions_setVisibility(opts, C.uint(E.Visibility)), "setVisibility") + return firstErr +} + +// SetEnqOptions sets all the enqueue options +func (Q *Queue) SetEnqOptions(E EnqOptions) error { + var opts *C.dpiEnqOptions + if C.dpiQueue_getEnqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getEnqOptions: %w", Q.conn.drv.getError()) + } + return E.toOra(Q.conn.drv, opts) +} + +// DeqOptions are the options used to dequeue a message. +type DeqOptions struct { + Condition, Consumer, Correlation string + MsgID, Transformation string + Mode DeqMode + DeliveryMode DeliveryMode + Navigation DeqNavigation + Visibility Visibility + Wait uint32 +} + +func (D *DeqOptions) fromOra(d *drv, opts *C.dpiDeqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + var value *C.char + var length C.uint + D.Transformation = "" + if OK(C.dpiDeqOptions_getTransformation(opts, &value, &length), "getTransformation") { + D.Transformation = C.GoStringN(value, C.int(length)) + } + D.Condition = "" + if OK(C.dpiDeqOptions_getCondition(opts, &value, &length), "getCondifion") { + D.Condition = C.GoStringN(value, C.int(length)) + } + D.Consumer = "" + if OK(C.dpiDeqOptions_getConsumerName(opts, &value, &length), "getConsumer") { + D.Consumer = C.GoStringN(value, C.int(length)) + } + D.Correlation = "" + if OK(C.dpiDeqOptions_getCorrelation(opts, &value, &length), "getCorrelation") { + D.Correlation = C.GoStringN(value, C.int(length)) + } + D.DeliveryMode = DeliverPersistent + var mode C.dpiDeqMode + if OK(C.dpiDeqOptions_getMode(opts, &mode), "getMode") { + D.Mode = DeqMode(mode) + } + D.MsgID = "" + if OK(C.dpiDeqOptions_getMsgId(opts, &value, &length), "getMsgId") { + D.MsgID = C.GoStringN(value, C.int(length)) + } + var nav C.dpiDeqNavigation + if OK(C.dpiDeqOptions_getNavigation(opts, &nav), "getNavigation") { + D.Navigation = DeqNavigation(nav) + } + var vis C.dpiVisibility + if OK(C.dpiDeqOptions_getVisibility(opts, &vis), "getVisibility") { + D.Visibility = Visibility(vis) + } + D.Wait = 0 + var u32 C.uint + if OK(C.dpiDeqOptions_getWait(opts, &u32), "getWait") { + D.Wait = uint32(u32) + } + return firstErr +} + +func (D DeqOptions) toOra(d *drv, opts *C.dpiDeqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + cs := C.CString(D.Transformation) + OK(C.dpiDeqOptions_setTransformation(opts, cs, C.uint(len(D.Transformation))), "setTransformation") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Condition) + OK(C.dpiDeqOptions_setCondition(opts, cs, C.uint(len(D.Condition))), "setCondifion") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Consumer) + OK(C.dpiDeqOptions_setConsumerName(opts, cs, C.uint(len(D.Consumer))), "setConsumer") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Correlation) + OK(C.dpiDeqOptions_setCorrelation(opts, cs, C.uint(len(D.Correlation))), "setCorrelation") + C.free(unsafe.Pointer(cs)) + + OK(C.dpiDeqOptions_setDeliveryMode(opts, C.dpiMessageDeliveryMode(D.DeliveryMode)), "setDeliveryMode") + OK(C.dpiDeqOptions_setMode(opts, C.dpiDeqMode(D.Mode)), "setMode") + + cs = C.CString(D.MsgID) + OK(C.dpiDeqOptions_setMsgId(opts, cs, C.uint(len(D.MsgID))), "setMsgId") + C.free(unsafe.Pointer(cs)) + + OK(C.dpiDeqOptions_setNavigation(opts, C.dpiDeqNavigation(D.Navigation)), "setNavigation") + + OK(C.dpiDeqOptions_setVisibility(opts, C.dpiVisibility(D.Visibility)), "setVisibility") + + OK(C.dpiDeqOptions_setWait(opts, C.uint(D.Wait)), "setWait") + + return firstErr +} + +// SetDeqOptions sets all the dequeue options +func (Q *Queue) SetDeqOptions(D DeqOptions) error { + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + return D.toOra(Q.conn.drv, opts) +} + +// SetDeqCorrelation is a convenience function setting the Correlation DeqOption +func (Q *Queue) SetDeqCorrelation(correlation string) error { + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + cs := C.CString(correlation) + ok := C.dpiDeqOptions_setCorrelation(opts, cs, C.uint(len(correlation))) == C.DPI_FAILURE + C.free(unsafe.Pointer(cs)) + if !ok { + return errors.Errorf("setCorrelation: %w", Q.conn.drv.getError()) + } + return nil +} + +const ( + NoWait = uint32(0) + WaitForever = uint32(1<<31 - 1) +) + +// MessageState constants representing message's state. +type MessageState uint32 + +const ( + // MsgStateReady says that "The message is ready to be processed". + MsgStateReady = MessageState(C.DPI_MSG_STATE_READY) + // MsgStateWaiting says that "The message is waiting for the delay time to expire". + MsgStateWaiting = MessageState(C.DPI_MSG_STATE_WAITING) + // MsgStateProcessed says that "The message has already been processed and is retained". + MsgStateProcessed = MessageState(C.DPI_MSG_STATE_PROCESSED) + // MsgStateExpired says that "The message has been moved to the exception queue". + MsgStateExpired = MessageState(C.DPI_MSG_STATE_EXPIRED) +) + +// DeliveryMode constants for delivery modes. +type DeliveryMode uint32 + +const ( + // DeliverPersistent is to Dequeue only persistent messages from the queue. This is the default mode. + DeliverPersistent = DeliveryMode(C.DPI_MODE_MSG_PERSISTENT) + // DeliverBuffered is to Dequeue only buffered messages from the queue. + DeliverBuffered = DeliveryMode(C.DPI_MODE_MSG_BUFFERED) + // DeliverPersistentOrBuffered is to Dequeue both persistent and buffered messages from the queue. + DeliverPersistentOrBuffered = DeliveryMode(C.DPI_MODE_MSG_PERSISTENT_OR_BUFFERED) +) + +// Visibility constants represents visibility. +type Visibility uint32 + +const ( + // VisibleImmediate means that "The message is not part of the current transaction but constitutes a transaction of its own". + VisibleImmediate = Visibility(C.DPI_VISIBILITY_IMMEDIATE) + // VisibleOnCommit means that "The message is part of the current transaction. This is the default value". + VisibleOnCommit = Visibility(C.DPI_VISIBILITY_ON_COMMIT) +) + +// DeqMode constants for dequeue modes. +type DeqMode uint32 + +const ( + // DeqRemove reads the message and updates or deletes it. This is the default mode. Note that the message may be retained in the queue table based on retention properties. + DeqRemove = DeqMode(C.DPI_MODE_DEQ_REMOVE) + // DeqBrows reads the message without acquiring a lock on the message (equivalent to a SELECT statement). + DeqBrowse = DeqMode(C.DPI_MODE_DEQ_BROWSE) + // DeqLocked reads the message and obtain a write lock on the message (equivalent to a SELECT FOR UPDATE statement). + DeqLocked = DeqMode(C.DPI_MODE_DEQ_LOCKED) + // DeqPeek confirms receipt of the message but does not deliver the actual message content. + DeqPeek = DeqMode(C.DPI_MODE_DEQ_REMOVE_NO_DATA) +) + +// DeqNavigation constants for navigation. +type DeqNavigation uint32 + +const ( + // NavFirst retrieves the first available message that matches the search criteria. This resets the position to the beginning of the queue. + NavFirst = DeqNavigation(C.DPI_DEQ_NAV_FIRST_MSG) + // NavNext skips the remainder of the current transaction group (if any) and retrieves the first message of the next transaction group. This option can only be used if message grouping is enabled for the queue. + NavNextTran = DeqNavigation(C.DPI_DEQ_NAV_NEXT_TRANSACTION) + // NavNext Retrieves the next available message that matches the search criteria. This is the default method. + NavNext = DeqNavigation(C.DPI_DEQ_NAV_NEXT_MSG) +) diff --git a/vendor/gopkg.in/goracle.v2/rows.go b/vendor/github.com/godror/godror/rows.go similarity index 92% rename from vendor/gopkg.in/goracle.v2/rows.go rename to vendor/github.com/godror/godror/rows.go index 6b54d821f34..e870338d773 100644 --- a/vendor/gopkg.in/goracle.v2/rows.go +++ b/vendor/github.com/godror/godror/rows.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include "dpiImpl.h" @@ -30,7 +20,7 @@ import ( "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) var _ = driver.Rows((*rows)(nil)) @@ -72,17 +62,16 @@ func (r *rows) Close() error { if r == nil { return nil } - r.columns = nil - r.data = nil - for _, v := range r.vars { - C.dpiVar_release(v) + vars, st := r.vars, r.statement + r.columns, r.vars, r.data, r.statement, r.nextRs = nil, nil, nil, nil, nil + for _, v := range vars[:cap(vars)] { + if v != nil { + C.dpiVar_release(v) + } } - r.vars = nil - if r.statement == nil { + if st == nil { return nil } - st := r.statement - r.statement = nil st.Lock() defer st.Unlock() @@ -91,7 +80,7 @@ func (r *rows) Close() error { } var err error if C.dpiStmt_release(st.dpiStmt) == C.DPI_FAILURE { - err = errors.Wrap(r.getError(), "rows/dpiStmt_release") + err = errors.Errorf("rows/dpiStmt_release: %w", r.getError()) } return err } @@ -266,6 +255,8 @@ func (r *rows) ColumnTypeScanType(index int) reflect.Type { // size as the Columns() are wide. // // Next should return io.EOF when there are no more rows. +// +// As with all Objects, you MUST call Close on the returned Object instances when they're not needed anymore! func (r *rows) Next(dest []driver.Value) error { if r.err != nil { return r.err @@ -280,7 +271,7 @@ func (r *rows) Next(dest []driver.Value) error { if r.fetched == 0 { var moreRows C.int if C.dpiStmt_fetchRows(r.dpiStmt, C.uint32_t(r.statement.FetchRowCount()), &r.bufferRowIndex, &r.fetched, &moreRows) == C.DPI_FAILURE { - return errors.Wrap(r.getError(), "Next") + return errors.Errorf("Next: %w", r.getError()) } if Log != nil { Log("msg", "fetched", "bri", r.bufferRowIndex, "fetched", r.fetched, "moreRows", moreRows, "len(data)", len(r.data), "cols", len(r.columns)) @@ -296,7 +287,7 @@ func (r *rows) Next(dest []driver.Value) error { var n C.uint32_t var data *C.dpiData if C.dpiVar_getReturnedData(r.vars[i], 0, &n, &data) == C.DPI_FAILURE { - return errors.Wrapf(r.getError(), "getReturnedData[%d]", i) + return errors.Errorf("getReturnedData[%d]: %w", i, r.getError()) } r.data[i] = (*[maxArraySize]C.dpiData)(unsafe.Pointer(data))[:n:n] //fmt.Printf("data %d=%+v\n%+v\n", n, data, r.data[i][0]) @@ -313,7 +304,7 @@ func (r *rows) Next(dest []driver.Value) error { typ := col.OracleType d := &r.data[i][r.bufferRowIndex] isNull := d.isNull == 1 - if Log != nil { + if false && Log != nil { Log("msg", "Next", "i", i, "row", r.bufferRowIndex, "typ", typ, "null", isNull) //, "data", fmt.Sprintf("%+v", d), "typ", typ) } @@ -352,7 +343,12 @@ func (r *rows) Next(dest []driver.Value) error { dest[i] = printFloat(float64(C.dpiData_getDouble(d))) default: b := C.dpiData_getBytes(d) - dest[i] = Number(C.GoStringN(b.ptr, C.int(b.length))) + s := C.GoStringN(b.ptr, C.int(b.length)) + if r.NumberAsString() { + dest[i] = s + } else { + dest[i] = Number(s) + } if Log != nil { Log("msg", "b", "i", i, "ptr", b.ptr, "length", b.length, "typ", col.NativeType, "int64", C.dpiData_getInt64(d), "dest", dest[i]) } @@ -436,7 +432,7 @@ func (r *rows) Next(dest []driver.Value) error { C.DPI_NATIVE_TYPE_LOB: isClob := typ == C.DPI_ORACLE_TYPE_CLOB || typ == C.DPI_ORACLE_TYPE_NCLOB if isNull { - if isClob && r.ClobAsString() { + if isClob && (r.ClobAsString() || !r.LobAsReader()) { dest[i] = "" } else { dest[i] = nil @@ -444,9 +440,11 @@ func (r *rows) Next(dest []driver.Value) error { continue } rdr := &dpiLobReader{dpiLob: C.dpiData_getLOB(d), conn: r.conn, IsClob: isClob} - if isClob && r.ClobAsString() { + if isClob && (r.ClobAsString() || !r.LobAsReader()) { sb := stringBuilders.Get() - if _, err := io.Copy(sb, rdr); err != nil { + _, err := io.Copy(sb, rdr) + C.dpiLob_close(rdr.dpiLob) + if err != nil { stringBuilders.Put(sb) return err } @@ -466,7 +464,7 @@ func (r *rows) Next(dest []driver.Value) error { } var colCount C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &colCount) == C.DPI_FAILURE { - return errors.Wrap(r.getError(), "getNumQueryColumns") + return errors.Errorf("getNumQueryColumns: %w", r.getError()) } st.Lock() r2, err := st.openRows(int(colCount)) @@ -488,7 +486,7 @@ func (r *rows) Next(dest []driver.Value) error { dest[i] = nil continue } - o, err := wrapObject(r.drv, col.ObjectType, C.dpiData_getObject(d)) + o, err := wrapObject(r.conn, col.ObjectType, C.dpiData_getObject(d)) if err != nil { return err } @@ -503,6 +501,10 @@ func (r *rows) Next(dest []driver.Value) error { r.bufferRowIndex++ r.fetched-- + if Log != nil { + Log("msg", "scanned", "row", r.bufferRowIndex, "dest", dest) + } + return nil } @@ -562,7 +564,7 @@ func (r *rows) getImplicitResult() { r.origSt = st } if C.dpiStmt_getImplicitResult(st.dpiStmt, &r.nextRs) == C.DPI_FAILURE { - r.nextRsErr = errors.Wrap(r.getError(), "getImplicitResult") + r.nextRsErr = errors.Errorf("getImplicitResult: %w", r.getError()) } } func (r *rows) HasNextResultSet() bool { @@ -586,14 +588,14 @@ func (r *rows) NextResultSet() error { return r.nextRsErr } if r.nextRs == nil { - return errors.Wrap(io.EOF, "getImplicitResult") + return errors.Errorf("getImplicitResult: %w", io.EOF) } } st := &statement{conn: r.conn, dpiStmt: r.nextRs} var n C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &n) == C.DPI_FAILURE { - return errors.Wrapf(io.EOF, "getNumQueryColumns: %v", r.getError()) + return errors.Errorf("getNumQueryColumns: %w: %w", r.getError(), io.EOF) } // keep the originam statement for the succeeding NextResultSet calls. nr, err := st.openRows(int(n)) diff --git a/vendor/github.com/godror/godror/sid/sid.go b/vendor/github.com/godror/godror/sid/sid.go new file mode 100644 index 00000000000..b1fb0953142 --- /dev/null +++ b/vendor/github.com/godror/godror/sid/sid.go @@ -0,0 +1,531 @@ +// Copyright 2019 Tamás Gulácsi +// +// +// Licensed 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/LIENSE-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 ONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sid + +import ( + "fmt" + "io" + "strconv" + "strings" + "unicode" + + errors "golang.org/x/xerrors" +) + +// Statement can Parse and Print Oracle connection descriptor (DESRIPTION=(ADDRESS=...)) format. +// It can be used to parse or build a SID. +// +// See https://docs.oracle.com/cd/B28359_01/network.111/b28317/tnsnames.htm#NETRF271 +type Statement struct { + Name, Value string + Statements []Statement +} + +func (cs Statement) String() string { + var buf strings.Builder + cs.Print(&buf, "\n", " ") + return buf.String() +} +func (cs Statement) Print(w io.Writer, prefix, indent string) { + fmt.Fprintf(w, "%s(%s=%s", prefix, cs.Name, cs.Value) + if cs.Value == "" { + for _, s := range cs.Statements { + s.Print(w, prefix+indent, indent) + } + } + io.WriteString(w, ")") +} + +func ParseConnDescription(s string) (Statement, error) { + var cs Statement + _, err := cs.Parse(s) + return cs, err +} +func (cs *Statement) Parse(s string) (string, error) { + ltrim := func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) } + s = ltrim(s) + if s == "" || s[0] != '(' { + return s, nil + } + i := strings.IndexByte(s[1:], '=') + 1 + if i <= 0 || strings.Contains(s[1:i], ")") { + return s, errors.Errorf("no = after ( in %q", s) + } + cs.Name = s[1:i] + s = ltrim(s[i+1:]) + + if s == "" { + return s, nil + } + if s[0] != '(' { + if i = strings.IndexByte(s, ')'); i < 0 || strings.Contains(s[1:i], "(") { + return s, errors.Errorf("no ) after = in %q", s) + } + cs.Value = s[:i] + s = ltrim(s[i+1:]) + return s, nil + } + + for s != "" && s[0] == '(' { + var sub Statement + var err error + if s, err = sub.Parse(s); err != nil { + return s, err + } + if sub.Name == "" { + break + } + cs.Statements = append(cs.Statements, sub) + } + s = ltrim(s) + if s != "" && s[0] == ')' { + s = ltrim(s[1:]) + } + return s, nil +} + +type DescriptionList struct { + Options ListOptions + Descriptions []Description + TypeOfService string +} + +func (cd DescriptionList) Print(w io.Writer, prefix, indent string) { + io.WriteString(w, prefix+"(DESCRIPTION_LIST=") + cd.Options.Print(w, prefix, indent) + for _, d := range cd.Descriptions { + d.Print(w, prefix, indent) + } + if cd.TypeOfService != "" { + fmt.Fprintf(w, "%s(TYPE_OF_SERVICE=%s)", prefix, cd.TypeOfService) + } + io.WriteString(w, ")") +} +func (cd *DescriptionList) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "DESCRIPTION_LIST" { + ss = ss[0].Statements + } + cd.TypeOfService = "" + if err := cd.Options.Parse(ss); err != nil { + return err + } + cd.Descriptions = cd.Descriptions[:0] + for _, s := range ss { + switch s.Name { + case "DESCRIPTION": + var d Description + if err := d.Parse(s.Statements); err != nil { + return err + } + cd.Descriptions = append(cd.Descriptions, d) + case "TYPE_OF_SERVICE": + cd.TypeOfService = s.Value + } + } + return cd.Options.Parse(ss) +} + +type Description struct { + TCPKeepAlive bool + SDU int + Bufs BufSizes + Options ListOptions + Addresses []Address + AddressList AddressList + ConnectData ConnectData + TypeOfService string + Security Security +} + +func (d Description) Print(w io.Writer, prefix, indent string) { + if d.IsZero() { + return + } + io.WriteString(w, prefix+"(DESCRIPTION=") + if d.TCPKeepAlive { + io.WriteString(w, prefix+"(ENABLE=broken)") + } + if d.SDU != 0 { + fmt.Fprintf(w, prefix+"(SDU=%d)", d.SDU) + } + d.Bufs.Print(w, prefix, indent) + d.Options.Print(w, prefix, indent) + for _, a := range d.Addresses { + a.Print(w, prefix, indent) + } + d.AddressList.Print(w, prefix, indent) + d.ConnectData.Print(w, prefix, indent) + if d.TypeOfService != "" { + fmt.Fprintf(w, "%s(TYPE_OF_SERVICE=%s)", prefix, d.TypeOfService) + } + d.Security.Print(w, prefix, indent) + io.WriteString(w, ")") +} +func (d Description) IsZero() bool { + return !d.TCPKeepAlive && d.SDU == 0 && d.Bufs.IsZero() && d.Options.IsZero() && len(d.Addresses) == 0 && d.AddressList.IsZero() && d.ConnectData.IsZero() && d.TypeOfService == "" && d.Security.IsZero() +} +func (d *Description) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "DESCRIPTION" { + ss = ss[0].Statements + } + d.TCPKeepAlive, d.SDU = false, 0 + for _, s := range ss { + switch s.Name { + case "ADDRESS": + var a Address + if err := a.Parse(s.Statements); err != nil { + return err + } + if !a.IsZero() { + d.Addresses = append(d.Addresses, a) + } + case "ADDRESS_LIST": + if err := d.AddressList.Parse(s.Statements); err != nil { + return err + } + case "CONNECT_DATA": + if err := d.ConnectData.Parse(s.Statements); err != nil { + return err + } + case "ENABLE": + d.TCPKeepAlive = d.TCPKeepAlive || s.Value == "broken" + case "SDU": + var err error + if d.SDU, err = strconv.Atoi(s.Value); err != nil { + return err + } + case "SECURITY": + if err := d.Security.Parse(s.Statements); err != nil { + return err + } + } + } + if err := d.Bufs.Parse(ss); err != nil { + return err + } + if err := d.Options.Parse(ss); err != nil { + return err + } + return nil +} + +type Address struct { + Protocol, Host string + Port int + BufSizes +} + +func (a Address) Print(w io.Writer, prefix, indent string) { + if a.IsZero() { + return + } + io.WriteString(w, prefix+"(ADDRESS=") + if a.Protocol != "" { + fmt.Fprintf(w, "%s(PROTOCOL=%s)", prefix, a.Protocol) + } + if a.Host != "" { + fmt.Fprintf(w, "%s(HOST=%s)", prefix, a.Host) + } + if a.Port != 0 { + fmt.Fprintf(w, "%s(PORT=%d)", prefix, a.Port) + } + a.BufSizes.Print(w, prefix, indent) + io.WriteString(w, ")") +} +func (a Address) IsZero() bool { + return a.Protocol == "" && a.Host == "" && a.Port == 0 && a.BufSizes.IsZero() +} +func (a *Address) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "ADDRESS" { + ss = ss[0].Statements + } + for _, s := range ss { + switch s.Name { + case "PROTOCOL": + a.Protocol = s.Value + case "HOST": + a.Host = s.Value + case "PORT": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + a.Port = i + } + } + return a.BufSizes.Parse(ss) +} + +type BufSizes struct { + RecvBufSize, SendBufSize int +} + +func (bs BufSizes) Print(w io.Writer, prefix, indent string) { + if bs.RecvBufSize > 0 { + fmt.Fprintf(w, "%s(RECV_BUF_SIZE=%d)", prefix, bs.RecvBufSize) + } + if bs.SendBufSize > 0 { + fmt.Fprintf(w, "%s(SEND_BUF_SIZE=%d)", prefix, bs.SendBufSize) + } +} +func (bs BufSizes) IsZero() bool { return bs.RecvBufSize > 0 && bs.SendBufSize > 0 } +func (bs *BufSizes) Parse(ss []Statement) error { + for _, s := range ss { + switch s.Name { + case "RECV_BUF_SIZE", "SEND_BUF_SIZE": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + if s.Name == "RECV_BUF_SIZE" { + bs.RecvBufSize = i + } else { + bs.SendBufSize = i + } + } + } + return nil +} + +type ListOptions struct { + Failover, LoadBalance, SourceRoute bool +} + +func (lo ListOptions) Print(w io.Writer, prefix, indent string) { + if lo.Failover { + io.WriteString(w, prefix+"(FAILOVER=on)") + } + if lo.LoadBalance { + io.WriteString(w, prefix+"(LOAD_BALANE=on)") + } + if lo.SourceRoute { + io.WriteString(w, prefix+"(SOURE_ROUTE=on)") + } +} +func (lo ListOptions) IsZero() bool { return !lo.Failover && !lo.LoadBalance && !lo.SourceRoute } +func s2b(s string) bool { return s == "on" || s == "yes" || s == "true" } +func (lo *ListOptions) Parse(ss []Statement) error { + *lo = ListOptions{} + for _, s := range ss { + switch s.Name { + case "FAILOVER": + lo.Failover = s2b(s.Value) + case "LOAD_BALANE": + lo.LoadBalance = s2b(s.Value) + case "SourceRoute": + lo.SourceRoute = s2b(s.Value) + } + } + return nil +} + +type AddressList struct { + Options ListOptions + Addresses []Address +} + +func (al AddressList) Print(w io.Writer, prefix, indent string) { + if al.IsZero() { + return + } + io.WriteString(w, prefix+"(ADDRESS_LIST=") + al.Options.Print(w, prefix, indent) + for _, a := range al.Addresses { + a.Print(w, prefix, indent) + } + io.WriteString(w, ")") +} +func (al AddressList) IsZero() bool { return al.Options.IsZero() && len(al.Addresses) == 0 } +func (al *AddressList) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "ADDRESS_LIST" { + ss = ss[0].Statements + } + if err := al.Options.Parse(ss); err != nil { + return err + } + al.Addresses = al.Addresses[:0] + for _, s := range ss { + switch s.Name { + case "ADDRESS": + var a Address + if err := a.Parse(s.Statements); err != nil { + return err + } + if !a.IsZero() { + al.Addresses = append(al.Addresses, a) + } + } + } + return nil +} + +type ConnectData struct { + FailoverMode FailoverMode + ServiceName, SID string + GlobalName, InstanceName, RDBDatabase string + Hs bool + Server ServiceHandler +} + +func (cd ConnectData) Print(w io.Writer, prefix, indent string) { + if cd.IsZero() { + return + } + io.WriteString(w, prefix+"(CONNECT_DATA=") + cd.FailoverMode.Print(w, prefix, indent) + if cd.GlobalName != "" { + fmt.Fprintf(w, "%s(GLOBAL_NAME=%s)", prefix, cd.GlobalName) + } + if cd.InstanceName != "" { + fmt.Fprintf(w, "%s(INSTANCE_NAME=%s)", prefix, cd.InstanceName) + } + if cd.RDBDatabase != "" { + fmt.Fprintf(w, "%s(RDB_DATABASE=%s)", prefix, cd.RDBDatabase) + } + if cd.ServiceName != "" { + fmt.Fprintf(w, "%s(SERVICE_NAME=%s)", prefix, cd.ServiceName) + } + if cd.SID != "" { + fmt.Fprintf(w, "%s(SID=%s)", prefix, cd.SID) + } + if cd.Hs { + io.WriteString(w, prefix+"(HS=ok)") + } + if cd.Server != "" { + fmt.Fprintf(w, "%s(SERVER=%s)", prefix, cd.Server) + } + io.WriteString(w, ")") +} +func (cd ConnectData) IsZero() bool { + return cd.FailoverMode.IsZero() && cd.GlobalName == "" && cd.InstanceName == "" && cd.RDBDatabase == "" && cd.ServiceName == "" && cd.SID == "" && !cd.Hs && cd.Server == "" +} +func (cd *ConnectData) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "CONNECT_DATA" { + ss = ss[0].Statements + } + cd.Hs = false + for _, s := range ss { + switch s.Name { + case "FAILOVER_MODE": + if err := cd.FailoverMode.Parse(s.Statements); err != nil { + return err + } + case "GLOBAL_NAME": + cd.GlobalName = s.Value + case "INSTANCE_NAME": + cd.InstanceName = s.Value + case "RDB_DATABASE": + cd.RDBDatabase = s.Value + case "SERVICE_NAME": + cd.ServiceName = s.Value + case "SID": + cd.SID = s.Value + case "HS": + cd.Hs = s.Value == "ok" + case "SERVER": + cd.Server = ServiceHandler(s.Value) + } + } + return nil +} + +type FailoverMode struct { + Backup, Type, Method string + Retry, Delay int +} + +func (fo FailoverMode) Print(w io.Writer, prefix, indent string) { + if fo.IsZero() { + return + } + io.WriteString(w, prefix+"(FAILOVER_MODE=") + if fo.Backup != "" { + fmt.Fprintf(w, "%s(BACKUP=%s)", prefix, fo.Backup) + } + if fo.Type != "" { + fmt.Fprintf(w, "%s(TYPE=%s)", prefix, fo.Type) + } + if fo.Method != "" { + fmt.Fprintf(w, "%s(METHOD=%s)", prefix, fo.Method) + } + if fo.Retry != 0 { + fmt.Fprintf(w, "%s(RETRY=%d)", prefix, fo.Retry) + } + if fo.Delay != 0 { + fmt.Fprintf(w, "%s(DELAY=%d)", prefix, fo.Delay) + } + io.WriteString(w, ")") +} +func (fo FailoverMode) IsZero() bool { + return fo.Backup == "" && fo.Type == "" && fo.Method == "" && fo.Retry == 0 && fo.Delay == 0 +} +func (fo *FailoverMode) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "FAILOVER_MODE" { + ss = ss[0].Statements + } + for _, s := range ss { + switch s.Name { + case "BACKUP": + fo.Backup = s.Value + case "TYPE": + fo.Type = s.Value + case "METHOD": + fo.Method = s.Value + case "RETRY", "DELAY": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + if s.Name == "RETRY" { + fo.Retry = i + } else { + fo.Delay = i + } + } + } + return nil +} + +type ServiceHandler string + +const ( + Dedicated = ServiceHandler("dedicated") + Shared = ServiceHandler("shared") + Pooled = ServiceHandler("pooled") +) + +type Security struct { + SSLServerCertDN string +} + +func (sec Security) Print(w io.Writer, prefix, indent string) { + if sec.SSLServerCertDN != "" { + fmt.Fprintf(w, "%s(SECURITY=(SSL_SERVER_CERT_DN=%s))", prefix, sec.SSLServerCertDN) + } +} +func (sec Security) IsZero() bool { return sec.SSLServerCertDN == "" } +func (sec *Security) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "SECURITY" { + ss = ss[0].Statements + } + sec.SSLServerCertDN = "" + for _, s := range ss { + if s.Name == "SSL_SERVER_CERT_DN" { + sec.SSLServerCertDN = s.Value + } + } + return nil +} diff --git a/vendor/gopkg.in/goracle.v2/stmt.go b/vendor/github.com/godror/godror/stmt.go similarity index 88% rename from vendor/gopkg.in/goracle.v2/stmt.go rename to vendor/github.com/godror/godror/stmt.go index 6e8e6215365..0e0775b363d 100644 --- a/vendor/gopkg.in/goracle.v2/stmt.go +++ b/vendor/github.com/godror/godror/stmt.go @@ -1,25 +1,24 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include #include "dpiImpl.h" const int sizeof_dpiData = sizeof(void); + +void godror_setFromString(dpiVar *dv, uint32_t pos, const _GoString_ value) { + uint32_t length; + length = _GoStringLen(value); + if( length == 0 ) { + return; + } + dpiVar_setFromBytes(dv, pos, _GoStringPtr(value), length); +} */ import "C" import ( @@ -30,11 +29,12 @@ import ( "io" "reflect" "strconv" + "strings" "sync" "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) type stmtOptions struct { @@ -45,6 +45,7 @@ type stmtOptions struct { plSQLArrays bool lobAsReader bool magicTypeConversion bool + numberAsString bool } func (o stmtOptions) ExecMode() C.dpiExecMode { @@ -55,8 +56,10 @@ func (o stmtOptions) ExecMode() C.dpiExecMode { } func (o stmtOptions) ArraySize() int { - if o.arraySize <= 0 || o.arraySize > 32<<10 { + if o.arraySize <= 0 { return DefaultArraySize + } else if o.arraySize > 1<<16 { + return 1 << 16 } return o.arraySize } @@ -72,6 +75,7 @@ func (o stmtOptions) ClobAsString() bool { return !o.lobAsReader } func (o stmtOptions) LobAsReader() bool { return o.lobAsReader } func (o stmtOptions) MagicTypeConversion() bool { return o.magicTypeConversion } +func (o stmtOptions) NumberAsString() bool { return o.numberAsString } // Option holds statement options. type Option func(*stmtOptions) @@ -135,6 +139,11 @@ func MagicTypeConversion() Option { return func(o *stmtOptions) { o.magicTypeConversion = true } } +// NumberAsString returns an option to return numbers as string, not Number. +func NumberAsString() Option { + return func(o *stmtOptions) { o.numberAsString = true } +} + // CallTimeout sets the round-trip timeout (OCI_ATTR_CALL_TIMEOUT). // // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/handle-and-descriptor-attributes.html#GUID-D8EE68EB-7E38-4068-B06E-DF5686379E5E @@ -178,36 +187,16 @@ func (st *statement) Close() error { st.Lock() defer st.Unlock() - return st.close() -} -func (st *statement) close() error { - if st == nil { - return nil - } - dpiStmt := st.dpiStmt - c := st.conn - st.cleanup() - - var si C.dpiStmtInfo - if dpiStmt != nil && - C.dpiStmt_getInfo(dpiStmt, &si) != C.DPI_FAILURE && // this is just to check the validity of dpiStmt, to avoid SIGSEGV - C.dpiStmt_release(dpiStmt) != C.DPI_FAILURE { - return nil - } - if c == nil { - return driver.ErrBadConn - } - return errors.Wrap(c.getError(), "statement/dpiStmt_release") + return st.close(false) } - -func (st *statement) cleanup() error { +func (st *statement) close(keepDpiStmt bool) error { if st == nil { return nil } - for _, v := range st.vars { - C.dpiVar_release(v) - } + c, dpiStmt, vars := st.conn, st.dpiStmt, st.vars + st.isSlice = nil + st.query = "" st.data = nil st.vars = nil st.varInfos = nil @@ -215,13 +204,29 @@ func (st *statement) cleanup() error { st.dests = nil st.columns = nil st.dpiStmt = nil - c := st.conn st.conn = nil + for _, v := range vars[:cap(vars)] { + if v != nil { + C.dpiVar_release(v) + } + } + + if !keepDpiStmt { + var si C.dpiStmtInfo + if dpiStmt != nil && + C.dpiStmt_getInfo(dpiStmt, &si) != C.DPI_FAILURE && // this is just to check the validity of dpiStmt, to avoid SIGSEGV + C.dpiStmt_release(dpiStmt) != C.DPI_FAILURE { + return nil + } + } if c == nil { return driver.ErrBadConn } - return errors.Wrap(c.getError(), "statement/dpiStmt_release") + if err := c.getError(); err != nil { + return errors.Errorf("statement/dpiStmt_release: %w", err) + } + return nil } // Exec executes a query that doesn't return rows, such @@ -253,6 +258,8 @@ func (st *statement) Query(args []driver.Value) (driver.Rows, error) { // ExecContext executes a query that doesn't return rows, such as an INSERT or UPDATE. // // ExecContext must honor the context timeout and return when it is canceled. +// +// Cancelation/timeout is honored, execution is broken, but you may have to disable out-of-bound execution - see https://github.com/oracle/odpi/issues/116 for details. func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) (res driver.Result, err error) { if err = ctx.Err(); err != nil { return nil, err @@ -262,9 +269,10 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) closeIfBadConn := func(err error) error { if err != nil && err == driver.ErrBadConn { if Log != nil { - Log("error", driver.ErrBadConn) + Log("error", err) } - st.close() + st.close(false) + st.conn.close(true) } return err } @@ -328,15 +336,13 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if err == nil { var info C.dpiStmtInfo if C.dpiStmt_getInfo(st.dpiStmt, &info) == C.DPI_FAILURE { - err = errors.Wrap(st.getError(), "getInfo") + err = errors.Errorf("getInfo: %w", st.getError()) } st.isReturning = info.isReturning != 0 return } - cdr, ok := errors.Cause(err).(interface { - Code() int - }) - if !ok { + var cdr interface{ Code() int } + if !errors.As(err, &cdr) { break } switch code := cdr.Code(); code { @@ -349,7 +355,11 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) } break } - done <- maybeBadConn(errors.Wrapf(err, "dpiStmt_execute(mode=%d arrLen=%d)", mode, st.arrLen)) + if err == nil { + done <- nil + return + } + done <- maybeBadConn(errors.Errorf("dpiStmt_execute(mode=%d arrLen=%d): %w", mode, st.arrLen, err), nil) }() select { @@ -369,8 +379,11 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK statement") } _ = st.Break() - st.cleanup() - return nil, driver.ErrBadConn + st.close(false) + if err := st.conn.Close(); err != nil { + return nil, err + } + return nil, ctx.Err() } } @@ -386,7 +399,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) data := &st.data[i][0] if C.dpiVar_getReturnedData(st.vars[i], 0, &n, &data) == C.DPI_FAILURE { err = st.getError() - return nil, errors.Wrapf(closeIfBadConn(err), "%d.getReturnedData", i) + return nil, errors.Errorf("%d.getReturnedData: %w", i, closeIfBadConn(err)) } if n == 0 { st.data[i] = st.data[i][:0] @@ -400,7 +413,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if Log != nil { Log("get", i, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d. get[%d]", i, 0) + return nil, errors.Errorf("%d. get[%d]: %w", i, 0, closeIfBadConn(err)) } continue } @@ -410,14 +423,14 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if Log != nil { Log("msg", "getNumElementsInArray", "i", i, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d.getNumElementsInArray", i) + return nil, errors.Errorf("%d.getNumElementsInArray: %w", i, closeIfBadConn(err)) } //fmt.Printf("i=%d dest=%T %#v\n", i, dest, dest) if err = get(dest, st.data[i][:n]); err != nil { if Log != nil { Log("msg", "get", "i", i, "n", n, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d. get", i) + return nil, errors.Errorf("%d. get: %w", i, closeIfBadConn(err)) } } var count C.uint64_t @@ -430,6 +443,8 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) // QueryContext executes a query that may return rows, such as a SELECT. // // QueryContext must honor the context timeout and return when it is canceled. +// +// Cancelation/timeout is honored, execution is broken, but you may have to disable out-of-bound execution - see https://github.com/oracle/odpi/issues/116 for details. func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { if err := ctx.Err(); err != nil { return nil, err @@ -438,7 +453,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) closeIfBadConn := func(err error) error { if err != nil && err == driver.ErrBadConn { - st.close() + if Log != nil { + Log("error", err) + } + st.close(false) + st.conn.close(true) } return err } @@ -469,6 +488,12 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) return nil, closeIfBadConn(err) } + mode := st.ExecMode() + //fmt.Printf("%p.%p: inTran? %t\n%s\n", st.conn, st, st.inTransaction, st.query) + if !st.inTransaction { + mode |= C.DPI_MODE_EXEC_COMMIT_ON_SUCCESS + } + // execute var colCount C.uint32_t done := make(chan error, 1) @@ -481,7 +506,7 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) return } st.setCallTimeout(ctx) - if C.dpiStmt_execute(st.dpiStmt, st.ExecMode(), &colCount) != C.DPI_FAILURE { + if C.dpiStmt_execute(st.dpiStmt, mode, &colCount) != C.DPI_FAILURE { break } if err = ctx.Err(); err == nil { @@ -491,7 +516,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) } } } - done <- maybeBadConn(errors.Wrap(err, "dpiStmt_execute")) + if err == nil { + done <- nil + return + } + done <- maybeBadConn(errors.Errorf("dpiStmt_execute: %w", err), nil) }() select { @@ -510,8 +539,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK query") } _ = st.Break() - st.cleanup() - return nil, driver.ErrBadConn + st.close(false) + if err := st.conn.Close(); err != nil { + return nil, err + } + return nil, ctx.Err() } } rows, err := st.openRows(int(colCount)) @@ -539,10 +571,6 @@ func (st *statement) NumInput() int { return 0 } - if !go10 { - return -1 - } - st.Lock() defer st.Unlock() var cnt C.uint32_t @@ -587,12 +615,10 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { if Log != nil { Log("enter", "bindVars", "args", args) } - if cap(st.vars) < len(args) || cap(st.varInfos) < len(args) { - for i, v := range st.vars { - if v != nil { - C.dpiVar_release(v) - st.vars[i], st.varInfos[i] = nil, varInfo{} - } + for i, v := range st.vars[:cap(st.vars)] { + if v != nil { + C.dpiVar_release(v) + st.vars[i], st.varInfos[i] = nil, varInfo{} } } var named bool @@ -713,7 +739,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { var err error if value, err = st.bindVarTypeSwitch(info, &(st.gets[i]), value); err != nil { - return errors.Wrapf(err, "%d. arg", i+1) + return errors.Errorf("%d. arg: %w", i+1, err) } var rv reflect.Value @@ -742,12 +768,8 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { return errors.Errorf("maximum array size allowed is %d", maxArraySize) } if st.vars[i] == nil || st.data[i] == nil || st.varInfos[i] != vi { - if st.vars[i] != nil { - C.dpiVar_release(st.vars[i]) - st.vars[i] = nil - } if st.vars[i], st.data[i], err = st.newVar(vi); err != nil { - return errors.WithMessage(err, fmt.Sprintf("%d", i)) + return errors.Errorf("%d: %w", i, err) } st.varInfos[i] = vi } @@ -760,7 +782,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("C", "dpiVar_setNumElementsInArray", "i", i, "n", 0) } if C.dpiVar_setNumElementsInArray(dv, C.uint32_t(0)) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "setNumElementsInArray[%d](%d)", i, 0) + return errors.Errorf("setNumElementsInArray[%d](%d): %w", i, 0, st.getError()) } } continue @@ -771,7 +793,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("msg", "set", "i", i, "value", fmt.Sprintf("%T=%#v", value, value)) } if err := info.set(dv, data[:1], value); err != nil { - return errors.Wrapf(err, "set(data[%d][%d], %#v (%T))", i, 0, value, value) + return errors.Errorf("set(data[%d][%d], %#v (%T)): %w", i, 0, value, value, err) } continue } @@ -783,7 +805,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("C", "dpiVar_setNumElementsInArray", "i", i, "n", n) } if C.dpiVar_setNumElementsInArray(dv, C.uint32_t(n)) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "%+v.setNumElementsInArray[%d](%d)", dv, i, n) + return errors.Errorf("%+v.setNumElementsInArray[%d](%d): %w", dv, i, n, st.getError()) } } //fmt.Println("n:", len(st.data[i])) @@ -796,7 +818,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { for i, v := range st.vars { //if Log != nil {Log("C", "dpiStmt_bindByPos", "dpiStmt", st.dpiStmt, "i", i, "v", v) } if C.dpiStmt_bindByPos(st.dpiStmt, C.uint32_t(i+1), v) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "bindByPos[%d]", i) + return errors.Errorf("bindByPos[%d]: %w", i, st.getError()) } } return nil @@ -811,7 +833,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { res := C.dpiStmt_bindByName(st.dpiStmt, cName, C.uint32_t(len(name)), st.vars[i]) C.free(unsafe.Pointer(cName)) if res == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "bindByName[%q]", name) + return errors.Errorf("bindByName[%q]: %w", name, st.getError()) } } return nil @@ -835,7 +857,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int if isValuer { var err error if value, err = vlr.Value(); err != nil { - return value, errors.Wrap(err, "arg.Value()") + return value, errors.Errorf("arg.Value(): %w", err) } return st.bindVarTypeSwitch(info, get, value) } @@ -1017,7 +1039,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } info.set = dataSetBytes if info.isOut { - info.bufSize = 4000 + info.bufSize = 32767 *get = dataGetBytes } @@ -1073,8 +1095,10 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } case *Object: - info.objType = v.ObjectType.dpiObjectType - info.typ, info.natTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + if !nilPtr && v != nil { + info.objType = v.ObjectType.dpiObjectType + info.typ, info.natTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + } info.set = st.dataSetObject if info.isOut { *get = st.dataGetObject @@ -1094,7 +1118,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } var err error if value, err = vlr.Value(); err != nil { - return value, errors.Wrap(err, "arg.Value()") + return value, errors.Errorf("arg.Value(): %w", err) } return st.bindVarTypeSwitch(info, get, value) } @@ -1139,6 +1163,13 @@ func dataSetBool(dv *C.dpiVar, data []C.dpiData, vv interface{}) error { return dataSetNull(dv, data, nil) } b := C.int(0) + if v, ok := vv.(bool); ok { + if v { + b = 1 + } + C.dpiData_setBool(&data[0], b) + return nil + } if bb, ok := vv.([]bool); ok { for i, v := range bb { if v { @@ -1146,10 +1177,10 @@ func dataSetBool(dv *C.dpiVar, data []C.dpiData, vv interface{}) error { } C.dpiData_setBool(&data[i], b) } - } else { - for i := range data { - data[i].isNull = 1 - } + return nil + } + for i := range data { + data[i].isNull = 1 } return nil } @@ -1507,18 +1538,27 @@ func dataGetBytes(v interface{}, data []C.dpiData) error { *x = nil return nil } - b := C.dpiData_getBytes(&data[0]) + db := C.dpiData_getBytes(&data[0]) + b := ((*[32767]byte)(unsafe.Pointer(db.ptr)))[:db.length:db.length] + // b must be copied + *x = append((*x)[:0], b...) - *x = ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length] case *[][]byte: + maX := (*x)[:cap(*x)] *x = (*x)[:0] for i := range data { if data[i].isNull == 1 { *x = append(*x, nil) continue } - b := C.dpiData_getBytes(&data[i]) - *x = append(*x, ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length]) + db := C.dpiData_getBytes(&data[i]) + b := ((*[32767]byte)(unsafe.Pointer(db.ptr)))[:db.length:db.length] + // b must be copied + if i < len(maX) { + *x = append(*x, append(maX[i][:0], b...)) + } else { + *x = append(*x, append(make([]byte, 0, len(b)), b...)) + } } case *Number: @@ -1702,7 +1742,7 @@ func (c *conn) dataGetStmtC(row *driver.Rows, data *C.dpiData) error { var n C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &n) == C.DPI_FAILURE { *row = &rows{ - err: errors.Wrapf(io.EOF, "getNumQueryColumns: %v", c.getError()), + err: errors.Errorf("getNumQueryColumns: %w: %w", c.getError(), io.EOF), } return nil } @@ -1777,7 +1817,7 @@ func (c *conn) dataSetLOB(dv *C.dpiVar, data []C.dpiData, vv interface{}) error } var lob *C.dpiLob if C.dpiConn_newTempLob(c.dpiConn, typ, &lob) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "newTempLob(typ=%d)", typ) + return errors.Errorf("newTempLob(typ=%d): %w", typ, c.getError()) } var chunkSize C.uint32_t _ = C.dpiLob_getChunkSize(lob, &chunkSize) @@ -1832,8 +1872,15 @@ func (c *conn) dataSetObject(dv *C.dpiVar, data []C.dpiData, vv interface{}) err switch o := vv.(type) { case Object: objs[0] = o + case *Object: + objs[0] = *o case []Object: objs = o + case []*Object: + objs = make([]Object, len(o)) + for i, x := range o { + objs[i] = *x + } case ObjectWriter: err := o.WriteObject() if err != nil { @@ -1858,10 +1905,12 @@ func (c *conn) dataSetObject(dv *C.dpiVar, data []C.dpiData, vv interface{}) err for i, obj := range objs { if obj.dpiObject == nil { data[i].isNull = 1 - return nil + continue } data[i].isNull = 0 - C.dpiVar_setFromObject(dv, C.uint32_t(i), obj.dpiObject) + if C.dpiVar_setFromObject(dv, C.uint32_t(i), obj.dpiObject) == C.DPI_FAILURE { + return errors.Errorf("setFromObject: %w", c.getError()) + } } return nil } @@ -1949,7 +1998,7 @@ func (st *statement) openRows(colCount int) (*rows, error) { var ti C.dpiDataTypeInfo for i := 0; i < colCount; i++ { if C.dpiStmt_getQueryInfo(st.dpiStmt, C.uint32_t(i+1), &info) == C.DPI_FAILURE { - return nil, errors.Wrapf(st.getError(), "getQueryInfo[%d]", i) + return nil, errors.Errorf("getQueryInfo[%d]: %w", i, st.getError()) } ti = info.typeInfo bufSize := int(ti.clientSizeInBytes) @@ -2002,11 +2051,11 @@ func (st *statement) openRows(colCount int) (*rows, error) { } if C.dpiStmt_define(st.dpiStmt, C.uint32_t(i+1), r.vars[i]) == C.DPI_FAILURE { - return nil, errors.Wrapf(st.getError(), "define[%d]", i) + return nil, errors.Errorf("define[%d]: %w", i, st.getError()) } } if C.dpiStmt_addRef(st.dpiStmt) == C.DPI_FAILURE { - return &r, errors.Wrap(st.getError(), "dpiStmt_addRef") + return &r, errors.Errorf("dpiStmt_addRef: %w", st.getError()) } st.columns = r.columns return &r, nil @@ -2023,3 +2072,41 @@ type Column struct { Scale C.int8_t Nullable bool } + +func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { + C.godror_setFromString(dv, pos, x) +} + +var stringBuilders = stringBuilderPool{ + p: &sync.Pool{New: func() interface{} { return &strings.Builder{} }}, +} + +type stringBuilderPool struct { + p *sync.Pool +} + +func (sb stringBuilderPool) Get() *strings.Builder { + return sb.p.Get().(*strings.Builder) +} +func (sb *stringBuilderPool) Put(b *strings.Builder) { + b.Reset() + sb.p.Put(b) +} + +/* +// ResetSession is called while a connection is in the connection +// pool. No queries will run on this connection until this method returns. +// +// If the connection is bad this should return driver.ErrBadConn to prevent +// the connection from being returned to the connection pool. Any other +// error will be discarded. +func (c *conn) ResetSession(ctx context.Context) error { + if Log != nil { + Log("msg", "ResetSession", "conn", c.dpiConn) + } + //subCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + //err := c.Ping(subCtx) + //cancel() + return c.Ping(ctx) +} +*/ diff --git a/vendor/gopkg.in/goracle.v2/subscr.c b/vendor/github.com/godror/godror/subscr.c similarity index 100% rename from vendor/gopkg.in/goracle.v2/subscr.c rename to vendor/github.com/godror/godror/subscr.c diff --git a/vendor/gopkg.in/goracle.v2/subscr.go b/vendor/github.com/godror/godror/subscr.go similarity index 86% rename from vendor/gopkg.in/goracle.v2/subscr.go rename to vendor/github.com/godror/godror/subscr.go index 6286ec10c84..07355e591c7 100644 --- a/vendor/gopkg.in/goracle.v2/subscr.go +++ b/vendor/github.com/godror/godror/subscr.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed 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. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -30,7 +20,7 @@ import ( "strings" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // CallbackSubscr is the callback for C code on subscription event. @@ -171,9 +161,9 @@ func (c *conn) NewSubscription(name string, cb func(Event)) (*Subscription, erro ) == C.DPI_FAILURE { C.free(unsafe.Pointer(params)) C.free(unsafe.Pointer(dpiSubscr)) - err := errors.Wrap(c.getError(), "newSubscription") - if strings.Contains(errors.Cause(err).Error(), "DPI-1065:") { - err = errors.WithMessage(err, "specify \"enableEvents=1\" connection parameter on connection to be able to use subscriptions") + err := errors.Errorf("newSubscription: %w", c.getError()) + if strings.Contains(errors.Unwrap(err).Error(), "DPI-1065:") { + err = errors.Errorf("specify \"enableEvents=1\" connection parameter on connection to be able to use subscriptions: %w", err) } return nil, err } @@ -190,18 +180,18 @@ func (s *Subscription) Register(qry string, params ...interface{}) error { var dpiStmt *C.dpiStmt if C.dpiSubscr_prepareStmt(s.dpiSubscr, cQry, C.uint32_t(len(qry)), &dpiStmt) == C.DPI_FAILURE { - return errors.Wrapf(s.getError(), "prepareStmt[%p]", s.dpiSubscr) + return errors.Errorf("prepareStmt[%p]: %w", s.dpiSubscr, s.getError()) } defer func() { C.dpiStmt_release(dpiStmt) }() mode := C.dpiExecMode(C.DPI_MODE_EXEC_DEFAULT) var qCols C.uint32_t if C.dpiStmt_execute(dpiStmt, mode, &qCols) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "executeStmt") + return errors.Errorf("executeStmt: %w", s.getError()) } var queryID C.uint64_t if C.dpiStmt_getSubscrQueryId(dpiStmt, &queryID) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "getSubscrQueryId") + return errors.Errorf("getSubscrQueryId: %w", s.getError()) } if Log != nil { Log("msg", "subscribed", "query", qry, "id", queryID) @@ -223,7 +213,7 @@ func (s *Subscription) Close() error { return nil } if C.dpiConn_unsubscribe(conn.dpiConn, dpiSubscr) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "close") + return errors.Errorf("close: %w", s.getError()) } return nil } @@ -236,10 +226,10 @@ const ( EvtStartup = EventType(C.DPI_EVENT_STARTUP) EvtShutdown = EventType(C.DPI_EVENT_SHUTDOWN) EvtShutdownAny = EventType(C.DPI_EVENT_SHUTDOWN_ANY) - EvtDropDB = EventType(C.DPI_EVENT_DROP_DB) EvtDereg = EventType(C.DPI_EVENT_DEREG) EvtObjChange = EventType(C.DPI_EVENT_OBJCHANGE) EvtQueryChange = EventType(C.DPI_EVENT_QUERYCHANGE) + EvtAQ = EventType(C.DPI_EVENT_AQ) ) // Operation in the DB. diff --git a/vendor/gopkg.in/goracle.v2/version.go b/vendor/github.com/godror/godror/version.go similarity index 57% rename from vendor/gopkg.in/goracle.v2/version.go rename to vendor/github.com/godror/godror/version.go index 111b3462741..5dace8e1b09 100644 --- a/vendor/gopkg.in/goracle.v2/version.go +++ b/vendor/github.com/godror/godror/version.go @@ -1,6 +1,10 @@ -package goracle +// Copyright 2019 Tamás Gulácsi. +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -//go:generate bash -c "echo 3.1.4>odpi-version; set -x; curl -L https://github.com/oracle/odpi/archive/v$(cat odpi-version).tar.gz | tar xzvf - odpi-$(cat odpi-version)/{embed,include,src,CONTRIBUTING.md,LICENSE.md,README.md} && rm -rf odpi && mv odpi-$(cat odpi-version) odpi; rm -f odpi-version" +package godror + +//go:generate bash -c "echo 3.3.0>odpi-version; set -x; curl -L https://github.com/oracle/odpi/archive/v$(cat odpi-version).tar.gz | tar xzvf - odpi-$(cat odpi-version)/{embed,include,src,CONTRIBUTING.md,LICENSE.md,README.md} && rm -rf odpi && mv odpi-$(cat odpi-version) odpi; rm -f odpi-version" // Version of this driver -const Version = "v2.15.3" +const Version = "v0.0.1" diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/xerrors/LICENSE new file mode 100644 index 00000000000..e4a47e17f14 --- /dev/null +++ b/vendor/golang.org/x/xerrors/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/xerrors/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/vendor/golang.org/x/xerrors/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/xerrors/README b/vendor/golang.org/x/xerrors/README new file mode 100644 index 00000000000..aac7867a560 --- /dev/null +++ b/vendor/golang.org/x/xerrors/README @@ -0,0 +1,2 @@ +This repository holds the transition packages for the new Go 1.13 error values. +See golang.org/design/29934-error-values. diff --git a/vendor/golang.org/x/xerrors/adaptor.go b/vendor/golang.org/x/xerrors/adaptor.go new file mode 100644 index 00000000000..4317f248331 --- /dev/null +++ b/vendor/golang.org/x/xerrors/adaptor.go @@ -0,0 +1,193 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strconv" +) + +// FormatError calls the FormatError method of f with an errors.Printer +// configured according to s and verb, and writes the result to s. +func FormatError(f Formatter, s fmt.State, verb rune) { + // Assuming this function is only called from the Format method, and given + // that FormatError takes precedence over Format, it cannot be called from + // any package that supports errors.Formatter. It is therefore safe to + // disregard that State may be a specific printer implementation and use one + // of our choice instead. + + // limitations: does not support printing error as Go struct. + + var ( + sep = " " // separator before next error + p = &state{State: s} + direct = true + ) + + var err error = f + + switch verb { + // Note that this switch must match the preference order + // for ordinary string printing (%#v before %+v, and so on). + + case 'v': + if s.Flag('#') { + if stringer, ok := err.(fmt.GoStringer); ok { + io.WriteString(&p.buf, stringer.GoString()) + goto exit + } + // proceed as if it were %v + } else if s.Flag('+') { + p.printDetail = true + sep = "\n - " + } + case 's': + case 'q', 'x', 'X': + // Use an intermediate buffer in the rare cases that precision, + // truncation, or one of the alternative verbs (q, x, and X) are + // specified. + direct = false + + default: + p.buf.WriteString("%!") + p.buf.WriteRune(verb) + p.buf.WriteByte('(') + switch { + case err != nil: + p.buf.WriteString(reflect.TypeOf(f).String()) + default: + p.buf.WriteString("") + } + p.buf.WriteByte(')') + io.Copy(s, &p.buf) + return + } + +loop: + for { + switch v := err.(type) { + case Formatter: + err = v.FormatError((*printer)(p)) + case fmt.Formatter: + v.Format(p, 'v') + break loop + default: + io.WriteString(&p.buf, v.Error()) + break loop + } + if err == nil { + break + } + if p.needColon || !p.printDetail { + p.buf.WriteByte(':') + p.needColon = false + } + p.buf.WriteString(sep) + p.inDetail = false + p.needNewline = false + } + +exit: + width, okW := s.Width() + prec, okP := s.Precision() + + if !direct || (okW && width > 0) || okP { + // Construct format string from State s. + format := []byte{'%'} + if s.Flag('-') { + format = append(format, '-') + } + if s.Flag('+') { + format = append(format, '+') + } + if s.Flag(' ') { + format = append(format, ' ') + } + if okW { + format = strconv.AppendInt(format, int64(width), 10) + } + if okP { + format = append(format, '.') + format = strconv.AppendInt(format, int64(prec), 10) + } + format = append(format, string(verb)...) + fmt.Fprintf(s, string(format), p.buf.String()) + } else { + io.Copy(s, &p.buf) + } +} + +var detailSep = []byte("\n ") + +// state tracks error printing state. It implements fmt.State. +type state struct { + fmt.State + buf bytes.Buffer + + printDetail bool + inDetail bool + needColon bool + needNewline bool +} + +func (s *state) Write(b []byte) (n int, err error) { + if s.printDetail { + if len(b) == 0 { + return 0, nil + } + if s.inDetail && s.needColon { + s.needNewline = true + if b[0] == '\n' { + b = b[1:] + } + } + k := 0 + for i, c := range b { + if s.needNewline { + if s.inDetail && s.needColon { + s.buf.WriteByte(':') + s.needColon = false + } + s.buf.Write(detailSep) + s.needNewline = false + } + if c == '\n' { + s.buf.Write(b[k:i]) + k = i + 1 + s.needNewline = true + } + } + s.buf.Write(b[k:]) + if !s.inDetail { + s.needColon = true + } + } else if !s.inDetail { + s.buf.Write(b) + } + return len(b), nil +} + +// printer wraps a state to implement an xerrors.Printer. +type printer state + +func (s *printer) Print(args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprint((*state)(s), args...) + } +} + +func (s *printer) Printf(format string, args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprintf((*state)(s), format, args...) + } +} + +func (s *printer) Detail() bool { + s.inDetail = true + return s.printDetail +} diff --git a/vendor/golang.org/x/xerrors/codereview.cfg b/vendor/golang.org/x/xerrors/codereview.cfg new file mode 100644 index 00000000000..3f8b14b64e8 --- /dev/null +++ b/vendor/golang.org/x/xerrors/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/vendor/golang.org/x/xerrors/doc.go b/vendor/golang.org/x/xerrors/doc.go new file mode 100644 index 00000000000..eef99d9d54d --- /dev/null +++ b/vendor/golang.org/x/xerrors/doc.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xerrors implements functions to manipulate errors. +// +// This package is based on the Go 2 proposal for error values: +// https://golang.org/design/29934-error-values +// +// These functions were incorporated into the standard library's errors package +// in Go 1.13: +// - Is +// - As +// - Unwrap +// +// Also, Errorf's %w verb was incorporated into fmt.Errorf. +// +// Use this package to get equivalent behavior in all supported Go versions. +// +// No other features of this package were included in Go 1.13, and at present +// there are no plans to include any of them. +package xerrors // import "golang.org/x/xerrors" diff --git a/vendor/golang.org/x/xerrors/errors.go b/vendor/golang.org/x/xerrors/errors.go new file mode 100644 index 00000000000..e88d3772d86 --- /dev/null +++ b/vendor/golang.org/x/xerrors/errors.go @@ -0,0 +1,33 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import "fmt" + +// errorString is a trivial implementation of error. +type errorString struct { + s string + frame Frame +} + +// New returns an error that formats as the given text. +// +// The returned error contains a Frame set to the caller's location and +// implements Formatter to show this information when printed with details. +func New(text string) error { + return &errorString{text, Caller(1)} +} + +func (e *errorString) Error() string { + return e.s +} + +func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *errorString) FormatError(p Printer) (next error) { + p.Print(e.s) + e.frame.Format(p) + return nil +} diff --git a/vendor/golang.org/x/xerrors/fmt.go b/vendor/golang.org/x/xerrors/fmt.go new file mode 100644 index 00000000000..829862ddf6a --- /dev/null +++ b/vendor/golang.org/x/xerrors/fmt.go @@ -0,0 +1,187 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "fmt" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/xerrors/internal" +) + +const percentBangString = "%!" + +// Errorf formats according to a format specifier and returns the string as a +// value that satisfies error. +// +// The returned error includes the file and line number of the caller when +// formatted with additional detail enabled. If the last argument is an error +// the returned error's Format method will return it if the format string ends +// with ": %s", ": %v", or ": %w". If the last argument is an error and the +// format string ends with ": %w", the returned error implements an Unwrap +// method returning it. +// +// If the format specifier includes a %w verb with an error operand in a +// position other than at the end, the returned error will still implement an +// Unwrap method returning the operand, but the error's Format method will not +// return the wrapped error. +// +// It is invalid to include more than one %w verb or to supply it with an +// operand that does not implement the error interface. The %w verb is otherwise +// a synonym for %v. +func Errorf(format string, a ...interface{}) error { + format = formatPlusW(format) + // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. + wrap := strings.HasSuffix(format, ": %w") + idx, format2, ok := parsePercentW(format) + percentWElsewhere := !wrap && idx >= 0 + if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { + err := errorAt(a, len(a)-1) + if err == nil { + return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + } + // TODO: this is not entirely correct. The error value could be + // printed elsewhere in format if it mixes numbered with unnumbered + // substitutions. With relatively small changes to doPrintf we can + // have it optionally ignore extra arguments and pass the argument + // list in its entirety. + msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + if wrap { + return &wrapError{msg, err, frame} + } + return &noWrapError{msg, err, frame} + } + // Support %w anywhere. + // TODO: don't repeat the wrapped error's message when %w occurs in the middle. + msg := fmt.Sprintf(format2, a...) + if idx < 0 { + return &noWrapError{msg, nil, Caller(1)} + } + err := errorAt(a, idx) + if !ok || err == nil { + // Too many %ws or argument of %w is not an error. Approximate the Go + // 1.13 fmt.Errorf message. + return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} + } + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + return &wrapError{msg, err, frame} +} + +func errorAt(args []interface{}, i int) error { + if i < 0 || i >= len(args) { + return nil + } + err, ok := args[i].(error) + if !ok { + return nil + } + return err +} + +// formatPlusW is used to avoid the vet check that will barf at %w. +func formatPlusW(s string) string { + return s +} + +// Return the index of the only %w in format, or -1 if none. +// Also return a rewritten format string with %w replaced by %v, and +// false if there is more than one %w. +// TODO: handle "%[N]w". +func parsePercentW(format string) (idx int, newFormat string, ok bool) { + // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. + idx = -1 + ok = true + n := 0 + sz := 0 + var isW bool + for i := 0; i < len(format); i += sz { + if format[i] != '%' { + sz = 1 + continue + } + // "%%" is not a format directive. + if i+1 < len(format) && format[i+1] == '%' { + sz = 2 + continue + } + sz, isW = parsePrintfVerb(format[i:]) + if isW { + if idx >= 0 { + ok = false + } else { + idx = n + } + // "Replace" the last character, the 'w', with a 'v'. + p := i + sz - 1 + format = format[:p] + "v" + format[p+1:] + } + n++ + } + return idx, format, ok +} + +// Parse the printf verb starting with a % at s[0]. +// Return how many bytes it occupies and whether the verb is 'w'. +func parsePrintfVerb(s string) (int, bool) { + // Assume only that the directive is a sequence of non-letters followed by a single letter. + sz := 0 + var r rune + for i := 1; i < len(s); i += sz { + r, sz = utf8.DecodeRuneInString(s[i:]) + if unicode.IsLetter(r) { + return i + sz, r == 'w' + } + } + return len(s), false +} + +type noWrapError struct { + msg string + err error + frame Frame +} + +func (e *noWrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *noWrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +type wrapError struct { + msg string + err error + frame Frame +} + +func (e *wrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *wrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +func (e *wrapError) Unwrap() error { + return e.err +} diff --git a/vendor/golang.org/x/xerrors/format.go b/vendor/golang.org/x/xerrors/format.go new file mode 100644 index 00000000000..1bc9c26b97f --- /dev/null +++ b/vendor/golang.org/x/xerrors/format.go @@ -0,0 +1,34 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +// A Formatter formats error messages. +type Formatter interface { + error + + // FormatError prints the receiver's first error and returns the next error in + // the error chain, if any. + FormatError(p Printer) (next error) +} + +// A Printer formats error messages. +// +// The most common implementation of Printer is the one provided by package fmt +// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message +// typically provide their own implementations. +type Printer interface { + // Print appends args to the message output. + Print(args ...interface{}) + + // Printf writes a formatted string. + Printf(format string, args ...interface{}) + + // Detail reports whether error detail is requested. + // After the first call to Detail, all text written to the Printer + // is formatted as additional detail, or ignored when + // detail has not been requested. + // If Detail returns false, the caller can avoid printing the detail at all. + Detail() bool +} diff --git a/vendor/golang.org/x/xerrors/frame.go b/vendor/golang.org/x/xerrors/frame.go new file mode 100644 index 00000000000..0de628ec501 --- /dev/null +++ b/vendor/golang.org/x/xerrors/frame.go @@ -0,0 +1,56 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "runtime" +) + +// A Frame contains part of a call stack. +type Frame struct { + // Make room for three PCs: the one we were asked for, what it called, + // and possibly a PC for skipPleaseUseCallersFrames. See: + // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 + frames [3]uintptr +} + +// Caller returns a Frame that describes a frame on the caller's stack. +// The argument skip is the number of frames to skip over. +// Caller(0) returns the frame for the caller of Caller. +func Caller(skip int) Frame { + var s Frame + runtime.Callers(skip+1, s.frames[:]) + return s +} + +// location reports the file, line, and function of a frame. +// +// The returned function may be "" even if file and line are not. +func (f Frame) location() (function, file string, line int) { + frames := runtime.CallersFrames(f.frames[:]) + if _, ok := frames.Next(); !ok { + return "", "", 0 + } + fr, ok := frames.Next() + if !ok { + return "", "", 0 + } + return fr.Function, fr.File, fr.Line +} + +// Format prints the stack as error detail. +// It should be called from an error's Format implementation +// after printing any other error detail. +func (f Frame) Format(p Printer) { + if p.Detail() { + function, file, line := f.location() + if function != "" { + p.Printf("%s\n ", function) + } + if file != "" { + p.Printf("%s:%d\n", file, line) + } + } +} diff --git a/vendor/golang.org/x/xerrors/go.mod b/vendor/golang.org/x/xerrors/go.mod new file mode 100644 index 00000000000..870d4f612db --- /dev/null +++ b/vendor/golang.org/x/xerrors/go.mod @@ -0,0 +1,3 @@ +module golang.org/x/xerrors + +go 1.11 diff --git a/vendor/golang.org/x/xerrors/internal/internal.go b/vendor/golang.org/x/xerrors/internal/internal.go new file mode 100644 index 00000000000..89f4eca5df7 --- /dev/null +++ b/vendor/golang.org/x/xerrors/internal/internal.go @@ -0,0 +1,8 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +// EnableTrace indicates whether stack information should be recorded in errors. +var EnableTrace = true diff --git a/vendor/golang.org/x/xerrors/wrap.go b/vendor/golang.org/x/xerrors/wrap.go new file mode 100644 index 00000000000..9a3b510374e --- /dev/null +++ b/vendor/golang.org/x/xerrors/wrap.go @@ -0,0 +1,106 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "reflect" +) + +// A Wrapper provides context around another error. +type Wrapper interface { + // Unwrap returns the next error in the error chain. + // If there is no next error, Unwrap returns nil. + Unwrap() error +} + +// Opaque returns an error with the same error formatting as err +// but that does not match err and cannot be unwrapped. +func Opaque(err error) error { + return noWrapper{err} +} + +type noWrapper struct { + error +} + +func (e noWrapper) FormatError(p Printer) (next error) { + if f, ok := e.error.(Formatter); ok { + return f.FormatError(p) + } + p.Print(e.error) + return nil +} + +// Unwrap returns the result of calling the Unwrap method on err, if err implements +// Unwrap. Otherwise, Unwrap returns nil. +func Unwrap(err error) error { + u, ok := err.(Wrapper) + if !ok { + return nil + } + return u.Unwrap() +} + +// Is reports whether any error in err's chain matches target. +// +// An error is considered to match a target if it is equal to that target or if +// it implements a method Is(error) bool such that Is(target) returns true. +func Is(err, target error) bool { + if target == nil { + return err == target + } + + isComparable := reflect.TypeOf(target).Comparable() + for { + if isComparable && err == target { + return true + } + if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { + return true + } + // TODO: consider supporing target.Is(err). This would allow + // user-definable predicates, but also may allow for coping with sloppy + // APIs, thereby making it easier to get away with them. + if err = Unwrap(err); err == nil { + return false + } + } +} + +// As finds the first error in err's chain that matches the type to which target +// points, and if so, sets the target to its value and returns true. An error +// matches a type if it is assignable to the target type, or if it has a method +// As(interface{}) bool such that As(target) returns true. As will panic if target +// is not a non-nil pointer to a type which implements error or is of interface type. +// +// The As method should set the target to its value and return true if err +// matches the type to which target points. +func As(err error, target interface{}) bool { + if target == nil { + panic("errors: target cannot be nil") + } + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + panic("errors: target must be a non-nil pointer") + } + if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { + panic("errors: *target must be interface or implement error") + } + targetType := typ.Elem() + for err != nil { + if reflect.TypeOf(err).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(err)) + return true + } + if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { + return true + } + err = Unwrap(err) + } + return false +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile b/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile deleted file mode 100644 index dacc43c3afa..00000000000 --- a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM ubuntu:16.04 - -LABEL maintainer="sergey@makinen.ru" - -ENV DEBIAN_FRONTEND noninteractive - -ENV ORACLE_INSTANTCLIENT_MAJOR 12.2 -ENV ORACLE_INSTANTCLIENT_VERSION 12.2.0.1.0 -ENV ORACLE /usr/local/oracle -ENV ORACLE_HOME $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 -ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:$ORACLE_HOME/lib -ENV C_INCLUDE_PATH $C_INCLUDE_PATH:$ORACLE/include/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 - -RUN apt-get update && apt-get install -y libaio1 \ - curl rpm2cpio cpio \ - && mkdir $ORACLE && TMP_DIR="$(mktemp -d)" && cd "$TMP_DIR" \ - && curl -L https://github.com/sergeymakinen/docker-oracle-instant-client/raw/assets/oracle-instantclient$ORACLE_INSTANTCLIENT_MAJOR-basic-$ORACLE_INSTANTCLIENT_VERSION-1.x86_64.rpm -o basic.rpm \ - && rpm2cpio basic.rpm | cpio -i -d -v && cp -r usr/* $ORACLE && rm -rf ./* \ - && ln -s libclntsh.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libclntsh.so.$ORACLE_INSTANTCLIENT_MAJOR \ - && ln -s libocci.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libocci.so.$ORACLE_INSTANTCLIENT_MAJOR \ - && curl -L https://github.com/sergeymakinen/docker-oracle-instant-client/raw/assets/oracle-instantclient$ORACLE_INSTANTCLIENT_MAJOR-devel-$ORACLE_INSTANTCLIENT_VERSION-1.x86_64.rpm -o devel.rpm \ - && rpm2cpio devel.rpm | cpio -i -d -v && cp -r usr/* $ORACLE && rm -rf "$TMP_DIR" \ - && echo "$ORACLE_HOME/lib" > /etc/ld.so.conf.d/oracle.conf && chmod o+r /etc/ld.so.conf.d/oracle.conf && ldconfig \ - && rm -rf /var/lib/apt/lists/* && apt-get purge -y --auto-remove curl rpm2cpio cpio diff --git a/vendor/gopkg.in/goracle.v2/drv_10.go b/vendor/gopkg.in/goracle.v2/drv_10.go deleted file mode 100644 index e6fd6941aca..00000000000 --- a/vendor/gopkg.in/goracle.v2/drv_10.go +++ /dev/null @@ -1,106 +0,0 @@ -// +build go1.10 - -// Copyright 2019 Tamás Gulácsi -// -// -// Licensed 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 goracle - -import ( - "context" - "database/sql/driver" - "fmt" - "strings" - - "github.com/pkg/errors" -) - -var _ = driver.Connector((*connector)(nil)) - -type connector struct { - ConnectionParams - *drv - onInit func(driver.Conn) error -} - -// OpenConnector must parse the name in the same format that Driver.Open -// parses the name parameter. -func (d *drv) OpenConnector(name string) (driver.Connector, error) { - P, err := ParseConnString(name) - if err != nil { - return nil, err - } - - return connector{ConnectionParams: P, drv: d}, nil -} - -// Connect returns a connection to the database. -// Connect may return a cached connection (one previously -// closed), but doing so is unnecessary; the sql package -// maintains a pool of idle connections for efficient re-use. -// -// The provided context.Context is for dialing purposes only -// (see net.DialContext) and should not be stored or used for -// other purposes. -// -// The returned connection is only used by one goroutine at a -// time. -func (c connector) Connect(context.Context) (driver.Conn, error) { - conn, err := c.drv.openConn(c.ConnectionParams) - if err != nil || c.onInit == nil || !conn.newSession { - return conn, err - } - if err = c.onInit(conn); err != nil { - conn.Close() - return nil, err - } - return conn, nil -} - -// Driver returns the underlying Driver of the Connector, -// mainly to maintain compatibility with the Driver method -// on sql.DB. -func (c connector) Driver() driver.Driver { return c.drv } - -// NewConnector returns a driver.Connector to be used with sql.OpenDB, -// which calls the given onInit if the connection is new. -func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { - cxr, err := defaultDrv.OpenConnector(name) - if err != nil { - return nil, err - } - cx := cxr.(connector) - cx.onInit = onInit - return cx, err -} - -// NewSessionIniter returns a function suitable for use in NewConnector as onInit, -// which calls "ALTER SESSION SET =''" for each element of the given map. -func NewSessionIniter(m map[string]string) func(driver.Conn) error { - return func(cx driver.Conn) error { - for k, v := range m { - qry := fmt.Sprintf("ALTER SESSION SET %s = '%s'", k, strings.ReplaceAll(v, "'", "''")) - st, err := cx.Prepare(qry) - if err != nil { - return errors.Wrap(err, qry) - } - _, err = st.Exec(nil) //nolint:SA1019 - st.Close() - if err != nil { - return err - } - } - return nil - } -} diff --git a/vendor/gopkg.in/goracle.v2/drv_posix.go b/vendor/gopkg.in/goracle.v2/drv_posix.go deleted file mode 100644 index 0f3de24337e..00000000000 --- a/vendor/gopkg.in/goracle.v2/drv_posix.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !windows - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed 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 goracle - -// #cgo LDFLAGS: -ldl -lpthread -import "C" diff --git a/vendor/gopkg.in/goracle.v2/go.mod b/vendor/gopkg.in/goracle.v2/go.mod deleted file mode 100644 index dddc925735b..00000000000 --- a/vendor/gopkg.in/goracle.v2/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module gopkg.in/goracle.v2 - -require ( - github.com/go-kit/kit v0.8.0 - github.com/go-logfmt/logfmt v0.4.0 // indirect - github.com/go-stack/stack v1.8.0 // indirect - github.com/google/go-cmp v0.2.0 - github.com/pkg/errors v0.8.0 - golang.org/x/sync v0.0.0-20181108010431-42b317875d0f -) diff --git a/vendor/gopkg.in/goracle.v2/go.sum b/vendor/gopkg.in/goracle.v2/go.sum deleted file mode 100644 index 3bcd4a1c117..00000000000 --- a/vendor/gopkg.in/goracle.v2/go.sum +++ /dev/null @@ -1,14 +0,0 @@ -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/vendor/gopkg.in/goracle.v2/stmt_go09.go b/vendor/gopkg.in/goracle.v2/stmt_go09.go deleted file mode 100644 index 6c731f8ed64..00000000000 --- a/vendor/gopkg.in/goracle.v2/stmt_go09.go +++ /dev/null @@ -1,52 +0,0 @@ -// +build !go1.10 - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed 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 goracle - -/* -#include -#include "dpiImpl.h" -*/ -import "C" -import ( - "bytes" - "sync" - "unsafe" -) - -const go10 = false - -func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { - b := []byte(x) - C.dpiVar_setFromBytes(dv, pos, (*C.char)(unsafe.Pointer(&b[0])), C.uint32_t(len(b))) -} - -var stringBuilders = stringBuilderPool{ - p: &sync.Pool{New: func() interface{} { return bytes.NewBuffer(make([]byte, 0, 1024)) }}, -} - -type stringBuilderPool struct { - p *sync.Pool -} - -func (sb stringBuilderPool) Get() *bytes.Buffer { - return sb.p.Get().(*bytes.Buffer) -} -func (sb *stringBuilderPool) Put(b *bytes.Buffer) { - b.Reset() - sb.p.Put(b) -} diff --git a/vendor/gopkg.in/goracle.v2/stmt_go10.go b/vendor/gopkg.in/goracle.v2/stmt_go10.go deleted file mode 100644 index 5bc1da80073..00000000000 --- a/vendor/gopkg.in/goracle.v2/stmt_go10.go +++ /dev/null @@ -1,78 +0,0 @@ -// +build go1.10 - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed 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 goracle - -/* -#include -#include "dpiImpl.h" - -void goracle_setFromString(dpiVar *dv, uint32_t pos, const _GoString_ value) { - uint32_t length; - length = _GoStringLen(value); - if( length == 0 ) { - return; - } - dpiVar_setFromBytes(dv, pos, _GoStringPtr(value), length); -} -*/ -import "C" -import ( - //"context" - "strings" - "sync" -) - -const go10 = true - -func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { - C.goracle_setFromString(dv, pos, x) -} - -var stringBuilders = stringBuilderPool{ - p: &sync.Pool{New: func() interface{} { return &strings.Builder{} }}, -} - -type stringBuilderPool struct { - p *sync.Pool -} - -func (sb stringBuilderPool) Get() *strings.Builder { - return sb.p.Get().(*strings.Builder) -} -func (sb *stringBuilderPool) Put(b *strings.Builder) { - b.Reset() - sb.p.Put(b) -} - -/* -// ResetSession is called while a connection is in the connection -// pool. No queries will run on this connection until this method returns. -// -// If the connection is bad this should return driver.ErrBadConn to prevent -// the connection from being returned to the connection pool. Any other -// error will be discarded. -func (c *conn) ResetSession(ctx context.Context) error { - if Log != nil { - Log("msg", "ResetSession", "conn", c.dpiConn) - } - //subCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - //err := c.Ping(subCtx) - //cancel() - return c.Ping(ctx) -} -*/ diff --git a/vendor/vendor.json b/vendor/vendor.json index e37769ac625..3ee78bf7257 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3448,6 +3448,15 @@ "revision": "37bf87eef99d69c4f1d3528bd66e3a87dc201472", "revisionTime": "2019-09-30T11:59:46Z" }, + { + "checksumSHA1": "fW8mQy9XfBOcO8dwudie7NHXC5o=", + "path": "github.com/godror/godror", + "revision": "446a29355d2967f04604e8e015a3343917860adf", + "revisionTime": "2019-12-12T16:49:28Z", + "tree": true, + "version": "v0.9.0", + "versionExact": "v0.9.0" + }, { "checksumSHA1": "MlaWEe1K+Kpb9wDF88qPoqO1uro=", "path": "github.com/gofrs/flock", @@ -5666,12 +5675,16 @@ "versionExact": "release-branch.go1.13" }, { - "checksumSHA1": "WvhCpgIKNQ1psrswDf1GC5hFKWM=", - "path": "google.golang.org/api/compute/v1", - "revision": "8a410c21381766a810817fd6200fce8838ecb277", - "revisionTime": "2019-11-15T18:09:15Z", - "version": "v0.14.0", - "versionExact": "v0.14.0" + "checksumSHA1": "uIgpefsunMZTr8uZTJKcevvU/yg=", + "path": "golang.org/x/xerrors", + "revision": "9bdfabe68543c54f90421aeb9a60ef8061b5b544", + "revisionTime": "2019-07-19T19:12:34Z" + }, + { + "checksumSHA1": "LnzK4nslUNXBIfAt9PbXCJCvMdA=", + "path": "golang.org/x/xerrors/internal", + "revision": "9bdfabe68543c54f90421aeb9a60ef8061b5b544", + "revisionTime": "2019-07-19T19:12:34Z" }, { "checksumSHA1": "xzYkHGnGgOHW4QNWLR4jbx+81P0=", @@ -5681,6 +5694,14 @@ "version": "v0.7.0", "versionExact": "v0.7.0" }, + { + "checksumSHA1": "WvhCpgIKNQ1psrswDf1GC5hFKWM=", + "path": "google.golang.org/api/compute/v1", + "revision": "8a410c21381766a810817fd6200fce8838ecb277", + "revisionTime": "2019-11-15T18:09:15Z", + "version": "v0.14.0", + "versionExact": "v0.14.0" + }, { "checksumSHA1": "FhzGDPlkW5SaQGtSgKnjQAiYVk0=", "path": "google.golang.org/api/gensupport", @@ -5721,6 +5742,12 @@ "version": "v0.7.0", "versionExact": "v0.7.0" }, + { + "path": "google.golang.org/api/internal/gensupport", + "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", + "version": "v0.7.0", + "versionExact": "v0.7.0" + }, { "checksumSHA1": "I4Oe5Q+AuaxmN3duL38r2evqGKk=", "path": "google.golang.org/api/internal/gensupport", @@ -5736,12 +5763,6 @@ "revisionTime": "2019-11-15T18:09:15Z", "version": "v0.14.0", "versionExact": "v0.14.0" - }, - { - "path": "google.golang.org/api/internal/gensupport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "version": "v0.7.0", - "versionExact": "v0.7.0" }, { "checksumSHA1": "zh9AcT6oNvhnOqb7w7njY48TkvI=", @@ -6394,12 +6415,6 @@ "version": "v1.25.1", "versionExact": "v1.25.1" }, - { - "checksumSHA1": "+/UD9mGRnKxOhZW3+B+VJdIIPn8=", - "path": "gopkg.in/goracle.v2", - "revision": "3222d7159b45fce95150f06a57e1bcc2868108d3", - "revisionTime": "2019-05-30T18:40:54Z" - }, { "checksumSHA1": "6f8MEU31llHM1sLM/GGH4/Qxu0A=", "path": "gopkg.in/inf.v0", diff --git a/x-pack/metricbeat/module/oracle/connection.go b/x-pack/metricbeat/module/oracle/connection.go index b418c4ac5f8..96add9ced08 100644 --- a/x-pack/metricbeat/module/oracle/connection.go +++ b/x-pack/metricbeat/module/oracle/connection.go @@ -7,7 +7,7 @@ package oracle import ( "database/sql" - "gopkg.in/goracle.v2" + "github.com/godror/godror" "github.com/elastic/beats/metricbeat/mb" "github.com/elastic/beats/metricbeat/mb/parse" @@ -37,7 +37,7 @@ func init() { // NewConnection returns a connection already established with Oracle func NewConnection(c *ConnectionDetails) (*sql.DB, error) { - params, err := goracle.ParseConnString(c.Hosts[0]) + params, err := godror.ParseConnString(c.Hosts[0]) if err != nil { return nil, errors.Wrap(err, "error trying to parse connection string in field 'hosts'") } @@ -54,7 +54,7 @@ func NewConnection(c *ConnectionDetails) (*sql.DB, error) { return nil, errors.New("a user with DBA permissions are required, check your connection details on field `hosts`") } - db, err := sql.Open("goracle", params.StringWithPassword()) + db, err := sql.Open("godror", params.StringWithPassword()) if err != nil { return nil, errors.Wrap(err, "could not open database") } diff --git a/x-pack/metricbeat/module/oracle/performance/metricset_test.go b/x-pack/metricbeat/module/oracle/performance/metricset_test.go index b6182b5b41d..80d16a4e495 100644 --- a/x-pack/metricbeat/module/oracle/performance/metricset_test.go +++ b/x-pack/metricbeat/module/oracle/performance/metricset_test.go @@ -9,7 +9,7 @@ package performance import ( "testing" - _ "gopkg.in/goracle.v2" + _ "github.com/godror/godror" "github.com/elastic/beats/libbeat/common" mbtest "github.com/elastic/beats/metricbeat/mb/testing" diff --git a/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go b/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go index a7934647826..f0bb4b672d8 100644 --- a/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go +++ b/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go @@ -9,7 +9,7 @@ package tablespace import ( "testing" - _ "gopkg.in/goracle.v2" + _ "github.com/godror/godror" "github.com/elastic/beats/libbeat/tests/compose" mbtest "github.com/elastic/beats/metricbeat/mb/testing" diff --git a/x-pack/metricbeat/module/oracle/testing.go b/x-pack/metricbeat/module/oracle/testing.go index 06c87b10b56..5ffe9cd83f4 100644 --- a/x-pack/metricbeat/module/oracle/testing.go +++ b/x-pack/metricbeat/module/oracle/testing.go @@ -8,12 +8,12 @@ import ( "fmt" "os" - "gopkg.in/goracle.v2" + "github.com/godror/godror" ) // GetOracleConnectionDetails return a valid SID to use for testing func GetOracleConnectionDetails(host string) string { - params := goracle.ConnectionParams{ + params := godror.ConnectionParams{ SID: fmt.Sprintf("%s/%s", host, GetOracleEnvServiceName()), Username: GetOracleEnvUsername(), Password: GetOracleEnvPassword(), From 2657f713ed3d1f1c169e19177a4456707d1188bd Mon Sep 17 00:00:00 2001 From: Mariana Dima Date: Tue, 21 Jan 2020 12:27:04 +0100 Subject: [PATCH 26/37] Move pdh query to shared location in order for new modules/metricsets to reuse (#15503) * Move pdh query to shared location * Update changelog * Fix make update * mage fmt * fix changelog --- CHANGELOG.next.asciidoc | 1 + .../windows/pdh}/defs_pdh_windows.go | 2 +- .../windows/pdh}/defs_pdh_windows_386.go | 2 +- .../windows/pdh}/defs_pdh_windows_amd64.go | 2 +- .../windows => helper/windows/pdh}/doc.go | 11 +++-- .../windows/pdh}/mkpdh_defs.go | 2 +- .../windows/pdh}/pdh_query_windows.go | 40 +++++++++---------- .../windows/pdh}/pdh_query_windows_test.go | 8 ++-- .../windows/pdh}/pdh_windows.go | 2 +- .../windows/pdh}/pdh_windows_test.go | 2 +- .../windows/pdh}/zpdh_windows.go | 2 +- metricbeat/{module => helper}/windows/run.go | 0 metricbeat/module/windows/perfmon/doc.go | 8 ---- metricbeat/module/windows/perfmon/perfmon.go | 2 +- ...ration_windows_test.go => perfmon_test.go} | 24 ++++++----- metricbeat/module/windows/perfmon/reader.go | 18 +++++---- .../module/windows/perfmon/reader_test.go | 8 ++-- metricbeat/module/windows/service/doc.go | 4 +- 18 files changed, 69 insertions(+), 69 deletions(-) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/defs_pdh_windows.go (99%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/defs_pdh_windows_386.go (99%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/defs_pdh_windows_amd64.go (99%) rename metricbeat/{module/windows => helper/windows/pdh}/doc.go (62%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/mkpdh_defs.go (99%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/pdh_query_windows.go (89%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/pdh_query_windows_test.go (94%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/pdh_windows.go (99%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/pdh_windows_test.go (99%) rename metricbeat/{module/windows/perfmon => helper/windows/pdh}/zpdh_windows.go (99%) rename metricbeat/{module => helper}/windows/run.go (100%) rename metricbeat/module/windows/perfmon/{pdh_integration_windows_test.go => perfmon_test.go} (94%) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index f02abf640f6..252e214e044 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -83,6 +83,7 @@ TLS or Beats that accept connections over TLS and validate client certificates. *Metricbeat* +- Move the windows pdh implementation from perfmon to a shared location in order for future modules/metricsets to make use of. {pull}15503[15503] - Add lambda metricset in aws module. {pull}15260[15260] - Expand data for the `system/memory` metricset {pull}15492[15492] - Add azure `storage` metricset in order to retrieve metric values for storage accounts. {issue}14548[14548] {pull}15342[15342] diff --git a/metricbeat/module/windows/perfmon/defs_pdh_windows.go b/metricbeat/helper/windows/pdh/defs_pdh_windows.go similarity index 99% rename from metricbeat/module/windows/perfmon/defs_pdh_windows.go rename to metricbeat/helper/windows/pdh/defs_pdh_windows.go index 97f070a600a..bcc62c4ffd1 100644 --- a/metricbeat/module/windows/perfmon/defs_pdh_windows.go +++ b/metricbeat/helper/windows/pdh/defs_pdh_windows.go @@ -20,7 +20,7 @@ // +build ignore -package perfmon +package pdh /* #include diff --git a/metricbeat/module/windows/perfmon/defs_pdh_windows_386.go b/metricbeat/helper/windows/pdh/defs_pdh_windows_386.go similarity index 99% rename from metricbeat/module/windows/perfmon/defs_pdh_windows_386.go rename to metricbeat/helper/windows/pdh/defs_pdh_windows_386.go index 3995b8b9b01..e794050dcf5 100644 --- a/metricbeat/module/windows/perfmon/defs_pdh_windows_386.go +++ b/metricbeat/helper/windows/pdh/defs_pdh_windows_386.go @@ -18,7 +18,7 @@ // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo.exe -godefs defs_pdh_windows.go -package perfmon +package pdh type PdhErrno uintptr diff --git a/metricbeat/module/windows/perfmon/defs_pdh_windows_amd64.go b/metricbeat/helper/windows/pdh/defs_pdh_windows_amd64.go similarity index 99% rename from metricbeat/module/windows/perfmon/defs_pdh_windows_amd64.go rename to metricbeat/helper/windows/pdh/defs_pdh_windows_amd64.go index 3995b8b9b01..e794050dcf5 100644 --- a/metricbeat/module/windows/perfmon/defs_pdh_windows_amd64.go +++ b/metricbeat/helper/windows/pdh/defs_pdh_windows_amd64.go @@ -18,7 +18,7 @@ // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo.exe -godefs defs_pdh_windows.go -package perfmon +package pdh type PdhErrno uintptr diff --git a/metricbeat/module/windows/doc.go b/metricbeat/helper/windows/pdh/doc.go similarity index 62% rename from metricbeat/module/windows/doc.go rename to metricbeat/helper/windows/pdh/doc.go index 7068d9f2ef9..fc6ec0cd132 100644 --- a/metricbeat/module/windows/doc.go +++ b/metricbeat/helper/windows/pdh/doc.go @@ -15,7 +15,10 @@ // specific language governing permissions and limitations // under the License. -/* -Package windows is a Metricbeat module that contains MetricSets. -*/ -package windows +package pdh + +//go:generate go run mkpdh_defs.go +//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_pdh_windows.go" -goarch amd64 -output defs_pdh_windows_amd64.go +//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_pdh_windows.go" -goarch 386 -output defs_pdh_windows_386.go +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zpdh_windows.go pdh_windows.go +//go:generate gofmt -w defs_pdh_windows_amd64.go defs_pdh_windows_386.go zpdh_windows.go diff --git a/metricbeat/module/windows/perfmon/mkpdh_defs.go b/metricbeat/helper/windows/pdh/mkpdh_defs.go similarity index 99% rename from metricbeat/module/windows/perfmon/mkpdh_defs.go rename to metricbeat/helper/windows/pdh/mkpdh_defs.go index 1f30a1161fb..fd71b98bb27 100644 --- a/metricbeat/module/windows/perfmon/mkpdh_defs.go +++ b/metricbeat/helper/windows/pdh/mkpdh_defs.go @@ -48,7 +48,7 @@ const fileTemplate = ` // +build ignore -package perfmon +package pdh /* #include diff --git a/metricbeat/module/windows/perfmon/pdh_query_windows.go b/metricbeat/helper/windows/pdh/pdh_query_windows.go similarity index 89% rename from metricbeat/module/windows/perfmon/pdh_query_windows.go rename to metricbeat/helper/windows/pdh/pdh_query_windows.go index 5c5a7149d3b..c7d8f0d82bf 100644 --- a/metricbeat/module/windows/perfmon/pdh_query_windows.go +++ b/metricbeat/helper/windows/pdh/pdh_query_windows.go @@ -17,7 +17,7 @@ // +build windows -package perfmon +package pdh import ( "regexp" @@ -43,8 +43,8 @@ type Counter struct { // Query contains the pdh. type Query struct { - handle PdhQueryHandle - counters map[string]*Counter + Handle PdhQueryHandle + Counters map[string]*Counter } // CounterValue contains the performance counter values. @@ -60,42 +60,42 @@ func (q *Query) Open() error { if err != nil { return err } - q.handle = h - q.counters = make(map[string]*Counter) + q.Handle = h + q.Counters = make(map[string]*Counter) return nil } // AddEnglishCounter adds the specified counter to the query. func (q *Query) AddEnglishCounter(counterPath string) (PdhCounterHandle, error) { - h, err := PdhAddEnglishCounter(q.handle, counterPath, 0) + h, err := PdhAddEnglishCounter(q.Handle, counterPath, 0) return h, err } // AddCounter adds the specified counter to the query. -func (q *Query) AddCounter(counterPath string, counter CounterConfig, wildcard bool) error { - if _, found := q.counters[counterPath]; found { +func (q *Query) AddCounter(counterPath string, instance string, format string, wildcard bool) error { + if _, found := q.Counters[counterPath]; found { return nil } var err error var instanceName string // Extract the instance name from the counterPath. - if counter.InstanceName == "" || wildcard { + if instance == "" || wildcard { instanceName, err = matchInstanceName(counterPath) if err != nil { return err } } else { - instanceName = counter.InstanceName + instanceName = instance } - h, err := PdhAddCounter(q.handle, counterPath, 0) + h, err := PdhAddCounter(q.Handle, counterPath, 0) if err != nil { return err } - q.counters[counterPath] = &Counter{ + q.Counters[counterPath] = &Counter{ handle: h, instanceName: instanceName, - format: getPDHFormat(counter.Format), + format: getPDHFormat(format), } return nil } @@ -134,7 +134,7 @@ func (q *Query) RemoveUnusedCounters(counters []string) error { } } unused := make(map[string]*Counter) - for counterPath, counter := range q.counters { + for counterPath, counter := range q.Counters { if !matchCounter(counterPath, counters) { unused[counterPath] = counter } @@ -147,7 +147,7 @@ func (q *Query) RemoveUnusedCounters(counters []string) error { if err != nil { return err } - delete(q.counters, counterPath) + delete(q.Counters, counterPath) } return nil } @@ -163,16 +163,16 @@ func matchCounter(counterPath string, counterList []string) bool { // CollectData collects the value for all counters in the query. func (q *Query) CollectData() error { - return PdhCollectQueryData(q.handle) + return PdhCollectQueryData(q.Handle) } // GetFormattedCounterValues returns an array of formatted values for a query. func (q *Query) GetFormattedCounterValues() (map[string][]CounterValue, error) { - if q.counters == nil || len(q.counters) == 0 { + if q.Counters == nil || len(q.Counters) == 0 { return nil, errors.New("no counter list found") } - rtn := make(map[string][]CounterValue, len(q.counters)) - for path, counter := range q.counters { + rtn := make(map[string][]CounterValue, len(q.Counters)) + for path, counter := range q.Counters { rtn[path] = append(rtn[path], getCounterValue(counter)) } return rtn, nil @@ -206,7 +206,7 @@ func (q *Query) ExpandWildCardPath(wildCardPath string) ([]string, error) { // Close closes the query and all of its counters. func (q *Query) Close() error { - return PdhCloseQuery(q.handle) + return PdhCloseQuery(q.Handle) } // matchInstanceName will check first for instance and then for any objects names. diff --git a/metricbeat/module/windows/perfmon/pdh_query_windows_test.go b/metricbeat/helper/windows/pdh/pdh_query_windows_test.go similarity index 94% rename from metricbeat/module/windows/perfmon/pdh_query_windows_test.go rename to metricbeat/helper/windows/pdh/pdh_query_windows_test.go index 4e45ec82718..2b5038e42c4 100644 --- a/metricbeat/module/windows/perfmon/pdh_query_windows_test.go +++ b/metricbeat/helper/windows/pdh/pdh_query_windows_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package perfmon +package pdh import ( "syscall" @@ -38,8 +38,7 @@ func TestAddCounterInvalidArgWhenQueryClosed(t *testing.T) { queryPath, err := q.GetCounterPaths(validQuery) // if windows os language is ENG then err will be nil, else the GetCounterPaths will execute the AddCounter if assert.NoError(t, err) { - counter := CounterConfig{Format: "float", InstanceName: "TestInstanceName"} - err = q.AddCounter(queryPath[0], counter, false) + err = q.AddCounter(queryPath[0], "TestInstanceName", "float", false) assert.Error(t, err, PDH_INVALID_HANDLE) } else { assert.Error(t, err, PDH_INVALID_ARGUMENT) @@ -70,12 +69,11 @@ func TestSuccessfulQuery(t *testing.T) { t.Fatal(err) } defer q.Close() - counter := CounterConfig{Format: "float", InstanceName: "TestInstanceName"} queryPath, err := q.GetCounterPaths(validQuery) if err != nil { t.Fatal(err) } - err = q.AddCounter(queryPath[0], counter, false) + err = q.AddCounter(queryPath[0], "TestInstanceName", "floar", false) if err != nil { t.Fatal(err) } diff --git a/metricbeat/module/windows/perfmon/pdh_windows.go b/metricbeat/helper/windows/pdh/pdh_windows.go similarity index 99% rename from metricbeat/module/windows/perfmon/pdh_windows.go rename to metricbeat/helper/windows/pdh/pdh_windows.go index b817ddaec16..bccca2c5784 100644 --- a/metricbeat/module/windows/perfmon/pdh_windows.go +++ b/metricbeat/helper/windows/pdh/pdh_windows.go @@ -17,7 +17,7 @@ // +build windows -package perfmon +package pdh import ( "strconv" diff --git a/metricbeat/module/windows/perfmon/pdh_windows_test.go b/metricbeat/helper/windows/pdh/pdh_windows_test.go similarity index 99% rename from metricbeat/module/windows/perfmon/pdh_windows_test.go rename to metricbeat/helper/windows/pdh/pdh_windows_test.go index be08eac32d2..c17a68c31c3 100644 --- a/metricbeat/module/windows/perfmon/pdh_windows_test.go +++ b/metricbeat/helper/windows/pdh/pdh_windows_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package perfmon +package pdh import ( "syscall" diff --git a/metricbeat/module/windows/perfmon/zpdh_windows.go b/metricbeat/helper/windows/pdh/zpdh_windows.go similarity index 99% rename from metricbeat/module/windows/perfmon/zpdh_windows.go rename to metricbeat/helper/windows/pdh/zpdh_windows.go index 85cb93dcc75..8d2891b73cb 100644 --- a/metricbeat/module/windows/perfmon/zpdh_windows.go +++ b/metricbeat/helper/windows/pdh/zpdh_windows.go @@ -17,7 +17,7 @@ // Code generated by 'go generate'; DO NOT EDIT. -package perfmon +package pdh import ( "syscall" diff --git a/metricbeat/module/windows/run.go b/metricbeat/helper/windows/run.go similarity index 100% rename from metricbeat/module/windows/run.go rename to metricbeat/helper/windows/run.go diff --git a/metricbeat/module/windows/perfmon/doc.go b/metricbeat/module/windows/perfmon/doc.go index 66e0df7b5da..bab02b5f128 100644 --- a/metricbeat/module/windows/perfmon/doc.go +++ b/metricbeat/module/windows/perfmon/doc.go @@ -15,12 +15,4 @@ // specific language governing permissions and limitations // under the License. -// Package perfmon implements a Metricbeat metricset for reading Windows -// performance counters. package perfmon - -//go:generate go run mkpdh_defs.go -//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_pdh_windows.go" -goarch amd64 -output defs_pdh_windows_amd64.go -//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_pdh_windows.go" -goarch 386 -output defs_pdh_windows_386.go -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zpdh_windows.go pdh_windows.go -//go:generate gofmt -w defs_pdh_windows_amd64.go defs_pdh_windows_386.go zpdh_windows.go diff --git a/metricbeat/module/windows/perfmon/perfmon.go b/metricbeat/module/windows/perfmon/perfmon.go index 05210599854..a3d048ebcf7 100644 --- a/metricbeat/module/windows/perfmon/perfmon.go +++ b/metricbeat/module/windows/perfmon/perfmon.go @@ -90,7 +90,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // Fetch fetches events and reports them upstream func (m *MetricSet) Fetch(report mb.ReporterV2) error { // if the ignore_non_existent_counters flag is set and no valid counter paths are found the Read func will still execute, a check is done before - if len(m.reader.query.counters) == 0 { + if len(m.reader.query.Counters) == 0 { return errors.New("no counters to read") } diff --git a/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go b/metricbeat/module/windows/perfmon/perfmon_test.go similarity index 94% rename from metricbeat/module/windows/perfmon/pdh_integration_windows_test.go rename to metricbeat/module/windows/perfmon/perfmon_test.go index 1fe12ab20d1..77599ce82c4 100644 --- a/metricbeat/module/windows/perfmon/pdh_integration_windows_test.go +++ b/metricbeat/module/windows/perfmon/perfmon_test.go @@ -24,6 +24,8 @@ import ( "testing" "time" + "github.com/elastic/beats/metricbeat/helper/windows/pdh" + "github.com/elastic/beats/libbeat/common" "github.com/pkg/errors" @@ -106,7 +108,7 @@ func TestCounterWithNoInstanceName(t *testing.T) { } func TestQuery(t *testing.T) { - var q Query + var q pdh.Query err := q.Open() if err != nil { t.Fatal(err) @@ -117,7 +119,7 @@ func TestQuery(t *testing.T) { if err != nil { t.Fatal(err) } - err = q.AddCounter(path[0], counter, false) + err = q.AddCounter(path[0], counter.InstanceName, counter.Format, false) if err != nil { t.Fatal(err) } @@ -177,7 +179,7 @@ func TestNonExistingCounter(t *testing.T) { config.CounterConfig[0].Format = "float" handle, err := NewReader(config) if assert.Error(t, err) { - assert.EqualValues(t, PDH_CSTATUS_NO_COUNTER, errors.Cause(err)) + assert.EqualValues(t, pdh.PDH_CSTATUS_NO_COUNTER, errors.Cause(err)) } if handle != nil { @@ -200,7 +202,7 @@ func TestIgnoreNonExistentCounter(t *testing.T) { values, err := handle.Read() if assert.Error(t, err) { - assert.EqualValues(t, PDH_NO_DATA, errors.Cause(err)) + assert.EqualValues(t, pdh.PDH_NO_DATA, errors.Cause(err)) } if handle != nil { @@ -221,7 +223,7 @@ func TestNonExistingObject(t *testing.T) { config.CounterConfig[0].Format = "float" handle, err := NewReader(config) if assert.Error(t, err) { - assert.EqualValues(t, PDH_CSTATUS_NO_OBJECT, errors.Cause(err)) + assert.EqualValues(t, pdh.PDH_CSTATUS_NO_OBJECT, errors.Cause(err)) } if handle != nil { @@ -231,7 +233,7 @@ func TestNonExistingObject(t *testing.T) { } func TestLongOutputFormat(t *testing.T) { - var query Query + var query pdh.Query err := query.Open() if err != nil { t.Fatal(err) @@ -243,8 +245,8 @@ func TestLongOutputFormat(t *testing.T) { t.Fatal(err) } assert.NotZero(t, len(path)) - err = query.AddCounter(path[0], counter, false) - if err != nil && err != PDH_NO_MORE_DATA { + err = query.AddCounter(path[0], counter.InstanceName, counter.Format, false) + if err != nil && err != pdh.PDH_NO_MORE_DATA { t.Fatal(err) } @@ -271,7 +273,7 @@ func TestLongOutputFormat(t *testing.T) { } func TestFloatOutputFormat(t *testing.T) { - var query Query + var query pdh.Query err := query.Open() if err != nil { t.Fatal(err) @@ -283,8 +285,8 @@ func TestFloatOutputFormat(t *testing.T) { t.Fatal(err) } assert.NotZero(t, len(path)) - err = query.AddCounter(path[0], counter, false) - if err != nil && err != PDH_NO_MORE_DATA { + err = query.AddCounter(path[0], counter.InstanceName, counter.Format, false) + if err != nil && err != pdh.PDH_NO_MORE_DATA { t.Fatal(err) } diff --git a/metricbeat/module/windows/perfmon/reader.go b/metricbeat/module/windows/perfmon/reader.go index b7837862ffc..51eef6b7e95 100644 --- a/metricbeat/module/windows/perfmon/reader.go +++ b/metricbeat/module/windows/perfmon/reader.go @@ -24,6 +24,8 @@ import ( "strconv" "strings" + "github.com/elastic/beats/metricbeat/helper/windows/pdh" + "github.com/pkg/errors" "github.com/elastic/beats/libbeat/common" @@ -37,7 +39,7 @@ var ( // Reader will contain the config options type Reader struct { - query Query // PDH Query + query pdh.Query // PDH Query instanceLabel map[string]string // Mapping of counter path to key used for the label (e.g. processor.name) measurement map[string]string // Mapping of counter path to key used for the value (e.g. processor.cpu_time). executed bool // Indicates if the query has been executed. @@ -47,7 +49,7 @@ type Reader struct { // NewReader creates a new instance of Reader. func NewReader(config Config) (*Reader, error) { - var query Query + var query pdh.Query if err := query.Open(); err != nil { return nil, err } @@ -63,8 +65,8 @@ func NewReader(config Config) (*Reader, error) { if err != nil { if config.IgnoreNECounters { switch err { - case PDH_CSTATUS_NO_COUNTER, PDH_CSTATUS_NO_COUNTERNAME, - PDH_CSTATUS_NO_INSTANCE, PDH_CSTATUS_NO_OBJECT: + case pdh.PDH_CSTATUS_NO_COUNTER, pdh.PDH_CSTATUS_NO_COUNTERNAME, + pdh.PDH_CSTATUS_NO_INSTANCE, pdh.PDH_CSTATUS_NO_OBJECT: r.log.Infow("Ignoring non existent counter", "error", err, logp.Namespace("perfmon"), "query", counter.Query) continue @@ -85,7 +87,7 @@ func NewReader(config Config) (*Reader, error) { return nil, errors.Errorf(`failed to expand counter (query="%v")`, counter.Query) } for _, v := range childQueries { - if err := query.AddCounter(v, counter, len(childQueries) > 1); err != nil { + if err := query.AddCounter(v, counter.InstanceName, counter.Format, len(childQueries) > 1); err != nil { return nil, errors.Wrapf(err, `failed to add counter (query="%v")`, counter.Query) } r.instanceLabel[v] = counter.InstanceLabel @@ -104,8 +106,8 @@ func (r *Reader) RefreshCounterPaths() error { if err != nil { if r.config.IgnoreNECounters { switch err { - case PDH_CSTATUS_NO_COUNTER, PDH_CSTATUS_NO_COUNTERNAME, - PDH_CSTATUS_NO_INSTANCE, PDH_CSTATUS_NO_OBJECT: + case pdh.PDH_CSTATUS_NO_COUNTER, pdh.PDH_CSTATUS_NO_COUNTERNAME, + pdh.PDH_CSTATUS_NO_INSTANCE, pdh.PDH_CSTATUS_NO_OBJECT: r.log.Infow("Ignoring non existent counter", "error", err, logp.Namespace("perfmon"), "query", counter.Query) continue @@ -118,7 +120,7 @@ func (r *Reader) RefreshCounterPaths() error { // there are cases when the ExpandWildCardPath will retrieve a successful status but not an expanded query so we need to check for the size of the list if err == nil && len(childQueries) >= 1 && !strings.Contains(childQueries[0], "*") { for _, v := range childQueries { - if err := r.query.AddCounter(v, counter, len(childQueries) > 1); err != nil { + if err := r.query.AddCounter(v, counter.InstanceName, counter.Format, len(childQueries) > 1); err != nil { return errors.Wrapf(err, "failed to add counter (query='%v')", counter.Query) } r.instanceLabel[v] = counter.InstanceLabel diff --git a/metricbeat/module/windows/perfmon/reader_test.go b/metricbeat/module/windows/perfmon/reader_test.go index 8b4a921b3c3..dd5a58aa522 100644 --- a/metricbeat/module/windows/perfmon/reader_test.go +++ b/metricbeat/module/windows/perfmon/reader_test.go @@ -25,6 +25,8 @@ import ( "github.com/stretchr/testify/assert" ) +var validQuery = `\Processor Information(_Total)\% Processor Time` + // TestNewReaderWhenQueryPathNotProvided will check for invalid/no query. func TestNewReaderWhenQueryPathNotProvided(t *testing.T) { counter := CounterConfig{Format: "float", InstanceName: "TestInstanceName"} @@ -51,9 +53,9 @@ func TestNewReaderWithValidQueryPath(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, reader) assert.NotNil(t, reader.query) - assert.NotNil(t, reader.query.handle) - assert.NotNil(t, reader.query.counters) - assert.NotZero(t, len(reader.query.counters)) + assert.NotNil(t, reader.query.Handle) + assert.NotNil(t, reader.query.Counters) + assert.NotZero(t, len(reader.query.Counters)) defer reader.Close() } diff --git a/metricbeat/module/windows/service/doc.go b/metricbeat/module/windows/service/doc.go index 608c063433b..1bcbc98e250 100644 --- a/metricbeat/module/windows/service/doc.go +++ b/metricbeat/module/windows/service/doc.go @@ -18,7 +18,7 @@ // Package service implements a Metricbeat metricset for reading Windows Services package service -//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_service_windows.go" -goarch amd64 -output defs_service_windows_amd64.go -//go:generate go run ../run.go -cmd "go tool cgo -godefs defs_service_windows.go" -goarch 386 -output defs_service_windows_386.go +//go:generate go run ../../../helper/windows/run.go -cmd "go tool cgo -godefs defs_service_windows.go" -goarch amd64 -output defs_service_windows_amd64.go +//go:generate go run ../../../helper/windows/run.go -cmd "go tool cgo -godefs defs_service_windows.go" -goarch 386 -output defs_service_windows_386.go //go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zservice_windows.go service_windows.go //go:generate gofmt -w defs_service_windows_amd64.go defs_service_windows_386.go From 8c71abc3dd960e510ae34d91e464fcd913676455 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 21 Jan 2020 15:46:53 +0100 Subject: [PATCH 27/37] Remove datasource option from SQL module and add tests (#15686) Remove datasource option from SQL module. This option was intended to set the DSN of a database connection, and we were ignoring the hosts setting. In other SQL modules we are using the values in hosts as DSNs, do here the same for consistency. Host is redacted when we cannot parse it as it can contain passwords. StandardizeEvent is exposed in mbtest.Fetcher interface so we can more easily check contents of events in tests. Add integration tests of the module with MySQL and PostgreSQL. Add real data.json with data from MySQL and PostgreSQL. --- metricbeat/docs/modules/sql.asciidoc | 5 +- metricbeat/mb/testing/fetcher.go | 14 ++ x-pack/metricbeat/metricbeat.reference.yml | 3 +- x-pack/metricbeat/module/sql/_meta/config.yml | 3 +- .../metricbeat/module/sql/_meta/docs.asciidoc | 2 +- .../metricbeat/module/sql/docker-compose.yml | 12 ++ .../module/sql/query/_meta/data.json | 46 ++++--- .../module/sql/query/_meta/data_postgres.json | 45 +++++++ x-pack/metricbeat/module/sql/query/dsn.go | 42 ++++++ x-pack/metricbeat/module/sql/query/query.go | 20 ++- .../sql/query/query_integration_test.go | 126 ++++++++++++++++++ x-pack/metricbeat/modules.d/sql.yml.disabled | 3 +- 12 files changed, 279 insertions(+), 42 deletions(-) create mode 100644 x-pack/metricbeat/module/sql/docker-compose.yml create mode 100644 x-pack/metricbeat/module/sql/query/_meta/data_postgres.json create mode 100644 x-pack/metricbeat/module/sql/query/dsn.go create mode 100644 x-pack/metricbeat/module/sql/query/query_integration_test.go diff --git a/metricbeat/docs/modules/sql.asciidoc b/metricbeat/docs/modules/sql.asciidoc index 30e5baf89da..c3f3d412ea7 100644 --- a/metricbeat/docs/modules/sql.asciidoc +++ b/metricbeat/docs/modules/sql.asciidoc @@ -8,7 +8,7 @@ This file is generated! See scripts/mage/docs_collector.go beta[] -This is the sql module that fetches metrics from a SQL database. You can define driver, datasource and SQL query. +This is the sql module that fetches metrics from a SQL database. You can define driver and SQL query. @@ -26,10 +26,9 @@ metricbeat.modules: metricsets: - query period: 10s - hosts: ["localhost"] + hosts: ["user=myuser password=mypassword dbname=mydb sslmode=disable"] driver: "postgres" - datasource: "user=myuser password=mypassword dbname=mydb sslmode=disable" sql_query: "select now()" ---- diff --git a/metricbeat/mb/testing/fetcher.go b/metricbeat/mb/testing/fetcher.go index be8264b5cbb..5b01e1b8138 100644 --- a/metricbeat/mb/testing/fetcher.go +++ b/metricbeat/mb/testing/fetcher.go @@ -20,6 +20,7 @@ package testing import ( "testing" + "github.com/elastic/beats/libbeat/beat" "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/metricbeat/mb" ) @@ -32,6 +33,7 @@ type Fetcher interface { FetchEvents() ([]mb.Event, []error) WriteEvents(testing.TB, string) WriteEventsCond(testing.TB, string, func(common.MapStr) bool) + StandardizeEvent(mb.Event, ...mb.EventModifier) beat.Event } // NewFetcher returns a test fetcher from a Metricset configuration @@ -73,6 +75,10 @@ func (f *reportingMetricSetV2Fetcher) WriteEventsCond(t testing.TB, path string, } } +func (f *reportingMetricSetV2Fetcher) StandardizeEvent(event mb.Event, modifiers ...mb.EventModifier) beat.Event { + return StandardizeEvent(f, event, modifiers...) +} + type reportingMetricSetV2FetcherError struct { mb.ReportingMetricSetV2Error } @@ -96,6 +102,10 @@ func (f *reportingMetricSetV2FetcherError) WriteEventsCond(t testing.TB, path st } } +func (f *reportingMetricSetV2FetcherError) StandardizeEvent(event mb.Event, modifiers ...mb.EventModifier) beat.Event { + return StandardizeEvent(f, event, modifiers...) +} + type reportingMetricSetV2FetcherWithContext struct { mb.ReportingMetricSetV2WithContext } @@ -118,3 +128,7 @@ func (f *reportingMetricSetV2FetcherWithContext) WriteEventsCond(t testing.TB, p t.Fatal("writing events", err) } } + +func (f *reportingMetricSetV2FetcherWithContext) StandardizeEvent(event mb.Event, modifiers ...mb.EventModifier) beat.Event { + return StandardizeEvent(f, event, modifiers...) +} diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 7eef53265a2..60e79272f77 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -971,10 +971,9 @@ metricbeat.modules: metricsets: - query period: 10s - hosts: ["localhost"] + hosts: ["user=myuser password=mypassword dbname=mydb sslmode=disable"] driver: "postgres" - datasource: "user=myuser password=mypassword dbname=mydb sslmode=disable" sql_query: "select now()" diff --git a/x-pack/metricbeat/module/sql/_meta/config.yml b/x-pack/metricbeat/module/sql/_meta/config.yml index 92b5f388221..5c6a419e77b 100644 --- a/x-pack/metricbeat/module/sql/_meta/config.yml +++ b/x-pack/metricbeat/module/sql/_meta/config.yml @@ -2,9 +2,8 @@ metricsets: - query period: 10s - hosts: ["localhost"] + hosts: ["user=myuser password=mypassword dbname=mydb sslmode=disable"] driver: "postgres" - datasource: "user=myuser password=mypassword dbname=mydb sslmode=disable" sql_query: "select now()" diff --git a/x-pack/metricbeat/module/sql/_meta/docs.asciidoc b/x-pack/metricbeat/module/sql/_meta/docs.asciidoc index d7bb818a58b..f22edf1fa20 100644 --- a/x-pack/metricbeat/module/sql/_meta/docs.asciidoc +++ b/x-pack/metricbeat/module/sql/_meta/docs.asciidoc @@ -1,3 +1,3 @@ -This is the sql module that fetches metrics from a SQL database. You can define driver, datasource and SQL query. +This is the sql module that fetches metrics from a SQL database. You can define driver and SQL query. diff --git a/x-pack/metricbeat/module/sql/docker-compose.yml b/x-pack/metricbeat/module/sql/docker-compose.yml new file mode 100644 index 00000000000..a053c322d30 --- /dev/null +++ b/x-pack/metricbeat/module/sql/docker-compose.yml @@ -0,0 +1,12 @@ +version: '2.3' + +services: + mysql: + extends: + file: ../../../../metricbeat/module/mysql/docker-compose.yml + service: mysql + + postgresql: + extends: + file: ../../../../metricbeat/module/postgresql/docker-compose.yml + service: postgresql diff --git a/x-pack/metricbeat/module/sql/query/_meta/data.json b/x-pack/metricbeat/module/sql/query/_meta/data.json index 1a92415be34..799c66fe7bc 100644 --- a/x-pack/metricbeat/module/sql/query/_meta/data.json +++ b/x-pack/metricbeat/module/sql/query/_meta/data.json @@ -1,26 +1,30 @@ { - "@timestamp":"2016-05-23T08:05:34.853Z", - "beat":{ - "hostname":"beathost", - "name":"beathost" + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "sql.query", + "duration": 115000, + "module": "sql" }, - "metricset":{ - "host":"localhost", - "module":"sql", - "name":"query", - "rtt":44269 + "metricset": { + "name": "query", + "period": 10000 }, - "sql":{ - "metrics":{ - "numeric":{ - "mynumericfield":1 - }, - "string":{ - "mystringfield":"abc" - } + "service": { + "address": "172.22.0.3:3306", + "type": "sql" + }, + "sql": { + "driver": "mysql", + "metrics": { + "numeric": { + "table_rows": 6 + }, + "string": { + "engine": "InnoDB", + "table_name": "sys_config", + "table_schema": "sys" + } }, - "driver":"postgres", - "query":"select * from mytable" - }, - "type":"metricsets" + "query": "select table_schema, table_name, engine, table_rows from information_schema.tables where table_rows \u003e 0;" + } } \ No newline at end of file diff --git a/x-pack/metricbeat/module/sql/query/_meta/data_postgres.json b/x-pack/metricbeat/module/sql/query/_meta/data_postgres.json new file mode 100644 index 00000000000..0f2db40c5b1 --- /dev/null +++ b/x-pack/metricbeat/module/sql/query/_meta/data_postgres.json @@ -0,0 +1,45 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "sql.query", + "duration": 115000, + "module": "sql" + }, + "metricset": { + "name": "query", + "period": 10000 + }, + "service": { + "address": "172.22.0.2:5432", + "type": "sql" + }, + "sql": { + "driver": "postgres", + "metrics": { + "numeric": { + "blk_read_time": 0, + "blk_write_time": 0, + "blks_hit": 1923, + "blks_read": 111, + "conflicts": 0, + "datid": 12379, + "deadlocks": 0, + "numbackends": 1, + "temp_bytes": 0, + "temp_files": 0, + "tup_deleted": 0, + "tup_fetched": 1249, + "tup_inserted": 0, + "tup_returned": 1356, + "tup_updated": 0, + "xact_commit": 18, + "xact_rollback": 0 + }, + "string": { + "datname": "postgres", + "stats_reset": "2020-01-21 11:23:56.53" + } + }, + "query": "select * from pg_stat_database" + } +} \ No newline at end of file diff --git a/x-pack/metricbeat/module/sql/query/dsn.go b/x-pack/metricbeat/module/sql/query/dsn.go new file mode 100644 index 00000000000..2a472c3fbe5 --- /dev/null +++ b/x-pack/metricbeat/module/sql/query/dsn.go @@ -0,0 +1,42 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package query + +import ( + "net/url" + + "github.com/go-sql-driver/mysql" + + "github.com/elastic/beats/metricbeat/mb" +) + +// ParseDSN tries to parse the host +func ParseDSN(mod mb.Module, host string) (mb.HostData, error) { + // TODO: Add support for `username` and `password` as module options + + sanitized := sanitize(host) + + return mb.HostData{ + URI: host, + SanitizedURI: sanitized, + Host: sanitized, + }, nil +} + +func sanitize(host string) string { + // Host is a standard URL + if url, err := url.Parse(host); err == nil && len(url.Host) > 0 { + return url.Host + } + + // Host is a MySQL DSN + if config, err := mysql.ParseDSN(host); err == nil { + return config.Addr + } + + // TODO: Add support for PostgreSQL connection strings and other formats + + return "(redacted)" +} diff --git a/x-pack/metricbeat/module/sql/query/query.go b/x-pack/metricbeat/module/sql/query/query.go index 884df1b9df9..3322144d993 100644 --- a/x-pack/metricbeat/module/sql/query/query.go +++ b/x-pack/metricbeat/module/sql/query/query.go @@ -10,13 +10,12 @@ import ( "strings" "time" + "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/common/cfgwarn" "github.com/elastic/beats/metricbeat/mb" - - "github.com/jmoiron/sqlx" ) // init registers the MetricSet with the central registry as soon as the program @@ -24,7 +23,9 @@ import ( // the MetricSet for each host defined in the module's configuration. After the // MetricSet has been created then Fetch will begin to be called periodically. func init() { - mb.Registry.MustAddMetricSet("sql", "query", New) + mb.Registry.MustAddMetricSet("sql", "query", New, + mb.WithHostParser(ParseDSN), + ) } // MetricSet holds any configuration or state information. It must implement @@ -33,9 +34,8 @@ func init() { // interface methods except for Fetch. type MetricSet struct { mb.BaseMetricSet - Driver string - Datasource string - Query string + Driver string + Query string } // New creates a new instance of the MetricSet. New is responsible for unpacking @@ -44,9 +44,8 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { cfgwarn.Beta("The sql query metricset is beta.") config := struct { - Driver string `config:"driver"` - Datasource string `config:"datasource"` - Query string `config:"sql_query"` + Driver string `config:"driver"` + Query string `config:"sql_query"` }{} if err := base.Module().UnpackConfig(&config); err != nil { @@ -56,7 +55,6 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return &MetricSet{ BaseMetricSet: base, Driver: config.Driver, - Datasource: config.Datasource, Query: config.Query, }, nil } @@ -65,7 +63,7 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). func (m *MetricSet) Fetch(report mb.ReporterV2) error { - db, err := sqlx.Open(m.Driver, m.Datasource) + db, err := sqlx.Open(m.Driver, m.HostData().URI) if err != nil { return errors.Wrap(err, "error opening connection") } diff --git a/x-pack/metricbeat/module/sql/query/query_integration_test.go b/x-pack/metricbeat/module/sql/query/query_integration_test.go new file mode 100644 index 00000000000..d7e04f23c40 --- /dev/null +++ b/x-pack/metricbeat/module/sql/query/query_integration_test.go @@ -0,0 +1,126 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build integration + +package query + +import ( + "fmt" + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + // Drivers + _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" + + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/tests/compose" + "github.com/elastic/beats/metricbeat/mb" + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + "github.com/elastic/beats/metricbeat/module/mysql" + "github.com/elastic/beats/metricbeat/module/postgresql" +) + +type testFetchConfig struct { + Driver string + Query string + Host string + + Assertion func(t *testing.T, event beat.Event) +} + +func TestMySQL(t *testing.T) { + service := compose.EnsureUp(t, "mysql") + config := testFetchConfig{ + Driver: "mysql", + Query: "select table_schema, table_name, engine, table_rows from information_schema.tables where table_rows > 0;", + Host: mysql.GetMySQLEnvDSN(service.Host()), + Assertion: assertFieldNotContains("service.address", ":test@"), + } + + t.Run("fetch", func(t *testing.T) { + testFetch(t, config) + }) + + t.Run("data", func(t *testing.T) { + testData(t, config, "") + }) +} + +func TestPostgreSQL(t *testing.T) { + service := compose.EnsureUp(t, "postgresql") + host, port, err := net.SplitHostPort(service.Host()) + require.NoError(t, err) + + user := postgresql.GetEnvUsername() + password := postgresql.GetEnvPassword() + + config := testFetchConfig{ + Driver: "postgres", + Query: "select * from pg_stat_database", + Host: fmt.Sprintf("user=%s password=%s sslmode=disable host=%s port=%s", user, password, host, port), + Assertion: assertFieldNotContains("service.address", "password="+password), + } + + t.Run("fetch", func(t *testing.T) { + testFetch(t, config) + }) + + config = testFetchConfig{ + Driver: "postgres", + Query: "select * from pg_stat_database", + Host: fmt.Sprintf("postgres://%s:%s@%s:%s/?sslmode=disable", user, password, host, port), + Assertion: assertFieldNotContains("service.address", ":"+password+"@"), + } + + t.Run("fetch with URL", func(t *testing.T) { + testFetch(t, config) + }) + + t.Run("data", func(t *testing.T) { + testData(t, config, "./_meta/data_postgres.json") + }) +} + +func testFetch(t *testing.T, cfg testFetchConfig) { + m := mbtest.NewFetcher(t, getConfig(cfg)) + events, errs := m.FetchEvents() + require.Empty(t, errs) + require.NotEmpty(t, events) + t.Logf("%s/%s event: %+v", m.Module().Name(), m.Name(), events[0]) + + if cfg.Assertion != nil { + for _, event := range events { + cfg.Assertion(t, m.StandardizeEvent(event, mb.AddMetricSetInfo)) + } + } +} + +func testData(t *testing.T, cfg testFetchConfig, postfix string) { + m := mbtest.NewFetcher(t, getConfig(cfg)) + m.WriteEvents(t, postfix) +} + +func getConfig(cfg testFetchConfig) map[string]interface{} { + return map[string]interface{}{ + "module": "sql", + "metricsets": []string{"query"}, + "hosts": []string{cfg.Host}, + "driver": cfg.Driver, + "sql_query": cfg.Query, + } +} + +func assertFieldNotContains(field, s string) func(t *testing.T, event beat.Event) { + return func(t *testing.T, event beat.Event) { + value, err := event.GetValue(field) + assert.NoError(t, err) + require.NotEmpty(t, value.(string)) + require.NotContains(t, value.(string), s) + } +} diff --git a/x-pack/metricbeat/modules.d/sql.yml.disabled b/x-pack/metricbeat/modules.d/sql.yml.disabled index ab839d64f49..31f15547123 100644 --- a/x-pack/metricbeat/modules.d/sql.yml.disabled +++ b/x-pack/metricbeat/modules.d/sql.yml.disabled @@ -5,9 +5,8 @@ metricsets: - query period: 10s - hosts: ["localhost"] + hosts: ["user=myuser password=mypassword dbname=mydb sslmode=disable"] driver: "postgres" - datasource: "user=myuser password=mypassword dbname=mydb sslmode=disable" sql_query: "select now()" From 935e58fbd8f4c2e64789330554ea9add57e8b1b7 Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Tue, 21 Jan 2020 06:54:39 -0800 Subject: [PATCH 28/37] [metricbeat] add service metricset to reference documentation (#15643) * add service metricset to ref docs * update xpack docs --- metricbeat/docs/modules/system.asciidoc | 4 ++++ metricbeat/metricbeat.reference.yml | 4 ++++ metricbeat/module/system/_meta/config.reference.yml | 4 ++++ x-pack/metricbeat/metricbeat.reference.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc index 5a9da32636d..a832eb5f854 100644 --- a/metricbeat/docs/modules/system.asciidoc +++ b/metricbeat/docs/modules/system.asciidoc @@ -172,6 +172,7 @@ metricbeat.modules: #- fsstat # File system summary metrics #- raid # Raid #- socket # Sockets and connection info (linux only) + #- service # systemd service information enabled: true period: 10s processes: ['.*'] @@ -229,6 +230,9 @@ metricbeat.modules: # Diskio configurations #diskio.include_devices: [] + + # Filter systemd services by status or sub-status + #service.state_filter: [] ---- [float] diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 4b502f44d07..6adc5c22956 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -73,6 +73,7 @@ metricbeat.modules: #- fsstat # File system summary metrics #- raid # Raid #- socket # Sockets and connection info (linux only) + #- service # systemd service information enabled: true period: 10s processes: ['.*'] @@ -131,6 +132,9 @@ metricbeat.modules: # Diskio configurations #diskio.include_devices: [] + # Filter systemd services by status or sub-status + #service.state_filter: [] + #------------------------------ Aerospike Module ------------------------------ - module: aerospike metricsets: ["namespace"] diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml index c22fc6ac279..a30b782ac63 100644 --- a/metricbeat/module/system/_meta/config.reference.yml +++ b/metricbeat/module/system/_meta/config.reference.yml @@ -14,6 +14,7 @@ #- fsstat # File system summary metrics #- raid # Raid #- socket # Sockets and connection info (linux only) + #- service # systemd service information enabled: true period: 10s processes: ['.*'] @@ -71,3 +72,6 @@ # Diskio configurations #diskio.include_devices: [] + + # Filter systemd services by status or sub-status + #service.state_filter: [] diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 60e79272f77..b5939aecede 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -73,6 +73,7 @@ metricbeat.modules: #- fsstat # File system summary metrics #- raid # Raid #- socket # Sockets and connection info (linux only) + #- service # systemd service information enabled: true period: 10s processes: ['.*'] @@ -131,6 +132,9 @@ metricbeat.modules: # Diskio configurations #diskio.include_devices: [] + # Filter systemd services by status or sub-status + #service.state_filter: [] + #------------------------------- Activemq Module ------------------------------- - module: activemq metricsets: ['broker', 'queue', 'topic'] From c7e137c4f72a4e0e57ff8841dfa35a8a4b6b9994 Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Tue, 21 Jan 2020 08:57:52 -0800 Subject: [PATCH 29/37] [metricbeat] Add divide by zero check to docker/diskio (#15649) * add NaN check to docker/diskio * return 0 --- metricbeat/module/docker/diskio/helper.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/metricbeat/module/docker/diskio/helper.go b/metricbeat/module/docker/diskio/helper.go index 17895944e28..e75c21b886f 100644 --- a/metricbeat/module/docker/diskio/helper.go +++ b/metricbeat/module/docker/diskio/helper.go @@ -174,5 +174,11 @@ func calculatePerSecond(duration time.Duration, old uint64, new uint64) float64 if value < 0 { value = 0 } - return value / duration.Seconds() + + timeSec := duration.Seconds() + if timeSec == 0 { + return 0 + } + + return value / timeSec } From 7b2f8731a5475c0d91923ba7eebfdb6dc39595a2 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Tue, 21 Jan 2020 18:13:45 +0100 Subject: [PATCH 30/37] Change joda style pattern to java style (#15695) since 7.0 elasticsearch is using java.time style patterns. YYYY becomes yyyy --- libbeat/docs/shared-ilm.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbeat/docs/shared-ilm.asciidoc b/libbeat/docs/shared-ilm.asciidoc index 12069381c2c..4b96dcdbf27 100644 --- a/libbeat/docs/shared-ilm.asciidoc +++ b/libbeat/docs/shared-ilm.asciidoc @@ -66,7 +66,7 @@ Date math is supported in this setting. For example: [source,yaml] ---- -setup.ilm.pattern: "{now/M{YYYY.MM}}-000001" +setup.ilm.pattern: "{now/M{yyyy.MM}}-000001" ---- For more information, see From 7960c77e92844df1b060a288969bc86ac4268003 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 21 Jan 2020 11:42:54 -0800 Subject: [PATCH 31/37] [DOCS] Add missing config options to shared file (#15136) * [DOCS] Add missing config options to shared file * Add fixes from review * Run mage fmt update to fix build error --- auditbeat/docs/auditbeat-options.asciidoc | 56 +++++++++++++++++++ auditbeat/docs/modules/auditd.asciidoc | 16 +++++- .../docs/modules/file_integrity.asciidoc | 12 +++- auditbeat/module/auditd/_meta/docs.asciidoc | 11 +++- .../module/file_integrity/_meta/docs.asciidoc | 7 ++- auditbeat/scripts/docs_collector.py | 6 ++ x-pack/auditbeat/docs/modules/system.asciidoc | 14 +++-- .../module/system/_meta/docs.asciidoc | 9 ++- 8 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 auditbeat/docs/auditbeat-options.asciidoc diff --git a/auditbeat/docs/auditbeat-options.asciidoc b/auditbeat/docs/auditbeat-options.asciidoc new file mode 100644 index 00000000000..8233f79cee1 --- /dev/null +++ b/auditbeat/docs/auditbeat-options.asciidoc @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +//// This content is shared by all Auditbeat modules. Make sure you keep the +//// descriptions generic enough to work for all modules. To include +//// this file, use: +//// +//// include::{docdir}/auditbeat-options.asciidoc[] +//// +////////////////////////////////////////////////////////////////////////// + +[id="module-standard-options-{modulename}"] +[float] +==== Standard configuration options + +You can specify the following options for any {beatname_uc} module. + +*`module`*:: The name of the module to run. + +ifeval::["{modulename}"=="system"] +*`datasets`*:: A list of datasets to execute. +endif::[] + +*`enabled`*:: A Boolean value that specifies whether the module is enabled. + +ifeval::["{modulename}"=="system"] +*`period`*:: The frequency at which the datasets check for changes. If a system +is not reachable, {beatname_uc} returns an error for each period. This setting +is required. For most datasets, especially `process` and `socket`, a shorter +period is recommended. +endif::[] + +*`fields`*:: A dictionary of fields that will be sent with the dataset event. This setting +is optional. + +*`tags`*:: A list of tags that will be sent with the dataset event. This setting is +optional. + +*`processors`*:: A list of processors to apply to the data generated by the dataset. ++ +See <> for information about specifying +processors in your config. + +*`index`*:: If present, this formatted string overrides the index for events from this +module (for elasticsearch outputs), or sets the `raw_index` field of the event's +metadata (for other outputs). This string can only refer to the agent name and +version and the event timestamp; for access to dynamic fields, use +`output.elasticsearch.index` or a processor. ++ +Example value: `"%{[agent.name]}-myindex-%{+yyyy.MM.dd}"` might +expand to +"{beatname_lc}-myindex-2019.12.13"+. + +*`keep_null`*:: If this option is set to true, fields with `null` values will be published in +the output document. By default, `keep_null` is set to `false`. + +*`service.name`*:: A name given by the user to the service the data is collected from. It can be +used for example to identify information collected from nodes of different +clusters with the same `service.type`. diff --git a/auditbeat/docs/modules/auditd.asciidoc b/auditbeat/docs/modules/auditd.asciidoc index c419c66db39..e913160d9cb 100644 --- a/auditbeat/docs/modules/auditd.asciidoc +++ b/auditbeat/docs/modules/auditd.asciidoc @@ -2,6 +2,8 @@ This file is generated! See scripts/docs_collector.py //// +:modulename: auditd + [id="{beatname_lc}-module-auditd"] == Auditd Module @@ -135,6 +137,10 @@ following example shows all configuration options with their default values. backpressure_strategy: auto ---- +This module also supports the +<> +described later. + *`socket_type`*:: This optional setting controls the type of socket that {beatname_uc} uses to receive events from the kernel. The two options are `unicast` and `multicast`. @@ -189,7 +195,8 @@ setting is primarily used for development and debugging purposes. installed to the kernel. There should be one rule per line. Comments can be embedded in the string using `#` as a prefix. The format for rules is the same used by the Linux `auditctl` utility. {beatname_uc} supports adding file watches -(`-w`) and syscall rules (`-a` or `-A`). +(`-w`) and syscall rules (`-a` or `-A`). For more information, see +<>. *`audit_rule_files`*:: A list of files to load audit rules from. This files are loaded after the rules declared in `audit_rules` are loaded. Wildcards are @@ -218,10 +225,10 @@ time. - `none`: No backpressure mitigation measures are enabled. -- -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] [float] +[[audit-rules]] === Audit rules The audit rules are where you configure the activities that are audited. These @@ -304,3 +311,6 @@ auditbeat.modules: ---- + +:modulename!: + diff --git a/auditbeat/docs/modules/file_integrity.asciidoc b/auditbeat/docs/modules/file_integrity.asciidoc index c420818cb39..42f0378de64 100644 --- a/auditbeat/docs/modules/file_integrity.asciidoc +++ b/auditbeat/docs/modules/file_integrity.asciidoc @@ -2,6 +2,8 @@ This file is generated! See scripts/docs_collector.py //// +:modulename: file_integrity + [id="{beatname_lc}-module-file_integrity"] == File Integrity Module @@ -66,6 +68,10 @@ Linux. recursive: false ---- +This module also supports the +<> +described later. + *`paths`*:: A list of paths (directories or files) to watch. Globs are not supported. The specified paths should exist when the metricset is started. @@ -122,8 +128,7 @@ of this directories are watched. If `recursive` is set to `true`, the `file_integrity` module will watch for changes on this directories and all their subdirectories. -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] [float] @@ -146,3 +151,6 @@ auditbeat.modules: ---- + +:modulename!: + diff --git a/auditbeat/module/auditd/_meta/docs.asciidoc b/auditbeat/module/auditd/_meta/docs.asciidoc index 45e3e3de934..4585b7179ff 100644 --- a/auditbeat/module/auditd/_meta/docs.asciidoc +++ b/auditbeat/module/auditd/_meta/docs.asciidoc @@ -130,6 +130,10 @@ following example shows all configuration options with their default values. backpressure_strategy: auto ---- +This module also supports the +<> +described later. + *`socket_type`*:: This optional setting controls the type of socket that {beatname_uc} uses to receive events from the kernel. The two options are `unicast` and `multicast`. @@ -184,7 +188,8 @@ setting is primarily used for development and debugging purposes. installed to the kernel. There should be one rule per line. Comments can be embedded in the string using `#` as a prefix. The format for rules is the same used by the Linux `auditctl` utility. {beatname_uc} supports adding file watches -(`-w`) and syscall rules (`-a` or `-A`). +(`-w`) and syscall rules (`-a` or `-A`). For more information, see +<>. *`audit_rule_files`*:: A list of files to load audit rules from. This files are loaded after the rules declared in `audit_rules` are loaded. Wildcards are @@ -213,10 +218,10 @@ time. - `none`: No backpressure mitigation measures are enabled. -- -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] [float] +[[audit-rules]] === Audit rules The audit rules are where you configure the activities that are audited. These diff --git a/auditbeat/module/file_integrity/_meta/docs.asciidoc b/auditbeat/module/file_integrity/_meta/docs.asciidoc index 9282b289589..372e9fc3b47 100644 --- a/auditbeat/module/file_integrity/_meta/docs.asciidoc +++ b/auditbeat/module/file_integrity/_meta/docs.asciidoc @@ -61,6 +61,10 @@ Linux. recursive: false ---- +This module also supports the +<> +described later. + *`paths`*:: A list of paths (directories or files) to watch. Globs are not supported. The specified paths should exist when the metricset is started. @@ -117,5 +121,4 @@ of this directories are watched. If `recursive` is set to `true`, the `file_integrity` module will watch for changes on this directories and all their subdirectories. -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] diff --git a/auditbeat/scripts/docs_collector.py b/auditbeat/scripts/docs_collector.py index 8c5d532ae8e..5e897bde3ed 100644 --- a/auditbeat/scripts/docs_collector.py +++ b/auditbeat/scripts/docs_collector.py @@ -44,6 +44,9 @@ def collect(base_paths): os.mkdir(os.path.join(module_docs_path(module_dir), "modules", module)) module_file = generated_note + + module_file += ":modulename: " + module + "\n\n" + module_file += "[id=\"{beatname_lc}-module-" + module + "\"]\n" with open(module_doc) as f: @@ -84,6 +87,9 @@ def collect(base_paths): module_file += "----\n\n" + # Close modulename variable + module_file += "\n:modulename!:\n\n" + module_links = "" module_includes = "" diff --git a/x-pack/auditbeat/docs/modules/system.asciidoc b/x-pack/auditbeat/docs/modules/system.asciidoc index dc80845aa24..361af353c43 100644 --- a/x-pack/auditbeat/docs/modules/system.asciidoc +++ b/x-pack/auditbeat/docs/modules/system.asciidoc @@ -2,9 +2,10 @@ This file is generated! See scripts/docs_collector.py //// +:modulename: system + [id="{beatname_lc}-module-system"] [role="xpack"] - == System Module beta[] @@ -72,8 +73,9 @@ sample suggested configuration. user.detect_password_changes: true ---- -*`period`*:: The frequency at which the datasets check for changes. For most -datasets - esp. `process` and `socket` - a shorter period is recommended. +This module also supports the +<> +described later. *`state.period`*:: The frequency at which the datasets send full state information. This option can be overridden per dataset using `{dataset}.state.period`. @@ -85,8 +87,7 @@ the `beat.db` file to detect changes between Auditbeat restarts. The `beat.db` f should be readable only by the root user and be treated similar to the shadow file itself. -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] [float] === Suggested configuration @@ -151,6 +152,9 @@ auditbeat.modules: login.btmp_file_pattern: /var/log/btmp* ---- + +:modulename!: + [float] === Datasets diff --git a/x-pack/auditbeat/module/system/_meta/docs.asciidoc b/x-pack/auditbeat/module/system/_meta/docs.asciidoc index 30d97edb478..2e91d2db116 100644 --- a/x-pack/auditbeat/module/system/_meta/docs.asciidoc +++ b/x-pack/auditbeat/module/system/_meta/docs.asciidoc @@ -1,5 +1,4 @@ [role="xpack"] - == System Module beta[] @@ -67,8 +66,9 @@ sample suggested configuration. user.detect_password_changes: true ---- -*`period`*:: The frequency at which the datasets check for changes. For most -datasets - esp. `process` and `socket` - a shorter period is recommended. +This module also supports the +<> +described later. *`state.period`*:: The frequency at which the datasets send full state information. This option can be overridden per dataset using `{dataset}.state.period`. @@ -80,8 +80,7 @@ the `beat.db` file to detect changes between Auditbeat restarts. The `beat.db` f should be readable only by the root user and be treated similar to the shadow file itself. -*`keep_null`*:: If this option is set to true, fields with `null` values will be -published in the output document. By default, `keep_null` is set to `false`. +include::{docdir}/auditbeat-options.asciidoc[] [float] === Suggested configuration From 4a408e5a249c053a16401ae214da3d20b9ea6bbe Mon Sep 17 00:00:00 2001 From: "Amanda H. L. de Andrade Katz" Date: Tue, 21 Jan 2020 18:39:18 -0300 Subject: [PATCH 32/37] [Heartbeat] Support for multiple status codes #13595 (#15587) Allow for multiple status codes in config. Fixes https://github.com/elastic/beats/issues/13595 --- heartbeat/docs/heartbeat-options.asciidoc | 22 ++++---- heartbeat/monitors/active/http/check.go | 10 ++-- heartbeat/monitors/active/http/check_test.go | 59 ++++++++++++++++++++ heartbeat/monitors/active/http/config.go | 3 +- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/heartbeat/docs/heartbeat-options.asciidoc b/heartbeat/docs/heartbeat-options.asciidoc index f72e631781d..6becc27a7a9 100644 --- a/heartbeat/docs/heartbeat-options.asciidoc +++ b/heartbeat/docs/heartbeat-options.asciidoc @@ -34,7 +34,7 @@ heartbeat.monitors: - type: http schedule: '@every 5s' hosts: ["http://localhost:80/service/status"] - check.response.status: 200 + check.response.status: [200] heartbeat.scheduler: limit: 10 ---------------------------------------------------------------------- @@ -69,7 +69,7 @@ monitor definitions only, e.g. what is normally under the `heartbeat.monitors` s - type: http schedule: '@every 5s' hosts: ["http://localhost:80/service/status"] - check.response.status: 200 + check.response.status: [200] ---------------------------------------------------------------------- [float] @@ -429,7 +429,7 @@ The username for authenticating with the server. The credentials are passed with the request. This setting is optional. You need to specify credentials when your `check.response` settings require it. -For example, you can check for a 403 response (`check.response.status: 403`) +For example, you can check for a 403 response (`check.response.status: [403]`) without setting credentials. [float] @@ -489,7 +489,7 @@ Example configuration: schedule: '@every 5s' hosts: ["http://myhost:80"] check.request.method: HEAD - check.response.status: 200 + check.response.status: [200] ------------------------------------------------------------------------------- @@ -517,7 +517,7 @@ to the endpoint `/demo/add` # urlencode the body: body: "name=first&email=someemail%40someemailprovider.com" check.response: - status: 200 + status: [200] body: - Saved - saved @@ -525,14 +525,14 @@ to the endpoint `/demo/add` Under `check.response`, specify these options: -*`status`*:: The expected status code. 4xx and 5xx codes are considered `down` by default. Other codes are considered `up`. +*`status`*:: A list of expected status codes. 4xx and 5xx codes are considered `down` by default. Other codes are considered `up`. *`headers`*:: The required response headers. *`body`*:: A list of regular expressions to match the the body output. Only a single expression needs to match. HTTP response bodies of up to 100MiB are supported. Example configuration: This monitor examines the -response body for the strings `saved` or `Saved` +response body for the strings `saved` or `Saved` and expects 200 or 201 status codes [source,yaml] ------------------------------------------------------------------------------- @@ -546,7 +546,7 @@ response body for the strings `saved` or `Saved` # urlencode the body: body: "name=first&email=someemail%40someemailprovider.com" check.response: - status: 200 + status: [200, 201] body: - Saved - saved @@ -568,7 +568,7 @@ contains JSON: headers: 'X-API-Key': '12345-mykey-67890' check.response: - status: 200 + status: [200] json: - description: check status condition: @@ -589,7 +589,7 @@ patterns: headers: 'X-API-Key': '12345-mykey-67890' check.response: - status: 200 + status: [200] body: - hello - world @@ -608,7 +608,7 @@ regex: headers: 'X-API-Key': '12345-mykey-67890' check.response: - status: 200 + status: [200] body: '(?s)first.*second.*third' ------------------------------------------------------------------------------- diff --git a/heartbeat/monitors/active/http/check.go b/heartbeat/monitors/active/http/check.go index 8976cd56304..4ff5ab4a470 100644 --- a/heartbeat/monitors/active/http/check.go +++ b/heartbeat/monitors/active/http/check.go @@ -77,7 +77,7 @@ func makeValidateResponse(config *responseParameters) (multiValidator, error) { var respValidators []respValidator var bodyValidators []bodyValidator - if config.Status > 0 { + if len(config.Status) > 0 { respValidators = append(respValidators, checkStatus(config.Status)) } else { respValidators = append(respValidators, checkStatusOK) @@ -102,10 +102,12 @@ func makeValidateResponse(config *responseParameters) (multiValidator, error) { return multiValidator{respValidators, bodyValidators}, nil } -func checkStatus(status uint16) respValidator { +func checkStatus(status []uint16) respValidator { return func(r *http.Response) error { - if r.StatusCode == int(status) { - return nil + for _, v := range status { + if r.StatusCode == int(v) { + return nil + } } return fmt.Errorf("received status code %v expecting %v", r.StatusCode, status) } diff --git a/heartbeat/monitors/active/http/check_test.go b/heartbeat/monitors/active/http/check_test.go index a705ca34454..3c3e42caa06 100644 --- a/heartbeat/monitors/active/http/check_test.go +++ b/heartbeat/monitors/active/http/check_test.go @@ -268,3 +268,62 @@ func TestCheckJsonWithIntegerComparison(t *testing.T) { } } + +func TestCheckStatus(t *testing.T) { + + var matchTests = []struct { + description string + status []uint16 + statusRec int + result bool + }{ + { + "not match multiple values", + []uint16{200, 301, 302}, + 500, + false, + }, + { + "match multiple values", + []uint16{200, 301, 302}, + 200, + true, + }, + { + "not match single value", + []uint16{200}, + 201, + false, + }, + { + "match single value", + []uint16{200}, + 200, + true, + }, + } + + for _, test := range matchTests { + t.Run(test.description, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(test.statusRec) + })) + defer ts.Close() + + res, err := http.Get(ts.URL) + if err != nil { + log.Fatal(err) + } + + check := checkStatus(test.status)(res) + + if result := (check == nil); result != test.result { + if test.result { + t.Fatalf("Expected at least one of status: %d to match status: %d", test.status, test.statusRec) + } else { + t.Fatalf("Did not expect status: %d to match status: %d", test.status, test.statusRec) + } + } + }) + } +} diff --git a/heartbeat/monitors/active/http/config.go b/heartbeat/monitors/active/http/config.go index 033d8fab628..e195f4209e3 100644 --- a/heartbeat/monitors/active/http/config.go +++ b/heartbeat/monitors/active/http/config.go @@ -74,7 +74,7 @@ type requestParameters struct { type responseParameters struct { // expected HTTP response configuration - Status uint16 `config:"status" verify:"min=0, max=699"` + Status []uint16 `config:"status"` RecvHeaders map[string]string `config:"headers"` RecvBody []match.Matcher `config:"body"` RecvJSON []*jsonResponseCheck `config:"json"` @@ -105,7 +105,6 @@ var defaultConfig = Config{ SendBody: "", }, Response: responseParameters{ - Status: 0, RecvHeaders: nil, RecvBody: []match.Matcher{}, RecvJSON: nil, From 121ece3ebab45556a8b6a3c7a167cc199dbd874a Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Tue, 21 Jan 2020 22:38:31 -0600 Subject: [PATCH 33/37] Add missing changelog entry for #15587 (#15721) --- CHANGELOG.next.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 252e214e044..b59f02281ab 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -78,6 +78,8 @@ TLS or Beats that accept connections over TLS and validate client certificates. *Heartbeat* +- Allow a list of status codes for HTTP checks. {pull}15587[15587] + *Journalbeat* From 6e2ca410e90cdf85fcd1122f1849543b5d0b7b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Wed, 22 Jan 2020 14:07:31 +0100 Subject: [PATCH 34/37] Update github.com/godror/godror to v0.10.4 (#15737) ## What does this PR do? This PR updates the dependency `github.com/godror/godror` to v0.10.4. ## Why is it important? Packaging of Metricbeat fails due to the issue in the `godror` version we are currently using. See more about the problem: https://github.com/godror/godror/issues/8 --- NOTICE.txt | 4 +- vendor/github.com/godror/godror/CHANGELOG.md | 305 +--------- vendor/github.com/godror/godror/conn.go | 115 ++-- .../godror/godror/contrib/free.db/reset.sql | 15 + vendor/github.com/godror/godror/data.go | 82 ++- vendor/github.com/godror/godror/drv.go | 557 +++++++----------- vendor/github.com/godror/godror/go.mod | 2 +- vendor/github.com/godror/godror/obj.go | 154 +++-- vendor/github.com/godror/godror/orahlp.go | 199 +++++++ vendor/github.com/godror/godror/queue.go | 24 +- vendor/github.com/godror/godror/stmt.go | 23 +- vendor/github.com/godror/godror/subscr.go | 28 +- vendor/github.com/godror/godror/version.go | 4 +- vendor/vendor.json | 10 +- 14 files changed, 696 insertions(+), 826 deletions(-) create mode 100644 vendor/github.com/godror/godror/contrib/free.db/reset.sql diff --git a/NOTICE.txt b/NOTICE.txt index 08a37d10a5b..5e3a26acd96 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2101,8 +2101,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------- Dependency: github.com/godror/godror -Version: v0.9.0 -Revision: 446a29355d2967f04604e8e015a3343917860adf +Version: v0.10.4 +Revision: 0123d49bd73e1bed106ac8b6af67f943fbbf06e2 License type (autodetected): Apache-2.0 ./vendor/github.com/godror/godror/LICENSE.md: -------------------------------------------------------------------- diff --git a/vendor/github.com/godror/godror/CHANGELOG.md b/vendor/github.com/godror/godror/CHANGELOG.md index 0541bbe23b5..72e335fffd1 100644 --- a/vendor/github.com/godror/godror/CHANGELOG.md +++ b/vendor/github.com/godror/godror/CHANGELOG.md @@ -5,307 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] -### Added - -## [2.24.0] -### Changed -- License: SPDX-License-Identifier: UPL-1.0 OR APL-2.0 - -## [2.23.5] -### Changed -- ODPI-C v3.3.0 - -## [2.23.2] -### Changed -- Close statement (and dpiStmt) on Break/bad conn. - -## [2.23.0] -### Added -- Conn.Timezone() returns the connection's timezone -- allow setting the timezone with Timezone ConnectionParam. -- Support to change password with NewPassword ConnectionParams. - -### Changed -- set DefaultEnqOptions and DefaultDeqOptions in NewQueue. -- make ConnectionParams.WaitTimeout, SessionMaxLifeTime, SessionTimeout be time.Duration. - -## [2.21.3] - 2019-10-03 -### Added -- Export Queue.PayloadObjectType -- Queue.SetEnqOptions, Queue.SetDeqOptions, Queue.SetDeqCorrelation - -## [2.21.1] - 2019-10-02 -### Changed -- Really close the connection if it's bad. For #194. -- ODPI-C v3.2.2 -- de-embed conn from Queue. - -## [2.20.1] - 2019-09-05 -### Added -- AsOraErr function - -### Changed -- Object.reset set attributes to null. -- Use golang.org/x/xerrors instead of github.com/pkg/errors. -- ObjectType.Close became unexported. - -## [2.20.0] - 2019-09-04 -### Added -- ObjectType cache in connection. -- Queue support with Objects. - -### Changed -- ObjectType.Close became unexported. -- Change Object Set/Get -- use golang.org/x/xerrors instead of github.com/pkg/errors. - -## [2.19.0] - 2019-08-15 -### Changed -- Require Context for getConn and thus in ClientVersion, ServerVersion, GetObjectType, DriverConn functions. - -## [2.18.5] - 2019-08-14 -### Changed -- Remove log.Println left in... - -## [2.18.4] - 2019-08-14 -### Changed -- Timezone detection: DBTIMEZONE is plain wrong, parse from SYSTIMESTAMP. - -## [2.18.3] - 2019-08-13 -### Changed -- GetObjectType uppercases the name by default. -- Upgrade to ODPI-C v3.2.1 - -## [2.18.2] - 2019-07-23 -### Changed -- Force copying of bytes (garbage appears Out with RAW). - -## [2.18.0] - 2019-07-16 -### Added -- Setable pool session timeouts. - -## [2.16.4] - 2019-06-26 -### Changed -- Fix bool input (#166). -- Allow region name from DBTIMEZONE, not just offset. - -## [2.16.2] - 2019-05-27 -### Changed -- Make Query AUTOCOMMIT like Exec - it's needed to release Rows for "FOR UPDATE". - -## [2.16.1] - 2019-05-27 -### Added -- Data.SetNull -- Expose dpiConn_newVar - -## [2.16.0] - 2019-05-17 -### Changed -- NumberAsString new option for #159. - -## [2.15.3] - 2019-05-16 -### Changed -- ParseConnString: reorder logic to allow 'sys/... as sysdba' (without @) - -## [2.15.3] - 2019-05-16 -### Changed -- ParseConnString: reorder logic to allow 'sys/... as sysdba' (without @) - -## [2.15.2] - 2019-05-12 -### Changed -- Use time.Local if it equals with DBTIMEZONE (use DST of time.Local). - -## [2.15.1] - 2019-05-09 -### Changed -- Fix heterogenous pools (broken with 2.14.1) - -## [2.15.0] - 2019-05-09 -### Added -- Implement dataGetObject to access custom user types -- Add ObjectScanner and ObjectWriter interfaces to provide a way to load/update values from/to a struct and database object type. - -## [2.14.2] - 2019-05-07 -### Added -- Cache timezone with the pool and in the conn struct, too. - -## [2.14.1] - 2019-05-07 -- Try to get the serve DBTIMEZONE, if fails use time.Local - -## [2.14.0] - 2019-05-07 -### Changed -- Default to time.Local in DATE types when sending to DB, too. - -## [2.13.2] - 2019-05-07 -### Changed -- Default to time.Local timezone for DATE types. - -## [2.13.1] - 2019-05-06 -### Changed -- Fix 'INTERVAL DAY TO SECOND' NULL case. - -## [2.12.8] - 2019-05-02 -### Added -- NewConnector, NewSessionIniter - -## [2.12.7] - 2019-04-24 -### Changed -- ODPI-C v3.1.4 (rowcount for PL/SQL block) - -## [2.12.6] - 2019-04-12 -### Added -- Allow calling with LOB got from DB, and don't copy it - see #135. - -## [2.12.5] - 2019-04-03 -### Added -- Make it compile under Go 1.9. - -## [2.12.4] - 2019-03-13 -## Added -- Upgrade to ODPI-C v3.1.3 - -## [2.12.3] - 2019-02-20 -### Changed -- Use ODPI-C v3.1.1 -### Added -- Make godror.drv implement driver.DriverContext with OpenConnector. - -## [2.12.2] - 2019-02-15 -### Changed -- Use ODPI-C v3.1.1 - -## [2.12.0] - 2019-01-21 -### Changed -- Use ODPI-C v3.1.0 - -## [2.11.2] - 2019-01-15 -### Changed -- ISOLATION LEVEL READ COMMITTED (typo) fix. - -## [2.11.1] - 2018-12-13 -### Changed -- Use C.dpiAuthMode, C.dpiStartupMode, C.dpiShutdownMode instead of C.uint - for #129. - -## [2.11.0] - 2018-12-13 -### Changed -- Do not set empty SID from ORACLE_SID/TWO_TASK environment variables, leave it to ODPI. - -### Added -- Allow PRELIM authentication to allow Startup and Shutdown. - -## [2.10.1] - 2018-11-23 -### Changed -- Don't call SET TRANSACTION if not really needed in BeginTx - if the isolation level hasn't changed. - -## [2.10.0] - 2018-11-18 -### Added -- Implement RowsNextResultSet to return implicit result sets set by DBMS_SQL.return. -- Allow using heterogeneous pools with user set with ContextWithUserPassw. - -## [2.9.1] - 2018-11-14 -### Added -- allow RETURNING with empty result set (such as UPDATE). -- Allow SELECT to return object types. - -### Changed -- fixed Number.MarshalJSON (see #112)' - -## [2.9.0] - 2018-10-12 -### Changed -- The default type for BLOB is []byte and for CLOB is a string - no need for ClobAsString() option. - -## [2.8.2] - 2018-10-01 -### Changed -- Fix the driver.Valuer handling, make it the last resort - -## [2.8.1] - 2018-09-27 -### Added -- CallTimeout option to set a per-statement OCI_ATTR_CALL_TIMEOUT. -- Allow login with " AS SYSASM", as requested in #100. - -### Changed -- Hash the password ("SECRET-sasdas=") in ConnectionParams.String(). - -## [2.8.0] - 2018-09-21 -### Added -- WrapRows wraps a driver.Rows (such as a returned cursor from a stored procedure) as an sql.Rows for easier handling. - -### Changed -- Do not allow events by default, make them opt-in with EnableEvents connection parameter - see #98. - -## [2.7.1] - 2018-09-17 -### Changed -- Inherit parent statement's Options for statements returned as sql.Out. - -## [2.7.0] - 2018-09-14 -### Changed -- Update ODPI-C to v3.0.0. - -## [2.6.0] - 2018-08-31 -### Changed -- convert named types to their underlying scalar values - see #96, using MagicTypeConversion() option. - -## [2.5.11] - 2018-08-30 -### Added -- Allow driver.Valuer as Query argument - see #94. - -## [2.5.10] - 2018-08-26 -### Changed -- use sergeymakinen/oracle-instant-client:12.2 docker for tests -- added ODPI-C and other licenses into LICENSE.md -- fill varInfo.ObjectType for better Object support - -## [2.5.9] - 2018-08-03 -### Added -- add CHANGELOG -- check that `len(dest) == len(rows.columns)` in `rows.Next(dest)` - -### Changed -- after a Break, don't release a stmt, that may fail with SIGSEGV - see #84. - -## [2.5.8] - 2018-07-27 -### Changed -- noConnectionPooling option became standaloneConnection - -## [2.5.7] - 2018-07-25 -### Added -- noConnectionPooling option to force not using a session pool - -## [2.5.6] - 2018-07-18 -### Changed -- use ODPI-C v2.4.2 -- remove all logging/printing of passwords - -## [2.5.5] - 2018-07-03 -### Added -- allow *int with nil value to be used as NULL - -## [2.5.4] - 2018-06-29 -### Added -- allow ReadOnly transactions - -## [2.5.3] - 2018-06-29 -### Changed -- decrease maxArraySize to be compilable on 32-bit architectures. - -### Removed -- remove C struct size Printf - -## [2.5.2] - 2018-06-22 -### Changed -- fix liveness check in statement.Close - -## [2.5.1] - 2018-06-15 -### Changed -- sid -> service_name in docs -- travis: 1.10.3 -- less embedding of structs, clearer API docs +## [0.10.0] ### Added -- support RETURNING from DML -- set timeouts on poolCreateParams +- onInit parameter in the connection url (and OnInit in ConnectionParams) +- export Drv to be able to register new driver wrapping *godror.Drv. +- ContextWithUserPassw requires a connClass argument, too. -## [2.5.0] - 2018-05-15 +## [0.9.2] ### Changed -- update ODPI-C to v2.4.0 -- initialize context / load lib only on first Open, to allow import without Oracle Client installed -- use golangci-lint +- Make Data embed dpiData, not *dpiData diff --git a/vendor/github.com/godror/godror/conn.go b/vendor/github.com/godror/godror/conn.go index f1476349729..2f5db308c2d 100644 --- a/vendor/github.com/godror/godror/conn.go +++ b/vendor/github.com/godror/godror/conn.go @@ -33,7 +33,7 @@ const wrapResultset = "--WRAP_RESULTSET--" // with 32-bit platforms. The size of a `C.dpiData` is 32 Byte on a 64-bit system, `C.dpiSubscrMessageTable` is 40 bytes. // So this is 2^25. // See https://github.com/go-godror/godror/issues/73#issuecomment-401281714 -const maxArraySize = (1<<32)/C.sizeof_dpiSubscrMessageTable - 1 +const maxArraySize = (1<<30)/C.sizeof_dpiSubscrMessageTable - 1 var _ = driver.Conn((*conn)(nil)) var _ = driver.ConnBeginTx((*conn)(nil)) @@ -43,19 +43,19 @@ var _ = driver.Pinger((*conn)(nil)) //var _ = driver.ExecerContext((*conn)(nil)) type conn struct { - connParams ConnectionParams currentTT TraceTag + connParams ConnectionParams Client, Server VersionInfo tranParams tranParams - sync.RWMutex - currentUser string - *drv - dpiConn *C.dpiConn - inTransaction bool - newSession bool - timeZone *time.Location - tzOffSecs int - objTypes map[string]ObjectType + mu sync.RWMutex + currentUser string + drv *drv + dpiConn *C.dpiConn + timeZone *time.Location + objTypes map[string]ObjectType + tzOffSecs int + inTransaction bool + newSession bool } func (c *conn) getError() error { @@ -66,8 +66,8 @@ func (c *conn) getError() error { } func (c *conn) Break() error { - c.RLock() - defer c.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() if Log != nil { Log("msg", "Break", "dpiConn", c.dpiConn) } @@ -77,6 +77,8 @@ func (c *conn) Break() error { return nil } +func (c *conn) ClientVersion() (VersionInfo, error) { return c.drv.ClientVersion() } + // Ping checks the connection's state. // // WARNING: as database/sql calls database/sql/driver.Open when it needs @@ -90,8 +92,8 @@ func (c *conn) Ping(ctx context.Context) error { if err := c.ensureContextUser(ctx); err != nil { return err } - c.RLock() - defer c.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() done := make(chan error, 1) go func() { defer close(done) @@ -136,8 +138,8 @@ func (c *conn) Close() error { if c == nil { return nil } - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() return c.close(true) } @@ -160,7 +162,7 @@ func (c *conn) close(doNotReuse bool) error { continue } seen[nm] = struct{}{} - o.close() + o.close(doNotReuse) } if !doNotReuse { return nil @@ -252,19 +254,19 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e c.tranParams = todo } - c.RLock() + c.mu.RLock() inTran := c.inTransaction - c.RUnlock() + c.mu.RUnlock() if inTran { return nil, errors.New("already in transaction") } - c.Lock() + c.mu.Lock() c.inTransaction = true - c.Unlock() + c.mu.Unlock() if tt, ok := ctx.Value(traceTagCtxKey).(TraceTag); ok { - c.Lock() + c.mu.Lock() c.setTraceTag(tt) - c.Unlock() + c.mu.Unlock() } return c, nil } @@ -284,9 +286,9 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e return nil, err } if tt, ok := ctx.Value(traceTagCtxKey).(TraceTag); ok { - c.Lock() + c.mu.Lock() c.setTraceTag(tt) - c.Unlock() + c.mu.Unlock() } if query == getConnection { if Log != nil { @@ -299,8 +301,8 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e defer func() { C.free(unsafe.Pointer(cSQL)) }() - c.RLock() - defer c.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() var dpiStmt *C.dpiStmt if C.dpiConn_prepareStmt(c.dpiConn, 0, cSQL, C.uint32_t(len(query)), nil, 0, (**C.dpiStmt)(unsafe.Pointer(&dpiStmt)), @@ -316,7 +318,7 @@ func (c *conn) Rollback() error { return c.endTran(false) } func (c *conn) endTran(isCommit bool) error { - c.Lock() + c.mu.Lock() c.inTransaction = false c.tranParams = tranParams{} @@ -332,7 +334,7 @@ func (c *conn) endTran(isCommit bool) error { err = maybeBadConn(errors.Errorf("Rollback: %w", c.getError()), c) } } - c.Unlock() + c.mu.Unlock() //fmt.Printf("%p.%s\n", c, msg) return err } @@ -385,13 +387,43 @@ func (c *conn) ServerVersion() (VersionInfo, error) { return c.Server, nil } -func (c *conn) init() error { +func (c *conn) init(onInit []string) error { if c.Client.Version == 0 { var err error if c.Client, err = c.drv.ClientVersion(); err != nil { return err } } + + if err := c.initVersionTZ(); err != nil || len(onInit) == 0 || !c.newSession { + return err + } + if Log != nil { + Log("newSession", c.newSession, "onInit", onInit) + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Duration(len(onInit))*time.Second) + defer cancel() + if Log != nil { + Log("doOnInit", len(onInit)) + } + for _, qry := range onInit { + if Log != nil { + Log("onInit", qry) + } + st, err := c.PrepareContext(ctx, qry) + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + _, err = st.Exec(nil) //lint:ignore SA1019 - it's hard to use ExecContext here + st.Close() + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + } + return nil + } + +func (c *conn) initVersionTZ() error { if c.Server.Version == 0 { var v C.dpiVersionInfo var release *C.char @@ -690,18 +722,16 @@ const userpwCtxKey = ctxKey("userPw") // ContextWithUserPassw returns a context with the specified user and password, // to be used with heterogeneous pools. -func ContextWithUserPassw(ctx context.Context, user, password string) context.Context { - return context.WithValue(ctx, userpwCtxKey, [2]string{user, password}) +func ContextWithUserPassw(ctx context.Context, user, password, connClass string) context.Context { + return context.WithValue(ctx, userpwCtxKey, [3]string{user, password, connClass}) } func (c *conn) ensureContextUser(ctx context.Context) error { - if !c.connParams.HeterogeneousPool { + if !(c.connParams.HeterogeneousPool || c.connParams.StandaloneConnection) { return nil } - - var up [2]string - var ok bool - if up, ok = ctx.Value(userpwCtxKey).([2]string); !ok || up[0] == c.currentUser { + up, ok := ctx.Value(userpwCtxKey).([3]string) + if !ok || up[0] == c.currentUser { return nil } @@ -711,14 +741,7 @@ func (c *conn) ensureContextUser(ctx context.Context) error { } } - c.Lock() - defer c.Unlock() - - if err := c.acquireConn(up[0], up[1]); err != nil { - return err - } - - return c.init() + return c.acquireConn(up[0], up[1], up[2]) } // StartupMode for the database. diff --git a/vendor/github.com/godror/godror/contrib/free.db/reset.sql b/vendor/github.com/godror/godror/contrib/free.db/reset.sql new file mode 100644 index 00000000000..c8666143455 --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/reset.sql @@ -0,0 +1,15 @@ +WHENEVER SQLERROR CONTINUE + +DROP USER test CASCADE; + +WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK + +CREATE USER test IDENTIFIED BY r97oUPimsmTOIcBaeeDF; +ALTER USER test QUOTA 100m ON data; +GRANT create session, create table, create type, create sequence, create synonym, create procedure, change notification TO test; +GRANT EXECUTE ON SYS.DBMS_AQ TO test; +GRANT EXECUTE ON SYS.DBMS_AQADM TO test; + +GRANT create user, drop user, alter user TO test; +GRANT connect TO test WITH admin option; +GRANT create session TO test WITH admin option; diff --git a/vendor/github.com/godror/godror/data.go b/vendor/github.com/godror/godror/data.go index 1d78c8abbae..c42f3ec189a 100644 --- a/vendor/github.com/godror/godror/data.go +++ b/vendor/github.com/godror/godror/data.go @@ -24,7 +24,8 @@ import ( // Data holds the data to/from Oracle. type Data struct { ObjectType ObjectType - dpiData *C.dpiData + dpiData C.dpiData + implicitObj bool NativeTypeNum C.dpiNativeTypeNum } @@ -35,22 +36,22 @@ func NewData(v interface{}) (*Data, error) { if v == nil { return nil, errors.Errorf("%s: %w", "nil type", ErrNotSupported) } - data := Data{dpiData: &C.dpiData{isNull: 1}} + data := Data{dpiData: C.dpiData{isNull: 1}} return &data, data.Set(v) } // IsNull returns whether the data is null. func (d *Data) IsNull() bool { - // Use of C.dpiData_getIsNull(d.dpiData) would be safer, + // Use of C.dpiData_getIsNull(&d.dpiData) would be safer, // but ODPI-C 3.1.4 just returns dpiData->isNull, so do the same // without calling CGO. - return d == nil || d.dpiData == nil || d.dpiData.isNull == 1 + return d == nil || d.dpiData.isNull == 1 } // SetNull sets the value of the data to be the null value. func (d *Data) SetNull() { if !d.IsNull() { - // Maybe C.dpiData_setNull(d.dpiData) would be safer, but as we don't use C.dpiData_getIsNull, + // Maybe C.dpiData_setNull(&d.dpiData) would be safer, but as we don't use C.dpiData_getIsNull, // and those functions (at least in ODPI-C 3.1.4) just operate on data->isNull directly, // don't use CGO if possible. d.dpiData.isNull = 1 @@ -59,7 +60,7 @@ func (d *Data) SetNull() { // GetBool returns the bool data. func (d *Data) GetBool() bool { - return !d.IsNull() && C.dpiData_getBool(d.dpiData) == 1 + return !d.IsNull() && C.dpiData_getBool(&d.dpiData) == 1 } // SetBool sets the data as bool. @@ -68,7 +69,7 @@ func (d *Data) SetBool(b bool) { if b { i = 1 } - C.dpiData_setBool(d.dpiData, i) + C.dpiData_setBool(&d.dpiData, i) } // GetBytes returns the []byte from the data. @@ -76,7 +77,7 @@ func (d *Data) GetBytes() []byte { if d.IsNull() { return nil } - b := C.dpiData_getBytes(d.dpiData) + b := C.dpiData_getBytes(&d.dpiData) if b.ptr == nil || b.length == 0 { return nil } @@ -89,7 +90,7 @@ func (d *Data) SetBytes(b []byte) { d.dpiData.isNull = 1 return } - C.dpiData_setBytes(d.dpiData, (*C.char)(unsafe.Pointer(&b[0])), C.uint32_t(len(b))) + C.dpiData_setBytes(&d.dpiData, (*C.char)(unsafe.Pointer(&b[0])), C.uint32_t(len(b))) } // GetFloat32 gets float32 from the data. @@ -97,12 +98,12 @@ func (d *Data) GetFloat32() float32 { if d.IsNull() { return 0 } - return float32(C.dpiData_getFloat(d.dpiData)) + return float32(C.dpiData_getFloat(&d.dpiData)) } // SetFloat32 sets the data as float32. func (d *Data) SetFloat32(f float32) { - C.dpiData_setFloat(d.dpiData, C.float(f)) + C.dpiData_setFloat(&d.dpiData, C.float(f)) } // GetFloat64 gets float64 from the data. @@ -111,12 +112,12 @@ func (d *Data) GetFloat64() float64 { if d.IsNull() { return 0 } - return float64(C.dpiData_getDouble(d.dpiData)) + return float64(C.dpiData_getDouble(&d.dpiData)) } // SetFloat64 sets the data as float64. func (d *Data) SetFloat64(f float64) { - C.dpiData_setDouble(d.dpiData, C.double(f)) + C.dpiData_setDouble(&d.dpiData, C.double(f)) } // GetInt64 gets int64 from the data. @@ -124,12 +125,12 @@ func (d *Data) GetInt64() int64 { if d.IsNull() { return 0 } - return int64(C.dpiData_getInt64(d.dpiData)) + return int64(C.dpiData_getInt64(&d.dpiData)) } // SetInt64 sets the data as int64. func (d *Data) SetInt64(i int64) { - C.dpiData_setInt64(d.dpiData, C.int64_t(i)) + C.dpiData_setInt64(&d.dpiData, C.int64_t(i)) } // GetIntervalDS gets duration as interval date-seconds from data. @@ -137,7 +138,7 @@ func (d *Data) GetIntervalDS() time.Duration { if d.IsNull() { return 0 } - ds := C.dpiData_getIntervalDS(d.dpiData) + ds := C.dpiData_getIntervalDS(&d.dpiData) return time.Duration(ds.days)*24*time.Hour + time.Duration(ds.hours)*time.Hour + time.Duration(ds.minutes)*time.Minute + @@ -147,7 +148,7 @@ func (d *Data) GetIntervalDS() time.Duration { // SetIntervalDS sets the duration as interval date-seconds to data. func (d *Data) SetIntervalDS(dur time.Duration) { - C.dpiData_setIntervalDS(d.dpiData, + C.dpiData_setIntervalDS(&d.dpiData, C.int32_t(int64(dur.Hours())/24), C.int32_t(int64(dur.Hours())%24), C.int32_t(dur.Minutes()), C.int32_t(dur.Seconds()), C.int32_t(dur.Nanoseconds()), @@ -159,13 +160,13 @@ func (d *Data) GetIntervalYM() IntervalYM { if d.IsNull() { return IntervalYM{} } - ym := C.dpiData_getIntervalYM(d.dpiData) + ym := C.dpiData_getIntervalYM(&d.dpiData) return IntervalYM{Years: int(ym.years), Months: int(ym.months)} } // SetIntervalYM sets IntervalYM to the data. func (d *Data) SetIntervalYM(ym IntervalYM) { - C.dpiData_setIntervalYM(d.dpiData, C.int32_t(ym.Years), C.int32_t(ym.Months)) + C.dpiData_setIntervalYM(&d.dpiData, C.int32_t(ym.Years), C.int32_t(ym.Months)) } // GetLob gets data as Lob. @@ -173,31 +174,33 @@ func (d *Data) GetLob() *Lob { if d.IsNull() { return nil } - return &Lob{Reader: &dpiLobReader{dpiLob: C.dpiData_getLOB(d.dpiData)}} + return &Lob{Reader: &dpiLobReader{dpiLob: C.dpiData_getLOB(&d.dpiData)}} } // SetLob sets Lob to the data. func (d *Data) SetLob(lob *DirectLob) { - C.dpiData_setLOB(d.dpiData, lob.dpiLob) + C.dpiData_setLOB(&d.dpiData, lob.dpiLob) } // GetObject gets Object from data. // // As with all Objects, you MUST call Close on it when not needed anymore! func (d *Data) GetObject() *Object { - if d == nil || d.dpiData == nil { + if d == nil { panic("null") } if d.IsNull() { return nil } - o := C.dpiData_getObject(d.dpiData) + o := C.dpiData_getObject(&d.dpiData) if o == nil { return nil } - if C.dpiObject_addRef(o) == C.DPI_FAILURE { - panic(d.ObjectType.getError()) + if !d.implicitObj { + if C.dpiObject_addRef(o) == C.DPI_FAILURE { + panic(d.ObjectType.getError()) + } } obj := &Object{dpiObject: o, ObjectType: d.ObjectType} obj.init() @@ -206,7 +209,7 @@ func (d *Data) GetObject() *Object { // SetObject sets Object to data. func (d *Data) SetObject(o *Object) { - C.dpiData_setObject(d.dpiData, o.dpiObject) + C.dpiData_setObject(&d.dpiData, o.dpiObject) } // GetStmt gets Stmt from data. @@ -214,12 +217,12 @@ func (d *Data) GetStmt() driver.Stmt { if d.IsNull() { return nil } - return &statement{dpiStmt: C.dpiData_getStmt(d.dpiData)} + return &statement{dpiStmt: C.dpiData_getStmt(&d.dpiData)} } // SetStmt sets Stmt to data. func (d *Data) SetStmt(s *statement) { - C.dpiData_setStmt(d.dpiData, s.dpiStmt) + C.dpiData_setStmt(&d.dpiData, s.dpiStmt) } // GetTime gets Time from data. @@ -227,7 +230,7 @@ func (d *Data) GetTime() time.Time { if d.IsNull() { return time.Time{} } - ts := C.dpiData_getTimestamp(d.dpiData) + ts := C.dpiData_getTimestamp(&d.dpiData) return time.Date( int(ts.year), time.Month(ts.month), int(ts.day), int(ts.hour), int(ts.minute), int(ts.second), int(ts.fsecond), @@ -239,7 +242,7 @@ func (d *Data) GetTime() time.Time { // SetTime sets Time to data. func (d *Data) SetTime(t time.Time) { _, z := t.Zone() - C.dpiData_setTimestamp(d.dpiData, + C.dpiData_setTimestamp(&d.dpiData, C.int16_t(t.Year()), C.uint8_t(t.Month()), C.uint8_t(t.Day()), C.uint8_t(t.Hour()), C.uint8_t(t.Minute()), C.uint8_t(t.Second()), C.uint32_t(t.Nanosecond()), C.int8_t(z/3600), C.int8_t((z%3600)/60), @@ -251,12 +254,12 @@ func (d *Data) GetUint64() uint64 { if d.IsNull() { return 0 } - return uint64(C.dpiData_getUint64(d.dpiData)) + return uint64(C.dpiData_getUint64(&d.dpiData)) } // SetUint64 sets data to uint64. func (d *Data) SetUint64(u uint64) { - C.dpiData_setUint64(d.dpiData, C.uint64_t(u)) + C.dpiData_setUint64(&d.dpiData, C.uint64_t(u)) } // IntervalYM holds Years and Months as interval. @@ -301,9 +304,6 @@ func (d *Data) Set(v interface{}) error { if v == nil { return errors.Errorf("%s: %w", "nil type", ErrNotSupported) } - if d.dpiData == nil { - d.dpiData = &C.dpiData{isNull: 1} - } switch x := v.(type) { case int32: d.NativeTypeNum = C.DPI_NATIVE_TYPE_INT64 @@ -373,14 +373,15 @@ func (c *conn) NewData(baseType interface{}, sliceLen, bufSize int) ([]*Data, er return nil, err } - _, dpiData, err := c.newVar(vi) + v, dpiData, err := c.newVar(vi) if err != nil { return nil, err } + defer C.dpiVar_release(v) data := make([]*Data, sliceLen) for i := 0; i < sliceLen; i++ { - data[i] = &Data{dpiData: &dpiData[i], NativeTypeNum: vi.NatTyp} + data[i] = &Data{dpiData: dpiData[i], NativeTypeNum: vi.NatTyp} } return data, nil @@ -461,10 +462,7 @@ func newVarInfo(baseType interface{}, sliceLen, bufSize int) (varInfo, error) { func (d *Data) reset() { d.NativeTypeNum = 0 d.ObjectType = ObjectType{} - if d.dpiData == nil { - d.dpiData = &C.dpiData{} - } else { - d.SetBytes(nil) - } + d.implicitObj = false + d.SetBytes(nil) d.dpiData.isNull = 1 } diff --git a/vendor/github.com/godror/godror/drv.go b/vendor/github.com/godror/godror/drv.go index 8ad65fd4c58..5699088871e 100644 --- a/vendor/github.com/godror/godror/drv.go +++ b/vendor/github.com/godror/godror/drv.go @@ -26,7 +26,8 @@ // poolSessionMaxLifetime=1h& \ // poolSessionTimeout=30s& \ // timezone=Local& \ -// newPassword= +// newPassword= \ +// onInit=ALTER+SESSION+SET+current_schema%3Dmy_schema // // These are the defaults. Many advocate that a static session pool (min=max, incr=0) // is better, with 1-10 sessions per CPU thread. @@ -57,7 +58,6 @@ import ( "fmt" "hash/fnv" "io" - "math" "net/url" "strconv" "strings" @@ -87,7 +87,9 @@ const ( DpiVersionNumber = C.DPI_VERSION_NUMBER // DriverName is set on the connection to be seen in the DB - DriverName = "github.com/godror/godror : " + Version + // + // It cannot be longer than 30 bytes ! + DriverName = "godror : " + Version // DefaultPoolMinSessions specifies the default value for minSessions for pool creation. DefaultPoolMinSessions = 1 @@ -108,238 +110,39 @@ const ( DefaultMaxLifeTime = 1 * time.Hour ) -// Number as string -type Number string - -var ( - // Int64 for converting to-from int64. - Int64 = intType{} - // Float64 for converting to-from float64. - Float64 = floatType{} - // Num for converting to-from Number (string) - Num = numType{} -) - -type intType struct{} - -func (intType) String() string { return "Int64" } -func (intType) ConvertValue(v interface{}) (driver.Value, error) { - if Log != nil { - Log("ConvertValue", "Int64", "value", v) - } - switch x := v.(type) { - case int8: - return int64(x), nil - case int16: - return int64(x), nil - case int32: - return int64(x), nil - case int64: - return x, nil - case uint16: - return int64(x), nil - case uint32: - return int64(x), nil - case uint64: - return int64(x), nil - case float32: - if _, f := math.Modf(float64(x)); f != 0 { - return int64(x), errors.Errorf("non-zero fractional part: %f", f) - } - return int64(x), nil - case float64: - if _, f := math.Modf(x); f != 0 { - return int64(x), errors.Errorf("non-zero fractional part: %f", f) - } - return int64(x), nil - case string: - if x == "" { - return 0, nil - } - return strconv.ParseInt(x, 10, 64) - case Number: - if x == "" { - return 0, nil - } - return strconv.ParseInt(string(x), 10, 64) - default: - return nil, errors.Errorf("unknown type %T", v) - } -} - -type floatType struct{} - -func (floatType) String() string { return "Float64" } -func (floatType) ConvertValue(v interface{}) (driver.Value, error) { - if Log != nil { - Log("ConvertValue", "Float64", "value", v) - } - switch x := v.(type) { - case int8: - return float64(x), nil - case int16: - return float64(x), nil - case int32: - return float64(x), nil - case uint16: - return float64(x), nil - case uint32: - return float64(x), nil - case int64: - return float64(x), nil - case uint64: - return float64(x), nil - case float32: - return float64(x), nil - case float64: - return x, nil - case string: - if x == "" { - return 0, nil - } - return strconv.ParseFloat(x, 64) - case Number: - if x == "" { - return 0, nil - } - return strconv.ParseFloat(string(x), 64) - default: - return nil, errors.Errorf("unknown type %T", v) - } -} - -type numType struct{} - -func (numType) String() string { return "Num" } -func (numType) ConvertValue(v interface{}) (driver.Value, error) { - if Log != nil { - Log("ConvertValue", "Num", "value", v) - } - switch x := v.(type) { - case string: - if x == "" { - return 0, nil - } - return x, nil - case Number: - if x == "" { - return 0, nil - } - return string(x), nil - case int8, int16, int32, int64, uint16, uint32, uint64: - return fmt.Sprintf("%d", x), nil - case float32, float64: - return fmt.Sprintf("%f", x), nil - default: - return nil, errors.Errorf("unknown type %T", v) - } -} -func (n Number) String() string { return string(n) } - -// Value returns the Number as driver.Value -func (n Number) Value() (driver.Value, error) { - return string(n), nil -} - -// Scan into the Number from a driver.Value. -func (n *Number) Scan(v interface{}) error { - if v == nil { - *n = "" - return nil - } - switch x := v.(type) { - case string: - *n = Number(x) - case Number: - *n = x - case int8, int16, int32, int64, uint16, uint32, uint64: - *n = Number(fmt.Sprintf("%d", x)) - case float32, float64: - *n = Number(fmt.Sprintf("%f", x)) - default: - return errors.Errorf("unknown type %T", v) - } - return nil -} - -// MarshalText marshals a Number to text. -func (n Number) MarshalText() ([]byte, error) { return []byte(n), nil } - -// UnmarshalText parses text into a Number. -func (n *Number) UnmarshalText(p []byte) error { - var dotNum int - for i, c := range p { - if !(c == '-' && i == 0 || '0' <= c && c <= '9') { - if c == '.' { - dotNum++ - if dotNum == 1 { - continue - } - } - return errors.Errorf("unknown char %c in %q", c, p) - } - } - *n = Number(p) - return nil -} - -// MarshalJSON marshals a Number into a JSON string. -func (n Number) MarshalJSON() ([]byte, error) { - b, err := n.MarshalText() - b2 := make([]byte, 1, 1+len(b)+1) - b2[0] = '"' - b2 = append(b2, b...) - b2 = append(b2, '"') - return b2, err -} - -// UnmarshalJSON parses a JSON string into the Number. -func (n *Number) UnmarshalJSON(p []byte) error { - *n = Number("") - if len(p) == 0 { - return nil - } - if len(p) > 2 && p[0] == '"' && p[len(p)-1] == '"' { - p = p[1 : len(p)-1] - } - return n.UnmarshalText(p) -} - // Log function. By default, it's nil, and thus logs nothing. // If you want to change this, change it to a github.com/go-kit/kit/log.Swapper.Log // or analog to be race-free. var Log func(...interface{}) error -var defaultDrv *drv +var defaultDrv = &drv{} func init() { - defaultDrv = newDrv() sql.Register("godror", defaultDrv) } -func newDrv() *drv { - return &drv{pools: make(map[string]*connPool)} -} - var _ = driver.Driver((*drv)(nil)) type drv struct { - clientVersion VersionInfo mu sync.Mutex dpiContext *C.dpiContext pools map[string]*connPool + clientVersion VersionInfo } type connPool struct { dpiPool *C.dpiPool - serverVersion VersionInfo timeZone *time.Location tzOffSecs int + serverVersion VersionInfo } func (d *drv) init() error { d.mu.Lock() defer d.mu.Unlock() + if d.pools == nil { + d.pools = make(map[string]*connPool) + } if d.dpiContext != nil { return nil } @@ -376,81 +179,38 @@ func (d *drv) ClientVersion() (VersionInfo, error) { return d.clientVersion, nil } +var cUTF8, cDriverName = C.CString("AL32UTF8"), C.CString(DriverName) + func (d *drv) openConn(P ConnectionParams) (*conn, error) { if err := d.init(); err != nil { return nil, err } - c := conn{drv: d, connParams: P, timeZone: time.Local} + P.Comb() + c := &conn{drv: d, connParams: P, timeZone: time.Local, Client: d.clientVersion} connString := P.String() - defer func() { - d.mu.Lock() - if Log != nil { - Log("pools", d.pools, "conn", P.String()) - } - d.mu.Unlock() - }() - - authMode := C.dpiAuthMode(C.DPI_MODE_AUTH_DEFAULT) - // OR all the modes together - for _, elt := range []struct { - Is bool - Mode C.dpiAuthMode - }{ - {P.IsSysDBA, C.DPI_MODE_AUTH_SYSDBA}, - {P.IsSysOper, C.DPI_MODE_AUTH_SYSOPER}, - {P.IsSysASM, C.DPI_MODE_AUTH_SYSASM}, - {P.IsPrelim, C.DPI_MODE_AUTH_PRELIM}, - } { - if elt.Is { - authMode |= elt.Mode - } - } - P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass - if P.IsPrelim || P.StandaloneConnection { - // Prelim: the shared memory may not exist when Oracle is shut down. - P.ConnClass = "" + if Log != nil { + defer func() { + d.mu.Lock() + Log("pools", d.pools, "conn", P.String(), "drv", fmt.Sprintf("%p", d)) + d.mu.Unlock() + }() } - extAuth := C.int(b2i(P.Username == "" && P.Password == "")) - var connCreateParams C.dpiConnCreateParams - if C.dpiContext_initConnCreateParams(d.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return nil, errors.Errorf("initConnCreateParams: %w", d.getError()) - } - connCreateParams.authMode = authMode - connCreateParams.externalAuth = extAuth - if P.ConnClass != "" { - cConnClass := C.CString(P.ConnClass) - defer C.free(unsafe.Pointer(cConnClass)) - connCreateParams.connectionClass = cConnClass - connCreateParams.connectionClassLength = C.uint32_t(len(P.ConnClass)) - } if !(P.IsSysDBA || P.IsSysOper || P.IsSysASM || P.IsPrelim || P.StandaloneConnection) { d.mu.Lock() dp := d.pools[connString] d.mu.Unlock() if dp != nil { //Proxy authenticated connections to database will be provided by methods with context - c.mu.Lock() - c.Client, c.Server = d.clientVersion, dp.serverVersion - c.timeZone, c.tzOffSecs = dp.timeZone, dp.tzOffSecs - c.mu.Unlock() - if err := c.acquireConn("", ""); err != nil { - return nil, err - } - err := c.init() - if err == nil { - c.mu.Lock() - dp.serverVersion = c.Server - dp.timeZone, dp.tzOffSecs = c.timeZone, c.tzOffSecs - c.mu.Unlock() - } - return &c, err + err := dp.acquireConn(c, P) + return c, err } } - var cUserName, cPassword, cNewPassword *C.char + extAuth := C.int(b2i(P.Username == "" && P.Password == "")) + var cUserName, cPassword, cNewPassword, cConnClass *C.char if !(P.Username == "" && P.Password == "") { cUserName, cPassword = C.CString(P.Username), C.CString(P.Password) } @@ -458,8 +218,6 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { if P.SID != "" { cSid = C.CString(P.SID) } - cUTF8, cConnClass := C.CString("AL32UTF8"), C.CString(P.ConnClass) - cDriverName := C.CString(DriverName) defer func() { if cUserName != nil { C.free(unsafe.Pointer(cUserName)) @@ -471,9 +229,9 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { if cSid != nil { C.free(unsafe.Pointer(cSid)) } - C.free(unsafe.Pointer(cUTF8)) - C.free(unsafe.Pointer(cConnClass)) - C.free(unsafe.Pointer(cDriverName)) + if cConnClass != nil { + C.free(unsafe.Pointer(cConnClass)) + } }() var commonCreateParams C.dpiCommonCreateParams if C.dpiContext_initCommonCreateParams(d.dpiContext, &commonCreateParams) == C.DPI_FAILURE { @@ -489,32 +247,9 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { commonCreateParams.driverNameLength = C.uint32_t(len(DriverName)) if P.IsSysDBA || P.IsSysOper || P.IsSysASM || P.IsPrelim || P.StandaloneConnection { - if P.NewPassword != "" { - cNewPassword = C.CString(P.NewPassword) - connCreateParams.newPassword = cNewPassword - connCreateParams.newPasswordLength = C.uint32_t(len(P.NewPassword)) - } - dc := C.malloc(C.sizeof_void) - if Log != nil { - Log("C", "dpiConn_create", "params", P.String(), "common", commonCreateParams, "conn", connCreateParams) - } - if C.dpiConn_create( - d.dpiContext, - cUserName, C.uint32_t(len(P.Username)), - cPassword, C.uint32_t(len(P.Password)), - cSid, C.uint32_t(len(P.SID)), - &commonCreateParams, - &connCreateParams, - (**C.dpiConn)(unsafe.Pointer(&dc)), - ) == C.DPI_FAILURE { - C.free(unsafe.Pointer(dc)) - return nil, errors.Errorf("username=%q sid=%q params=%+v: %w", P.Username, P.SID, connCreateParams, d.getError()) - } - c.dpiConn = (*C.dpiConn)(dc) - c.currentUser = P.Username - c.newSession = true - err := c.init() - return &c, err + // no pool + c.connParams = P + return c, c.acquireConn(P.Username, P.Password, P.ConnClass) } var poolCreateParams C.dpiPoolCreateParams if C.dpiContext_initPoolCreateParams(d.dpiContext, &poolCreateParams) == C.DPI_FAILURE { @@ -566,24 +301,79 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { return nil, errors.Errorf("params=%s extAuth=%v: %w", P.String(), extAuth, d.getError()) } C.dpiPool_setStmtCacheSize(dp, 40) + pool := &connPool{dpiPool: dp} d.mu.Lock() - d.pools[connString] = &connPool{dpiPool: dp} + d.pools[connString] = pool d.mu.Unlock() - return d.openConn(P) + return c, pool.acquireConn(c, P) } -func (c *conn) acquireConn(user, pass string) error { +func (dp *connPool) acquireConn(c *conn, P ConnectionParams) error { + P.Comb() + c.mu.Lock() + c.connParams = P + c.Client, c.Server = c.drv.clientVersion, dp.serverVersion + c.timeZone, c.tzOffSecs = dp.timeZone, dp.tzOffSecs + c.mu.Unlock() + var connCreateParams C.dpiConnCreateParams - if C.dpiContext_initConnCreateParams(c.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return errors.Errorf("initConnCreateParams: %w", "", c.getError()) + if C.dpiContext_initConnCreateParams(c.drv.dpiContext, &connCreateParams) == C.DPI_FAILURE { + return errors.Errorf("initConnCreateParams: %w", c.drv.getError()) + } + if P.ConnClass != "" { + cConnClass := C.CString(P.ConnClass) + defer C.free(unsafe.Pointer(cConnClass)) + connCreateParams.connectionClass = cConnClass + connCreateParams.connectionClassLength = C.uint32_t(len(P.ConnClass)) } - dc := C.malloc(C.sizeof_void) - if Log != nil { - Log("C", "dpiPool_acquirePoolConnection", "conn", connCreateParams) + if C.dpiPool_acquireConnection( + dp.dpiPool, + nil, 0, nil, 0, + &connCreateParams, + (**C.dpiConn)(unsafe.Pointer(&dc)), + ) == C.DPI_FAILURE { + C.free(unsafe.Pointer(dc)) + return errors.Errorf("acquirePoolConnection(user=%q, params=%#v): %w", P.Username, connCreateParams, c.getError()) } - var cUserName, cPassword *C.char + + c.mu.Lock() + c.dpiConn = (*C.dpiConn)(dc) + c.currentUser = P.Username + c.newSession = connCreateParams.outNewSession == 1 + c.mu.Unlock() + err := c.init(P.OnInit) + if err == nil { + c.mu.Lock() + dp.serverVersion = c.Server + dp.timeZone, dp.tzOffSecs = c.timeZone, c.tzOffSecs + c.mu.Unlock() + } + + return err +} + +func (c *conn) acquireConn(user, pass, connClass string) error { + P := c.connParams + if !(P.IsSysDBA || P.IsSysOper || P.IsSysASM || P.IsPrelim || P.StandaloneConnection) { + c.drv.mu.Lock() + pool := c.drv.pools[P.String()] + if Log != nil { + Log("pools", c.drv.pools, "drv", fmt.Sprintf("%p", c.drv)) + } + c.drv.mu.Unlock() + if pool != nil { + P.Username, P.Password, P.ConnClass = user, pass, connClass + return pool.acquireConn(c, P) + } + } + + var connCreateParams C.dpiConnCreateParams + if C.dpiContext_initConnCreateParams(c.drv.dpiContext, &connCreateParams) == C.DPI_FAILURE { + return errors.Errorf("initConnCreateParams: %w", c.drv.getError()) + } + var cUserName, cPassword, cNewPassword, cConnClass, cSid *C.char defer func() { if cUserName != nil { C.free(unsafe.Pointer(cUserName)) @@ -591,6 +381,15 @@ func (c *conn) acquireConn(user, pass string) error { if cPassword != nil { C.free(unsafe.Pointer(cPassword)) } + if cNewPassword != nil { + C.free(unsafe.Pointer(cNewPassword)) + } + if cConnClass != nil { + C.free(unsafe.Pointer(cConnClass)) + } + if cSid != nil { + C.free(unsafe.Pointer(cSid)) + } }() if user != "" { cUserName = C.CString(user) @@ -598,52 +397,79 @@ func (c *conn) acquireConn(user, pass string) error { if pass != "" { cPassword = C.CString(pass) } + if connClass != "" { + cConnClass = C.CString(connClass) + connCreateParams.connectionClass = cConnClass + connCreateParams.connectionClassLength = C.uint32_t(len(connClass)) + } + var commonCreateParams C.dpiCommonCreateParams + if C.dpiContext_initCommonCreateParams(c.drv.dpiContext, &commonCreateParams) == C.DPI_FAILURE { + return errors.Errorf("initCommonCreateParams: %w", c.drv.getError()) + } + commonCreateParams.createMode = C.DPI_MODE_CREATE_DEFAULT | C.DPI_MODE_CREATE_THREADED + if P.EnableEvents { + commonCreateParams.createMode |= C.DPI_MODE_CREATE_EVENTS + } + commonCreateParams.encoding = cUTF8 + commonCreateParams.nencoding = cUTF8 + commonCreateParams.driverName = cDriverName + commonCreateParams.driverNameLength = C.uint32_t(len(DriverName)) - c.drv.mu.Lock() - pool := c.pools[c.connParams.String()] - c.drv.mu.Unlock() - if C.dpiPool_acquireConnection( - pool.dpiPool, - cUserName, C.uint32_t(len(user)), cPassword, C.uint32_t(len(pass)), + if P.SID != "" { + cSid = C.CString(P.SID) + } + connCreateParams.authMode = P.authMode() + extAuth := C.int(b2i(user == "" && pass == "")) + connCreateParams.externalAuth = extAuth + if P.NewPassword != "" { + cNewPassword = C.CString(P.NewPassword) + connCreateParams.newPassword = cNewPassword + connCreateParams.newPasswordLength = C.uint32_t(len(P.NewPassword)) + } + if Log != nil { + Log("C", "dpiConn_create", "params", P.String(), "common", commonCreateParams, "conn", connCreateParams) + } + dc := C.malloc(C.sizeof_void) + if C.dpiConn_create( + c.drv.dpiContext, + cUserName, C.uint32_t(len(user)), + cPassword, C.uint32_t(len(pass)), + cSid, C.uint32_t(len(P.SID)), + &commonCreateParams, &connCreateParams, (**C.dpiConn)(unsafe.Pointer(&dc)), ) == C.DPI_FAILURE { C.free(unsafe.Pointer(dc)) - return errors.Errorf("acquirePoolConnection: %w", c.getError()) + return errors.Errorf("username=%q sid=%q params=%+v: %w", user, P.SID, connCreateParams, c.drv.getError()) } - c.mu.Lock() c.dpiConn = (*C.dpiConn)(dc) c.currentUser = user - c.newSession = connCreateParams.outNewSession == 1 - c.Client, c.Server = c.drv.clientVersion, pool.serverVersion - c.timeZone, c.tzOffSecs = pool.timeZone, pool.tzOffSecs - c.mu.Unlock() - err := c.init() - if err == nil { - c.mu.Lock() - pool.serverVersion = c.Server - pool.timeZone, pool.tzOffSecs = c.timeZone, c.tzOffSecs - c.mu.Unlock() + c.newSession = true + P.Username, P.Password, P.ConnClass = user, pass, connClass + if P.NewPassword != "" { + P.Password, P.NewPassword = P.NewPassword, "" } - - return err + c.connParams = P + c.mu.Unlock() + return c.init(P.OnInit) } // ConnectionParams holds the params for a connection (pool). // You can use ConnectionParams{...}.StringWithPassword() // as a connection string in sql.Open. type ConnectionParams struct { + OnInit []string Username, Password, SID, ConnClass string // NewPassword is used iff StandaloneConnection is true! NewPassword string MinSessions, MaxSessions, PoolIncrement int WaitTimeout, MaxLifeTime, SessionTimeout time.Duration + Timezone *time.Location IsSysDBA, IsSysOper, IsSysASM, IsPrelim bool HeterogeneousPool bool StandaloneConnection bool EnableEvents bool - Timezone *time.Location } // String returns the string representation of ConnectionParams. @@ -713,6 +539,7 @@ func (P ConnectionParams) string(class, withPassword bool) string { q.Add("poolWaitTimeout", P.WaitTimeout.String()) q.Add("poolSessionMaxLifetime", P.MaxLifeTime.String()) q.Add("poolSessionTimeout", P.SessionTimeout.String()) + q["onInit"] = P.OnInit return (&url.URL{ Scheme: "oracle", User: url.UserPassword(P.Username, password), @@ -722,6 +549,15 @@ func (P ConnectionParams) string(class, withPassword bool) string { }).String() } +func (P *ConnectionParams) Comb() { + P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass + if P.IsPrelim || P.StandaloneConnection { + // Prelim: the shared memory may not exist when Oracle is shut down. + P.ConnClass = "" + P.HeterogeneousPool = false + } +} + // ParseConnString parses the given connection string into a struct. func ParseConnString(connString string) (ConnectionParams, error) { P := ConnectionParams{ @@ -815,14 +651,6 @@ func ParseConnString(connString string) (ConnectionParams, error) { } } - P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass - if P.IsPrelim { - P.ConnClass = "" - } - if P.StandaloneConnection { - P.NewPassword = q.Get("newPassword") - } - for _, task := range []struct { Dest *int Key string @@ -878,9 +706,40 @@ func ParseConnString(connString string) (ConnectionParams, error) { } else if P.PoolIncrement < 1 { P.PoolIncrement = 1 } + P.OnInit = q["onInit"] + + P.Comb() + if P.StandaloneConnection { + P.NewPassword = q.Get("newPassword") + } + return P, nil } +// SetSessionParamOnInit adds an "ALTER SESSION k=v" to the OnInit task list. +func (P *ConnectionParams) SetSessionParamOnInit(k, v string) { + P.OnInit = append(P.OnInit, fmt.Sprintf("ALTER SESSION SET %s = q'(%s)'", k, strings.Replace(v, "'", "''", -1))) +} + +func (P ConnectionParams) authMode() C.dpiAuthMode { + authMode := C.dpiAuthMode(C.DPI_MODE_AUTH_DEFAULT) + // OR all the modes together + for _, elt := range []struct { + Is bool + Mode C.dpiAuthMode + }{ + {P.IsSysDBA, C.DPI_MODE_AUTH_SYSDBA}, + {P.IsSysOper, C.DPI_MODE_AUTH_SYSOPER}, + {P.IsSysASM, C.DPI_MODE_AUTH_SYSASM}, + {P.IsPrelim, C.DPI_MODE_AUTH_PRELIM}, + } { + if elt.Is { + authMode |= elt.Mode + } + } + return authMode +} + // OraErr is an error holding the ORA-01234 code and the message. type OraErr struct { message string @@ -950,15 +809,15 @@ func b2i(b bool) uint8 { // VersionInfo holds version info returned by Oracle DB. type VersionInfo struct { ServerRelease string - Version, Release, Update, PortRelease, PortUpdate, Full int + Version, Release, Update, PortRelease, PortUpdate, Full uint8 } func (V *VersionInfo) set(v *C.dpiVersionInfo) { *V = VersionInfo{ - Version: int(v.versionNum), - Release: int(v.releaseNum), Update: int(v.updateNum), - PortRelease: int(v.portReleaseNum), PortUpdate: int(v.portUpdateNum), - Full: int(v.fullVersionNum), + Version: uint8(v.versionNum), + Release: uint8(v.releaseNum), Update: uint8(v.updateNum), + PortRelease: uint8(v.portReleaseNum), PortUpdate: uint8(v.portUpdateNum), + Full: uint8(v.fullVersionNum), } } func (V VersionInfo) String() string { @@ -1012,12 +871,13 @@ func ContextWithLog(ctx context.Context, logF func(...interface{}) error) contex return context.WithValue(ctx, logCtxKey, logF) } +var _ = driver.DriverContext((*drv)(nil)) var _ = driver.Connector((*connector)(nil)) type connector struct { - ConnectionParams - *drv + drv *drv onInit func(driver.Conn) error + ConnectionParams } // OpenConnector must parse the name in the same format that Driver.Open @@ -1062,9 +922,9 @@ func (c connector) Driver() driver.Driver { return c.drv } // NewConnector returns a driver.Connector to be used with sql.OpenDB, // which calls the given onInit if the connection is new. // -// For an example, see NewSessionIniter. -func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { - cxr, err := defaultDrv.OpenConnector(name) +// For an onInit example, see NewSessionIniter. +func (d *drv) NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { + cxr, err := d.OpenConnector(name) if err != nil { return nil, err } @@ -1073,6 +933,15 @@ func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector return cx, err } +// NewConnector returns a driver.Connector to be used with sql.OpenDB, +// (for the default Driver registered with godror) +// which calls the given onInit if the connection is new. +// +// For an onInit example, see NewSessionIniter. +func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { + return defaultDrv.NewConnector(name, onInit) +} + // NewSessionIniter returns a function suitable for use in NewConnector as onInit, // which calls "ALTER SESSION SET =''" for each element of the given map. func NewSessionIniter(m map[string]string) func(driver.Conn) error { diff --git a/vendor/github.com/godror/godror/go.mod b/vendor/github.com/godror/godror/go.mod index d7c794d6705..86f145abad2 100644 --- a/vendor/github.com/godror/godror/go.mod +++ b/vendor/github.com/godror/godror/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/go-kit/kit v0.9.0 - github.com/go-logfmt/logfmt v0.4.0 // indirect + github.com/go-logfmt/logfmt v0.4.0 github.com/go-stack/stack v1.8.0 // indirect github.com/google/go-cmp v0.3.1 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e diff --git a/vendor/github.com/godror/godror/obj.go b/vendor/github.com/godror/godror/obj.go index a5d35505420..17d03d732fa 100644 --- a/vendor/github.com/godror/godror/obj.go +++ b/vendor/github.com/godror/godror/obj.go @@ -15,6 +15,7 @@ import ( "fmt" "reflect" "strings" + "sync" "unsafe" errors "golang.org/x/xerrors" @@ -24,9 +25,8 @@ var _ = fmt.Printf // Object represents a dpiObject. type Object struct { - ObjectType - scratch Data dpiObject *C.dpiObject + ObjectType } func (O *Object) getError() error { return O.conn.getError() } @@ -45,20 +45,18 @@ func (O *Object) GetAttribute(data *Data, name string) error { } data.reset() - if data.dpiData == nil { - data.dpiData = &C.dpiData{isNull: 0} - } data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType + data.implicitObj = true // the maximum length of that buffer must be supplied // in the value.asBytes.length attribute before calling this function. if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { var a [39]byte - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(len(a))) + C.dpiData_setBytes(&data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(len(a))) } //fmt.Printf("getAttributeValue(%p, %p, %d, %+v)\n", O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) - if C.dpiObject_getAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { + if C.dpiObject_getAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return errors.Errorf("getAttributeValue(%q, obj=%+v, attr=%+v, typ=%d): %w", name, O, attr.dpiObjectAttr, data.NativeTypeNum, O.getError()) } //fmt.Printf("getAttributeValue(%p, %q=%p, %d, %+v)\n", O.dpiObject, attr.Name, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) @@ -75,7 +73,7 @@ func (O *Object) SetAttribute(name string, data *Data) error { data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType } - if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { + if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return O.getError() } return nil @@ -86,10 +84,12 @@ func (O *Object) Set(name string, v interface{}) error { if data, ok := v.(*Data); ok { return O.SetAttribute(name, data) } - if err := O.scratch.Set(v); err != nil { + d := scratch.Get() + defer scratch.Put(d) + if err := d.Set(v); err != nil { return err } - return O.SetAttribute(name, &O.scratch) + return O.SetAttribute(name, d) } // ResetAttributes prepare all attributes for use the object as IN parameter @@ -101,9 +101,9 @@ func (O *Object) ResetAttributes() error { data.ObjectType = attr.ObjectType if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { a := make([]byte, attr.Precision) - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(attr.Precision)) + C.dpiData_setBytes(&data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(attr.Precision)) } - if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { + if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return O.getError() } } @@ -113,14 +113,16 @@ func (O *Object) ResetAttributes() error { // Get scans the named attribute into dest, and returns it. func (O *Object) Get(name string) (interface{}, error) { - if err := O.GetAttribute(&O.scratch, name); err != nil { + d := scratch.Get() + defer scratch.Put(d) + if err := O.GetAttribute(d, name); err != nil { return nil, err } - isObject := O.scratch.IsObject() + isObject := d.IsObject() if isObject { - O.scratch.ObjectType = O.Attributes[name].ObjectType + d.ObjectType = O.Attributes[name].ObjectType } - v := O.scratch.Get() + v := d.Get() if !isObject { return v, nil } @@ -138,11 +140,11 @@ func (O *Object) ObjectRef() *Object { // Collection returns &ObjectCollection{Object: O} iff the Object is a collection. // Otherwise it returns nil. -func (O *Object) Collection() *ObjectCollection { +func (O *Object) Collection() ObjectCollection { if O.ObjectType.CollectionOf == nil { - return nil + return ObjectCollection{} } - return &ObjectCollection{Object: O} + return ObjectCollection{Object: O} } // Close releases a reference to the object. @@ -171,20 +173,22 @@ var ErrNotCollection = errors.New("not collection") var ErrNotExist = errors.New("not exist") // AsSlice retrieves the collection into a slice. -func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { +func (O ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { var dr reflect.Value needsInit := dest == nil if !needsInit { dr = reflect.ValueOf(dest) } + d := scratch.Get() + defer scratch.Put(d) for i, err := O.First(); err == nil; i, err = O.Next(i) { if O.CollectionOf.NativeTypeNum == C.DPI_NATIVE_TYPE_OBJECT { - O.scratch.ObjectType = *O.CollectionOf + d.ObjectType = *O.CollectionOf } - if err = O.GetItem(&O.scratch, i); err != nil { + if err = O.GetItem(d, i); err != nil { return dest, err } - vr := reflect.ValueOf(O.scratch.Get()) + vr := reflect.ValueOf(d.Get()) if needsInit { needsInit = false length, lengthErr := O.Len() @@ -199,37 +203,38 @@ func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { } // AppendData to the collection. -func (O *ObjectCollection) AppendData(data *Data) error { - if C.dpiObject_appendElement(O.dpiObject, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { +func (O ObjectCollection) AppendData(data *Data) error { + if C.dpiObject_appendElement(O.dpiObject, data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return errors.Errorf("append(%d): %w", data.NativeTypeNum, O.getError()) } return nil } // Append v to the collection. -func (O *ObjectCollection) Append(v interface{}) error { +func (O ObjectCollection) Append(v interface{}) error { if data, ok := v.(*Data); ok { return O.AppendData(data) } - if err := O.scratch.Set(v); err != nil { + d := scratch.Get() + defer scratch.Put(d) + if err := d.Set(v); err != nil { return err } - return O.AppendData(&O.scratch) + return O.AppendData(d) } // AppendObject adds an Object to the collection. -func (O *ObjectCollection) AppendObject(obj *Object) error { - O.scratch = Data{ - ObjectType: obj.ObjectType, - NativeTypeNum: C.DPI_NATIVE_TYPE_OBJECT, - dpiData: &C.dpiData{isNull: 1}, - } - O.scratch.SetObject(obj) - return O.Append(&O.scratch) +func (O ObjectCollection) AppendObject(obj *Object) error { + d := scratch.Get() + defer scratch.Put(d) + d.ObjectType = obj.ObjectType + d.NativeTypeNum = C.DPI_NATIVE_TYPE_OBJECT + d.SetObject(obj) + return O.Append(d) } // Delete i-th element of the collection. -func (O *ObjectCollection) Delete(i int) error { +func (O ObjectCollection) Delete(i int) error { if C.dpiObject_deleteElementByIndex(O.dpiObject, C.int32_t(i)) == C.DPI_FAILURE { return errors.Errorf("delete(%d): %w", i, O.getError()) } @@ -237,7 +242,7 @@ func (O *ObjectCollection) Delete(i int) error { } // GetItem gets the i-th element of the collection into data. -func (O *ObjectCollection) GetItem(data *Data, i int) error { +func (O ObjectCollection) GetItem(data *Data, i int) error { if data == nil { panic("data cannot be nil") } @@ -252,40 +257,43 @@ func (O *ObjectCollection) GetItem(data *Data, i int) error { data.reset() data.NativeTypeNum = O.CollectionOf.NativeTypeNum data.ObjectType = *O.CollectionOf - if C.dpiObject_getElementValueByIndex(O.dpiObject, idx, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { + data.implicitObj = true + if C.dpiObject_getElementValueByIndex(O.dpiObject, idx, data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return errors.Errorf("get(%d[%d]): %w", idx, data.NativeTypeNum, O.getError()) } return nil } // Get the i-th element of the collection. -func (O *ObjectCollection) Get(i int) (interface{}, error) { +func (O ObjectCollection) Get(i int) (interface{}, error) { var data Data err := O.GetItem(&data, i) return data.Get(), err } // SetItem sets the i-th element of the collection with data. -func (O *ObjectCollection) SetItem(i int, data *Data) error { - if C.dpiObject_setElementValueByIndex(O.dpiObject, C.int32_t(i), data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { +func (O ObjectCollection) SetItem(i int, data *Data) error { + if C.dpiObject_setElementValueByIndex(O.dpiObject, C.int32_t(i), data.NativeTypeNum, &data.dpiData) == C.DPI_FAILURE { return errors.Errorf("set(%d[%d]): %w", i, data.NativeTypeNum, O.getError()) } return nil } // Set the i-th element of the collection with value. -func (O *ObjectCollection) Set(i int, v interface{}) error { +func (O ObjectCollection) Set(i int, v interface{}) error { if data, ok := v.(*Data); ok { return O.SetItem(i, data) } - if err := O.scratch.Set(v); err != nil { + d := scratch.Get() + defer scratch.Put(d) + if err := d.Set(v); err != nil { return err } - return O.SetItem(i, &O.scratch) + return O.SetItem(i, d) } // First returns the first element's index of the collection. -func (O *ObjectCollection) First() (int, error) { +func (O ObjectCollection) First() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getFirstIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { @@ -298,7 +306,7 @@ func (O *ObjectCollection) First() (int, error) { } // Last returns the index of the last element. -func (O *ObjectCollection) Last() (int, error) { +func (O ObjectCollection) Last() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getLastIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { @@ -311,7 +319,7 @@ func (O *ObjectCollection) Last() (int, error) { } // Next returns the succeeding index of i. -func (O *ObjectCollection) Next(i int) (int, error) { +func (O ObjectCollection) Next(i int) (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getNextIndex(O.dpiObject, C.int32_t(i), &idx, &exists) == C.DPI_FAILURE { @@ -324,7 +332,7 @@ func (O *ObjectCollection) Next(i int) (int, error) { } // Len returns the length of the collection. -func (O *ObjectCollection) Len() (int, error) { +func (O ObjectCollection) Len() (int, error) { var size C.int32_t if C.dpiObject_getSize(O.dpiObject, &size) == C.DPI_FAILURE { return 0, errors.Errorf("len: %w", O.getError()) @@ -333,7 +341,7 @@ func (O *ObjectCollection) Len() (int, error) { } // Trim the collection to n. -func (O *ObjectCollection) Trim(n int) error { +func (O ObjectCollection) Trim(n int) error { if C.dpiObject_trim(O.dpiObject, C.uint32_t(n)) == C.DPI_FAILURE { return O.getError() } @@ -342,13 +350,14 @@ func (O *ObjectCollection) Trim(n int) error { // ObjectType holds type info of an Object. type ObjectType struct { - dpiObjectType *C.dpiObjectType + Schema, Name string + Attributes map[string]ObjectAttribute + conn *conn + dpiObjectType *C.dpiObjectType - Schema, Name string DBSize, ClientSizeInBytes, CharSize int CollectionOf *ObjectType - Attributes map[string]ObjectAttribute OracleTypeNum C.dpiOracleTypeNum NativeTypeNum C.dpiNativeTypeNum Precision int16 @@ -397,6 +406,7 @@ func (c *conn) GetObjectType(name string) (ObjectType, error) { err := t.init() if err == nil { c.objTypes[name] = t + c.objTypes[t.FullName()] = t } return t, err } @@ -417,25 +427,32 @@ func (t ObjectType) NewObject() (*Object, error) { // NewCollection returns a new Collection object with ObjectType type. // If the ObjectType is not a Collection, it returns ErrNotCollection error. -func (t ObjectType) NewCollection() (*ObjectCollection, error) { +func (t ObjectType) NewCollection() (ObjectCollection, error) { if t.CollectionOf == nil { - return nil, ErrNotCollection + return ObjectCollection{}, ErrNotCollection } O, err := t.NewObject() if err != nil { - return nil, err + return ObjectCollection{}, err } - return &ObjectCollection{Object: O}, nil + return ObjectCollection{Object: O}, nil } // Close releases a reference to the object type. -func (t *ObjectType) close() error { +func (t *ObjectType) close(doNotReuse bool) error { if t == nil { return nil } attributes, d := t.Attributes, t.dpiObjectType t.Attributes, t.dpiObjectType = nil, nil + if t.CollectionOf != nil { + err := t.CollectionOf.close(false) + if err != nil { + return err + } + } + for _, attr := range attributes { err := attr.Close() if err != nil { @@ -443,7 +460,7 @@ func (t *ObjectType) close() error { } } - if d == nil { + if d == nil || !doNotReuse { return nil } @@ -500,9 +517,12 @@ func (t *ObjectType) init() error { t.CollectionOf.Name = t.Name } } + if ot, ok := t.conn.objTypes[t.FullName()]; ok { + t.Attributes = ot.Attributes + return nil + } if numAttributes == 0 { t.Attributes = map[string]ObjectAttribute{} - t.conn.objTypes[t.FullName()] = *t return nil } t.Attributes = make(map[string]ObjectAttribute, numAttributes) @@ -534,7 +554,6 @@ func (t *ObjectType) init() error { //fmt.Printf("%d=%q. typ=%+v sub=%+v\n", i, objAttr.Name, typ, sub) t.Attributes[objAttr.Name] = objAttr } - t.conn.objTypes[t.FullName()] = *t return nil } @@ -581,6 +600,12 @@ func (A ObjectAttribute) Close() error { if C.dpiObjectAttr_release(attr) == C.DPI_FAILURE { return A.getError() } + if A.ObjectType.dpiObjectType != nil { + err := A.ObjectType.close(false) + if err != nil { + return err + } + } return nil } @@ -592,3 +617,10 @@ func GetObjectType(ctx context.Context, ex Execer, typeName string) (ObjectType, } return c.GetObjectType(typeName) } + +var scratch = &dataPool{Pool: sync.Pool{New: func() interface{} { return &Data{} }}} + +type dataPool struct{ sync.Pool } + +func (dp *dataPool) Get() *Data { return dp.Pool.Get().(*Data) } +func (dp *dataPool) Put(d *Data) { d.reset(); dp.Pool.Put(d) } diff --git a/vendor/github.com/godror/godror/orahlp.go b/vendor/github.com/godror/godror/orahlp.go index 94e1f74828d..b9b5068f51f 100644 --- a/vendor/github.com/godror/godror/orahlp.go +++ b/vendor/github.com/godror/godror/orahlp.go @@ -13,12 +13,211 @@ import ( "database/sql/driver" "fmt" "io" + "math" + "strconv" "sync" "time" errors "golang.org/x/xerrors" ) +// Number as string +type Number string + +var ( + // Int64 for converting to-from int64. + Int64 = intType{} + // Float64 for converting to-from float64. + Float64 = floatType{} + // Num for converting to-from Number (string) + Num = numType{} +) + +type intType struct{} + +func (intType) String() string { return "Int64" } +func (intType) ConvertValue(v interface{}) (driver.Value, error) { + if Log != nil { + Log("ConvertValue", "Int64", "value", v) + } + switch x := v.(type) { + case int8: + return int64(x), nil + case int16: + return int64(x), nil + case int32: + return int64(x), nil + case int64: + return x, nil + case uint16: + return int64(x), nil + case uint32: + return int64(x), nil + case uint64: + return int64(x), nil + case float32: + if _, f := math.Modf(float64(x)); f != 0 { + return int64(x), errors.Errorf("non-zero fractional part: %f", f) + } + return int64(x), nil + case float64: + if _, f := math.Modf(x); f != 0 { + return int64(x), errors.Errorf("non-zero fractional part: %f", f) + } + return int64(x), nil + case string: + if x == "" { + return 0, nil + } + return strconv.ParseInt(x, 10, 64) + case Number: + if x == "" { + return 0, nil + } + return strconv.ParseInt(string(x), 10, 64) + default: + return nil, errors.Errorf("unknown type %T", v) + } +} + +type floatType struct{} + +func (floatType) String() string { return "Float64" } +func (floatType) ConvertValue(v interface{}) (driver.Value, error) { + if Log != nil { + Log("ConvertValue", "Float64", "value", v) + } + switch x := v.(type) { + case int8: + return float64(x), nil + case int16: + return float64(x), nil + case int32: + return float64(x), nil + case uint16: + return float64(x), nil + case uint32: + return float64(x), nil + case int64: + return float64(x), nil + case uint64: + return float64(x), nil + case float32: + return float64(x), nil + case float64: + return x, nil + case string: + if x == "" { + return 0, nil + } + return strconv.ParseFloat(x, 64) + case Number: + if x == "" { + return 0, nil + } + return strconv.ParseFloat(string(x), 64) + default: + return nil, errors.Errorf("unknown type %T", v) + } +} + +type numType struct{} + +func (numType) String() string { return "Num" } +func (numType) ConvertValue(v interface{}) (driver.Value, error) { + if Log != nil { + Log("ConvertValue", "Num", "value", v) + } + switch x := v.(type) { + case string: + if x == "" { + return 0, nil + } + return x, nil + case Number: + if x == "" { + return 0, nil + } + return string(x), nil + case int8, int16, int32, int64, uint16, uint32, uint64: + return fmt.Sprintf("%d", x), nil + case float32, float64: + return fmt.Sprintf("%f", x), nil + default: + return nil, errors.Errorf("unknown type %T", v) + } +} +func (n Number) String() string { return string(n) } + +// Value returns the Number as driver.Value +func (n Number) Value() (driver.Value, error) { + return string(n), nil +} + +// Scan into the Number from a driver.Value. +func (n *Number) Scan(v interface{}) error { + if v == nil { + *n = "" + return nil + } + switch x := v.(type) { + case string: + *n = Number(x) + case Number: + *n = x + case int8, int16, int32, int64, uint16, uint32, uint64: + *n = Number(fmt.Sprintf("%d", x)) + case float32, float64: + *n = Number(fmt.Sprintf("%f", x)) + default: + return errors.Errorf("unknown type %T", v) + } + return nil +} + +// MarshalText marshals a Number to text. +func (n Number) MarshalText() ([]byte, error) { return []byte(n), nil } + +// UnmarshalText parses text into a Number. +func (n *Number) UnmarshalText(p []byte) error { + var dotNum int + for i, c := range p { + if !(c == '-' && i == 0 || '0' <= c && c <= '9') { + if c == '.' { + dotNum++ + if dotNum == 1 { + continue + } + } + return errors.Errorf("unknown char %c in %q", c, p) + } + } + *n = Number(p) + return nil +} + +// MarshalJSON marshals a Number into a JSON string. +func (n Number) MarshalJSON() ([]byte, error) { + b, err := n.MarshalText() + b2 := make([]byte, 1, 1+len(b)+1) + b2[0] = '"' + b2 = append(b2, b...) + b2 = append(b2, '"') + return b2, err +} + +// UnmarshalJSON parses a JSON string into the Number. +func (n *Number) UnmarshalJSON(p []byte) error { + *n = Number("") + if len(p) == 0 { + return nil + } + if len(p) > 2 && p[0] == '"' && p[len(p)-1] == '"' { + p = p[1 : len(p)-1] + } + return n.UnmarshalText(p) +} + // QueryColumn is the described column. type QueryColumn struct { Name string diff --git a/vendor/github.com/godror/godror/queue.go b/vendor/github.com/godror/godror/queue.go index 01f081452af..70b4d018377 100644 --- a/vendor/github.com/godror/godror/queue.go +++ b/vendor/github.com/godror/godror/queue.go @@ -40,13 +40,13 @@ var DefaultDeqOptions = DeqOptions{ // Queue represents an Oracle Advanced Queue. type Queue struct { - conn *conn - dpiQueue *C.dpiQueue PayloadObjectType ObjectType + props []*C.dpiMsgProps name string + conn *conn + dpiQueue *C.dpiQueue - mu sync.Mutex - props []*C.dpiMsgProps + mu sync.Mutex } // NewQueue creates a new Queue. @@ -211,15 +211,15 @@ func (Q *Queue) Enqueue(messages []Message) error { // Message is a message - either received or being sent. type Message struct { - DeliveryMode DeliveryMode - Enqueued time.Time - Delay, Expiration int32 - Priority, NumAttempts int32 Correlation, ExceptionQ string + Enqueued time.Time MsgID, OriginalMsgID [16]byte - State MessageState Raw []byte + Delay, Expiration int32 + Priority, NumAttempts int32 Object *Object + DeliveryMode DeliveryMode + State MessageState } func (M *Message) toOra(d *drv, props *C.dpiMsgProps) error { @@ -334,7 +334,7 @@ func (M *Message) fromOra(c *conn, props *C.dpiMsgProps, objType *ObjectType) er if n > MsgIDLength { n = MsgIDLength } - copy(M.MsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + copy(M.MsgID[:], C.GoBytes(unsafe.Pointer(value), n)) } M.OriginalMsgID = zeroMsgID @@ -343,7 +343,7 @@ func (M *Message) fromOra(c *conn, props *C.dpiMsgProps, objType *ObjectType) er if n > MsgIDLength { n = MsgIDLength } - copy(M.OriginalMsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + copy(M.OriginalMsgID[:], C.GoBytes(unsafe.Pointer(value), n)) } M.Priority = 0 @@ -362,7 +362,7 @@ func (M *Message) fromOra(c *conn, props *C.dpiMsgProps, objType *ObjectType) er var obj *C.dpiObject if OK(C.dpiMsgProps_getPayload(props, &obj, &value, &length), "getPayload") { if obj == nil { - M.Raw = append(make([]byte, 0, length), ((*[1 << 30]byte)(unsafe.Pointer(value)))[:int(length):int(length)]...) + M.Raw = C.GoBytes(unsafe.Pointer(value), C.int(length)) } else { if C.dpiObject_addRef(obj) == C.DPI_FAILURE { return objType.getError() diff --git a/vendor/github.com/godror/godror/stmt.go b/vendor/github.com/godror/godror/stmt.go index 0e0775b363d..3a2f6d291a1 100644 --- a/vendor/github.com/godror/godror/stmt.go +++ b/vendor/github.com/godror/godror/stmt.go @@ -285,8 +285,8 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) } st.isReturning = false - st.conn.RLock() - defer st.conn.RUnlock() + st.conn.mu.RLock() + defer st.conn.mu.RUnlock() // bind variables if err = st.bindVars(args, Log); err != nil { @@ -304,6 +304,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) // execute go func() { defer close(done) + var err error Loop: for i := 0; i < 3; i++ { if err = ctx.Err(); err != nil { @@ -339,7 +340,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) err = errors.Errorf("getInfo: %w", st.getError()) } st.isReturning = info.isReturning != 0 - return + break } var cdr interface{ Code() int } if !errors.As(err, &cdr) { @@ -379,7 +380,9 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK statement") } _ = st.Break() - st.close(false) + // For some reasons this SIGSEGVs if not not keepDpiStmt (try to close it), + st.close(true) + // so we hope that the following conn.Close closes the dpiStmt, too. if err := st.conn.Close(); err != nil { return nil, err } @@ -465,8 +468,8 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) st.Lock() defer st.Unlock() st.isReturning = false - st.conn.RLock() - defer st.conn.RUnlock() + st.conn.mu.RLock() + defer st.conn.mu.RUnlock() switch st.query { case getConnection: @@ -539,7 +542,9 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK query") } _ = st.Break() - st.close(false) + // For some reasons this SIGSEGVs if not not keepDpiStmt (try to close it), + st.close(true) + // so we hope that the following conn.Close closes the dpiStmt, too. if err := st.conn.Close(); err != nil { return nil, err } @@ -1920,13 +1925,13 @@ func (c *conn) dataGetObject(v interface{}, data []C.dpiData) error { case *Object: d := Data{ ObjectType: out.ObjectType, - dpiData: &data[0], + dpiData: data[0], } *out = *d.GetObject() case ObjectScanner: d := Data{ ObjectType: out.ObjectRef().ObjectType, - dpiData: &data[0], + dpiData: data[0], } return out.Scan(d.GetObject()) default: diff --git a/vendor/github.com/godror/godror/subscr.go b/vendor/github.com/godror/godror/subscr.go index 07355e591c7..872f7ee6969 100644 --- a/vendor/github.com/godror/godror/subscr.go +++ b/vendor/github.com/godror/godror/subscr.go @@ -18,11 +18,19 @@ import "C" import ( "log" "strings" + "sync" "unsafe" errors "golang.org/x/xerrors" ) +// Cannot pass *Subscription to C, so pass an uint64 that points to this map entry +var ( + subscriptionsMu sync.Mutex + subscriptions = make(map[uint64]*Subscription) + subscriptionsID uint64 +) + // CallbackSubscr is the callback for C code on subscription event. //export CallbackSubscr func CallbackSubscr(ctx unsafe.Pointer, message *C.dpiSubscrMessage) { @@ -30,7 +38,9 @@ func CallbackSubscr(ctx unsafe.Pointer, message *C.dpiSubscrMessage) { if ctx == nil { return } - subscr := (*Subscription)(ctx) + subscriptionsMu.Lock() + subscr := subscriptions[*((*uint64)(ctx))] + subscriptionsMu.Unlock() getRows := func(rws *C.dpiSubscrMessageRow, rwsNum C.uint32_t) []RowEvent { if rwsNum == 0 { @@ -124,6 +134,7 @@ type Subscription struct { conn *conn dpiSubscr *C.dpiSubscr callback func(Event) + ID uint64 } func (s *Subscription) getError() error { return s.conn.getError() } @@ -140,7 +151,7 @@ func (c *conn) NewSubscription(name string, cb func(Event)) (*Subscription, erro subscr := Subscription{conn: c, callback: cb} params := (*C.dpiSubscrCreateParams)(C.malloc(C.sizeof_dpiSubscrCreateParams)) //defer func() { C.free(unsafe.Pointer(params)) }() - C.dpiContext_initSubscrCreateParams(c.dpiContext, params) + C.dpiContext_initSubscrCreateParams(c.drv.dpiContext, params) params.subscrNamespace = C.DPI_SUBSCR_NAMESPACE_DBCHANGE params.protocol = C.DPI_SUBSCR_PROTO_CALLBACK params.qos = C.DPI_SUBSCR_QOS_BEST_EFFORT | C.DPI_SUBSCR_QOS_QUERY | C.DPI_SUBSCR_QOS_ROWIDS @@ -151,7 +162,15 @@ func (c *conn) NewSubscription(name string, cb func(Event)) (*Subscription, erro } // typedef void (*dpiSubscrCallback)(void* context, dpiSubscrMessage *message); params.callback = C.dpiSubscrCallback(C.CallbackSubscrDebug) - params.callbackContext = unsafe.Pointer(&subscr) + // cannot pass &subscr to C, so pass indirectly + subscriptionsMu.Lock() + subscriptionsID++ + subscr.ID = subscriptionsID + subscriptions[subscr.ID] = &subscr + subscriptionsMu.Unlock() + subscrID := (*C.uint64_t)(C.malloc(8)) + *subscrID = C.uint64_t(subscriptionsID) + params.callbackContext = unsafe.Pointer(subscrID) dpiSubscr := (*C.dpiSubscr)(C.malloc(C.sizeof_void)) @@ -204,6 +223,9 @@ func (s *Subscription) Register(qry string, params ...interface{}) error { // // This code is EXPERIMENTAL yet! func (s *Subscription) Close() error { + subscriptionsMu.Lock() + delete(subscriptions, s.ID) + subscriptionsMu.Unlock() dpiSubscr := s.dpiSubscr conn := s.conn s.conn = nil diff --git a/vendor/github.com/godror/godror/version.go b/vendor/github.com/godror/godror/version.go index 5dace8e1b09..66059da1141 100644 --- a/vendor/github.com/godror/godror/version.go +++ b/vendor/github.com/godror/godror/version.go @@ -1,4 +1,4 @@ -// Copyright 2019 Tamás Gulácsi. +// Copyright 2020 Tamás Gulácsi. // // SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 @@ -7,4 +7,4 @@ package godror //go:generate bash -c "echo 3.3.0>odpi-version; set -x; curl -L https://github.com/oracle/odpi/archive/v$(cat odpi-version).tar.gz | tar xzvf - odpi-$(cat odpi-version)/{embed,include,src,CONTRIBUTING.md,LICENSE.md,README.md} && rm -rf odpi && mv odpi-$(cat odpi-version) odpi; rm -f odpi-version" // Version of this driver -const Version = "v0.0.1" +const Version = "v0.10.4" diff --git a/vendor/vendor.json b/vendor/vendor.json index 3ee78bf7257..4dca573df82 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3449,13 +3449,13 @@ "revisionTime": "2019-09-30T11:59:46Z" }, { - "checksumSHA1": "fW8mQy9XfBOcO8dwudie7NHXC5o=", + "checksumSHA1": "xJkfP+WyfKJSBcEa+8T15QjNIr4=", "path": "github.com/godror/godror", - "revision": "446a29355d2967f04604e8e015a3343917860adf", - "revisionTime": "2019-12-12T16:49:28Z", + "revision": "0123d49bd73e1bed106ac8b6af67f943fbbf06e2", + "revisionTime": "2020-01-12T11:05:39Z", "tree": true, - "version": "v0.9.0", - "versionExact": "v0.9.0" + "version": "v0.10.4", + "versionExact": "v0.10.4" }, { "checksumSHA1": "MlaWEe1K+Kpb9wDF88qPoqO1uro=", From e042d5c829b0e02feae324c78dd560d8efedb9a6 Mon Sep 17 00:00:00 2001 From: Shaunak Kashyap Date: Wed, 22 Jan 2020 05:15:29 -0800 Subject: [PATCH 35/37] Collect normalized CPU percentages by default (#15729) * Collect normalized CPU percentages by default * Adding CHANGELOG entry * Updating x-pack/metricbeat --- CHANGELOG.next.asciidoc | 1 + metricbeat/docs/modules/system.asciidoc | 2 +- metricbeat/metricbeat.reference.yml | 2 +- metricbeat/module/system/_meta/config.reference.yml | 2 +- metricbeat/module/system/cpu/config.go | 2 +- x-pack/metricbeat/metricbeat.reference.yml | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b59f02281ab..6f43061131f 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -94,6 +94,7 @@ TLS or Beats that accept connections over TLS and validate client certificates. - Release elb module as GA. {pull}15485[15485] - Add a `system/network_summary` metricset {pull}15196[15196] - Add mesh metricset for Istio Metricbeat module{pull}15535[15535] +- Make the `system/cpu` metricset collect normalized CPU metrics by default. {issue}15618[15618] {pull}15729[15729] *Packetbeat* diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc index a832eb5f854..74c9c06a794 100644 --- a/metricbeat/docs/modules/system.asciidoc +++ b/metricbeat/docs/modules/system.asciidoc @@ -178,7 +178,7 @@ metricbeat.modules: processes: ['.*'] # Configure the metric types that are included by these metricsets. - cpu.metrics: ["percentages"] # The other available options are normalized_percentages and ticks. + cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. core.metrics: ["percentages"] # The other available option is ticks. # A list of filesystem types to ignore. The filesystem metricset will not diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 6adc5c22956..4a8dea2095b 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -79,7 +79,7 @@ metricbeat.modules: processes: ['.*'] # Configure the metric types that are included by these metricsets. - cpu.metrics: ["percentages"] # The other available options are normalized_percentages and ticks. + cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. core.metrics: ["percentages"] # The other available option is ticks. # A list of filesystem types to ignore. The filesystem metricset will not diff --git a/metricbeat/module/system/_meta/config.reference.yml b/metricbeat/module/system/_meta/config.reference.yml index a30b782ac63..a6023d23ddc 100644 --- a/metricbeat/module/system/_meta/config.reference.yml +++ b/metricbeat/module/system/_meta/config.reference.yml @@ -20,7 +20,7 @@ processes: ['.*'] # Configure the metric types that are included by these metricsets. - cpu.metrics: ["percentages"] # The other available options are normalized_percentages and ticks. + cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. core.metrics: ["percentages"] # The other available option is ticks. # A list of filesystem types to ignore. The filesystem metricset will not diff --git a/metricbeat/module/system/cpu/config.go b/metricbeat/module/system/cpu/config.go index 169d59ca1f9..291ee7963ef 100644 --- a/metricbeat/module/system/cpu/config.go +++ b/metricbeat/module/system/cpu/config.go @@ -62,5 +62,5 @@ func (c Config) Validate() error { } var defaultConfig = Config{ - Metrics: []string{percentages}, + Metrics: []string{percentages, normalizedPercentages}, } diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index b5939aecede..c5ab17ef96d 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -79,7 +79,7 @@ metricbeat.modules: processes: ['.*'] # Configure the metric types that are included by these metricsets. - cpu.metrics: ["percentages"] # The other available options are normalized_percentages and ticks. + cpu.metrics: ["percentages","normalized_percentages"] # The other available option is ticks. core.metrics: ["percentages"] # The other available option is ticks. # A list of filesystem types to ignore. The filesystem metricset will not From e0429cd9bda6293e9173d7e5318c5640a8bf2012 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 22 Jan 2020 16:09:23 +0100 Subject: [PATCH 36/37] Fix: mage check --- filebeat/include/list.go | 1 + filebeat/input/mqtt/client.go | 7 +- .../eclipse/paho.mqtt.golang/CONTRIBUTING.md | 56 + .../eclipse/paho.mqtt.golang/DISTRIBUTION | 15 + .../eclipse/paho.mqtt.golang/LICENSE | 87 ++ .../eclipse/paho.mqtt.golang/README.md | 71 + .../eclipse/paho.mqtt.golang/about.html | 41 + .../eclipse/paho.mqtt.golang/client.go | 965 +++++++++++++ .../eclipse/paho.mqtt.golang/components.go | 31 + .../eclipse/paho.mqtt.golang/edl-v10 | 15 + .../eclipse/paho.mqtt.golang/epl-v10 | 70 + .../eclipse/paho.mqtt.golang/filestore.go | 255 ++++ .../eclipse/paho.mqtt.golang/memstore.go | 138 ++ .../eclipse/paho.mqtt.golang/message.go | 127 ++ .../eclipse/paho.mqtt.golang/messageids.go | 141 ++ .../eclipse/paho.mqtt.golang/net.go | 330 +++++ .../eclipse/paho.mqtt.golang/notice.html | 108 ++ .../eclipse/paho.mqtt.golang/oops.go | 21 + .../eclipse/paho.mqtt.golang/options.go | 374 +++++ .../paho.mqtt.golang/options_reader.go | 161 +++ .../paho.mqtt.golang/packets/connack.go | 52 + .../paho.mqtt.golang/packets/connect.go | 151 +++ .../paho.mqtt.golang/packets/disconnect.go | 34 + .../paho.mqtt.golang/packets/packets.go | 346 +++++ .../paho.mqtt.golang/packets/pingreq.go | 34 + .../paho.mqtt.golang/packets/pingresp.go | 34 + .../paho.mqtt.golang/packets/puback.go | 42 + .../paho.mqtt.golang/packets/pubcomp.go | 42 + .../paho.mqtt.golang/packets/publish.go | 83 ++ .../paho.mqtt.golang/packets/pubrec.go | 42 + .../paho.mqtt.golang/packets/pubrel.go | 42 + .../paho.mqtt.golang/packets/suback.go | 57 + .../paho.mqtt.golang/packets/subscribe.go | 69 + .../paho.mqtt.golang/packets/unsuback.go | 42 + .../paho.mqtt.golang/packets/unsubscribe.go | 56 + .../eclipse/paho.mqtt.golang/ping.go | 69 + .../eclipse/paho.mqtt.golang/router.go | 181 +++ .../eclipse/paho.mqtt.golang/store.go | 136 ++ .../eclipse/paho.mqtt.golang/token.go | 183 +++ .../eclipse/paho.mqtt.golang/topic.go | 86 ++ .../eclipse/paho.mqtt.golang/trace.go | 40 + .../eclipse/paho.mqtt.golang/websocket.go | 95 ++ vendor/github.com/gorilla/websocket/AUTHORS | 9 + vendor/github.com/gorilla/websocket/LICENSE | 22 + vendor/github.com/gorilla/websocket/README.md | 64 + vendor/github.com/gorilla/websocket/client.go | 395 ++++++ .../gorilla/websocket/client_clone.go | 16 + .../gorilla/websocket/client_clone_legacy.go | 38 + .../gorilla/websocket/compression.go | 148 ++ vendor/github.com/gorilla/websocket/conn.go | 1201 +++++++++++++++++ .../gorilla/websocket/conn_write.go | 15 + .../gorilla/websocket/conn_write_legacy.go | 18 + vendor/github.com/gorilla/websocket/doc.go | 227 ++++ vendor/github.com/gorilla/websocket/go.mod | 3 + vendor/github.com/gorilla/websocket/go.sum | 2 + vendor/github.com/gorilla/websocket/join.go | 42 + vendor/github.com/gorilla/websocket/json.go | 60 + vendor/github.com/gorilla/websocket/mask.go | 54 + .../github.com/gorilla/websocket/mask_safe.go | 15 + .../github.com/gorilla/websocket/prepared.go | 102 ++ vendor/github.com/gorilla/websocket/proxy.go | 77 ++ vendor/github.com/gorilla/websocket/server.go | 363 +++++ vendor/github.com/gorilla/websocket/trace.go | 19 + .../github.com/gorilla/websocket/trace_17.go | 12 + vendor/github.com/gorilla/websocket/util.go | 283 ++++ .../gorilla/websocket/x_net_proxy.go | 473 +++++++ .../appengine/datastore/datastore.go | 407 ++++++ .../appengine/datastore/doc.go | 361 +++++ .../datastore/internal/cloudkey/cloudkey.go | 120 ++ .../datastore/internal/cloudpb/entity.pb.go | 344 +++++ .../appengine/datastore/key.go | 400 ++++++ .../appengine/datastore/keycompat.go | 89 ++ .../appengine/datastore/load.go | 429 ++++++ .../appengine/datastore/metadata.go | 78 ++ .../appengine/datastore/prop.go | 330 +++++ .../appengine/datastore/query.go | 774 +++++++++++ .../appengine/datastore/save.go | 333 +++++ .../appengine/datastore/transaction.go | 96 ++ .../gopkg.in/vmihailenco/msgpack.v2/LICENSE | 27 + .../gopkg.in/vmihailenco/msgpack.v2/Makefile | 5 + .../gopkg.in/vmihailenco/msgpack.v2/README.md | 69 + .../vmihailenco/msgpack.v2/appengine.go | 69 + .../vmihailenco/msgpack.v2/codes/codes.go | 76 ++ .../gopkg.in/vmihailenco/msgpack.v2/decode.go | 425 ++++++ .../vmihailenco/msgpack.v2/decode_map.go | 265 ++++ .../vmihailenco/msgpack.v2/decode_number.go | 270 ++++ .../vmihailenco/msgpack.v2/decode_query.go | 158 +++ .../vmihailenco/msgpack.v2/decode_slice.go | 197 +++ .../vmihailenco/msgpack.v2/decode_string.go | 168 +++ .../vmihailenco/msgpack.v2/decode_value.go | 248 ++++ .../gopkg.in/vmihailenco/msgpack.v2/encode.go | 144 ++ .../vmihailenco/msgpack.v2/encode_map.go | 166 +++ .../vmihailenco/msgpack.v2/encode_number.go | 138 ++ .../vmihailenco/msgpack.v2/encode_slice.go | 120 ++ .../vmihailenco/msgpack.v2/encode_value.go | 167 +++ vendor/gopkg.in/vmihailenco/msgpack.v2/ext.go | 200 +++ .../vmihailenco/msgpack.v2/msgpack.go | 19 + .../gopkg.in/vmihailenco/msgpack.v2/tags.go | 44 + .../gopkg.in/vmihailenco/msgpack.v2/time.go | 59 + .../gopkg.in/vmihailenco/msgpack.v2/types.go | 214 +++ vendor/vendor.json | 66 +- 101 files changed, 15654 insertions(+), 9 deletions(-) create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/CONTRIBUTING.md create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/DISTRIBUTION create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/LICENSE create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/README.md create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/about.html create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/client.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/components.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/edl-v10 create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/epl-v10 create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/filestore.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/memstore.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/message.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/messageids.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/net.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/notice.html create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/oops.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/options.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/options_reader.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/connack.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/connect.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/disconnect.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/packets.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/pingreq.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/pingresp.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/puback.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/pubcomp.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/publish.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrec.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrel.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/suback.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/subscribe.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/unsuback.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/packets/unsubscribe.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/ping.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/router.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/store.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/token.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/topic.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/trace.go create mode 100644 vendor/github.com/eclipse/paho.mqtt.golang/websocket.go create mode 100644 vendor/github.com/gorilla/websocket/AUTHORS create mode 100644 vendor/github.com/gorilla/websocket/LICENSE create mode 100644 vendor/github.com/gorilla/websocket/README.md create mode 100644 vendor/github.com/gorilla/websocket/client.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/compression.go create mode 100644 vendor/github.com/gorilla/websocket/conn.go create mode 100644 vendor/github.com/gorilla/websocket/conn_write.go create mode 100644 vendor/github.com/gorilla/websocket/conn_write_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/doc.go create mode 100644 vendor/github.com/gorilla/websocket/go.mod create mode 100644 vendor/github.com/gorilla/websocket/go.sum create mode 100644 vendor/github.com/gorilla/websocket/join.go create mode 100644 vendor/github.com/gorilla/websocket/json.go create mode 100644 vendor/github.com/gorilla/websocket/mask.go create mode 100644 vendor/github.com/gorilla/websocket/mask_safe.go create mode 100644 vendor/github.com/gorilla/websocket/prepared.go create mode 100644 vendor/github.com/gorilla/websocket/proxy.go create mode 100644 vendor/github.com/gorilla/websocket/server.go create mode 100644 vendor/github.com/gorilla/websocket/trace.go create mode 100644 vendor/github.com/gorilla/websocket/trace_17.go create mode 100644 vendor/github.com/gorilla/websocket/util.go create mode 100644 vendor/github.com/gorilla/websocket/x_net_proxy.go create mode 100644 vendor/google.golang.org/appengine/datastore/datastore.go create mode 100644 vendor/google.golang.org/appengine/datastore/doc.go create mode 100644 vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go create mode 100644 vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go create mode 100644 vendor/google.golang.org/appengine/datastore/key.go create mode 100644 vendor/google.golang.org/appengine/datastore/keycompat.go create mode 100644 vendor/google.golang.org/appengine/datastore/load.go create mode 100644 vendor/google.golang.org/appengine/datastore/metadata.go create mode 100644 vendor/google.golang.org/appengine/datastore/prop.go create mode 100644 vendor/google.golang.org/appengine/datastore/query.go create mode 100644 vendor/google.golang.org/appengine/datastore/save.go create mode 100644 vendor/google.golang.org/appengine/datastore/transaction.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/LICENSE create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/Makefile create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/README.md create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/appengine.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/codes/codes.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_map.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_number.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_query.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_slice.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_string.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/decode_value.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/encode.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/encode_map.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/encode_number.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/encode_slice.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/encode_value.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/ext.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/msgpack.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/tags.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/time.go create mode 100644 vendor/gopkg.in/vmihailenco/msgpack.v2/types.go diff --git a/filebeat/include/list.go b/filebeat/include/list.go index 72d70d9ae24..acaa460cfdf 100644 --- a/filebeat/include/list.go +++ b/filebeat/include/list.go @@ -25,6 +25,7 @@ import ( _ "github.com/elastic/beats/filebeat/input/docker" _ "github.com/elastic/beats/filebeat/input/kafka" _ "github.com/elastic/beats/filebeat/input/log" + _ "github.com/elastic/beats/filebeat/input/mqtt" _ "github.com/elastic/beats/filebeat/input/redis" _ "github.com/elastic/beats/filebeat/input/stdin" _ "github.com/elastic/beats/filebeat/input/syslog" diff --git a/filebeat/input/mqtt/client.go b/filebeat/input/mqtt/client.go index 9f09c1ce0a4..0079dbf78f4 100644 --- a/filebeat/input/mqtt/client.go +++ b/filebeat/input/mqtt/client.go @@ -25,10 +25,11 @@ import ( "strings" "time" + "gopkg.in/vmihailenco/msgpack.v2" + "github.com/elastic/beats/libbeat/beat" "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/logp" - "gopkg.in/vmihailenco/msgpack.v2" MQTT "github.com/eclipse/paho.mqtt.golang" ) @@ -157,9 +158,9 @@ func (input *mqttInput) onMessage(client MQTT.Client, msg MQTT.Message) { // Finally sending the message to elasticsearch beatEvent.Fields = eventFields - input.outlet.OnEvent(beatEvent) + isSent := input.outlet.OnEvent(beatEvent) - logp.Debug("MQTT", "Event sent: %t") + logp.Debug("MQTT", "Event sent: %t", isSent) } // connectionLostHandler will try to reconnect when connection is lost diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/CONTRIBUTING.md b/vendor/github.com/eclipse/paho.mqtt.golang/CONTRIBUTING.md new file mode 100644 index 00000000000..9791dc60318 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/CONTRIBUTING.md @@ -0,0 +1,56 @@ +Contributing to Paho +==================== + +Thanks for your interest in this project. + +Project description: +-------------------- + +The Paho project has been created to provide scalable open-source implementations of open and standard messaging protocols aimed at new, existing, and emerging applications for Machine-to-Machine (M2M) and Internet of Things (IoT). +Paho reflects the inherent physical and cost constraints of device connectivity. Its objectives include effective levels of decoupling between devices and applications, designed to keep markets open and encourage the rapid growth of scalable Web and Enterprise middleware and applications. Paho is being kicked off with MQTT publish/subscribe client implementations for use on embedded platforms, along with corresponding server support as determined by the community. + +- https://projects.eclipse.org/projects/technology.paho + +Developer resources: +-------------------- + +Information regarding source code management, builds, coding standards, and more. + +- https://projects.eclipse.org/projects/technology.paho/developer + +Contributor License Agreement: +------------------------------ + +Before your contribution can be accepted by the project, you need to create and electronically sign the Eclipse Foundation Contributor License Agreement (CLA). + +- http://www.eclipse.org/legal/CLA.php + +Contributing Code: +------------------ + +The Go client is developed in Github, see their documentation on the process of forking and pull requests; https://help.github.com/categories/collaborating-on-projects-using-pull-requests/ + +Git commit messages should follow the style described here; + +http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html + +Contact: +-------- + +Contact the project developers via the project's "dev" list. + +- https://dev.eclipse.org/mailman/listinfo/paho-dev + +Search for bugs: +---------------- + +This project uses Github issues to track ongoing development and issues. + +- https://github.com/eclipse/paho.mqtt.golang/issues + +Create a new bug: +----------------- + +Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome! + +- https://github.com/eclipse/paho.mqtt.golang/issues diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/DISTRIBUTION b/vendor/github.com/eclipse/paho.mqtt.golang/DISTRIBUTION new file mode 100644 index 00000000000..34e49731daa --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/DISTRIBUTION @@ -0,0 +1,15 @@ + + +Eclipse Distribution License - v 1.0 + +Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/LICENSE b/vendor/github.com/eclipse/paho.mqtt.golang/LICENSE new file mode 100644 index 00000000000..aa7cc810fa1 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/LICENSE @@ -0,0 +1,87 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. \ No newline at end of file diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/README.md b/vendor/github.com/eclipse/paho.mqtt.golang/README.md new file mode 100644 index 00000000000..8ba3f2039f8 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/README.md @@ -0,0 +1,71 @@ + +[![GoDoc](https://godoc.org/github.com/eclipse/paho.mqtt.golang?status.svg)](https://godoc.org/github.com/eclipse/paho.mqtt.golang) +[![Go Report Card](https://goreportcard.com/badge/github.com/eclipse/paho.mqtt.golang)](https://goreportcard.com/report/github.com/eclipse/paho.mqtt.golang) + +Eclipse Paho MQTT Go client +=========================== + + +This repository contains the source code for the [Eclipse Paho](http://eclipse.org/paho) MQTT Go client library. + +This code builds a library which enable applications to connect to an [MQTT](http://mqtt.org) broker to publish messages, and to subscribe to topics and receive published messages. + +This library supports a fully asynchronous mode of operation. + + +Installation and Build +---------------------- + +This client is designed to work with the standard Go tools, so installation is as easy as: + +``` +go get github.com/eclipse/paho.mqtt.golang +``` + +The client depends on Google's [proxy](https://godoc.org/golang.org/x/net/proxy) package and the [websockets](https://godoc.org/github.com/gorilla/websocket) package, +also easily installed with the commands: + +``` +go get github.com/gorilla/websocket +go get golang.org/x/net/proxy +``` + + +Usage and API +------------- + +Detailed API documentation is available by using to godoc tool, or can be browsed online +using the [godoc.org](http://godoc.org/github.com/eclipse/paho.mqtt.golang) service. + +Make use of the library by importing it in your Go client source code. For example, +``` +import "github.com/eclipse/paho.mqtt.golang" +``` + +Samples are available in the `cmd` directory for reference. + +Note: + +The library also supports using MQTT over websockets by using the `ws://` (unsecure) or `wss://` (secure) prefix in the URI. If the client is running behind a corporate http/https proxy then the following environment variables `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` are taken into account when establishing the connection. + + +Runtime tracing +--------------- + +Tracing is enabled by assigning logs (from the Go log package) to the logging endpoints, ERROR, CRITICAL, WARN and DEBUG + + +Reporting bugs +-------------- + +Please report bugs by raising issues for this project in github https://github.com/eclipse/paho.mqtt.golang/issues + + +More information +---------------- + +Discussion of the Paho clients takes place on the [Eclipse paho-dev mailing list](https://dev.eclipse.org/mailman/listinfo/paho-dev). + +General questions about the MQTT protocol are discussed in the [MQTT Google Group](https://groups.google.com/forum/?hl=en-US&fromgroups#!forum/mqtt). + +There is much more information available via the [MQTT community site](http://mqtt.org). diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/about.html b/vendor/github.com/eclipse/paho.mqtt.golang/about.html new file mode 100644 index 00000000000..b183f417abb --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/about.html @@ -0,0 +1,41 @@ + + + +About + + +

      About This Content

      + +

      December 9, 2013

      +

      License

      + +

      The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL") and Eclipse Distribution License Version 1.0 ("EDL"). +A copy of the EPL is available at +http://www.eclipse.org/legal/epl-v10.html +and a copy of the EDL is available at +http://www.eclipse.org/org/documents/edl-v10.php. +For purposes of the EPL, "Program" will mean the Content.

      + +

      If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

      + + +

      Third Party Content

      +

      The Content includes items that have been sourced from third parties as set out below. If you + did not receive this Content directly from the Eclipse Foundation, the following is provided + for informational purposes only, and you should look to the Redistributor's license for + terms and conditions of use.

      +

      + None

      +

      +

      + + + + diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/client.go b/vendor/github.com/eclipse/paho.mqtt.golang/client.go new file mode 100644 index 00000000000..a8743a23845 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/client.go @@ -0,0 +1,965 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +// Portions copyright © 2018 TIBCO Software Inc. + +// Package mqtt provides an MQTT v3.1.1 client library. +package mqtt + +import ( + "bytes" + "errors" + "fmt" + "net" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +const ( + disconnected uint32 = iota + connecting + reconnecting + connected +) + +// Client is the interface definition for a Client as used by this +// library, the interface is primarily to allow mocking tests. +// +// It is an MQTT v3.1.1 client for communicating +// with an MQTT server using non-blocking methods that allow work +// to be done in the background. +// An application may connect to an MQTT server using: +// A plain TCP socket +// A secure SSL/TLS socket +// A websocket +// To enable ensured message delivery at Quality of Service (QoS) levels +// described in the MQTT spec, a message persistence mechanism must be +// used. This is done by providing a type which implements the Store +// interface. For convenience, FileStore and MemoryStore are provided +// implementations that should be sufficient for most use cases. More +// information can be found in their respective documentation. +// Numerous connection options may be specified by configuring a +// and then supplying a ClientOptions type. +type Client interface { + // IsConnected returns a bool signifying whether + // the client is connected or not. + IsConnected() bool + // IsConnectionOpen return a bool signifying whether the client has an active + // connection to mqtt broker, i.e not in disconnected or reconnect mode + IsConnectionOpen() bool + // Connect will create a connection to the message broker, by default + // it will attempt to connect at v3.1.1 and auto retry at v3.1 if that + // fails + Connect() Token + // Disconnect will end the connection with the server, but not before waiting + // the specified number of milliseconds to wait for existing work to be + // completed. + Disconnect(quiesce uint) + // Publish will publish a message with the specified QoS and content + // to the specified topic. + // Returns a token to track delivery of the message to the broker + Publish(topic string, qos byte, retained bool, payload interface{}) Token + // Subscribe starts a new subscription. Provide a MessageHandler to be executed when + // a message is published on the topic provided, or nil for the default handler + Subscribe(topic string, qos byte, callback MessageHandler) Token + // SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to + // be executed when a message is published on one of the topics provided, or nil for the + // default handler + SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token + // Unsubscribe will end the subscription from each of the topics provided. + // Messages published to those topics from other clients will no longer be + // received. + Unsubscribe(topics ...string) Token + // AddRoute allows you to add a handler for messages on a specific topic + // without making a subscription. For example having a different handler + // for parts of a wildcard subscription + AddRoute(topic string, callback MessageHandler) + // OptionsReader returns a ClientOptionsReader which is a copy of the clientoptions + // in use by the client. + OptionsReader() ClientOptionsReader +} + +// client implements the Client interface +type client struct { + lastSent atomic.Value + lastReceived atomic.Value + pingOutstanding int32 + status uint32 + sync.RWMutex + messageIds + conn net.Conn + ibound chan packets.ControlPacket + obound chan *PacketAndToken + oboundP chan *PacketAndToken + msgRouter *router + stopRouter chan bool + incomingPubChan chan *packets.PublishPacket + errors chan error + stop chan struct{} + persist Store + options ClientOptions + optionsMu sync.Mutex // Protects the options in a few limited cases where needed for testing + workers sync.WaitGroup +} + +// NewClient will create an MQTT v3.1.1 client with all of the options specified +// in the provided ClientOptions. The client must have the Connect method called +// on it before it may be used. This is to make sure resources (such as a net +// connection) are created before the application is actually ready. +func NewClient(o *ClientOptions) Client { + c := &client{} + c.options = *o + + if c.options.Store == nil { + c.options.Store = NewMemoryStore() + } + switch c.options.ProtocolVersion { + case 3, 4: + c.options.protocolVersionExplicit = true + case 0x83, 0x84: + c.options.protocolVersionExplicit = true + default: + c.options.ProtocolVersion = 4 + c.options.protocolVersionExplicit = false + } + c.persist = c.options.Store + c.status = disconnected + c.messageIds = messageIds{index: make(map[uint16]tokenCompletor)} + c.msgRouter, c.stopRouter = newRouter() + c.msgRouter.setDefaultHandler(c.options.DefaultPublishHandler) + return c +} + +// AddRoute allows you to add a handler for messages on a specific topic +// without making a subscription. For example having a different handler +// for parts of a wildcard subscription +func (c *client) AddRoute(topic string, callback MessageHandler) { + if callback != nil { + c.msgRouter.addRoute(topic, callback) + } +} + +// IsConnected returns a bool signifying whether +// the client is connected or not. +// connected means that the connection is up now OR it will +// be established/reestablished automatically when possible +func (c *client) IsConnected() bool { + c.RLock() + defer c.RUnlock() + status := atomic.LoadUint32(&c.status) + switch { + case status == connected: + return true + case c.options.AutoReconnect && status > connecting: + return true + case c.options.ConnectRetry && status == connecting: + return true + default: + return false + } +} + +// IsConnectionOpen return a bool signifying whether the client has an active +// connection to mqtt broker, i.e not in disconnected or reconnect mode +func (c *client) IsConnectionOpen() bool { + c.RLock() + defer c.RUnlock() + status := atomic.LoadUint32(&c.status) + switch { + case status == connected: + return true + default: + return false + } +} + +func (c *client) connectionStatus() uint32 { + c.RLock() + defer c.RUnlock() + status := atomic.LoadUint32(&c.status) + return status +} + +func (c *client) setConnected(status uint32) { + c.Lock() + defer c.Unlock() + atomic.StoreUint32(&c.status, uint32(status)) +} + +//ErrNotConnected is the error returned from function calls that are +//made when the client is not connected to a broker +var ErrNotConnected = errors.New("Not Connected") + +// Connect will create a connection to the message broker, by default +// it will attempt to connect at v3.1.1 and auto retry at v3.1 if that +// fails +func (c *client) Connect() Token { + var err error + t := newToken(packets.Connect).(*ConnectToken) + DEBUG.Println(CLI, "Connect()") + + if c.options.ConnectRetry && atomic.LoadUint32(&c.status) != disconnected { + // if in any state other than disconnected and ConnectRetry is + // enabled then the connection will come up automatically + // client can assume connection is up + WARN.Println(CLI, "Connect() called but not disconnected") + t.returnCode = packets.Accepted + t.flowComplete() + return t + } + + c.obound = make(chan *PacketAndToken) + c.oboundP = make(chan *PacketAndToken) + c.ibound = make(chan packets.ControlPacket) + + c.persist.Open() + if c.options.ConnectRetry { + c.reserveStoredPublishIDs() // Reserve IDs to allow publish before connect complete + } + c.setConnected(connecting) + + go func() { + c.errors = make(chan error, 1) + c.stop = make(chan struct{}) + + var rc byte + protocolVersion := c.options.ProtocolVersion + + if len(c.options.Servers) == 0 { + t.setError(fmt.Errorf("No servers defined to connect to")) + return + } + + RETRYCONN: + c.optionsMu.Lock() // Protect c.options.Servers so that servers can be added in test cases + brokers := c.options.Servers + c.optionsMu.Unlock() + + for _, broker := range brokers { + cm := newConnectMsgFromOptions(&c.options, broker) + c.options.ProtocolVersion = protocolVersion + CONN: + DEBUG.Println(CLI, "about to write new connect msg") + c.Lock() + c.conn, err = openConnection(broker, c.options.TLSConfig, c.options.ConnectTimeout, + c.options.HTTPHeaders) + c.Unlock() + if err == nil { + DEBUG.Println(CLI, "socket connected to broker") + switch c.options.ProtocolVersion { + case 3: + DEBUG.Println(CLI, "Using MQTT 3.1 protocol") + cm.ProtocolName = "MQIsdp" + cm.ProtocolVersion = 3 + case 0x83: + DEBUG.Println(CLI, "Using MQTT 3.1b protocol") + cm.ProtocolName = "MQIsdp" + cm.ProtocolVersion = 0x83 + case 0x84: + DEBUG.Println(CLI, "Using MQTT 3.1.1b protocol") + cm.ProtocolName = "MQTT" + cm.ProtocolVersion = 0x84 + default: + DEBUG.Println(CLI, "Using MQTT 3.1.1 protocol") + c.options.ProtocolVersion = 4 + cm.ProtocolName = "MQTT" + cm.ProtocolVersion = 4 + } + cm.Write(c.conn) + + rc, t.sessionPresent = c.connect() + if rc != packets.Accepted { + c.Lock() + if c.conn != nil { + c.conn.Close() + c.conn = nil + } + c.Unlock() + //if the protocol version was explicitly set don't do any fallback + if c.options.protocolVersionExplicit { + ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not CONN_ACCEPTED, but rather", packets.ConnackReturnCodes[rc]) + continue + } + if c.options.ProtocolVersion == 4 { + DEBUG.Println(CLI, "Trying reconnect using MQTT 3.1 protocol") + c.options.ProtocolVersion = 3 + goto CONN + } + } + break + } else { + ERROR.Println(CLI, err.Error()) + WARN.Println(CLI, "failed to connect to broker, trying next") + rc = packets.ErrNetworkError + } + } + + if c.conn == nil { + if c.options.ConnectRetry { + DEBUG.Println(CLI, "Connect failed, sleeping for", int(c.options.ConnectRetryInterval.Seconds()), "seconds and will then retry") + time.Sleep(c.options.ConnectRetryInterval) + + if atomic.LoadUint32(&c.status) == connecting { + goto RETRYCONN + } + } + ERROR.Println(CLI, "Failed to connect to a broker") + c.setConnected(disconnected) + c.persist.Close() + t.returnCode = rc + if rc != packets.ErrNetworkError { + t.setError(packets.ConnErrors[rc]) + } else { + t.setError(fmt.Errorf("%s : %s", packets.ConnErrors[rc], err)) + } + return + } + + c.options.protocolVersionExplicit = true + + if c.options.KeepAlive != 0 { + atomic.StoreInt32(&c.pingOutstanding, 0) + c.lastReceived.Store(time.Now()) + c.lastSent.Store(time.Now()) + c.workers.Add(1) + go keepalive(c) + } + + c.incomingPubChan = make(chan *packets.PublishPacket) + c.msgRouter.matchAndDispatch(c.incomingPubChan, c.options.Order, c) + + c.setConnected(connected) + DEBUG.Println(CLI, "client is connected") + if c.options.OnConnect != nil { + go c.options.OnConnect(c) + } + + c.workers.Add(4) + go errorWatch(c) + go alllogic(c) + go outgoing(c) + go incoming(c) + + // Take care of any messages in the store + if !c.options.CleanSession { + c.workers.Add(1) // disconnect during resume can lead to reconnect being called before resume completes + c.resume(c.options.ResumeSubs) + } else { + c.persist.Reset() + } + + DEBUG.Println(CLI, "exit startClient") + t.flowComplete() + }() + return t +} + +// internal function used to reconnect the client when it loses its connection +func (c *client) reconnect() { + DEBUG.Println(CLI, "enter reconnect") + var ( + err error + + rc = byte(1) + sleep = time.Duration(1 * time.Second) + ) + + for rc != 0 && atomic.LoadUint32(&c.status) != disconnected { + if nil != c.options.OnReconnecting { + c.options.OnReconnecting(c, &c.options) + } + c.optionsMu.Lock() // Protect c.options.Servers so that servers can be added in test cases + brokers := c.options.Servers + c.optionsMu.Unlock() + for _, broker := range brokers { + cm := newConnectMsgFromOptions(&c.options, broker) + DEBUG.Println(CLI, "about to write new connect msg") + c.Lock() + c.conn, err = openConnection(broker, c.options.TLSConfig, c.options.ConnectTimeout, c.options.HTTPHeaders) + c.Unlock() + if err == nil { + DEBUG.Println(CLI, "socket connected to broker") + switch c.options.ProtocolVersion { + case 0x83: + DEBUG.Println(CLI, "Using MQTT 3.1b protocol") + cm.ProtocolName = "MQIsdp" + cm.ProtocolVersion = 0x83 + case 0x84: + DEBUG.Println(CLI, "Using MQTT 3.1.1b protocol") + cm.ProtocolName = "MQTT" + cm.ProtocolVersion = 0x84 + case 3: + DEBUG.Println(CLI, "Using MQTT 3.1 protocol") + cm.ProtocolName = "MQIsdp" + cm.ProtocolVersion = 3 + default: + DEBUG.Println(CLI, "Using MQTT 3.1.1 protocol") + cm.ProtocolName = "MQTT" + cm.ProtocolVersion = 4 + } + cm.Write(c.conn) + + rc, _ = c.connect() + if rc != packets.Accepted { + if c.conn != nil { + c.conn.Close() + c.conn = nil + } + //if the protocol version was explicitly set don't do any fallback + if c.options.protocolVersionExplicit { + ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not Accepted, but rather", packets.ConnackReturnCodes[rc]) + continue + } + } + break + } else { + ERROR.Println(CLI, err.Error()) + WARN.Println(CLI, "failed to connect to broker, trying next") + rc = packets.ErrNetworkError + } + } + if rc != 0 { + DEBUG.Println(CLI, "Reconnect failed, sleeping for", int(sleep.Seconds()), "seconds") + time.Sleep(sleep) + if sleep < c.options.MaxReconnectInterval { + sleep *= 2 + } + + if sleep > c.options.MaxReconnectInterval { + sleep = c.options.MaxReconnectInterval + } + } + } + // Disconnect() must have been called while we were trying to reconnect. + if c.connectionStatus() == disconnected { + DEBUG.Println(CLI, "Client moved to disconnected state while reconnecting, abandoning reconnect") + return + } + + c.stop = make(chan struct{}) + + if c.options.KeepAlive != 0 { + atomic.StoreInt32(&c.pingOutstanding, 0) + c.lastReceived.Store(time.Now()) + c.lastSent.Store(time.Now()) + c.workers.Add(1) + go keepalive(c) + } + + c.setConnected(connected) + DEBUG.Println(CLI, "client is reconnected") + if c.options.OnConnect != nil { + go c.options.OnConnect(c) + } + + c.workers.Add(4) + go errorWatch(c) + go alllogic(c) + go outgoing(c) + go incoming(c) + + c.workers.Add(1) // disconnect during resume can lead to reconnect being called before resume completes + c.resume(c.options.ResumeSubs) +} + +// This function is only used for receiving a connack +// when the connection is first started. +// This prevents receiving incoming data while resume +// is in progress if clean session is false. +func (c *client) connect() (byte, bool) { + DEBUG.Println(NET, "connect started") + + ca, err := packets.ReadPacket(c.conn) + if err != nil { + ERROR.Println(NET, "connect got error", err) + return packets.ErrNetworkError, false + } + if ca == nil { + ERROR.Println(NET, "received nil packet") + return packets.ErrNetworkError, false + } + + msg, ok := ca.(*packets.ConnackPacket) + if !ok { + ERROR.Println(NET, "received msg that was not CONNACK") + return packets.ErrNetworkError, false + } + + DEBUG.Println(NET, "received connack") + return msg.ReturnCode, msg.SessionPresent +} + +// Disconnect will end the connection with the server, but not before waiting +// the specified number of milliseconds to wait for existing work to be +// completed. +func (c *client) Disconnect(quiesce uint) { + status := atomic.LoadUint32(&c.status) + if status == connected { + DEBUG.Println(CLI, "disconnecting") + c.setConnected(disconnected) + + dm := packets.NewControlPacket(packets.Disconnect).(*packets.DisconnectPacket) + dt := newToken(packets.Disconnect) + c.oboundP <- &PacketAndToken{p: dm, t: dt} + + // wait for work to finish, or quiesce time consumed + dt.WaitTimeout(time.Duration(quiesce) * time.Millisecond) + } else { + WARN.Println(CLI, "Disconnect() called but not connected (disconnected/reconnecting)") + c.setConnected(disconnected) + } + + c.disconnect() +} + +// ForceDisconnect will end the connection with the mqtt broker immediately. +func (c *client) forceDisconnect() { + if !c.IsConnected() { + WARN.Println(CLI, "already disconnected") + return + } + c.setConnected(disconnected) + c.conn.Close() + DEBUG.Println(CLI, "forcefully disconnecting") + c.disconnect() +} + +func (c *client) internalConnLost(err error) { + // Only do anything if this was called and we are still "connected" + // forceDisconnect can cause incoming/outgoing/alllogic to end with + // error from closing the socket but state will be "disconnected" + if c.IsConnected() { + c.closeStop() + c.conn.Close() + c.workers.Wait() + if c.options.CleanSession && !c.options.AutoReconnect { + c.messageIds.cleanUp() + } + if c.options.AutoReconnect { + c.setConnected(reconnecting) + go c.reconnect() + } else { + c.setConnected(disconnected) + } + if c.options.OnConnectionLost != nil { + go c.options.OnConnectionLost(c, err) + } + } +} + +func (c *client) closeStop() { + c.Lock() + defer c.Unlock() + select { + case <-c.stop: + DEBUG.Println("In disconnect and stop channel is already closed") + default: + if c.stop != nil { + close(c.stop) + } + } +} + +func (c *client) closeStopRouter() { + c.Lock() + defer c.Unlock() + select { + case <-c.stopRouter: + DEBUG.Println("In disconnect and stop channel is already closed") + default: + if c.stopRouter != nil { + close(c.stopRouter) + } + } +} + +func (c *client) closeConn() { + c.Lock() + defer c.Unlock() + if c.conn != nil { + c.conn.Close() + } +} + +func (c *client) disconnect() { + c.closeStop() + c.closeConn() + c.workers.Wait() + c.messageIds.cleanUp() + c.closeStopRouter() + DEBUG.Println(CLI, "disconnected") + c.persist.Close() +} + +// Publish will publish a message with the specified QoS and content +// to the specified topic. +// Returns a token to track delivery of the message to the broker +func (c *client) Publish(topic string, qos byte, retained bool, payload interface{}) Token { + token := newToken(packets.Publish).(*PublishToken) + DEBUG.Println(CLI, "enter Publish") + switch { + case !c.IsConnected(): + token.setError(ErrNotConnected) + return token + case c.connectionStatus() == reconnecting && qos == 0: + token.flowComplete() + return token + } + pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) + pub.Qos = qos + pub.TopicName = topic + pub.Retain = retained + switch p := payload.(type) { + case string: + pub.Payload = []byte(p) + case []byte: + pub.Payload = p + case bytes.Buffer: + pub.Payload = p.Bytes() + default: + token.setError(fmt.Errorf("Unknown payload type")) + return token + } + + if pub.Qos != 0 && pub.MessageID == 0 { + pub.MessageID = c.getID(token) + token.messageID = pub.MessageID + } + persistOutbound(c.persist, pub) + switch c.connectionStatus() { + case connecting: + DEBUG.Println(CLI, "storing publish message (connecting), topic:", topic) + case reconnecting: + DEBUG.Println(CLI, "storing publish message (reconnecting), topic:", topic) + default: + DEBUG.Println(CLI, "sending publish message, topic:", topic) + publishWaitTimeout := c.options.WriteTimeout + if publishWaitTimeout == 0 { + publishWaitTimeout = time.Second * 30 + } + select { + case c.obound <- &PacketAndToken{p: pub, t: token}: + case <-time.After(publishWaitTimeout): + token.setError(errors.New("publish was broken by timeout")) + } + } + return token +} + +// Subscribe starts a new subscription. Provide a MessageHandler to be executed when +// a message is published on the topic provided. +func (c *client) Subscribe(topic string, qos byte, callback MessageHandler) Token { + token := newToken(packets.Subscribe).(*SubscribeToken) + DEBUG.Println(CLI, "enter Subscribe") + if !c.IsConnected() { + token.setError(ErrNotConnected) + return token + } + if !c.IsConnectionOpen() { + switch { + case !c.options.ResumeSubs: + // if not connected and resumesubs not set this sub will be thrown away + token.setError(fmt.Errorf("not currently connected and ResumeSubs not set")) + return token + case c.options.CleanSession && c.connectionStatus() == reconnecting: + // if reconnecting and cleansession is true this sub will be thrown away + token.setError(fmt.Errorf("reconnecting state and cleansession is true")) + return token + } + } + sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket) + if err := validateTopicAndQos(topic, qos); err != nil { + token.setError(err) + return token + } + sub.Topics = append(sub.Topics, topic) + sub.Qoss = append(sub.Qoss, qos) + + if strings.HasPrefix(topic, "$share/") { + topic = strings.Join(strings.Split(topic, "/")[2:], "/") + } + + if strings.HasPrefix(topic, "$queue/") { + topic = strings.TrimPrefix(topic, "$queue/") + } + + if callback != nil { + c.msgRouter.addRoute(topic, callback) + } + + token.subs = append(token.subs, topic) + + if sub.MessageID == 0 { + sub.MessageID = c.getID(token) + token.messageID = sub.MessageID + } + DEBUG.Println(CLI, sub.String()) + + persistOutbound(c.persist, sub) + switch c.connectionStatus() { + case connecting: + DEBUG.Println(CLI, "storing subscribe message (connecting), topic:", topic) + case reconnecting: + DEBUG.Println(CLI, "storing subscribe message (reconnecting), topic:", topic) + default: + DEBUG.Println(CLI, "sending subscribe message, topic:", topic) + subscribeWaitTimeout := c.options.WriteTimeout + if subscribeWaitTimeout == 0 { + subscribeWaitTimeout = time.Second * 30 + } + select { + case c.oboundP <- &PacketAndToken{p: sub, t: token}: + case <-time.After(subscribeWaitTimeout): + token.setError(errors.New("subscribe was broken by timeout")) + } + } + DEBUG.Println(CLI, "exit Subscribe") + return token +} + +// SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to +// be executed when a message is published on one of the topics provided. +func (c *client) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token { + var err error + token := newToken(packets.Subscribe).(*SubscribeToken) + DEBUG.Println(CLI, "enter SubscribeMultiple") + if !c.IsConnected() { + token.setError(ErrNotConnected) + return token + } + if !c.IsConnectionOpen() { + switch { + case !c.options.ResumeSubs: + // if not connected and resumesubs not set this sub will be thrown away + token.setError(fmt.Errorf("not currently connected and ResumeSubs not set")) + return token + case c.options.CleanSession && c.connectionStatus() == reconnecting: + // if reconnecting and cleansession is true this sub will be thrown away + token.setError(fmt.Errorf("reconnecting state and cleansession is true")) + return token + } + } + sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket) + if sub.Topics, sub.Qoss, err = validateSubscribeMap(filters); err != nil { + token.setError(err) + return token + } + + if callback != nil { + for topic := range filters { + c.msgRouter.addRoute(topic, callback) + } + } + token.subs = make([]string, len(sub.Topics)) + copy(token.subs, sub.Topics) + + if sub.MessageID == 0 { + sub.MessageID = c.getID(token) + token.messageID = sub.MessageID + } + persistOutbound(c.persist, sub) + switch c.connectionStatus() { + case connecting: + DEBUG.Println(CLI, "storing subscribe message (connecting), topics:", sub.Topics) + case reconnecting: + DEBUG.Println(CLI, "storing subscribe message (reconnecting), topics:", sub.Topics) + default: + DEBUG.Println(CLI, "sending subscribe message, topics:", sub.Topics) + subscribeWaitTimeout := c.options.WriteTimeout + if subscribeWaitTimeout == 0 { + subscribeWaitTimeout = time.Second * 30 + } + select { + case c.oboundP <- &PacketAndToken{p: sub, t: token}: + case <-time.After(subscribeWaitTimeout): + token.setError(errors.New("subscribe was broken by timeout")) + } + } + DEBUG.Println(CLI, "exit SubscribeMultiple") + return token +} + +// reserveStoredPublishIDs reserves the ids for publish packets in the persistent store to ensure these are not duplicated +func (c *client) reserveStoredPublishIDs() { + // The resume function sets the stored id for publish packets only (some other packets + // will get new ids in net code). This means that the only keys we need to ensure are + // unique are the publish ones (and these will completed/replaced in resume() ) + if !c.options.CleanSession { + storedKeys := c.persist.All() + for _, key := range storedKeys { + packet := c.persist.Get(key) + if packet == nil { + continue + } + switch packet.(type) { + case *packets.PublishPacket: + details := packet.Details() + token := &PlaceHolderToken{id: details.MessageID} + c.claimID(token, details.MessageID) + } + } + } +} + +// Load all stored messages and resend them +// Call this to ensure QOS > 1,2 even after an application crash +func (c *client) resume(subscription bool) { + defer c.workers.Done() // resume must complete before any attempt to reconnect is made + + storedKeys := c.persist.All() + for _, key := range storedKeys { + packet := c.persist.Get(key) + if packet == nil { + continue + } + details := packet.Details() + if isKeyOutbound(key) { + switch packet.(type) { + case *packets.SubscribePacket: + if subscription { + DEBUG.Println(STR, fmt.Sprintf("loaded pending subscribe (%d)", details.MessageID)) + subPacket := packet.(*packets.SubscribePacket) + token := newToken(packets.Subscribe).(*SubscribeToken) + token.messageID = details.MessageID + token.subs = append(token.subs, subPacket.Topics...) + c.claimID(token, details.MessageID) + select { + case c.oboundP <- &PacketAndToken{p: packet, t: token}: + case <-c.stop: + return + } + } + case *packets.UnsubscribePacket: + if subscription { + DEBUG.Println(STR, fmt.Sprintf("loaded pending unsubscribe (%d)", details.MessageID)) + token := newToken(packets.Unsubscribe).(*UnsubscribeToken) + select { + case c.oboundP <- &PacketAndToken{p: packet, t: token}: + case <-c.stop: + return + } + } + case *packets.PubrelPacket: + DEBUG.Println(STR, fmt.Sprintf("loaded pending pubrel (%d)", details.MessageID)) + select { + case c.oboundP <- &PacketAndToken{p: packet, t: nil}: + case <-c.stop: + return + } + case *packets.PublishPacket: + token := newToken(packets.Publish).(*PublishToken) + token.messageID = details.MessageID + c.claimID(token, details.MessageID) + DEBUG.Println(STR, fmt.Sprintf("loaded pending publish (%d)", details.MessageID)) + DEBUG.Println(STR, details) + select { + case c.obound <- &PacketAndToken{p: packet, t: token}: + case <-c.stop: + return + } + default: + ERROR.Println(STR, "invalid message type in store (discarded)") + c.persist.Del(key) + } + } else { + switch packet.(type) { + case *packets.PubrelPacket: + DEBUG.Println(STR, fmt.Sprintf("loaded pending incomming (%d)", details.MessageID)) + select { + case c.ibound <- packet: + case <-c.stop: + return + } + default: + ERROR.Println(STR, "invalid message type in store (discarded)") + c.persist.Del(key) + } + } + } +} + +// Unsubscribe will end the subscription from each of the topics provided. +// Messages published to those topics from other clients will no longer be +// received. +func (c *client) Unsubscribe(topics ...string) Token { + token := newToken(packets.Unsubscribe).(*UnsubscribeToken) + DEBUG.Println(CLI, "enter Unsubscribe") + if !c.IsConnected() { + token.setError(ErrNotConnected) + return token + } + if !c.IsConnectionOpen() { + switch { + case !c.options.ResumeSubs: + // if not connected and resumesubs not set this unsub will be thrown away + token.setError(fmt.Errorf("not currently connected and ResumeSubs not set")) + return token + case c.options.CleanSession && c.connectionStatus() == reconnecting: + // if reconnecting and cleansession is true this unsub will be thrown away + token.setError(fmt.Errorf("reconnecting state and cleansession is true")) + return token + } + } + unsub := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket) + unsub.Topics = make([]string, len(topics)) + copy(unsub.Topics, topics) + + if unsub.MessageID == 0 { + unsub.MessageID = c.getID(token) + token.messageID = unsub.MessageID + } + + persistOutbound(c.persist, unsub) + + switch c.connectionStatus() { + case connecting: + DEBUG.Println(CLI, "storing unsubscribe message (connecting), topics:", topics) + case reconnecting: + DEBUG.Println(CLI, "storing unsubscribe message (reconnecting), topics:", topics) + default: + DEBUG.Println(CLI, "sending unsubscribe message, topics:", topics) + subscribeWaitTimeout := c.options.WriteTimeout + if subscribeWaitTimeout == 0 { + subscribeWaitTimeout = time.Second * 30 + } + select { + case c.oboundP <- &PacketAndToken{p: unsub, t: token}: + for _, topic := range topics { + c.msgRouter.deleteRoute(topic) + } + case <-time.After(subscribeWaitTimeout): + token.setError(errors.New("unsubscribe was broken by timeout")) + } + } + + DEBUG.Println(CLI, "exit Unsubscribe") + return token +} + +// OptionsReader returns a ClientOptionsReader which is a copy of the clientoptions +// in use by the client. +func (c *client) OptionsReader() ClientOptionsReader { + r := ClientOptionsReader{options: &c.options} + return r +} + +//DefaultConnectionLostHandler is a definition of a function that simply +//reports to the DEBUG log the reason for the client losing a connection. +func DefaultConnectionLostHandler(client Client, reason error) { + DEBUG.Println("Connection lost:", reason.Error()) +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/components.go b/vendor/github.com/eclipse/paho.mqtt.golang/components.go new file mode 100644 index 00000000000..01f5fafdf8f --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/components.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +type component string + +// Component names for debug output +const ( + NET component = "[net] " + PNG component = "[pinger] " + CLI component = "[client] " + DEC component = "[decode] " + MES component = "[message] " + STR component = "[store] " + MID component = "[msgids] " + TST component = "[test] " + STA component = "[state] " + ERR component = "[error] " +) diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/edl-v10 b/vendor/github.com/eclipse/paho.mqtt.golang/edl-v10 new file mode 100644 index 00000000000..cf989f1456b --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/edl-v10 @@ -0,0 +1,15 @@ + +Eclipse Distribution License - v 1.0 + +Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/epl-v10 b/vendor/github.com/eclipse/paho.mqtt.golang/epl-v10 new file mode 100644 index 00000000000..79e486c3d2c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/epl-v10 @@ -0,0 +1,70 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/filestore.go b/vendor/github.com/eclipse/paho.mqtt.golang/filestore.go new file mode 100644 index 00000000000..d15f6146c2e --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/filestore.go @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "io/ioutil" + "os" + "path" + "sort" + "sync" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +const ( + msgExt = ".msg" + tmpExt = ".tmp" + corruptExt = ".CORRUPT" +) + +// FileStore implements the store interface using the filesystem to provide +// true persistence, even across client failure. This is designed to use a +// single directory per running client. If you are running multiple clients +// on the same filesystem, you will need to be careful to specify unique +// store directories for each. +type FileStore struct { + sync.RWMutex + directory string + opened bool +} + +// NewFileStore will create a new FileStore which stores its messages in the +// directory provided. +func NewFileStore(directory string) *FileStore { + store := &FileStore{ + directory: directory, + opened: false, + } + return store +} + +// Open will allow the FileStore to be used. +func (store *FileStore) Open() { + store.Lock() + defer store.Unlock() + // if no store directory was specified in ClientOpts, by default use the + // current working directory + if store.directory == "" { + store.directory, _ = os.Getwd() + } + + // if store dir exists, great, otherwise, create it + if !exists(store.directory) { + perms := os.FileMode(0770) + merr := os.MkdirAll(store.directory, perms) + chkerr(merr) + } + store.opened = true + DEBUG.Println(STR, "store is opened at", store.directory) +} + +// Close will disallow the FileStore from being used. +func (store *FileStore) Close() { + store.Lock() + defer store.Unlock() + store.opened = false + DEBUG.Println(STR, "store is closed") +} + +// Put will put a message into the store, associated with the provided +// key value. +func (store *FileStore) Put(key string, m packets.ControlPacket) { + store.Lock() + defer store.Unlock() + if !store.opened { + ERROR.Println(STR, "Trying to use file store, but not open") + return + } + full := fullpath(store.directory, key) + write(store.directory, key, m) + if !exists(full) { + ERROR.Println(STR, "file not created:", full) + } +} + +// Get will retrieve a message from the store, the one associated with +// the provided key value. +func (store *FileStore) Get(key string) packets.ControlPacket { + store.RLock() + defer store.RUnlock() + if !store.opened { + ERROR.Println(STR, "Trying to use file store, but not open") + return nil + } + filepath := fullpath(store.directory, key) + if !exists(filepath) { + return nil + } + mfile, oerr := os.Open(filepath) + chkerr(oerr) + msg, rerr := packets.ReadPacket(mfile) + chkerr(mfile.Close()) + + // Message was unreadable, return nil + if rerr != nil { + newpath := corruptpath(store.directory, key) + WARN.Println(STR, "corrupted file detected:", rerr.Error(), "archived at:", newpath) + os.Rename(filepath, newpath) + return nil + } + return msg +} + +// All will provide a list of all of the keys associated with messages +// currently residing in the FileStore. +func (store *FileStore) All() []string { + store.RLock() + defer store.RUnlock() + return store.all() +} + +// Del will remove the persisted message associated with the provided +// key from the FileStore. +func (store *FileStore) Del(key string) { + store.Lock() + defer store.Unlock() + store.del(key) +} + +// Reset will remove all persisted messages from the FileStore. +func (store *FileStore) Reset() { + store.Lock() + defer store.Unlock() + WARN.Println(STR, "FileStore Reset") + for _, key := range store.all() { + store.del(key) + } +} + +// lockless +func (store *FileStore) all() []string { + var err error + var keys []string + var files fileInfos + + if !store.opened { + ERROR.Println(STR, "Trying to use file store, but not open") + return nil + } + + files, err = ioutil.ReadDir(store.directory) + chkerr(err) + sort.Sort(files) + for _, f := range files { + DEBUG.Println(STR, "file in All():", f.Name()) + name := f.Name() + if name[len(name)-4:] != msgExt { + DEBUG.Println(STR, "skipping file, doesn't have right extension: ", name) + continue + } + key := name[0 : len(name)-4] // remove file extension + keys = append(keys, key) + } + return keys +} + +// lockless +func (store *FileStore) del(key string) { + if !store.opened { + ERROR.Println(STR, "Trying to use file store, but not open") + return + } + DEBUG.Println(STR, "store del filepath:", store.directory) + DEBUG.Println(STR, "store delete key:", key) + filepath := fullpath(store.directory, key) + DEBUG.Println(STR, "path of deletion:", filepath) + if !exists(filepath) { + WARN.Println(STR, "store could not delete key:", key) + return + } + rerr := os.Remove(filepath) + chkerr(rerr) + DEBUG.Println(STR, "del msg:", key) + if exists(filepath) { + ERROR.Println(STR, "file not deleted:", filepath) + } +} + +func fullpath(store string, key string) string { + p := path.Join(store, key+msgExt) + return p +} + +func tmppath(store string, key string) string { + p := path.Join(store, key+tmpExt) + return p +} + +func corruptpath(store string, key string) string { + p := path.Join(store, key+corruptExt) + return p +} + +// create file called "X.[messageid].tmp" located in the store +// the contents of the file is the bytes of the message, then +// rename it to "X.[messageid].msg", overwriting any existing +// message with the same id +// X will be 'i' for inbound messages, and O for outbound messages +func write(store, key string, m packets.ControlPacket) { + temppath := tmppath(store, key) + f, err := os.Create(temppath) + chkerr(err) + werr := m.Write(f) + chkerr(werr) + cerr := f.Close() + chkerr(cerr) + rerr := os.Rename(temppath, fullpath(store, key)) + chkerr(rerr) +} + +func exists(file string) bool { + if _, err := os.Stat(file); err != nil { + if os.IsNotExist(err) { + return false + } + chkerr(err) + } + return true +} + +type fileInfos []os.FileInfo + +func (f fileInfos) Len() int { + return len(f) +} + +func (f fileInfos) Swap(i, j int) { + f[i], f[j] = f[j], f[i] +} + +func (f fileInfos) Less(i, j int) bool { + return f[i].ModTime().Before(f[j].ModTime()) +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/memstore.go b/vendor/github.com/eclipse/paho.mqtt.golang/memstore.go new file mode 100644 index 00000000000..499c490bdbb --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/memstore.go @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "sync" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +// MemoryStore implements the store interface to provide a "persistence" +// mechanism wholly stored in memory. This is only useful for +// as long as the client instance exists. +type MemoryStore struct { + sync.RWMutex + messages map[string]packets.ControlPacket + opened bool +} + +// NewMemoryStore returns a pointer to a new instance of +// MemoryStore, the instance is not initialized and ready to +// use until Open() has been called on it. +func NewMemoryStore() *MemoryStore { + store := &MemoryStore{ + messages: make(map[string]packets.ControlPacket), + opened: false, + } + return store +} + +// Open initializes a MemoryStore instance. +func (store *MemoryStore) Open() { + store.Lock() + defer store.Unlock() + store.opened = true + DEBUG.Println(STR, "memorystore initialized") +} + +// Put takes a key and a pointer to a Message and stores the +// message. +func (store *MemoryStore) Put(key string, message packets.ControlPacket) { + store.Lock() + defer store.Unlock() + if !store.opened { + ERROR.Println(STR, "Trying to use memory store, but not open") + return + } + store.messages[key] = message +} + +// Get takes a key and looks in the store for a matching Message +// returning either the Message pointer or nil. +func (store *MemoryStore) Get(key string) packets.ControlPacket { + store.RLock() + defer store.RUnlock() + if !store.opened { + ERROR.Println(STR, "Trying to use memory store, but not open") + return nil + } + mid := mIDFromKey(key) + m := store.messages[key] + if m == nil { + CRITICAL.Println(STR, "memorystore get: message", mid, "not found") + } else { + DEBUG.Println(STR, "memorystore get: message", mid, "found") + } + return m +} + +// All returns a slice of strings containing all the keys currently +// in the MemoryStore. +func (store *MemoryStore) All() []string { + store.RLock() + defer store.RUnlock() + if !store.opened { + ERROR.Println(STR, "Trying to use memory store, but not open") + return nil + } + keys := []string{} + for k := range store.messages { + keys = append(keys, k) + } + return keys +} + +// Del takes a key, searches the MemoryStore and if the key is found +// deletes the Message pointer associated with it. +func (store *MemoryStore) Del(key string) { + store.Lock() + defer store.Unlock() + if !store.opened { + ERROR.Println(STR, "Trying to use memory store, but not open") + return + } + mid := mIDFromKey(key) + m := store.messages[key] + if m == nil { + WARN.Println(STR, "memorystore del: message", mid, "not found") + } else { + delete(store.messages, key) + DEBUG.Println(STR, "memorystore del: message", mid, "was deleted") + } +} + +// Close will disallow modifications to the state of the store. +func (store *MemoryStore) Close() { + store.Lock() + defer store.Unlock() + if !store.opened { + ERROR.Println(STR, "Trying to close memory store, but not open") + return + } + store.opened = false + DEBUG.Println(STR, "memorystore closed") +} + +// Reset eliminates all persisted message data in the store. +func (store *MemoryStore) Reset() { + store.Lock() + defer store.Unlock() + if !store.opened { + ERROR.Println(STR, "Trying to reset memory store, but not open") + } + store.messages = make(map[string]packets.ControlPacket) + WARN.Println(STR, "memorystore wiped") +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/message.go b/vendor/github.com/eclipse/paho.mqtt.golang/message.go new file mode 100644 index 00000000000..903e5dcf5e7 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/message.go @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "net/url" + + "github.com/eclipse/paho.mqtt.golang/packets" + "sync" +) + +// Message defines the externals that a message implementation must support +// these are received messages that are passed to the callbacks, not internal +// messages +type Message interface { + Duplicate() bool + Qos() byte + Retained() bool + Topic() string + MessageID() uint16 + Payload() []byte + Ack() +} + +type message struct { + duplicate bool + qos byte + retained bool + topic string + messageID uint16 + payload []byte + once sync.Once + ack func() +} + +func (m *message) Duplicate() bool { + return m.duplicate +} + +func (m *message) Qos() byte { + return m.qos +} + +func (m *message) Retained() bool { + return m.retained +} + +func (m *message) Topic() string { + return m.topic +} + +func (m *message) MessageID() uint16 { + return m.messageID +} + +func (m *message) Payload() []byte { + return m.payload +} + +func (m *message) Ack() { + m.once.Do(m.ack) +} + +func messageFromPublish(p *packets.PublishPacket, ack func()) Message { + return &message{ + duplicate: p.Dup, + qos: p.Qos, + retained: p.Retain, + topic: p.TopicName, + messageID: p.MessageID, + payload: p.Payload, + ack: ack, + } +} + +func newConnectMsgFromOptions(options *ClientOptions, broker *url.URL) *packets.ConnectPacket { + m := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket) + + m.CleanSession = options.CleanSession + m.WillFlag = options.WillEnabled + m.WillRetain = options.WillRetained + m.ClientIdentifier = options.ClientID + + if options.WillEnabled { + m.WillQos = options.WillQos + m.WillTopic = options.WillTopic + m.WillMessage = options.WillPayload + } + + username := options.Username + password := options.Password + if broker.User != nil { + username = broker.User.Username() + if pwd, ok := broker.User.Password(); ok { + password = pwd + } + } + if options.CredentialsProvider != nil { + username, password = options.CredentialsProvider() + } + + if username != "" { + m.UsernameFlag = true + m.Username = username + //mustn't have password without user as well + if password != "" { + m.PasswordFlag = true + m.Password = []byte(password) + } + } + + m.Keepalive = uint16(options.KeepAlive) + + return m +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/messageids.go b/vendor/github.com/eclipse/paho.mqtt.golang/messageids.go new file mode 100644 index 00000000000..e98cc24f846 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/messageids.go @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "fmt" + "sync" + "time" +) + +// MId is 16 bit message id as specified by the MQTT spec. +// In general, these values should not be depended upon by +// the client application. +type MId uint16 + +type messageIds struct { + sync.RWMutex + index map[uint16]tokenCompletor +} + +const ( + midMin uint16 = 1 + midMax uint16 = 65535 +) + +func (mids *messageIds) cleanUp() { + mids.Lock() + for _, token := range mids.index { + switch token.(type) { + case *PublishToken: + token.setError(fmt.Errorf("Connection lost before Publish completed")) + case *SubscribeToken: + token.setError(fmt.Errorf("Connection lost before Subscribe completed")) + case *UnsubscribeToken: + token.setError(fmt.Errorf("Connection lost before Unsubscribe completed")) + case nil: + continue + } + token.flowComplete() + } + mids.index = make(map[uint16]tokenCompletor) + mids.Unlock() + DEBUG.Println(MID, "cleaned up") +} + +func (mids *messageIds) freeID(id uint16) { + mids.Lock() + delete(mids.index, id) + mids.Unlock() +} + +func (mids *messageIds) claimID(token tokenCompletor, id uint16) { + mids.Lock() + defer mids.Unlock() + if _, ok := mids.index[id]; !ok { + mids.index[id] = token + } else { + old := mids.index[id] + old.flowComplete() + mids.index[id] = token + } +} + +func (mids *messageIds) getID(t tokenCompletor) uint16 { + mids.Lock() + defer mids.Unlock() + for i := midMin; i < midMax; i++ { + if _, ok := mids.index[i]; !ok { + mids.index[i] = t + return i + } + } + return 0 +} + +func (mids *messageIds) getToken(id uint16) tokenCompletor { + mids.RLock() + defer mids.RUnlock() + if token, ok := mids.index[id]; ok { + return token + } + return &DummyToken{id: id} +} + +type DummyToken struct { + id uint16 +} + +func (d *DummyToken) Wait() bool { + return true +} + +func (d *DummyToken) WaitTimeout(t time.Duration) bool { + return true +} + +func (d *DummyToken) flowComplete() { + ERROR.Printf("A lookup for token %d returned nil\n", d.id) +} + +func (d *DummyToken) Error() error { + return nil +} + +func (p *DummyToken) setError(e error) {} + +// PlaceHolderToken does nothing and was implemented to allow a messageid to be reserved +// it differs from DummyToken in that calling flowComplete does not generate an error (it +// is expected that flowComplete will be called when the token is overwritten with a real token) +type PlaceHolderToken struct { + id uint16 +} + +func (p *PlaceHolderToken) Wait() bool { + return true +} + +func (p *PlaceHolderToken) WaitTimeout(t time.Duration) bool { + return true +} + +func (p *PlaceHolderToken) flowComplete() { +} + +func (p *PlaceHolderToken) Error() error { + return nil +} + +func (p *PlaceHolderToken) setError(e error) {} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/net.go b/vendor/github.com/eclipse/paho.mqtt.golang/net.go new file mode 100644 index 00000000000..804cb3fc485 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/net.go @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "crypto/tls" + "errors" + "net" + "net/http" + "net/url" + "os" + "reflect" + "sync/atomic" + "time" + + "github.com/eclipse/paho.mqtt.golang/packets" + "golang.org/x/net/proxy" +) + +func signalError(c chan<- error, err error) { + select { + case c <- err: + default: + } +} + +func openConnection(uri *url.URL, tlsc *tls.Config, timeout time.Duration, headers http.Header) (net.Conn, error) { + switch uri.Scheme { + case "ws": + conn, err := NewWebsocket(uri.String(), nil, timeout, headers) + return conn, err + case "wss": + conn, err := NewWebsocket(uri.String(), tlsc, timeout, headers) + return conn, err + case "tcp": + allProxy := os.Getenv("all_proxy") + if len(allProxy) == 0 { + conn, err := net.DialTimeout("tcp", uri.Host, timeout) + if err != nil { + return nil, err + } + return conn, nil + } + proxyDialer := proxy.FromEnvironment() + + conn, err := proxyDialer.Dial("tcp", uri.Host) + if err != nil { + return nil, err + } + return conn, nil + case "unix": + conn, err := net.DialTimeout("unix", uri.Host, timeout) + if err != nil { + return nil, err + } + return conn, nil + case "ssl": + fallthrough + case "tls": + fallthrough + case "tcps": + allProxy := os.Getenv("all_proxy") + if len(allProxy) == 0 { + conn, err := tls.DialWithDialer(&net.Dialer{Timeout: timeout}, "tcp", uri.Host, tlsc) + if err != nil { + return nil, err + } + return conn, nil + } + proxyDialer := proxy.FromEnvironment() + + conn, err := proxyDialer.Dial("tcp", uri.Host) + if err != nil { + return nil, err + } + + tlsConn := tls.Client(conn, tlsc) + + err = tlsConn.Handshake() + if err != nil { + conn.Close() + return nil, err + } + + return tlsConn, nil + } + return nil, errors.New("Unknown protocol") +} + +// actually read incoming messages off the wire +// send Message object into ibound channel +func incoming(c *client) { + var err error + var cp packets.ControlPacket + + defer c.workers.Done() + + DEBUG.Println(NET, "incoming started") + + for { + if cp, err = packets.ReadPacket(c.conn); err != nil { + break + } + DEBUG.Println(NET, "Received Message") + select { + case c.ibound <- cp: + // Notify keepalive logic that we recently received a packet + if c.options.KeepAlive != 0 { + c.lastReceived.Store(time.Now()) + } + case <-c.stop: + // This avoids a deadlock should a message arrive while shutting down. + // In that case the "reader" of c.ibound might already be gone + WARN.Println(NET, "incoming dropped a received message during shutdown") + break + } + } + // We received an error on read. + // If disconnect is in progress, swallow error and return + select { + case <-c.stop: + DEBUG.Println(NET, "incoming stopped") + return + // Not trying to disconnect, send the error to the errors channel + default: + ERROR.Println(NET, "incoming stopped with error", err) + signalError(c.errors, err) + return + } +} + +// receive a Message object on obound, and then +// actually send outgoing message to the wire +func outgoing(c *client) { + defer c.workers.Done() + DEBUG.Println(NET, "outgoing started") + + for { + DEBUG.Println(NET, "outgoing waiting for an outbound message") + select { + case <-c.stop: + DEBUG.Println(NET, "outgoing stopped") + return + case pub := <-c.obound: + msg := pub.p.(*packets.PublishPacket) + + if c.options.WriteTimeout > 0 { + c.conn.SetWriteDeadline(time.Now().Add(c.options.WriteTimeout)) + } + + if err := msg.Write(c.conn); err != nil { + ERROR.Println(NET, "outgoing stopped with error", err) + pub.t.setError(err) + signalError(c.errors, err) + return + } + + if c.options.WriteTimeout > 0 { + // If we successfully wrote, we don't want the timeout to happen during an idle period + // so we reset it to infinite. + c.conn.SetWriteDeadline(time.Time{}) + } + + if msg.Qos == 0 { + pub.t.flowComplete() + } + DEBUG.Println(NET, "obound wrote msg, id:", msg.MessageID) + case msg := <-c.oboundP: + DEBUG.Println(NET, "obound priority msg to write, type", reflect.TypeOf(msg.p)) + if err := msg.p.Write(c.conn); err != nil { + ERROR.Println(NET, "outgoing stopped with error", err) + if msg.t != nil { + msg.t.setError(err) + } + signalError(c.errors, err) + return + } + switch msg.p.(type) { + case *packets.DisconnectPacket: + msg.t.(*DisconnectToken).flowComplete() + DEBUG.Println(NET, "outbound wrote disconnect, stopping") + return + } + } + // Reset ping timer after sending control packet. + if c.options.KeepAlive != 0 { + c.lastSent.Store(time.Now()) + } + } +} + +// receive Message objects on ibound +// store messages if necessary +// send replies on obound +// delete messages from store if necessary +func alllogic(c *client) { + defer c.workers.Done() + DEBUG.Println(NET, "logic started") + + for { + DEBUG.Println(NET, "logic waiting for msg on ibound") + + select { + case msg := <-c.ibound: + DEBUG.Println(NET, "logic got msg on ibound") + persistInbound(c.persist, msg) + switch m := msg.(type) { + case *packets.PingrespPacket: + DEBUG.Println(NET, "received pingresp") + atomic.StoreInt32(&c.pingOutstanding, 0) + case *packets.SubackPacket: + DEBUG.Println(NET, "received suback, id:", m.MessageID) + token := c.getToken(m.MessageID) + switch t := token.(type) { + case *SubscribeToken: + DEBUG.Println(NET, "granted qoss", m.ReturnCodes) + for i, qos := range m.ReturnCodes { + t.subResult[t.subs[i]] = qos + } + } + token.flowComplete() + c.freeID(m.MessageID) + case *packets.UnsubackPacket: + DEBUG.Println(NET, "received unsuback, id:", m.MessageID) + c.getToken(m.MessageID).flowComplete() + c.freeID(m.MessageID) + case *packets.PublishPacket: + DEBUG.Println(NET, "received publish, msgId:", m.MessageID) + DEBUG.Println(NET, "putting msg on onPubChan") + switch m.Qos { + case 2: + c.incomingPubChan <- m + DEBUG.Println(NET, "done putting msg on incomingPubChan") + case 1: + c.incomingPubChan <- m + DEBUG.Println(NET, "done putting msg on incomingPubChan") + case 0: + select { + case c.incomingPubChan <- m: + case <-c.stop: + } + DEBUG.Println(NET, "done putting msg on incomingPubChan") + } + case *packets.PubackPacket: + DEBUG.Println(NET, "received puback, id:", m.MessageID) + // c.receipts.get(msg.MsgId()) <- Receipt{} + // c.receipts.end(msg.MsgId()) + c.getToken(m.MessageID).flowComplete() + c.freeID(m.MessageID) + case *packets.PubrecPacket: + DEBUG.Println(NET, "received pubrec, id:", m.MessageID) + prel := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket) + prel.MessageID = m.MessageID + select { + case c.oboundP <- &PacketAndToken{p: prel, t: nil}: + case <-c.stop: + } + case *packets.PubrelPacket: + DEBUG.Println(NET, "received pubrel, id:", m.MessageID) + pc := packets.NewControlPacket(packets.Pubcomp).(*packets.PubcompPacket) + pc.MessageID = m.MessageID + persistOutbound(c.persist, pc) + select { + case c.oboundP <- &PacketAndToken{p: pc, t: nil}: + case <-c.stop: + } + case *packets.PubcompPacket: + DEBUG.Println(NET, "received pubcomp, id:", m.MessageID) + c.getToken(m.MessageID).flowComplete() + c.freeID(m.MessageID) + } + case <-c.stop: + WARN.Println(NET, "logic stopped") + return + } + } +} + +func (c *client) ackFunc(packet *packets.PublishPacket) func() { + return func() { + switch packet.Qos { + case 2: + pr := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket) + pr.MessageID = packet.MessageID + DEBUG.Println(NET, "putting pubrec msg on obound") + select { + case c.oboundP <- &PacketAndToken{p: pr, t: nil}: + case <-c.stop: + } + DEBUG.Println(NET, "done putting pubrec msg on obound") + case 1: + pa := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket) + pa.MessageID = packet.MessageID + DEBUG.Println(NET, "putting puback msg on obound") + persistOutbound(c.persist, pa) + select { + case c.oboundP <- &PacketAndToken{p: pa, t: nil}: + case <-c.stop: + } + DEBUG.Println(NET, "done putting puback msg on obound") + case 0: + // do nothing, since there is no need to send an ack packet back + } + } +} + +func errorWatch(c *client) { + defer c.workers.Done() + select { + case <-c.stop: + WARN.Println(NET, "errorWatch stopped") + return + case err := <-c.errors: + ERROR.Println(NET, "error triggered, stopping") + go c.internalConnLost(err) + return + } +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/notice.html b/vendor/github.com/eclipse/paho.mqtt.golang/notice.html new file mode 100644 index 00000000000..f19c483b9c8 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/notice.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

      Eclipse Foundation Software User Agreement

      +

      February 1, 2011

      + +

      Usage Of Content

      + +

      THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

      + +

      Applicable Licenses

      + +

      Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

      + +

      Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

      + +
        +
      • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
      • +
      • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
      • +
      • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
      • +
      • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
      • +
      + +

      The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

      + +
        +
      • The top-level (root) directory
      • +
      • Plug-in and Fragment directories
      • +
      • Inside Plug-ins and Fragments packaged as JARs
      • +
      • Sub-directories of the directory named "src" of certain Plug-ins
      • +
      • Feature directories
      • +
      + +

      Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

      + +

      THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

      + + + +

      IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

      + + +

      Use of Provisioning Technology

      + +

      The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

      + +

      You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

      + +
        +
      1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
      2. +
      3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
      4. +
      5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
      6. +
      + +

      Cryptography

      + +

      Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

      + +

      Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

      + + diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/oops.go b/vendor/github.com/eclipse/paho.mqtt.golang/oops.go new file mode 100644 index 00000000000..39630d7f28a --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/oops.go @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +func chkerr(e error) { + if e != nil { + panic(e) + } +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/options.go b/vendor/github.com/eclipse/paho.mqtt.golang/options.go new file mode 100644 index 00000000000..4a391192d43 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/options.go @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + * Måns Ansgariusson + */ + +// Portions copyright © 2018 TIBCO Software Inc. + +package mqtt + +import ( + "crypto/tls" + "net/http" + "net/url" + "regexp" + "strings" + "time" +) + +// CredentialsProvider allows the username and password to be updated +// before reconnecting. It should return the current username and password. +type CredentialsProvider func() (username string, password string) + +// MessageHandler is a callback type which can be set to be +// executed upon the arrival of messages published to topics +// to which the client is subscribed. +type MessageHandler func(Client, Message) + +// ConnectionLostHandler is a callback type which can be set to be +// executed upon an unintended disconnection from the MQTT broker. +// Disconnects caused by calling Disconnect or ForceDisconnect will +// not cause an OnConnectionLost callback to execute. +type ConnectionLostHandler func(Client, error) + +// OnConnectHandler is a callback that is called when the client +// state changes from unconnected/disconnected to connected. Both +// at initial connection and on reconnection +type OnConnectHandler func(Client) + +// ReconnectHandler is invoked prior to reconnecting after +// the initial connection is lost +type ReconnectHandler func(Client, *ClientOptions) + +// ClientOptions contains configurable options for an Client. +type ClientOptions struct { + Servers []*url.URL + ClientID string + Username string + Password string + CredentialsProvider CredentialsProvider + CleanSession bool + Order bool + WillEnabled bool + WillTopic string + WillPayload []byte + WillQos byte + WillRetained bool + ProtocolVersion uint + protocolVersionExplicit bool + TLSConfig *tls.Config + KeepAlive int64 + PingTimeout time.Duration + ConnectTimeout time.Duration + MaxReconnectInterval time.Duration + AutoReconnect bool + ConnectRetryInterval time.Duration + ConnectRetry bool + Store Store + DefaultPublishHandler MessageHandler + OnConnect OnConnectHandler + OnConnectionLost ConnectionLostHandler + OnReconnecting ReconnectHandler + WriteTimeout time.Duration + MessageChannelDepth uint + ResumeSubs bool + HTTPHeaders http.Header +} + +// NewClientOptions will create a new ClientClientOptions type with some +// default values. +// Port: 1883 +// CleanSession: True +// Order: True +// KeepAlive: 30 (seconds) +// ConnectTimeout: 30 (seconds) +// MaxReconnectInterval 10 (minutes) +// AutoReconnect: True +func NewClientOptions() *ClientOptions { + o := &ClientOptions{ + Servers: nil, + ClientID: "", + Username: "", + Password: "", + CleanSession: true, + Order: true, + WillEnabled: false, + WillTopic: "", + WillPayload: nil, + WillQos: 0, + WillRetained: false, + ProtocolVersion: 0, + protocolVersionExplicit: false, + KeepAlive: 30, + PingTimeout: 10 * time.Second, + ConnectTimeout: 30 * time.Second, + MaxReconnectInterval: 10 * time.Minute, + AutoReconnect: true, + ConnectRetryInterval: 30 * time.Second, + ConnectRetry: false, + Store: nil, + OnConnect: nil, + OnConnectionLost: DefaultConnectionLostHandler, + WriteTimeout: 0, // 0 represents timeout disabled + ResumeSubs: false, + HTTPHeaders: make(map[string][]string), + } + return o +} + +// AddBroker adds a broker URI to the list of brokers to be used. The format should be +// scheme://host:port +// Where "scheme" is one of "tcp", "ssl", or "ws", "host" is the ip-address (or hostname) +// and "port" is the port on which the broker is accepting connections. +// +// Default values for hostname is "127.0.0.1", for schema is "tcp://". +// +// An example broker URI would look like: tcp://foobar.com:1883 +func (o *ClientOptions) AddBroker(server string) *ClientOptions { + re := regexp.MustCompile(`%(25)?`) + if len(server) > 0 && server[0] == ':' { + server = "127.0.0.1" + server + } + if !strings.Contains(server, "://") { + server = "tcp://" + server + } + server = re.ReplaceAllLiteralString(server, "%25") + brokerURI, err := url.Parse(server) + if err != nil { + ERROR.Println(CLI, "Failed to parse %q broker address: %s", server, err) + return o + } + o.Servers = append(o.Servers, brokerURI) + return o +} + +// SetResumeSubs will enable resuming of stored (un)subscribe messages when connecting +// but not reconnecting if CleanSession is false. Otherwise these messages are discarded. +func (o *ClientOptions) SetResumeSubs(resume bool) *ClientOptions { + o.ResumeSubs = resume + return o +} + +// SetClientID will set the client id to be used by this client when +// connecting to the MQTT broker. According to the MQTT v3.1 specification, +// a client id must be no longer than 23 characters. +func (o *ClientOptions) SetClientID(id string) *ClientOptions { + o.ClientID = id + return o +} + +// SetUsername will set the username to be used by this client when connecting +// to the MQTT broker. Note: without the use of SSL/TLS, this information will +// be sent in plaintext across the wire. +func (o *ClientOptions) SetUsername(u string) *ClientOptions { + o.Username = u + return o +} + +// SetPassword will set the password to be used by this client when connecting +// to the MQTT broker. Note: without the use of SSL/TLS, this information will +// be sent in plaintext across the wire. +func (o *ClientOptions) SetPassword(p string) *ClientOptions { + o.Password = p + return o +} + +// SetCredentialsProvider will set a method to be called by this client when +// connecting to the MQTT broker that provide the current username and password. +// Note: without the use of SSL/TLS, this information will be sent +// in plaintext across the wire. +func (o *ClientOptions) SetCredentialsProvider(p CredentialsProvider) *ClientOptions { + o.CredentialsProvider = p + return o +} + +// SetCleanSession will set the "clean session" flag in the connect message +// when this client connects to an MQTT broker. By setting this flag, you are +// indicating that no messages saved by the broker for this client should be +// delivered. Any messages that were going to be sent by this client before +// diconnecting previously but didn't will not be sent upon connecting to the +// broker. +func (o *ClientOptions) SetCleanSession(clean bool) *ClientOptions { + o.CleanSession = clean + return o +} + +// SetOrderMatters will set the message routing to guarantee order within +// each QoS level. By default, this value is true. If set to false, +// this flag indicates that messages can be delivered asynchronously +// from the client to the application and possibly arrive out of order. +func (o *ClientOptions) SetOrderMatters(order bool) *ClientOptions { + o.Order = order + return o +} + +// SetTLSConfig will set an SSL/TLS configuration to be used when connecting +// to an MQTT broker. Please read the official Go documentation for more +// information. +func (o *ClientOptions) SetTLSConfig(t *tls.Config) *ClientOptions { + o.TLSConfig = t + return o +} + +// SetStore will set the implementation of the Store interface +// used to provide message persistence in cases where QoS levels +// QoS_ONE or QoS_TWO are used. If no store is provided, then the +// client will use MemoryStore by default. +func (o *ClientOptions) SetStore(s Store) *ClientOptions { + o.Store = s + return o +} + +// SetKeepAlive will set the amount of time (in seconds) that the client +// should wait before sending a PING request to the broker. This will +// allow the client to know that a connection has not been lost with the +// server. +func (o *ClientOptions) SetKeepAlive(k time.Duration) *ClientOptions { + o.KeepAlive = int64(k / time.Second) + return o +} + +// SetPingTimeout will set the amount of time (in seconds) that the client +// will wait after sending a PING request to the broker, before deciding +// that the connection has been lost. Default is 10 seconds. +func (o *ClientOptions) SetPingTimeout(k time.Duration) *ClientOptions { + o.PingTimeout = k + return o +} + +// SetProtocolVersion sets the MQTT version to be used to connect to the +// broker. Legitimate values are currently 3 - MQTT 3.1 or 4 - MQTT 3.1.1 +func (o *ClientOptions) SetProtocolVersion(pv uint) *ClientOptions { + if (pv >= 3 && pv <= 4) || (pv > 0x80) { + o.ProtocolVersion = pv + o.protocolVersionExplicit = true + } + return o +} + +// UnsetWill will cause any set will message to be disregarded. +func (o *ClientOptions) UnsetWill() *ClientOptions { + o.WillEnabled = false + return o +} + +// SetWill accepts a string will message to be set. When the client connects, +// it will give this will message to the broker, which will then publish the +// provided payload (the will) to any clients that are subscribed to the provided +// topic. +func (o *ClientOptions) SetWill(topic string, payload string, qos byte, retained bool) *ClientOptions { + o.SetBinaryWill(topic, []byte(payload), qos, retained) + return o +} + +// SetBinaryWill accepts a []byte will message to be set. When the client connects, +// it will give this will message to the broker, which will then publish the +// provided payload (the will) to any clients that are subscribed to the provided +// topic. +func (o *ClientOptions) SetBinaryWill(topic string, payload []byte, qos byte, retained bool) *ClientOptions { + o.WillEnabled = true + o.WillTopic = topic + o.WillPayload = payload + o.WillQos = qos + o.WillRetained = retained + return o +} + +// SetDefaultPublishHandler sets the MessageHandler that will be called when a message +// is received that does not match any known subscriptions. +func (o *ClientOptions) SetDefaultPublishHandler(defaultHandler MessageHandler) *ClientOptions { + o.DefaultPublishHandler = defaultHandler + return o +} + +// SetOnConnectHandler sets the function to be called when the client is connected. Both +// at initial connection time and upon automatic reconnect. +func (o *ClientOptions) SetOnConnectHandler(onConn OnConnectHandler) *ClientOptions { + o.OnConnect = onConn + return o +} + +// SetConnectionLostHandler will set the OnConnectionLost callback to be executed +// in the case where the client unexpectedly loses connection with the MQTT broker. +func (o *ClientOptions) SetConnectionLostHandler(onLost ConnectionLostHandler) *ClientOptions { + o.OnConnectionLost = onLost + return o +} + +// SetReconnectingHandler sets the OnReconnecting callback to be executed prior +// to the client attempting a reconnect to the MQTT broker. +func (o *ClientOptions) SetReconnectingHandler(cb ReconnectHandler) *ClientOptions { + o.OnReconnecting = cb + return o +} + +// SetWriteTimeout puts a limit on how long a mqtt publish should block until it unblocks with a +// timeout error. A duration of 0 never times out. Default 30 seconds +func (o *ClientOptions) SetWriteTimeout(t time.Duration) *ClientOptions { + o.WriteTimeout = t + return o +} + +// SetConnectTimeout limits how long the client will wait when trying to open a connection +// to an MQTT server before timing out and erroring the attempt. A duration of 0 never times out. +// Default 30 seconds. Currently only operational on TCP/TLS connections. +func (o *ClientOptions) SetConnectTimeout(t time.Duration) *ClientOptions { + o.ConnectTimeout = t + return o +} + +// SetMaxReconnectInterval sets the maximum time that will be waited between reconnection attempts +// when connection is lost +func (o *ClientOptions) SetMaxReconnectInterval(t time.Duration) *ClientOptions { + o.MaxReconnectInterval = t + return o +} + +// SetAutoReconnect sets whether the automatic reconnection logic should be used +// when the connection is lost, even if disabled the ConnectionLostHandler is still +// called +func (o *ClientOptions) SetAutoReconnect(a bool) *ClientOptions { + o.AutoReconnect = a + return o +} + +// SetConnectRetryInterval sets the time that will be waited between connection attempts +// when initially connecting if ConnectRetry is TRUE +func (o *ClientOptions) SetConnectRetryInterval(t time.Duration) *ClientOptions { + o.ConnectRetryInterval = t + return o +} + +// SetConnectRetry sets whether the connect function will automatically retry the connection +// in the event of a failure (when true the token returned by the Connect function will +// not complete until the connection is up or it is cancelled) +// If ConnectRetry is true then subscriptions should be requested in OnConnect handler +// Setting this to TRUE permits mesages to be published before the connection is established +func (o *ClientOptions) SetConnectRetry(a bool) *ClientOptions { + o.ConnectRetry = a + return o +} + +// SetMessageChannelDepth DEPRECATED The value set here no longer has any effect, this function +// remains so the API is not altered. +func (o *ClientOptions) SetMessageChannelDepth(s uint) *ClientOptions { + o.MessageChannelDepth = s + return o +} + +// SetHTTPHeaders sets the additional HTTP headers that will be sent in the WebSocket +// opening handshake. +func (o *ClientOptions) SetHTTPHeaders(h http.Header) *ClientOptions { + o.HTTPHeaders = h + return o +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/options_reader.go b/vendor/github.com/eclipse/paho.mqtt.golang/options_reader.go new file mode 100644 index 00000000000..0f252e88395 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/options_reader.go @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "crypto/tls" + "net/http" + "net/url" + "time" +) + +// ClientOptionsReader provides an interface for reading ClientOptions after the client has been initialized. +type ClientOptionsReader struct { + options *ClientOptions +} + +//Servers returns a slice of the servers defined in the clientoptions +func (r *ClientOptionsReader) Servers() []*url.URL { + s := make([]*url.URL, len(r.options.Servers)) + + for i, u := range r.options.Servers { + nu := *u + s[i] = &nu + } + + return s +} + +//ResumeSubs returns true if resuming stored (un)sub is enabled +func (r *ClientOptionsReader) ResumeSubs() bool { + s := r.options.ResumeSubs + return s +} + +//ClientID returns the set client id +func (r *ClientOptionsReader) ClientID() string { + s := r.options.ClientID + return s +} + +//Username returns the set username +func (r *ClientOptionsReader) Username() string { + s := r.options.Username + return s +} + +//Password returns the set password +func (r *ClientOptionsReader) Password() string { + s := r.options.Password + return s +} + +//CleanSession returns whether Cleansession is set +func (r *ClientOptionsReader) CleanSession() bool { + s := r.options.CleanSession + return s +} + +func (r *ClientOptionsReader) Order() bool { + s := r.options.Order + return s +} + +func (r *ClientOptionsReader) WillEnabled() bool { + s := r.options.WillEnabled + return s +} + +func (r *ClientOptionsReader) WillTopic() string { + s := r.options.WillTopic + return s +} + +func (r *ClientOptionsReader) WillPayload() []byte { + s := r.options.WillPayload + return s +} + +func (r *ClientOptionsReader) WillQos() byte { + s := r.options.WillQos + return s +} + +func (r *ClientOptionsReader) WillRetained() bool { + s := r.options.WillRetained + return s +} + +func (r *ClientOptionsReader) ProtocolVersion() uint { + s := r.options.ProtocolVersion + return s +} + +func (r *ClientOptionsReader) TLSConfig() *tls.Config { + s := r.options.TLSConfig + return s +} + +func (r *ClientOptionsReader) KeepAlive() time.Duration { + s := time.Duration(r.options.KeepAlive * int64(time.Second)) + return s +} + +func (r *ClientOptionsReader) PingTimeout() time.Duration { + s := r.options.PingTimeout + return s +} + +func (r *ClientOptionsReader) ConnectTimeout() time.Duration { + s := r.options.ConnectTimeout + return s +} + +func (r *ClientOptionsReader) MaxReconnectInterval() time.Duration { + s := r.options.MaxReconnectInterval + return s +} + +func (r *ClientOptionsReader) AutoReconnect() bool { + s := r.options.AutoReconnect + return s +} + +//ConnectRetryInterval returns the delay between retries on the initial connection (if ConnectRetry true) +func (r *ClientOptionsReader) ConnectRetryInterval() time.Duration { + s := r.options.ConnectRetryInterval + return s +} + +//ConnectRetry returns whether the initial connection request will be retried until connection established +func (r *ClientOptionsReader) ConnectRetry() bool { + s := r.options.ConnectRetry + return s +} + +func (r *ClientOptionsReader) WriteTimeout() time.Duration { + s := r.options.WriteTimeout + return s +} + +func (r *ClientOptionsReader) MessageChannelDepth() uint { + s := r.options.MessageChannelDepth + return s +} + +func (r *ClientOptionsReader) HTTPHeaders() http.Header { + h := r.options.HTTPHeaders + return h +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/connack.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/connack.go new file mode 100644 index 00000000000..de58c81e9ee --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/connack.go @@ -0,0 +1,52 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//ConnackPacket is an internal representation of the fields of the +//Connack MQTT packet +type ConnackPacket struct { + FixedHeader + SessionPresent bool + ReturnCode byte +} + +func (ca *ConnackPacket) String() string { + return fmt.Sprintf("%s sessionpresent: %t returncode: %d", ca.FixedHeader, ca.SessionPresent, ca.ReturnCode) +} + +func (ca *ConnackPacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + + body.WriteByte(boolToByte(ca.SessionPresent)) + body.WriteByte(ca.ReturnCode) + ca.FixedHeader.RemainingLength = 2 + packet := ca.FixedHeader.pack() + packet.Write(body.Bytes()) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (ca *ConnackPacket) Unpack(b io.Reader) error { + flags, err := decodeByte(b) + if err != nil { + return err + } + ca.SessionPresent = 1&flags > 0 + ca.ReturnCode, err = decodeByte(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (ca *ConnackPacket) Details() Details { + return Details{Qos: 0, MessageID: 0} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/connect.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/connect.go new file mode 100644 index 00000000000..da0fc05226e --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/connect.go @@ -0,0 +1,151 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//ConnectPacket is an internal representation of the fields of the +//Connect MQTT packet +type ConnectPacket struct { + FixedHeader + ProtocolName string + ProtocolVersion byte + CleanSession bool + WillFlag bool + WillQos byte + WillRetain bool + UsernameFlag bool + PasswordFlag bool + ReservedBit byte + Keepalive uint16 + + ClientIdentifier string + WillTopic string + WillMessage []byte + Username string + Password []byte +} + +func (c *ConnectPacket) String() string { + return fmt.Sprintf("%s protocolversion: %d protocolname: %s cleansession: %t willflag: %t WillQos: %d WillRetain: %t Usernameflag: %t Passwordflag: %t keepalive: %d clientId: %s willtopic: %s willmessage: %s Username: %s Password: %s", c.FixedHeader, c.ProtocolVersion, c.ProtocolName, c.CleanSession, c.WillFlag, c.WillQos, c.WillRetain, c.UsernameFlag, c.PasswordFlag, c.Keepalive, c.ClientIdentifier, c.WillTopic, c.WillMessage, c.Username, c.Password) +} + +func (c *ConnectPacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + + body.Write(encodeString(c.ProtocolName)) + body.WriteByte(c.ProtocolVersion) + body.WriteByte(boolToByte(c.CleanSession)<<1 | boolToByte(c.WillFlag)<<2 | c.WillQos<<3 | boolToByte(c.WillRetain)<<5 | boolToByte(c.PasswordFlag)<<6 | boolToByte(c.UsernameFlag)<<7) + body.Write(encodeUint16(c.Keepalive)) + body.Write(encodeString(c.ClientIdentifier)) + if c.WillFlag { + body.Write(encodeString(c.WillTopic)) + body.Write(encodeBytes(c.WillMessage)) + } + if c.UsernameFlag { + body.Write(encodeString(c.Username)) + } + if c.PasswordFlag { + body.Write(encodeBytes(c.Password)) + } + c.FixedHeader.RemainingLength = body.Len() + packet := c.FixedHeader.pack() + packet.Write(body.Bytes()) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (c *ConnectPacket) Unpack(b io.Reader) error { + var err error + c.ProtocolName, err = decodeString(b) + if err != nil { + return err + } + c.ProtocolVersion, err = decodeByte(b) + if err != nil { + return err + } + options, err := decodeByte(b) + if err != nil { + return err + } + c.ReservedBit = 1 & options + c.CleanSession = 1&(options>>1) > 0 + c.WillFlag = 1&(options>>2) > 0 + c.WillQos = 3 & (options >> 3) + c.WillRetain = 1&(options>>5) > 0 + c.PasswordFlag = 1&(options>>6) > 0 + c.UsernameFlag = 1&(options>>7) > 0 + c.Keepalive, err = decodeUint16(b) + if err != nil { + return err + } + c.ClientIdentifier, err = decodeString(b) + if err != nil { + return err + } + if c.WillFlag { + c.WillTopic, err = decodeString(b) + if err != nil { + return err + } + c.WillMessage, err = decodeBytes(b) + if err != nil { + return err + } + } + if c.UsernameFlag { + c.Username, err = decodeString(b) + if err != nil { + return err + } + } + if c.PasswordFlag { + c.Password, err = decodeBytes(b) + if err != nil { + return err + } + } + + return nil +} + +//Validate performs validation of the fields of a Connect packet +func (c *ConnectPacket) Validate() byte { + if c.PasswordFlag && !c.UsernameFlag { + return ErrRefusedBadUsernameOrPassword + } + if c.ReservedBit != 0 { + //Bad reserved bit + return ErrProtocolViolation + } + if (c.ProtocolName == "MQIsdp" && c.ProtocolVersion != 3) || (c.ProtocolName == "MQTT" && c.ProtocolVersion != 4) { + //Mismatched or unsupported protocol version + return ErrRefusedBadProtocolVersion + } + if c.ProtocolName != "MQIsdp" && c.ProtocolName != "MQTT" { + //Bad protocol name + return ErrProtocolViolation + } + if len(c.ClientIdentifier) > 65535 || len(c.Username) > 65535 || len(c.Password) > 65535 { + //Bad size field + return ErrProtocolViolation + } + if len(c.ClientIdentifier) == 0 && !c.CleanSession { + //Bad client identifier + return ErrRefusedIDRejected + } + return Accepted +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (c *ConnectPacket) Details() Details { + return Details{Qos: 0, MessageID: 0} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/disconnect.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/disconnect.go new file mode 100644 index 00000000000..c8d374508cf --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/disconnect.go @@ -0,0 +1,34 @@ +package packets + +import ( + "io" +) + +//DisconnectPacket is an internal representation of the fields of the +//Disconnect MQTT packet +type DisconnectPacket struct { + FixedHeader +} + +func (d *DisconnectPacket) String() string { + return d.FixedHeader.String() +} + +func (d *DisconnectPacket) Write(w io.Writer) error { + packet := d.FixedHeader.pack() + _, err := packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (d *DisconnectPacket) Unpack(b io.Reader) error { + return nil +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (d *DisconnectPacket) Details() Details { + return Details{Qos: 0, MessageID: 0} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/packets.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/packets.go new file mode 100644 index 00000000000..42eeb46d39c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/packets.go @@ -0,0 +1,346 @@ +package packets + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" +) + +//ControlPacket defines the interface for structs intended to hold +//decoded MQTT packets, either from being read or before being +//written +type ControlPacket interface { + Write(io.Writer) error + Unpack(io.Reader) error + String() string + Details() Details +} + +//PacketNames maps the constants for each of the MQTT packet types +//to a string representation of their name. +var PacketNames = map[uint8]string{ + 1: "CONNECT", + 2: "CONNACK", + 3: "PUBLISH", + 4: "PUBACK", + 5: "PUBREC", + 6: "PUBREL", + 7: "PUBCOMP", + 8: "SUBSCRIBE", + 9: "SUBACK", + 10: "UNSUBSCRIBE", + 11: "UNSUBACK", + 12: "PINGREQ", + 13: "PINGRESP", + 14: "DISCONNECT", +} + +//Below are the constants assigned to each of the MQTT packet types +const ( + Connect = 1 + Connack = 2 + Publish = 3 + Puback = 4 + Pubrec = 5 + Pubrel = 6 + Pubcomp = 7 + Subscribe = 8 + Suback = 9 + Unsubscribe = 10 + Unsuback = 11 + Pingreq = 12 + Pingresp = 13 + Disconnect = 14 +) + +//Below are the const definitions for error codes returned by +//Connect() +const ( + Accepted = 0x00 + ErrRefusedBadProtocolVersion = 0x01 + ErrRefusedIDRejected = 0x02 + ErrRefusedServerUnavailable = 0x03 + ErrRefusedBadUsernameOrPassword = 0x04 + ErrRefusedNotAuthorised = 0x05 + ErrNetworkError = 0xFE + ErrProtocolViolation = 0xFF +) + +//ConnackReturnCodes is a map of the error codes constants for Connect() +//to a string representation of the error +var ConnackReturnCodes = map[uint8]string{ + 0: "Connection Accepted", + 1: "Connection Refused: Bad Protocol Version", + 2: "Connection Refused: Client Identifier Rejected", + 3: "Connection Refused: Server Unavailable", + 4: "Connection Refused: Username or Password in unknown format", + 5: "Connection Refused: Not Authorised", + 254: "Connection Error", + 255: "Connection Refused: Protocol Violation", +} + +//ConnErrors is a map of the errors codes constants for Connect() +//to a Go error +var ConnErrors = map[byte]error{ + Accepted: nil, + ErrRefusedBadProtocolVersion: errors.New("Unnacceptable protocol version"), + ErrRefusedIDRejected: errors.New("Identifier rejected"), + ErrRefusedServerUnavailable: errors.New("Server Unavailable"), + ErrRefusedBadUsernameOrPassword: errors.New("Bad user name or password"), + ErrRefusedNotAuthorised: errors.New("Not Authorized"), + ErrNetworkError: errors.New("Network Error"), + ErrProtocolViolation: errors.New("Protocol Violation"), +} + +//ReadPacket takes an instance of an io.Reader (such as net.Conn) and attempts +//to read an MQTT packet from the stream. It returns a ControlPacket +//representing the decoded MQTT packet and an error. One of these returns will +//always be nil, a nil ControlPacket indicating an error occurred. +func ReadPacket(r io.Reader) (ControlPacket, error) { + var fh FixedHeader + b := make([]byte, 1) + + _, err := io.ReadFull(r, b) + if err != nil { + return nil, err + } + + err = fh.unpack(b[0], r) + if err != nil { + return nil, err + } + + cp, err := NewControlPacketWithHeader(fh) + if err != nil { + return nil, err + } + + packetBytes := make([]byte, fh.RemainingLength) + n, err := io.ReadFull(r, packetBytes) + if err != nil { + return nil, err + } + if n != fh.RemainingLength { + return nil, errors.New("Failed to read expected data") + } + + err = cp.Unpack(bytes.NewBuffer(packetBytes)) + return cp, err +} + +//NewControlPacket is used to create a new ControlPacket of the type specified +//by packetType, this is usually done by reference to the packet type constants +//defined in packets.go. The newly created ControlPacket is empty and a pointer +//is returned. +func NewControlPacket(packetType byte) ControlPacket { + switch packetType { + case Connect: + return &ConnectPacket{FixedHeader: FixedHeader{MessageType: Connect}} + case Connack: + return &ConnackPacket{FixedHeader: FixedHeader{MessageType: Connack}} + case Disconnect: + return &DisconnectPacket{FixedHeader: FixedHeader{MessageType: Disconnect}} + case Publish: + return &PublishPacket{FixedHeader: FixedHeader{MessageType: Publish}} + case Puback: + return &PubackPacket{FixedHeader: FixedHeader{MessageType: Puback}} + case Pubrec: + return &PubrecPacket{FixedHeader: FixedHeader{MessageType: Pubrec}} + case Pubrel: + return &PubrelPacket{FixedHeader: FixedHeader{MessageType: Pubrel, Qos: 1}} + case Pubcomp: + return &PubcompPacket{FixedHeader: FixedHeader{MessageType: Pubcomp}} + case Subscribe: + return &SubscribePacket{FixedHeader: FixedHeader{MessageType: Subscribe, Qos: 1}} + case Suback: + return &SubackPacket{FixedHeader: FixedHeader{MessageType: Suback}} + case Unsubscribe: + return &UnsubscribePacket{FixedHeader: FixedHeader{MessageType: Unsubscribe, Qos: 1}} + case Unsuback: + return &UnsubackPacket{FixedHeader: FixedHeader{MessageType: Unsuback}} + case Pingreq: + return &PingreqPacket{FixedHeader: FixedHeader{MessageType: Pingreq}} + case Pingresp: + return &PingrespPacket{FixedHeader: FixedHeader{MessageType: Pingresp}} + } + return nil +} + +//NewControlPacketWithHeader is used to create a new ControlPacket of the type +//specified within the FixedHeader that is passed to the function. +//The newly created ControlPacket is empty and a pointer is returned. +func NewControlPacketWithHeader(fh FixedHeader) (ControlPacket, error) { + switch fh.MessageType { + case Connect: + return &ConnectPacket{FixedHeader: fh}, nil + case Connack: + return &ConnackPacket{FixedHeader: fh}, nil + case Disconnect: + return &DisconnectPacket{FixedHeader: fh}, nil + case Publish: + return &PublishPacket{FixedHeader: fh}, nil + case Puback: + return &PubackPacket{FixedHeader: fh}, nil + case Pubrec: + return &PubrecPacket{FixedHeader: fh}, nil + case Pubrel: + return &PubrelPacket{FixedHeader: fh}, nil + case Pubcomp: + return &PubcompPacket{FixedHeader: fh}, nil + case Subscribe: + return &SubscribePacket{FixedHeader: fh}, nil + case Suback: + return &SubackPacket{FixedHeader: fh}, nil + case Unsubscribe: + return &UnsubscribePacket{FixedHeader: fh}, nil + case Unsuback: + return &UnsubackPacket{FixedHeader: fh}, nil + case Pingreq: + return &PingreqPacket{FixedHeader: fh}, nil + case Pingresp: + return &PingrespPacket{FixedHeader: fh}, nil + } + return nil, fmt.Errorf("unsupported packet type 0x%x", fh.MessageType) +} + +//Details struct returned by the Details() function called on +//ControlPackets to present details of the Qos and MessageID +//of the ControlPacket +type Details struct { + Qos byte + MessageID uint16 +} + +//FixedHeader is a struct to hold the decoded information from +//the fixed header of an MQTT ControlPacket +type FixedHeader struct { + MessageType byte + Dup bool + Qos byte + Retain bool + RemainingLength int +} + +func (fh FixedHeader) String() string { + return fmt.Sprintf("%s: dup: %t qos: %d retain: %t rLength: %d", PacketNames[fh.MessageType], fh.Dup, fh.Qos, fh.Retain, fh.RemainingLength) +} + +func boolToByte(b bool) byte { + switch b { + case true: + return 1 + default: + return 0 + } +} + +func (fh *FixedHeader) pack() bytes.Buffer { + var header bytes.Buffer + header.WriteByte(fh.MessageType<<4 | boolToByte(fh.Dup)<<3 | fh.Qos<<1 | boolToByte(fh.Retain)) + header.Write(encodeLength(fh.RemainingLength)) + return header +} + +func (fh *FixedHeader) unpack(typeAndFlags byte, r io.Reader) error { + fh.MessageType = typeAndFlags >> 4 + fh.Dup = (typeAndFlags>>3)&0x01 > 0 + fh.Qos = (typeAndFlags >> 1) & 0x03 + fh.Retain = typeAndFlags&0x01 > 0 + + var err error + fh.RemainingLength, err = decodeLength(r) + return err +} + +func decodeByte(b io.Reader) (byte, error) { + num := make([]byte, 1) + _, err := b.Read(num) + if err != nil { + return 0, err + } + + return num[0], nil +} + +func decodeUint16(b io.Reader) (uint16, error) { + num := make([]byte, 2) + _, err := b.Read(num) + if err != nil { + return 0, err + } + return binary.BigEndian.Uint16(num), nil +} + +func encodeUint16(num uint16) []byte { + bytes := make([]byte, 2) + binary.BigEndian.PutUint16(bytes, num) + return bytes +} + +func encodeString(field string) []byte { + return encodeBytes([]byte(field)) +} + +func decodeString(b io.Reader) (string, error) { + buf, err := decodeBytes(b) + return string(buf), err +} + +func decodeBytes(b io.Reader) ([]byte, error) { + fieldLength, err := decodeUint16(b) + if err != nil { + return nil, err + } + + field := make([]byte, fieldLength) + _, err = b.Read(field) + if err != nil { + return nil, err + } + + return field, nil +} + +func encodeBytes(field []byte) []byte { + fieldLength := make([]byte, 2) + binary.BigEndian.PutUint16(fieldLength, uint16(len(field))) + return append(fieldLength, field...) +} + +func encodeLength(length int) []byte { + var encLength []byte + for { + digit := byte(length % 128) + length /= 128 + if length > 0 { + digit |= 0x80 + } + encLength = append(encLength, digit) + if length == 0 { + break + } + } + return encLength +} + +func decodeLength(r io.Reader) (int, error) { + var rLength uint32 + var multiplier uint32 + b := make([]byte, 1) + for multiplier < 27 { //fix: Infinite '(digit & 128) == 1' will cause the dead loop + _, err := io.ReadFull(r, b) + if err != nil { + return 0, err + } + + digit := b[0] + rLength |= uint32(digit&127) << multiplier + if (digit & 128) == 0 { + break + } + multiplier += 7 + } + return int(rLength), nil +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingreq.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingreq.go new file mode 100644 index 00000000000..27e49fedadd --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingreq.go @@ -0,0 +1,34 @@ +package packets + +import ( + "io" +) + +//PingreqPacket is an internal representation of the fields of the +//Pingreq MQTT packet +type PingreqPacket struct { + FixedHeader +} + +func (pr *PingreqPacket) String() string { + return pr.FixedHeader.String() +} + +func (pr *PingreqPacket) Write(w io.Writer) error { + packet := pr.FixedHeader.pack() + _, err := packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pr *PingreqPacket) Unpack(b io.Reader) error { + return nil +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pr *PingreqPacket) Details() Details { + return Details{Qos: 0, MessageID: 0} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingresp.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingresp.go new file mode 100644 index 00000000000..86f6d926123 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pingresp.go @@ -0,0 +1,34 @@ +package packets + +import ( + "io" +) + +//PingrespPacket is an internal representation of the fields of the +//Pingresp MQTT packet +type PingrespPacket struct { + FixedHeader +} + +func (pr *PingrespPacket) String() string { + return pr.FixedHeader.String() +} + +func (pr *PingrespPacket) Write(w io.Writer) error { + packet := pr.FixedHeader.pack() + _, err := packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pr *PingrespPacket) Unpack(b io.Reader) error { + return nil +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pr *PingrespPacket) Details() Details { + return Details{Qos: 0, MessageID: 0} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/puback.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/puback.go new file mode 100644 index 00000000000..4f2ee0bbd1c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/puback.go @@ -0,0 +1,42 @@ +package packets + +import ( + "fmt" + "io" +) + +//PubackPacket is an internal representation of the fields of the +//Puback MQTT packet +type PubackPacket struct { + FixedHeader + MessageID uint16 +} + +func (pa *PubackPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", pa.FixedHeader, pa.MessageID) +} + +func (pa *PubackPacket) Write(w io.Writer) error { + var err error + pa.FixedHeader.RemainingLength = 2 + packet := pa.FixedHeader.pack() + packet.Write(encodeUint16(pa.MessageID)) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pa *PubackPacket) Unpack(b io.Reader) error { + var err error + pa.MessageID, err = decodeUint16(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pa *PubackPacket) Details() Details { + return Details{Qos: pa.Qos, MessageID: pa.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubcomp.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubcomp.go new file mode 100644 index 00000000000..494e2d52192 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubcomp.go @@ -0,0 +1,42 @@ +package packets + +import ( + "fmt" + "io" +) + +//PubcompPacket is an internal representation of the fields of the +//Pubcomp MQTT packet +type PubcompPacket struct { + FixedHeader + MessageID uint16 +} + +func (pc *PubcompPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", pc.FixedHeader, pc.MessageID) +} + +func (pc *PubcompPacket) Write(w io.Writer) error { + var err error + pc.FixedHeader.RemainingLength = 2 + packet := pc.FixedHeader.pack() + packet.Write(encodeUint16(pc.MessageID)) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pc *PubcompPacket) Unpack(b io.Reader) error { + var err error + pc.MessageID, err = decodeUint16(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pc *PubcompPacket) Details() Details { + return Details{Qos: pc.Qos, MessageID: pc.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/publish.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/publish.go new file mode 100644 index 00000000000..7d425780c0a --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/publish.go @@ -0,0 +1,83 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//PublishPacket is an internal representation of the fields of the +//Publish MQTT packet +type PublishPacket struct { + FixedHeader + TopicName string + MessageID uint16 + Payload []byte +} + +func (p *PublishPacket) String() string { + return fmt.Sprintf("%s topicName: %s MessageID: %d payload: %s", p.FixedHeader, p.TopicName, p.MessageID, string(p.Payload)) +} + +func (p *PublishPacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + + body.Write(encodeString(p.TopicName)) + if p.Qos > 0 { + body.Write(encodeUint16(p.MessageID)) + } + p.FixedHeader.RemainingLength = body.Len() + len(p.Payload) + packet := p.FixedHeader.pack() + packet.Write(body.Bytes()) + packet.Write(p.Payload) + _, err = w.Write(packet.Bytes()) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (p *PublishPacket) Unpack(b io.Reader) error { + var payloadLength = p.FixedHeader.RemainingLength + var err error + p.TopicName, err = decodeString(b) + if err != nil { + return err + } + + if p.Qos > 0 { + p.MessageID, err = decodeUint16(b) + if err != nil { + return err + } + payloadLength -= len(p.TopicName) + 4 + } else { + payloadLength -= len(p.TopicName) + 2 + } + if payloadLength < 0 { + return fmt.Errorf("Error unpacking publish, payload length < 0") + } + p.Payload = make([]byte, payloadLength) + _, err = b.Read(p.Payload) + + return err +} + +//Copy creates a new PublishPacket with the same topic and payload +//but an empty fixed header, useful for when you want to deliver +//a message with different properties such as Qos but the same +//content +func (p *PublishPacket) Copy() *PublishPacket { + newP := NewControlPacket(Publish).(*PublishPacket) + newP.TopicName = p.TopicName + newP.Payload = p.Payload + + return newP +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (p *PublishPacket) Details() Details { + return Details{Qos: p.Qos, MessageID: p.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrec.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrec.go new file mode 100644 index 00000000000..7056089f9d6 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrec.go @@ -0,0 +1,42 @@ +package packets + +import ( + "fmt" + "io" +) + +//PubrecPacket is an internal representation of the fields of the +//Pubrec MQTT packet +type PubrecPacket struct { + FixedHeader + MessageID uint16 +} + +func (pr *PubrecPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", pr.FixedHeader, pr.MessageID) +} + +func (pr *PubrecPacket) Write(w io.Writer) error { + var err error + pr.FixedHeader.RemainingLength = 2 + packet := pr.FixedHeader.pack() + packet.Write(encodeUint16(pr.MessageID)) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pr *PubrecPacket) Unpack(b io.Reader) error { + var err error + pr.MessageID, err = decodeUint16(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pr *PubrecPacket) Details() Details { + return Details{Qos: pr.Qos, MessageID: pr.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrel.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrel.go new file mode 100644 index 00000000000..27d7d32d81c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/pubrel.go @@ -0,0 +1,42 @@ +package packets + +import ( + "fmt" + "io" +) + +//PubrelPacket is an internal representation of the fields of the +//Pubrel MQTT packet +type PubrelPacket struct { + FixedHeader + MessageID uint16 +} + +func (pr *PubrelPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", pr.FixedHeader, pr.MessageID) +} + +func (pr *PubrelPacket) Write(w io.Writer) error { + var err error + pr.FixedHeader.RemainingLength = 2 + packet := pr.FixedHeader.pack() + packet.Write(encodeUint16(pr.MessageID)) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (pr *PubrelPacket) Unpack(b io.Reader) error { + var err error + pr.MessageID, err = decodeUint16(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (pr *PubrelPacket) Details() Details { + return Details{Qos: pr.Qos, MessageID: pr.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/suback.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/suback.go new file mode 100644 index 00000000000..263e19c6580 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/suback.go @@ -0,0 +1,57 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//SubackPacket is an internal representation of the fields of the +//Suback MQTT packet +type SubackPacket struct { + FixedHeader + MessageID uint16 + ReturnCodes []byte +} + +func (sa *SubackPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", sa.FixedHeader, sa.MessageID) +} + +func (sa *SubackPacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + body.Write(encodeUint16(sa.MessageID)) + body.Write(sa.ReturnCodes) + sa.FixedHeader.RemainingLength = body.Len() + packet := sa.FixedHeader.pack() + packet.Write(body.Bytes()) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (sa *SubackPacket) Unpack(b io.Reader) error { + var qosBuffer bytes.Buffer + var err error + sa.MessageID, err = decodeUint16(b) + if err != nil { + return err + } + + _, err = qosBuffer.ReadFrom(b) + if err != nil { + return err + } + sa.ReturnCodes = qosBuffer.Bytes() + + return nil +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (sa *SubackPacket) Details() Details { + return Details{Qos: 0, MessageID: sa.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/subscribe.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/subscribe.go new file mode 100644 index 00000000000..ab0e9734e42 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/subscribe.go @@ -0,0 +1,69 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//SubscribePacket is an internal representation of the fields of the +//Subscribe MQTT packet +type SubscribePacket struct { + FixedHeader + MessageID uint16 + Topics []string + Qoss []byte +} + +func (s *SubscribePacket) String() string { + return fmt.Sprintf("%s MessageID: %d topics: %s", s.FixedHeader, s.MessageID, s.Topics) +} + +func (s *SubscribePacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + + body.Write(encodeUint16(s.MessageID)) + for i, topic := range s.Topics { + body.Write(encodeString(topic)) + body.WriteByte(s.Qoss[i]) + } + s.FixedHeader.RemainingLength = body.Len() + packet := s.FixedHeader.pack() + packet.Write(body.Bytes()) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (s *SubscribePacket) Unpack(b io.Reader) error { + var err error + s.MessageID, err = decodeUint16(b) + if err != nil { + return err + } + payloadLength := s.FixedHeader.RemainingLength - 2 + for payloadLength > 0 { + topic, err := decodeString(b) + if err != nil { + return err + } + s.Topics = append(s.Topics, topic) + qos, err := decodeByte(b) + if err != nil { + return err + } + s.Qoss = append(s.Qoss, qos) + payloadLength -= 2 + len(topic) + 1 //2 bytes of string length, plus string, plus 1 byte for Qos + } + + return nil +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (s *SubscribePacket) Details() Details { + return Details{Qos: 1, MessageID: s.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsuback.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsuback.go new file mode 100644 index 00000000000..c6b2591d1e5 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsuback.go @@ -0,0 +1,42 @@ +package packets + +import ( + "fmt" + "io" +) + +//UnsubackPacket is an internal representation of the fields of the +//Unsuback MQTT packet +type UnsubackPacket struct { + FixedHeader + MessageID uint16 +} + +func (ua *UnsubackPacket) String() string { + return fmt.Sprintf("%s MessageID: %d", ua.FixedHeader, ua.MessageID) +} + +func (ua *UnsubackPacket) Write(w io.Writer) error { + var err error + ua.FixedHeader.RemainingLength = 2 + packet := ua.FixedHeader.pack() + packet.Write(encodeUint16(ua.MessageID)) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (ua *UnsubackPacket) Unpack(b io.Reader) error { + var err error + ua.MessageID, err = decodeUint16(b) + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (ua *UnsubackPacket) Details() Details { + return Details{Qos: 0, MessageID: ua.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsubscribe.go b/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsubscribe.go new file mode 100644 index 00000000000..e7a53bdecaf --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/packets/unsubscribe.go @@ -0,0 +1,56 @@ +package packets + +import ( + "bytes" + "fmt" + "io" +) + +//UnsubscribePacket is an internal representation of the fields of the +//Unsubscribe MQTT packet +type UnsubscribePacket struct { + FixedHeader + MessageID uint16 + Topics []string +} + +func (u *UnsubscribePacket) String() string { + return fmt.Sprintf("%s MessageID: %d", u.FixedHeader, u.MessageID) +} + +func (u *UnsubscribePacket) Write(w io.Writer) error { + var body bytes.Buffer + var err error + body.Write(encodeUint16(u.MessageID)) + for _, topic := range u.Topics { + body.Write(encodeString(topic)) + } + u.FixedHeader.RemainingLength = body.Len() + packet := u.FixedHeader.pack() + packet.Write(body.Bytes()) + _, err = packet.WriteTo(w) + + return err +} + +//Unpack decodes the details of a ControlPacket after the fixed +//header has been read +func (u *UnsubscribePacket) Unpack(b io.Reader) error { + var err error + u.MessageID, err = decodeUint16(b) + if err != nil { + return err + } + + for topic, err := decodeString(b); err == nil && topic != ""; topic, err = decodeString(b) { + u.Topics = append(u.Topics, topic) + } + + return err +} + +//Details returns a Details struct containing the Qos and +//MessageID of this ControlPacket +func (u *UnsubscribePacket) Details() Details { + return Details{Qos: 1, MessageID: u.MessageID} +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/ping.go b/vendor/github.com/eclipse/paho.mqtt.golang/ping.go new file mode 100644 index 00000000000..dbc1ff454b3 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/ping.go @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "errors" + "sync/atomic" + "time" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +func keepalive(c *client) { + defer c.workers.Done() + DEBUG.Println(PNG, "keepalive starting") + var checkInterval int64 + var pingSent time.Time + + if c.options.KeepAlive > 10 { + checkInterval = 5 + } else { + checkInterval = c.options.KeepAlive / 2 + } + + intervalTicker := time.NewTicker(time.Duration(checkInterval * int64(time.Second))) + defer intervalTicker.Stop() + + for { + select { + case <-c.stop: + DEBUG.Println(PNG, "keepalive stopped") + return + case <-intervalTicker.C: + lastSent := c.lastSent.Load().(time.Time) + lastReceived := c.lastReceived.Load().(time.Time) + + DEBUG.Println(PNG, "ping check", time.Since(lastSent).Seconds()) + if time.Since(lastSent) >= time.Duration(c.options.KeepAlive*int64(time.Second)) || time.Since(lastReceived) >= time.Duration(c.options.KeepAlive*int64(time.Second)) { + if atomic.LoadInt32(&c.pingOutstanding) == 0 { + DEBUG.Println(PNG, "keepalive sending ping") + ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket) + //We don't want to wait behind large messages being sent, the Write call + //will block until it it able to send the packet. + atomic.StoreInt32(&c.pingOutstanding, 1) + ping.Write(c.conn) + c.lastSent.Store(time.Now()) + pingSent = time.Now() + } + } + if atomic.LoadInt32(&c.pingOutstanding) > 0 && time.Since(pingSent) >= c.options.PingTimeout { + CRITICAL.Println(PNG, "pingresp not received, disconnecting") + c.errors <- errors.New("pingresp not received, disconnecting") + return + } + } + } +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/router.go b/vendor/github.com/eclipse/paho.mqtt.golang/router.go new file mode 100644 index 00000000000..dd55e0ddc3d --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/router.go @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "container/list" + "strings" + "sync" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +// route is a type which associates MQTT Topic strings with a +// callback to be executed upon the arrival of a message associated +// with a subscription to that topic. +type route struct { + topic string + callback MessageHandler +} + +// match takes a slice of strings which represent the route being tested having been split on '/' +// separators, and a slice of strings representing the topic string in the published message, similarly +// split. +// The function determines if the topic string matches the route according to the MQTT topic rules +// and returns a boolean of the outcome +func match(route []string, topic []string) bool { + if len(route) == 0 { + return len(topic) == 0 + } + + if len(topic) == 0 { + return route[0] == "#" + } + + if route[0] == "#" { + return true + } + + if (route[0] == "+") || (route[0] == topic[0]) { + return match(route[1:], topic[1:]) + } + return false +} + +func routeIncludesTopic(route, topic string) bool { + return match(routeSplit(route), strings.Split(topic, "/")) +} + +// removes $share and sharename when splitting the route to allow +// shared subscription routes to correctly match the topic +func routeSplit(route string) []string { + var result []string + if strings.HasPrefix(route, "$share") { + result = strings.Split(route, "/")[2:] + } else { + result = strings.Split(route, "/") + } + return result +} + +// match takes the topic string of the published message and does a basic compare to the +// string of the current Route, if they match it returns true +func (r *route) match(topic string) bool { + return r.topic == topic || routeIncludesTopic(r.topic, topic) +} + +type router struct { + sync.RWMutex + routes *list.List + defaultHandler MessageHandler + messages chan *packets.PublishPacket + stop chan bool +} + +// newRouter returns a new instance of a Router and channel which can be used to tell the Router +// to stop +func newRouter() (*router, chan bool) { + router := &router{routes: list.New(), messages: make(chan *packets.PublishPacket), stop: make(chan bool)} + stop := router.stop + return router, stop +} + +// addRoute takes a topic string and MessageHandler callback. It looks in the current list of +// routes to see if there is already a matching Route. If there is it replaces the current +// callback with the new one. If not it add a new entry to the list of Routes. +func (r *router) addRoute(topic string, callback MessageHandler) { + r.Lock() + defer r.Unlock() + for e := r.routes.Front(); e != nil; e = e.Next() { + if e.Value.(*route).topic == topic { + r := e.Value.(*route) + r.callback = callback + return + } + } + r.routes.PushBack(&route{topic: topic, callback: callback}) +} + +// deleteRoute takes a route string, looks for a matching Route in the list of Routes. If +// found it removes the Route from the list. +func (r *router) deleteRoute(topic string) { + r.Lock() + defer r.Unlock() + for e := r.routes.Front(); e != nil; e = e.Next() { + if e.Value.(*route).topic == topic { + r.routes.Remove(e) + return + } + } +} + +// setDefaultHandler assigns a default callback that will be called if no matching Route +// is found for an incoming Publish. +func (r *router) setDefaultHandler(handler MessageHandler) { + r.Lock() + defer r.Unlock() + r.defaultHandler = handler +} + +// matchAndDispatch takes a channel of Message pointers as input and starts a go routine that +// takes messages off the channel, matches them against the internal route list and calls the +// associated callback (or the defaultHandler, if one exists and no other route matched). If +// anything is sent down the stop channel the function will end. +func (r *router) matchAndDispatch(messages <-chan *packets.PublishPacket, order bool, client *client) { + go func() { + for { + select { + case message := <-messages: + sent := false + r.RLock() + m := messageFromPublish(message, client.ackFunc(message)) + handlers := []MessageHandler{} + for e := r.routes.Front(); e != nil; e = e.Next() { + if e.Value.(*route).match(message.TopicName) { + if order { + handlers = append(handlers, e.Value.(*route).callback) + } else { + hd := e.Value.(*route).callback + go func() { + hd(client, m) + m.Ack() + }() + } + sent = true + } + } + if !sent && r.defaultHandler != nil { + if order { + handlers = append(handlers, r.defaultHandler) + } else { + go func() { + r.defaultHandler(client, m) + m.Ack() + }() + } + } + r.RUnlock() + for _, handler := range handlers { + func() { + handler(client, m) + m.Ack() + }() + } + case <-r.stop: + return + } + } + }() +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/store.go b/vendor/github.com/eclipse/paho.mqtt.golang/store.go new file mode 100644 index 00000000000..24a76b7df3c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/store.go @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "fmt" + "strconv" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +const ( + inboundPrefix = "i." + outboundPrefix = "o." +) + +// Store is an interface which can be used to provide implementations +// for message persistence. +// Because we may have to store distinct messages with the same +// message ID, we need a unique key for each message. This is +// possible by prepending "i." or "o." to each message id +type Store interface { + Open() + Put(key string, message packets.ControlPacket) + Get(key string) packets.ControlPacket + All() []string + Del(key string) + Close() + Reset() +} + +// A key MUST have the form "X.[messageid]" +// where X is 'i' or 'o' +func mIDFromKey(key string) uint16 { + s := key[2:] + i, err := strconv.Atoi(s) + chkerr(err) + return uint16(i) +} + +// Return true if key prefix is outbound +func isKeyOutbound(key string) bool { + return key[:2] == outboundPrefix +} + +// Return true if key prefix is inbound +func isKeyInbound(key string) bool { + return key[:2] == inboundPrefix +} + +// Return a string of the form "i.[id]" +func inboundKeyFromMID(id uint16) string { + return fmt.Sprintf("%s%d", inboundPrefix, id) +} + +// Return a string of the form "o.[id]" +func outboundKeyFromMID(id uint16) string { + return fmt.Sprintf("%s%d", outboundPrefix, id) +} + +// govern which outgoing messages are persisted +func persistOutbound(s Store, m packets.ControlPacket) { + switch m.Details().Qos { + case 0: + switch m.(type) { + case *packets.PubackPacket, *packets.PubcompPacket: + // Sending puback. delete matching publish + // from ibound + s.Del(inboundKeyFromMID(m.Details().MessageID)) + } + case 1: + switch m.(type) { + case *packets.PublishPacket, *packets.PubrelPacket, *packets.SubscribePacket, *packets.UnsubscribePacket: + // Sending publish. store in obound + // until puback received + s.Put(outboundKeyFromMID(m.Details().MessageID), m) + default: + ERROR.Println(STR, "Asked to persist an invalid message type") + } + case 2: + switch m.(type) { + case *packets.PublishPacket: + // Sending publish. store in obound + // until pubrel received + s.Put(outboundKeyFromMID(m.Details().MessageID), m) + default: + ERROR.Println(STR, "Asked to persist an invalid message type") + } + } +} + +// govern which incoming messages are persisted +func persistInbound(s Store, m packets.ControlPacket) { + switch m.Details().Qos { + case 0: + switch m.(type) { + case *packets.PubackPacket, *packets.SubackPacket, *packets.UnsubackPacket, *packets.PubcompPacket: + // Received a puback. delete matching publish + // from obound + s.Del(outboundKeyFromMID(m.Details().MessageID)) + case *packets.PublishPacket, *packets.PubrecPacket, *packets.PingrespPacket, *packets.ConnackPacket: + default: + ERROR.Println(STR, "Asked to persist an invalid messages type") + } + case 1: + switch m.(type) { + case *packets.PublishPacket, *packets.PubrelPacket: + // Received a publish. store it in ibound + // until puback sent + s.Put(inboundKeyFromMID(m.Details().MessageID), m) + default: + ERROR.Println(STR, "Asked to persist an invalid messages type") + } + case 2: + switch m.(type) { + case *packets.PublishPacket: + // Received a publish. store it in ibound + // until pubrel received + s.Put(inboundKeyFromMID(m.Details().MessageID), m) + default: + ERROR.Println(STR, "Asked to persist an invalid messages type") + } + } +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/token.go b/vendor/github.com/eclipse/paho.mqtt.golang/token.go new file mode 100644 index 00000000000..6085546ff6c --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/token.go @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Allan Stockdill-Mander + */ + +package mqtt + +import ( + "sync" + "time" + + "github.com/eclipse/paho.mqtt.golang/packets" +) + +// PacketAndToken is a struct that contains both a ControlPacket and a +// Token. This struct is passed via channels between the client interface +// code and the underlying code responsible for sending and receiving +// MQTT messages. +type PacketAndToken struct { + p packets.ControlPacket + t tokenCompletor +} + +// Token defines the interface for the tokens used to indicate when +// actions have completed. +type Token interface { + Wait() bool + WaitTimeout(time.Duration) bool + Error() error +} + +type TokenErrorSetter interface { + setError(error) +} + +type tokenCompletor interface { + Token + TokenErrorSetter + flowComplete() +} + +type baseToken struct { + m sync.RWMutex + complete chan struct{} + err error +} + +// Wait will wait indefinitely for the Token to complete, ie the Publish +// to be sent and confirmed receipt from the broker +func (b *baseToken) Wait() bool { + <-b.complete + return true +} + +// WaitTimeout takes a time.Duration to wait for the flow associated with the +// Token to complete, returns true if it returned before the timeout or +// returns false if the timeout occurred. In the case of a timeout the Token +// does not have an error set in case the caller wishes to wait again +func (b *baseToken) WaitTimeout(d time.Duration) bool { + timer := time.NewTimer(d) + select { + case <-b.complete: + if !timer.Stop() { + <-timer.C + } + return true + case <-timer.C: + } + + return false +} + +func (b *baseToken) flowComplete() { + select { + case <-b.complete: + default: + close(b.complete) + } +} + +func (b *baseToken) Error() error { + b.m.RLock() + defer b.m.RUnlock() + return b.err +} + +func (b *baseToken) setError(e error) { + b.m.Lock() + b.err = e + b.flowComplete() + b.m.Unlock() +} + +func newToken(tType byte) tokenCompletor { + switch tType { + case packets.Connect: + return &ConnectToken{baseToken: baseToken{complete: make(chan struct{})}} + case packets.Subscribe: + return &SubscribeToken{baseToken: baseToken{complete: make(chan struct{})}, subResult: make(map[string]byte)} + case packets.Publish: + return &PublishToken{baseToken: baseToken{complete: make(chan struct{})}} + case packets.Unsubscribe: + return &UnsubscribeToken{baseToken: baseToken{complete: make(chan struct{})}} + case packets.Disconnect: + return &DisconnectToken{baseToken: baseToken{complete: make(chan struct{})}} + } + return nil +} + +// ConnectToken is an extension of Token containing the extra fields +// required to provide information about calls to Connect() +type ConnectToken struct { + baseToken + returnCode byte + sessionPresent bool +} + +// ReturnCode returns the acknowledgement code in the connack sent +// in response to a Connect() +func (c *ConnectToken) ReturnCode() byte { + c.m.RLock() + defer c.m.RUnlock() + return c.returnCode +} + +// SessionPresent returns a bool representing the value of the +// session present field in the connack sent in response to a Connect() +func (c *ConnectToken) SessionPresent() bool { + c.m.RLock() + defer c.m.RUnlock() + return c.sessionPresent +} + +// PublishToken is an extension of Token containing the extra fields +// required to provide information about calls to Publish() +type PublishToken struct { + baseToken + messageID uint16 +} + +// MessageID returns the MQTT message ID that was assigned to the +// Publish packet when it was sent to the broker +func (p *PublishToken) MessageID() uint16 { + return p.messageID +} + +// SubscribeToken is an extension of Token containing the extra fields +// required to provide information about calls to Subscribe() +type SubscribeToken struct { + baseToken + subs []string + subResult map[string]byte + messageID uint16 +} + +// Result returns a map of topics that were subscribed to along with +// the matching return code from the broker. This is either the Qos +// value of the subscription or an error code. +func (s *SubscribeToken) Result() map[string]byte { + s.m.RLock() + defer s.m.RUnlock() + return s.subResult +} + +// UnsubscribeToken is an extension of Token containing the extra fields +// required to provide information about calls to Unsubscribe() +type UnsubscribeToken struct { + baseToken + messageID uint16 +} + +// DisconnectToken is an extension of Token containing the extra fields +// required to provide information about calls to Disconnect() +type DisconnectToken struct { + baseToken +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/topic.go b/vendor/github.com/eclipse/paho.mqtt.golang/topic.go new file mode 100644 index 00000000000..01b536d73c5 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/topic.go @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +import ( + "errors" + "strings" +) + +//ErrInvalidQos is the error returned when an packet is to be sent +//with an invalid Qos value +var ErrInvalidQos = errors.New("Invalid QoS") + +//ErrInvalidTopicEmptyString is the error returned when a topic string +//is passed in that is 0 length +var ErrInvalidTopicEmptyString = errors.New("Invalid Topic; empty string") + +//ErrInvalidTopicMultilevel is the error returned when a topic string +//is passed in that has the multi level wildcard in any position but +//the last +var ErrInvalidTopicMultilevel = errors.New("Invalid Topic; multi-level wildcard must be last level") + +// Topic Names and Topic Filters +// The MQTT v3.1.1 spec clarifies a number of ambiguities with regard +// to the validity of Topic strings. +// - A Topic must be between 1 and 65535 bytes. +// - A Topic is case sensitive. +// - A Topic may contain whitespace. +// - A Topic containing a leading forward slash is different than a Topic without. +// - A Topic may be "/" (two levels, both empty string). +// - A Topic must be UTF-8 encoded. +// - A Topic may contain any number of levels. +// - A Topic may contain an empty level (two forward slashes in a row). +// - A TopicName may not contain a wildcard. +// - A TopicFilter may only have a # (multi-level) wildcard as the last level. +// - A TopicFilter may contain any number of + (single-level) wildcards. +// - A TopicFilter with a # will match the absence of a level +// Example: a subscription to "foo/#" will match messages published to "foo". + +func validateSubscribeMap(subs map[string]byte) ([]string, []byte, error) { + if len(subs) == 0 { + return nil, nil, errors.New("Invalid subscription; subscribe map must not be empty") + } + + var topics []string + var qoss []byte + for topic, qos := range subs { + if err := validateTopicAndQos(topic, qos); err != nil { + return nil, nil, err + } + topics = append(topics, topic) + qoss = append(qoss, qos) + } + + return topics, qoss, nil +} + +func validateTopicAndQos(topic string, qos byte) error { + if len(topic) == 0 { + return ErrInvalidTopicEmptyString + } + + levels := strings.Split(topic, "/") + for i, level := range levels { + if level == "#" && i != len(levels)-1 { + return ErrInvalidTopicMultilevel + } + } + + if qos > 2 { + return ErrInvalidQos + } + return nil +} diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/trace.go b/vendor/github.com/eclipse/paho.mqtt.golang/trace.go new file mode 100644 index 00000000000..195c8173dcf --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/trace.go @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Seth Hoenig + * Allan Stockdill-Mander + * Mike Robertson + */ + +package mqtt + +type ( + // Logger interface allows implementations to provide to this package any + // object that implements the methods defined in it. + Logger interface { + Println(v ...interface{}) + Printf(format string, v ...interface{}) + } + + // NOOPLogger implements the logger that does not perform any operation + // by default. This allows us to efficiently discard the unwanted messages. + NOOPLogger struct{} +) + +func (NOOPLogger) Println(v ...interface{}) {} +func (NOOPLogger) Printf(format string, v ...interface{}) {} + +// Internal levels of library output that are initialised to not print +// anything but can be overridden by programmer +var ( + ERROR Logger = NOOPLogger{} + CRITICAL Logger = NOOPLogger{} + WARN Logger = NOOPLogger{} + DEBUG Logger = NOOPLogger{} +) diff --git a/vendor/github.com/eclipse/paho.mqtt.golang/websocket.go b/vendor/github.com/eclipse/paho.mqtt.golang/websocket.go new file mode 100644 index 00000000000..5e8511e2241 --- /dev/null +++ b/vendor/github.com/eclipse/paho.mqtt.golang/websocket.go @@ -0,0 +1,95 @@ +package mqtt + +import ( + "crypto/tls" + "io" + "net" + "net/http" + "sync" + "time" + + "github.com/gorilla/websocket" +) + +// NewWebsocket returns a new websocket and returns a net.Conn compatible interface using the gorilla/websocket package +func NewWebsocket(host string, tlsc *tls.Config, timeout time.Duration, requestHeader http.Header) (net.Conn, error) { + if timeout == 0 { + timeout = 10 * time.Second + } + + dialer := &websocket.Dialer{ + Proxy: http.ProxyFromEnvironment, + HandshakeTimeout: timeout, + EnableCompression: false, + TLSClientConfig: tlsc, + Subprotocols: []string{"mqtt"}, + } + ws, _, err := dialer.Dial(host, requestHeader) + + if err != nil { + return nil, err + } + + wrapper := &websocketConnector{ + Conn: ws, + } + return wrapper, err +} + +// websocketConnector is a websocket wrapper so it satisfies the net.Conn interface so it is a +// drop in replacement of the golang.org/x/net/websocket package. +// Implementation guide taken from https://github.com/gorilla/websocket/issues/282 +type websocketConnector struct { + *websocket.Conn + r io.Reader + rio sync.Mutex + wio sync.Mutex +} + +// SetDeadline sets both the read and write deadlines +func (c *websocketConnector) SetDeadline(t time.Time) error { + if err := c.SetReadDeadline(t); err != nil { + return err + } + err := c.SetWriteDeadline(t) + return err +} + +// Write writes data to the websocket +func (c *websocketConnector) Write(p []byte) (int, error) { + c.wio.Lock() + defer c.wio.Unlock() + + err := c.WriteMessage(websocket.BinaryMessage, p) + if err != nil { + return 0, err + } + return len(p), nil +} + +// Read reads the current websocket frame +func (c *websocketConnector) Read(p []byte) (int, error) { + c.rio.Lock() + defer c.rio.Unlock() + for { + if c.r == nil { + // Advance to next message. + var err error + _, c.r, err = c.NextReader() + if err != nil { + return 0, err + } + } + n, err := c.r.Read(p) + if err == io.EOF { + // At end of message. + c.r = nil + if n > 0 { + return n, nil + } + // No data read, continue to next message. + continue + } + return n, err + } +} diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS new file mode 100644 index 00000000000..1931f400682 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/AUTHORS @@ -0,0 +1,9 @@ +# This is the official list of Gorilla WebSocket authors for copyright +# purposes. +# +# Please keep the list sorted. + +Gary Burd +Google LLC (https://opensource.google.com/) +Joachim Bauch + diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE new file mode 100644 index 00000000000..9171c972252 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md new file mode 100644 index 00000000000..0827d059c11 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/README.md @@ -0,0 +1,64 @@ +# Gorilla WebSocket + +[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) +[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket) + +Gorilla WebSocket is a [Go](http://golang.org/) implementation of the +[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. + +### Documentation + +* [API Reference](http://godoc.org/github.com/gorilla/websocket) +* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) +* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) +* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) +* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) + +### Status + +The Gorilla WebSocket package provides a complete and tested implementation of +the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The +package API is stable. + +### Installation + + go get github.com/gorilla/websocket + +### Protocol Compliance + +The Gorilla WebSocket package passes the server tests in the [Autobahn Test +Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn +subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). + +### Gorilla WebSocket compared with other packages + + + + + + + + + + + + + + + + + + +
      github.com/gorillagolang.org/x/net
      RFC 6455 Features
      Passes Autobahn Test SuiteYesNo
      Receive fragmented messageYesNo, see note 1
      Send close messageYesNo
      Send pings and receive pongsYesNo
      Get the type of a received data messageYesYes, see note 2
      Other Features
      Compression ExtensionsExperimentalNo
      Read message using io.ReaderYesNo, see note 3
      Write message using io.WriteCloserYesNo, see note 3
      + +Notes: + +1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). +2. The application can get the type of a received data message by implementing + a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) + function. +3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. + Read returns when the input buffer is full or a frame boundary is + encountered. Each call to Write sends a single frame message. The Gorilla + io.Reader and io.WriteCloser operate on a single WebSocket message. + diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go new file mode 100644 index 00000000000..962c06a391c --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client.go @@ -0,0 +1,395 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "context" + "crypto/tls" + "errors" + "io" + "io/ioutil" + "net" + "net/http" + "net/http/httptrace" + "net/url" + "strings" + "time" +) + +// ErrBadHandshake is returned when the server response to opening handshake is +// invalid. +var ErrBadHandshake = errors.New("websocket: bad handshake") + +var errInvalidCompression = errors.New("websocket: invalid compression negotiation") + +// NewClient creates a new client connection using the given net connection. +// The URL u specifies the host and request URI. Use requestHeader to specify +// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies +// (Cookie). Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etc. +// +// Deprecated: Use Dialer instead. +func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { + d := Dialer{ + ReadBufferSize: readBufSize, + WriteBufferSize: writeBufSize, + NetDial: func(net, addr string) (net.Conn, error) { + return netConn, nil + }, + } + return d.Dial(u.String(), requestHeader) +} + +// A Dialer contains options for connecting to WebSocket server. +type Dialer struct { + // NetDial specifies the dial function for creating TCP connections. If + // NetDial is nil, net.Dial is used. + NetDial func(network, addr string) (net.Conn, error) + + // NetDialContext specifies the dial function for creating TCP connections. If + // NetDialContext is nil, net.DialContext is used. + NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) + + // Proxy specifies a function to return a proxy for a given + // Request. If the function returns a non-nil error, the + // request is aborted with the provided error. + // If Proxy is nil or returns a nil *URL, no proxy is used. + Proxy func(*http.Request) (*url.URL, error) + + // TLSClientConfig specifies the TLS configuration to use with tls.Client. + // If nil, the default configuration is used. + TLSClientConfig *tls.Config + + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer + // size is zero, then a useful default size is used. The I/O buffer sizes + // do not limit the size of the messages that can be sent or received. + ReadBufferSize, WriteBufferSize int + + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + + // Subprotocols specifies the client's requested subprotocols. + Subprotocols []string + + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool + + // Jar specifies the cookie jar. + // If Jar is nil, cookies are not sent in requests and ignored + // in responses. + Jar http.CookieJar +} + +// Dial creates a new client connection by calling DialContext with a background context. +func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + return d.DialContext(context.Background(), urlStr, requestHeader) +} + +var errMalformedURL = errors.New("malformed ws or wss URL") + +func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { + hostPort = u.Host + hostNoPort = u.Host + if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { + hostNoPort = hostNoPort[:i] + } else { + switch u.Scheme { + case "wss": + hostPort += ":443" + case "https": + hostPort += ":443" + default: + hostPort += ":80" + } + } + return hostPort, hostNoPort +} + +// DefaultDialer is a dialer with all fields set to the default values. +var DefaultDialer = &Dialer{ + Proxy: http.ProxyFromEnvironment, + HandshakeTimeout: 45 * time.Second, +} + +// nilDialer is dialer to use when receiver is nil. +var nilDialer = *DefaultDialer + +// DialContext creates a new client connection. Use requestHeader to specify the +// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). +// Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// The context will be used in the request and in the Dialer. +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etcetera. The response body may not contain the entire response and does not +// need to be closed by the application. +func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + if d == nil { + d = &nilDialer + } + + challengeKey, err := generateChallengeKey() + if err != nil { + return nil, nil, err + } + + u, err := url.Parse(urlStr) + if err != nil { + return nil, nil, err + } + + switch u.Scheme { + case "ws": + u.Scheme = "http" + case "wss": + u.Scheme = "https" + default: + return nil, nil, errMalformedURL + } + + if u.User != nil { + // User name and password are not allowed in websocket URIs. + return nil, nil, errMalformedURL + } + + req := &http.Request{ + Method: "GET", + URL: u, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: u.Host, + } + req = req.WithContext(ctx) + + // Set the cookies present in the cookie jar of the dialer + if d.Jar != nil { + for _, cookie := range d.Jar.Cookies(u) { + req.AddCookie(cookie) + } + } + + // Set the request headers using the capitalization for names and values in + // RFC examples. Although the capitalization shouldn't matter, there are + // servers that depend on it. The Header.Set method is not used because the + // method canonicalizes the header names. + req.Header["Upgrade"] = []string{"websocket"} + req.Header["Connection"] = []string{"Upgrade"} + req.Header["Sec-WebSocket-Key"] = []string{challengeKey} + req.Header["Sec-WebSocket-Version"] = []string{"13"} + if len(d.Subprotocols) > 0 { + req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} + } + for k, vs := range requestHeader { + switch { + case k == "Host": + if len(vs) > 0 { + req.Host = vs[0] + } + case k == "Upgrade" || + k == "Connection" || + k == "Sec-Websocket-Key" || + k == "Sec-Websocket-Version" || + k == "Sec-Websocket-Extensions" || + (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): + return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) + case k == "Sec-Websocket-Protocol": + req.Header["Sec-WebSocket-Protocol"] = vs + default: + req.Header[k] = vs + } + } + + if d.EnableCompression { + req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"} + } + + if d.HandshakeTimeout != 0 { + var cancel func() + ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout) + defer cancel() + } + + // Get network dial function. + var netDial func(network, add string) (net.Conn, error) + + if d.NetDialContext != nil { + netDial = func(network, addr string) (net.Conn, error) { + return d.NetDialContext(ctx, network, addr) + } + } else if d.NetDial != nil { + netDial = d.NetDial + } else { + netDialer := &net.Dialer{} + netDial = func(network, addr string) (net.Conn, error) { + return netDialer.DialContext(ctx, network, addr) + } + } + + // If needed, wrap the dial function to set the connection deadline. + if deadline, ok := ctx.Deadline(); ok { + forwardDial := netDial + netDial = func(network, addr string) (net.Conn, error) { + c, err := forwardDial(network, addr) + if err != nil { + return nil, err + } + err = c.SetDeadline(deadline) + if err != nil { + c.Close() + return nil, err + } + return c, nil + } + } + + // If needed, wrap the dial function to connect through a proxy. + if d.Proxy != nil { + proxyURL, err := d.Proxy(req) + if err != nil { + return nil, nil, err + } + if proxyURL != nil { + dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) + if err != nil { + return nil, nil, err + } + netDial = dialer.Dial + } + } + + hostPort, hostNoPort := hostPortNoPort(u) + trace := httptrace.ContextClientTrace(ctx) + if trace != nil && trace.GetConn != nil { + trace.GetConn(hostPort) + } + + netConn, err := netDial("tcp", hostPort) + if trace != nil && trace.GotConn != nil { + trace.GotConn(httptrace.GotConnInfo{ + Conn: netConn, + }) + } + if err != nil { + return nil, nil, err + } + + defer func() { + if netConn != nil { + netConn.Close() + } + }() + + if u.Scheme == "https" { + cfg := cloneTLSConfig(d.TLSClientConfig) + if cfg.ServerName == "" { + cfg.ServerName = hostNoPort + } + tlsConn := tls.Client(netConn, cfg) + netConn = tlsConn + + var err error + if trace != nil { + err = doHandshakeWithTrace(trace, tlsConn, cfg) + } else { + err = doHandshake(tlsConn, cfg) + } + + if err != nil { + return nil, nil, err + } + } + + conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil) + + if err := req.Write(netConn); err != nil { + return nil, nil, err + } + + if trace != nil && trace.GotFirstResponseByte != nil { + if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 { + trace.GotFirstResponseByte() + } + } + + resp, err := http.ReadResponse(conn.br, req) + if err != nil { + return nil, nil, err + } + + if d.Jar != nil { + if rc := resp.Cookies(); len(rc) > 0 { + d.Jar.SetCookies(u, rc) + } + } + + if resp.StatusCode != 101 || + !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || + !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || + resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { + // Before closing the network connection on return from this + // function, slurp up some of the response to aid application + // debugging. + buf := make([]byte, 1024) + n, _ := io.ReadFull(resp.Body, buf) + resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) + return nil, resp, ErrBadHandshake + } + + for _, ext := range parseExtensions(resp.Header) { + if ext[""] != "permessage-deflate" { + continue + } + _, snct := ext["server_no_context_takeover"] + _, cnct := ext["client_no_context_takeover"] + if !snct || !cnct { + return nil, resp, errInvalidCompression + } + conn.newCompressionWriter = compressNoContextTakeover + conn.newDecompressionReader = decompressNoContextTakeover + break + } + + resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) + conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") + + netConn.SetDeadline(time.Time{}) + netConn = nil // to avoid close in defer. + return conn, resp, nil +} + +func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error { + if err := tlsConn.Handshake(); err != nil { + return err + } + if !cfg.InsecureSkipVerify { + if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go new file mode 100644 index 00000000000..4f0d943723a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone.go @@ -0,0 +1,16 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package websocket + +import "crypto/tls" + +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return cfg.Clone() +} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go new file mode 100644 index 00000000000..babb007fb41 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone_legacy.go @@ -0,0 +1,38 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package websocket + +import "crypto/tls" + +// cloneTLSConfig clones all public fields except the fields +// SessionTicketsDisabled and SessionTicketKey. This avoids copying the +// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a +// config in active use. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go new file mode 100644 index 00000000000..813ffb1e843 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -0,0 +1,148 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "compress/flate" + "errors" + "io" + "strings" + "sync" +) + +const ( + minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 + maxCompressionLevel = flate.BestCompression + defaultCompressionLevel = 1 +) + +var ( + flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool + flateReaderPool = sync.Pool{New: func() interface{} { + return flate.NewReader(nil) + }} +) + +func decompressNoContextTakeover(r io.Reader) io.ReadCloser { + const tail = + // Add four bytes as specified in RFC + "\x00\x00\xff\xff" + + // Add final block to squelch unexpected EOF error from flate reader. + "\x01\x00\x00\xff\xff" + + fr, _ := flateReaderPool.Get().(io.ReadCloser) + fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) + return &flateReadWrapper{fr} +} + +func isValidCompressionLevel(level int) bool { + return minCompressionLevel <= level && level <= maxCompressionLevel +} + +func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { + p := &flateWriterPools[level-minCompressionLevel] + tw := &truncWriter{w: w} + fw, _ := p.Get().(*flate.Writer) + if fw == nil { + fw, _ = flate.NewWriter(tw, level) + } else { + fw.Reset(tw) + } + return &flateWriteWrapper{fw: fw, tw: tw, p: p} +} + +// truncWriter is an io.Writer that writes all but the last four bytes of the +// stream to another io.Writer. +type truncWriter struct { + w io.WriteCloser + n int + p [4]byte +} + +func (w *truncWriter) Write(p []byte) (int, error) { + n := 0 + + // fill buffer first for simplicity. + if w.n < len(w.p) { + n = copy(w.p[w.n:], p) + p = p[n:] + w.n += n + if len(p) == 0 { + return n, nil + } + } + + m := len(p) + if m > len(w.p) { + m = len(w.p) + } + + if nn, err := w.w.Write(w.p[:m]); err != nil { + return n + nn, err + } + + copy(w.p[:], w.p[m:]) + copy(w.p[len(w.p)-m:], p[len(p)-m:]) + nn, err := w.w.Write(p[:len(p)-m]) + return n + nn, err +} + +type flateWriteWrapper struct { + fw *flate.Writer + tw *truncWriter + p *sync.Pool +} + +func (w *flateWriteWrapper) Write(p []byte) (int, error) { + if w.fw == nil { + return 0, errWriteClosed + } + return w.fw.Write(p) +} + +func (w *flateWriteWrapper) Close() error { + if w.fw == nil { + return errWriteClosed + } + err1 := w.fw.Flush() + w.p.Put(w.fw) + w.fw = nil + if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { + return errors.New("websocket: internal error, unexpected bytes at end of flate stream") + } + err2 := w.tw.w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +type flateReadWrapper struct { + fr io.ReadCloser +} + +func (r *flateReadWrapper) Read(p []byte) (int, error) { + if r.fr == nil { + return 0, io.ErrClosedPipe + } + n, err := r.fr.Read(p) + if err == io.EOF { + // Preemptively place the reader back in the pool. This helps with + // scenarios where the application does not call NextReader() soon after + // this final read. + r.Close() + } + return n, err +} + +func (r *flateReadWrapper) Close() error { + if r.fr == nil { + return io.ErrClosedPipe + } + err := r.fr.Close() + flateReaderPool.Put(r.fr) + r.fr = nil + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go new file mode 100644 index 00000000000..6f17cd29982 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -0,0 +1,1201 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "encoding/binary" + "errors" + "io" + "io/ioutil" + "math/rand" + "net" + "strconv" + "sync" + "time" + "unicode/utf8" +) + +const ( + // Frame header byte 0 bits from Section 5.2 of RFC 6455 + finalBit = 1 << 7 + rsv1Bit = 1 << 6 + rsv2Bit = 1 << 5 + rsv3Bit = 1 << 4 + + // Frame header byte 1 bits from Section 5.2 of RFC 6455 + maskBit = 1 << 7 + + maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask + maxControlFramePayloadSize = 125 + + writeWait = time.Second + + defaultReadBufferSize = 4096 + defaultWriteBufferSize = 4096 + + continuationFrame = 0 + noFrame = -1 +) + +// Close codes defined in RFC 6455, section 11.7. +const ( + CloseNormalClosure = 1000 + CloseGoingAway = 1001 + CloseProtocolError = 1002 + CloseUnsupportedData = 1003 + CloseNoStatusReceived = 1005 + CloseAbnormalClosure = 1006 + CloseInvalidFramePayloadData = 1007 + ClosePolicyViolation = 1008 + CloseMessageTooBig = 1009 + CloseMandatoryExtension = 1010 + CloseInternalServerErr = 1011 + CloseServiceRestart = 1012 + CloseTryAgainLater = 1013 + CloseTLSHandshake = 1015 +) + +// The message types are defined in RFC 6455, section 11.8. +const ( + // TextMessage denotes a text data message. The text message payload is + // interpreted as UTF-8 encoded text data. + TextMessage = 1 + + // BinaryMessage denotes a binary data message. + BinaryMessage = 2 + + // CloseMessage denotes a close control message. The optional message + // payload contains a numeric code and text. Use the FormatCloseMessage + // function to format a close message payload. + CloseMessage = 8 + + // PingMessage denotes a ping control message. The optional message payload + // is UTF-8 encoded text. + PingMessage = 9 + + // PongMessage denotes a pong control message. The optional message payload + // is UTF-8 encoded text. + PongMessage = 10 +) + +// ErrCloseSent is returned when the application writes a message to the +// connection after sending a close message. +var ErrCloseSent = errors.New("websocket: close sent") + +// ErrReadLimit is returned when reading a message that is larger than the +// read limit set for the connection. +var ErrReadLimit = errors.New("websocket: read limit exceeded") + +// netError satisfies the net Error interface. +type netError struct { + msg string + temporary bool + timeout bool +} + +func (e *netError) Error() string { return e.msg } +func (e *netError) Temporary() bool { return e.temporary } +func (e *netError) Timeout() bool { return e.timeout } + +// CloseError represents a close message. +type CloseError struct { + // Code is defined in RFC 6455, section 11.7. + Code int + + // Text is the optional text payload. + Text string +} + +func (e *CloseError) Error() string { + s := []byte("websocket: close ") + s = strconv.AppendInt(s, int64(e.Code), 10) + switch e.Code { + case CloseNormalClosure: + s = append(s, " (normal)"...) + case CloseGoingAway: + s = append(s, " (going away)"...) + case CloseProtocolError: + s = append(s, " (protocol error)"...) + case CloseUnsupportedData: + s = append(s, " (unsupported data)"...) + case CloseNoStatusReceived: + s = append(s, " (no status)"...) + case CloseAbnormalClosure: + s = append(s, " (abnormal closure)"...) + case CloseInvalidFramePayloadData: + s = append(s, " (invalid payload data)"...) + case ClosePolicyViolation: + s = append(s, " (policy violation)"...) + case CloseMessageTooBig: + s = append(s, " (message too big)"...) + case CloseMandatoryExtension: + s = append(s, " (mandatory extension missing)"...) + case CloseInternalServerErr: + s = append(s, " (internal server error)"...) + case CloseTLSHandshake: + s = append(s, " (TLS handshake error)"...) + } + if e.Text != "" { + s = append(s, ": "...) + s = append(s, e.Text...) + } + return string(s) +} + +// IsCloseError returns boolean indicating whether the error is a *CloseError +// with one of the specified codes. +func IsCloseError(err error, codes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range codes { + if e.Code == code { + return true + } + } + } + return false +} + +// IsUnexpectedCloseError returns boolean indicating whether the error is a +// *CloseError with a code not in the list of expected codes. +func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range expectedCodes { + if e.Code == code { + return false + } + } + return true + } + return false +} + +var ( + errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} + errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} + errBadWriteOpCode = errors.New("websocket: bad write message type") + errWriteClosed = errors.New("websocket: write closed") + errInvalidControlFrame = errors.New("websocket: invalid control frame") +) + +func newMaskKey() [4]byte { + n := rand.Uint32() + return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +} + +func hideTempErr(err error) error { + if e, ok := err.(net.Error); ok && e.Temporary() { + err = &netError{msg: e.Error(), timeout: e.Timeout()} + } + return err +} + +func isControl(frameType int) bool { + return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage +} + +func isData(frameType int) bool { + return frameType == TextMessage || frameType == BinaryMessage +} + +var validReceivedCloseCodes = map[int]bool{ + // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number + + CloseNormalClosure: true, + CloseGoingAway: true, + CloseProtocolError: true, + CloseUnsupportedData: true, + CloseNoStatusReceived: false, + CloseAbnormalClosure: false, + CloseInvalidFramePayloadData: true, + ClosePolicyViolation: true, + CloseMessageTooBig: true, + CloseMandatoryExtension: true, + CloseInternalServerErr: true, + CloseServiceRestart: true, + CloseTryAgainLater: true, + CloseTLSHandshake: false, +} + +func isValidReceivedCloseCode(code int) bool { + return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) +} + +// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this +// interface. The type of the value stored in a pool is not specified. +type BufferPool interface { + // Get gets a value from the pool or returns nil if the pool is empty. + Get() interface{} + // Put adds a value to the pool. + Put(interface{}) +} + +// writePoolData is the type added to the write buffer pool. This wrapper is +// used to prevent applications from peeking at and depending on the values +// added to the pool. +type writePoolData struct{ buf []byte } + +// The Conn type represents a WebSocket connection. +type Conn struct { + conn net.Conn + isServer bool + subprotocol string + + // Write fields + mu chan bool // used as mutex to protect write to conn + writeBuf []byte // frame is constructed in this buffer. + writePool BufferPool + writeBufSize int + writeDeadline time.Time + writer io.WriteCloser // the current writer returned to the application + isWriting bool // for best-effort concurrent write detection + + writeErrMu sync.Mutex + writeErr error + + enableWriteCompression bool + compressionLevel int + newCompressionWriter func(io.WriteCloser, int) io.WriteCloser + + // Read fields + reader io.ReadCloser // the current reader returned to the application + readErr error + br *bufio.Reader + // bytes remaining in current frame. + // set setReadRemaining to safely update this value and prevent overflow + readRemaining int64 + readFinal bool // true the current message has more frames. + readLength int64 // Message size. + readLimit int64 // Maximum message size. + readMaskPos int + readMaskKey [4]byte + handlePong func(string) error + handlePing func(string) error + handleClose func(int, string) error + readErrCount int + messageReader *messageReader // the current low-level reader + + readDecompress bool // whether last read frame had RSV1 set + newDecompressionReader func(io.Reader) io.ReadCloser +} + +func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn { + + if br == nil { + if readBufferSize == 0 { + readBufferSize = defaultReadBufferSize + } else if readBufferSize < maxControlFramePayloadSize { + // must be large enough for control frame + readBufferSize = maxControlFramePayloadSize + } + br = bufio.NewReaderSize(conn, readBufferSize) + } + + if writeBufferSize <= 0 { + writeBufferSize = defaultWriteBufferSize + } + writeBufferSize += maxFrameHeaderSize + + if writeBuf == nil && writeBufferPool == nil { + writeBuf = make([]byte, writeBufferSize) + } + + mu := make(chan bool, 1) + mu <- true + c := &Conn{ + isServer: isServer, + br: br, + conn: conn, + mu: mu, + readFinal: true, + writeBuf: writeBuf, + writePool: writeBufferPool, + writeBufSize: writeBufferSize, + enableWriteCompression: true, + compressionLevel: defaultCompressionLevel, + } + c.SetCloseHandler(nil) + c.SetPingHandler(nil) + c.SetPongHandler(nil) + return c +} + +// setReadRemaining tracks the number of bytes remaining on the connection. If n +// overflows, an ErrReadLimit is returned. +func (c *Conn) setReadRemaining(n int64) error { + if n < 0 { + return ErrReadLimit + } + + c.readRemaining = n + return nil +} + +// Subprotocol returns the negotiated protocol for the connection. +func (c *Conn) Subprotocol() string { + return c.subprotocol +} + +// Close closes the underlying network connection without sending or waiting +// for a close message. +func (c *Conn) Close() error { + return c.conn.Close() +} + +// LocalAddr returns the local network address. +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +// RemoteAddr returns the remote network address. +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +// Write methods + +func (c *Conn) writeFatal(err error) error { + err = hideTempErr(err) + c.writeErrMu.Lock() + if c.writeErr == nil { + c.writeErr = err + } + c.writeErrMu.Unlock() + return err +} + +func (c *Conn) read(n int) ([]byte, error) { + p, err := c.br.Peek(n) + if err == io.EOF { + err = errUnexpectedEOF + } + c.br.Discard(len(p)) + return p, err +} + +func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error { + <-c.mu + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + if len(buf1) == 0 { + _, err = c.conn.Write(buf0) + } else { + err = c.writeBufs(buf0, buf1) + } + if err != nil { + return c.writeFatal(err) + } + if frameType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return nil +} + +// WriteControl writes a control message with the given deadline. The allowed +// message types are CloseMessage, PingMessage and PongMessage. +func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { + if !isControl(messageType) { + return errBadWriteOpCode + } + if len(data) > maxControlFramePayloadSize { + return errInvalidControlFrame + } + + b0 := byte(messageType) | finalBit + b1 := byte(len(data)) + if !c.isServer { + b1 |= maskBit + } + + buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize) + buf = append(buf, b0, b1) + + if c.isServer { + buf = append(buf, data...) + } else { + key := newMaskKey() + buf = append(buf, key[:]...) + buf = append(buf, data...) + maskBytes(key, 0, buf[6:]) + } + + d := time.Hour * 1000 + if !deadline.IsZero() { + d = deadline.Sub(time.Now()) + if d < 0 { + return errWriteTimeout + } + } + + timer := time.NewTimer(d) + select { + case <-c.mu: + timer.Stop() + case <-timer.C: + return errWriteTimeout + } + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + _, err = c.conn.Write(buf) + if err != nil { + return c.writeFatal(err) + } + if messageType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return err +} + +// beginMessage prepares a connection and message writer for a new message. +func (c *Conn) beginMessage(mw *messageWriter, messageType int) error { + // Close previous writer if not already closed by the application. It's + // probably better to return an error in this situation, but we cannot + // change this without breaking existing applications. + if c.writer != nil { + c.writer.Close() + c.writer = nil + } + + if !isControl(messageType) && !isData(messageType) { + return errBadWriteOpCode + } + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + mw.c = c + mw.frameType = messageType + mw.pos = maxFrameHeaderSize + + if c.writeBuf == nil { + wpd, ok := c.writePool.Get().(writePoolData) + if ok { + c.writeBuf = wpd.buf + } else { + c.writeBuf = make([]byte, c.writeBufSize) + } + } + return nil +} + +// NextWriter returns a writer for the next message to send. The writer's Close +// method flushes the complete message to the network. +// +// There can be at most one open writer on a connection. NextWriter closes the +// previous writer if the application has not already done so. +// +// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and +// PongMessage) are supported. +func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { + var mw messageWriter + if err := c.beginMessage(&mw, messageType); err != nil { + return nil, err + } + c.writer = &mw + if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { + w := c.newCompressionWriter(c.writer, c.compressionLevel) + mw.compress = true + c.writer = w + } + return c.writer, nil +} + +type messageWriter struct { + c *Conn + compress bool // whether next call to flushFrame should set RSV1 + pos int // end of data in writeBuf. + frameType int // type of the current frame. + err error +} + +func (w *messageWriter) endMessage(err error) error { + if w.err != nil { + return err + } + c := w.c + w.err = err + c.writer = nil + if c.writePool != nil { + c.writePool.Put(writePoolData{buf: c.writeBuf}) + c.writeBuf = nil + } + return err +} + +// flushFrame writes buffered data and extra as a frame to the network. The +// final argument indicates that this is the last frame in the message. +func (w *messageWriter) flushFrame(final bool, extra []byte) error { + c := w.c + length := w.pos - maxFrameHeaderSize + len(extra) + + // Check for invalid control frames. + if isControl(w.frameType) && + (!final || length > maxControlFramePayloadSize) { + return w.endMessage(errInvalidControlFrame) + } + + b0 := byte(w.frameType) + if final { + b0 |= finalBit + } + if w.compress { + b0 |= rsv1Bit + } + w.compress = false + + b1 := byte(0) + if !c.isServer { + b1 |= maskBit + } + + // Assume that the frame starts at beginning of c.writeBuf. + framePos := 0 + if c.isServer { + // Adjust up if mask not included in the header. + framePos = 4 + } + + switch { + case length >= 65536: + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 127 + binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length)) + case length > 125: + framePos += 6 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 126 + binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length)) + default: + framePos += 8 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | byte(length) + } + + if !c.isServer { + key := newMaskKey() + copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) + maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) + if len(extra) > 0 { + return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))) + } + } + + // Write the buffers to the connection with best-effort detection of + // concurrent writes. See the concurrency section in the package + // documentation for more info. + + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + + err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) + + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + + if err != nil { + return w.endMessage(err) + } + + if final { + w.endMessage(errWriteClosed) + return nil + } + + // Setup for next frame. + w.pos = maxFrameHeaderSize + w.frameType = continuationFrame + return nil +} + +func (w *messageWriter) ncopy(max int) (int, error) { + n := len(w.c.writeBuf) - w.pos + if n <= 0 { + if err := w.flushFrame(false, nil); err != nil { + return 0, err + } + n = len(w.c.writeBuf) - w.pos + } + if n > max { + n = max + } + return n, nil +} + +func (w *messageWriter) Write(p []byte) (int, error) { + if w.err != nil { + return 0, w.err + } + + if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { + // Don't buffer large messages. + err := w.flushFrame(false, p) + if err != nil { + return 0, err + } + return len(p), nil + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) WriteString(p string) (int, error) { + if w.err != nil { + return 0, w.err + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { + if w.err != nil { + return 0, w.err + } + for { + if w.pos == len(w.c.writeBuf) { + err = w.flushFrame(false, nil) + if err != nil { + break + } + } + var n int + n, err = r.Read(w.c.writeBuf[w.pos:]) + w.pos += n + nn += int64(n) + if err != nil { + if err == io.EOF { + err = nil + } + break + } + } + return nn, err +} + +func (w *messageWriter) Close() error { + if w.err != nil { + return w.err + } + return w.flushFrame(true, nil) +} + +// WritePreparedMessage writes prepared message into connection. +func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { + frameType, frameData, err := pm.frame(prepareKey{ + isServer: c.isServer, + compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), + compressionLevel: c.compressionLevel, + }) + if err != nil { + return err + } + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + err = c.write(frameType, c.writeDeadline, frameData, nil) + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + return err +} + +// WriteMessage is a helper method for getting a writer using NextWriter, +// writing the message and closing the writer. +func (c *Conn) WriteMessage(messageType int, data []byte) error { + + if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { + // Fast path with no allocations and single frame. + + var mw messageWriter + if err := c.beginMessage(&mw, messageType); err != nil { + return err + } + n := copy(c.writeBuf[mw.pos:], data) + mw.pos += n + data = data[n:] + return mw.flushFrame(true, data) + } + + w, err := c.NextWriter(messageType) + if err != nil { + return err + } + if _, err = w.Write(data); err != nil { + return err + } + return w.Close() +} + +// SetWriteDeadline sets the write deadline on the underlying network +// connection. After a write has timed out, the websocket state is corrupt and +// all future writes will return an error. A zero value for t means writes will +// not time out. +func (c *Conn) SetWriteDeadline(t time.Time) error { + c.writeDeadline = t + return nil +} + +// Read methods + +func (c *Conn) advanceFrame() (int, error) { + // 1. Skip remainder of previous frame. + + if c.readRemaining > 0 { + if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { + return noFrame, err + } + } + + // 2. Read and parse first two bytes of frame header. + + p, err := c.read(2) + if err != nil { + return noFrame, err + } + + final := p[0]&finalBit != 0 + frameType := int(p[0] & 0xf) + mask := p[1]&maskBit != 0 + c.setReadRemaining(int64(p[1] & 0x7f)) + + c.readDecompress = false + if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { + c.readDecompress = true + p[0] &^= rsv1Bit + } + + if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { + return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) + } + + switch frameType { + case CloseMessage, PingMessage, PongMessage: + if c.readRemaining > maxControlFramePayloadSize { + return noFrame, c.handleProtocolError("control frame length > 125") + } + if !final { + return noFrame, c.handleProtocolError("control frame not final") + } + case TextMessage, BinaryMessage: + if !c.readFinal { + return noFrame, c.handleProtocolError("message start before final message frame") + } + c.readFinal = final + case continuationFrame: + if c.readFinal { + return noFrame, c.handleProtocolError("continuation after final message frame") + } + c.readFinal = final + default: + return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) + } + + // 3. Read and parse frame length as per + // https://tools.ietf.org/html/rfc6455#section-5.2 + // + // The length of the "Payload data", in bytes: if 0-125, that is the payload + // length. + // - If 126, the following 2 bytes interpreted as a 16-bit unsigned + // integer are the payload length. + // - If 127, the following 8 bytes interpreted as + // a 64-bit unsigned integer (the most significant bit MUST be 0) are the + // payload length. Multibyte length quantities are expressed in network byte + // order. + + switch c.readRemaining { + case 126: + p, err := c.read(2) + if err != nil { + return noFrame, err + } + + if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil { + return noFrame, err + } + case 127: + p, err := c.read(8) + if err != nil { + return noFrame, err + } + + if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil { + return noFrame, err + } + } + + // 4. Handle frame masking. + + if mask != c.isServer { + return noFrame, c.handleProtocolError("incorrect mask flag") + } + + if mask { + c.readMaskPos = 0 + p, err := c.read(len(c.readMaskKey)) + if err != nil { + return noFrame, err + } + copy(c.readMaskKey[:], p) + } + + // 5. For text and binary messages, enforce read limit and return. + + if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage { + + c.readLength += c.readRemaining + // Don't allow readLength to overflow in the presence of a large readRemaining + // counter. + if c.readLength < 0 { + return noFrame, ErrReadLimit + } + + if c.readLimit > 0 && c.readLength > c.readLimit { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) + return noFrame, ErrReadLimit + } + + return frameType, nil + } + + // 6. Read control frame payload. + + var payload []byte + if c.readRemaining > 0 { + payload, err = c.read(int(c.readRemaining)) + c.setReadRemaining(0) + if err != nil { + return noFrame, err + } + if c.isServer { + maskBytes(c.readMaskKey, 0, payload) + } + } + + // 7. Process control frame payload. + + switch frameType { + case PongMessage: + if err := c.handlePong(string(payload)); err != nil { + return noFrame, err + } + case PingMessage: + if err := c.handlePing(string(payload)); err != nil { + return noFrame, err + } + case CloseMessage: + closeCode := CloseNoStatusReceived + closeText := "" + if len(payload) >= 2 { + closeCode = int(binary.BigEndian.Uint16(payload)) + if !isValidReceivedCloseCode(closeCode) { + return noFrame, c.handleProtocolError("invalid close code") + } + closeText = string(payload[2:]) + if !utf8.ValidString(closeText) { + return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") + } + } + if err := c.handleClose(closeCode, closeText); err != nil { + return noFrame, err + } + return noFrame, &CloseError{Code: closeCode, Text: closeText} + } + + return frameType, nil +} + +func (c *Conn) handleProtocolError(message string) error { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) + return errors.New("websocket: " + message) +} + +// NextReader returns the next data message received from the peer. The +// returned messageType is either TextMessage or BinaryMessage. +// +// There can be at most one open reader on a connection. NextReader discards +// the previous message if the application has not already consumed it. +// +// Applications must break out of the application's read loop when this method +// returns a non-nil error value. Errors returned from this method are +// permanent. Once this method returns a non-nil error, all subsequent calls to +// this method return the same error. +func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { + // Close previous reader, only relevant for decompression. + if c.reader != nil { + c.reader.Close() + c.reader = nil + } + + c.messageReader = nil + c.readLength = 0 + + for c.readErr == nil { + frameType, err := c.advanceFrame() + if err != nil { + c.readErr = hideTempErr(err) + break + } + + if frameType == TextMessage || frameType == BinaryMessage { + c.messageReader = &messageReader{c} + c.reader = c.messageReader + if c.readDecompress { + c.reader = c.newDecompressionReader(c.reader) + } + return frameType, c.reader, nil + } + } + + // Applications that do handle the error returned from this method spin in + // tight loop on connection failure. To help application developers detect + // this error, panic on repeated reads to the failed connection. + c.readErrCount++ + if c.readErrCount >= 1000 { + panic("repeated read on failed websocket connection") + } + + return noFrame, nil, c.readErr +} + +type messageReader struct{ c *Conn } + +func (r *messageReader) Read(b []byte) (int, error) { + c := r.c + if c.messageReader != r { + return 0, io.EOF + } + + for c.readErr == nil { + + if c.readRemaining > 0 { + if int64(len(b)) > c.readRemaining { + b = b[:c.readRemaining] + } + n, err := c.br.Read(b) + c.readErr = hideTempErr(err) + if c.isServer { + c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) + } + rem := c.readRemaining + rem -= int64(n) + c.setReadRemaining(rem) + if c.readRemaining > 0 && c.readErr == io.EOF { + c.readErr = errUnexpectedEOF + } + return n, c.readErr + } + + if c.readFinal { + c.messageReader = nil + return 0, io.EOF + } + + frameType, err := c.advanceFrame() + switch { + case err != nil: + c.readErr = hideTempErr(err) + case frameType == TextMessage || frameType == BinaryMessage: + c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") + } + } + + err := c.readErr + if err == io.EOF && c.messageReader == r { + err = errUnexpectedEOF + } + return 0, err +} + +func (r *messageReader) Close() error { + return nil +} + +// ReadMessage is a helper method for getting a reader using NextReader and +// reading from that reader to a buffer. +func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { + var r io.Reader + messageType, r, err = c.NextReader() + if err != nil { + return messageType, nil, err + } + p, err = ioutil.ReadAll(r) + return messageType, p, err +} + +// SetReadDeadline sets the read deadline on the underlying network connection. +// After a read has timed out, the websocket connection state is corrupt and +// all future reads will return an error. A zero value for t means reads will +// not time out. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a +// message exceeds the limit, the connection sends a close message to the peer +// and returns ErrReadLimit to the application. +func (c *Conn) SetReadLimit(limit int64) { + c.readLimit = limit +} + +// CloseHandler returns the current close handler +func (c *Conn) CloseHandler() func(code int, text string) error { + return c.handleClose +} + +// SetCloseHandler sets the handler for close messages received from the peer. +// The code argument to h is the received close code or CloseNoStatusReceived +// if the close message is empty. The default close handler sends a close +// message back to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// close messages as described in the section on Control Messages above. +// +// The connection read methods return a CloseError when a close message is +// received. Most applications should handle close messages as part of their +// normal error handling. Applications should only set a close handler when the +// application must perform some action before sending a close message back to +// the peer. +func (c *Conn) SetCloseHandler(h func(code int, text string) error) { + if h == nil { + h = func(code int, text string) error { + message := FormatCloseMessage(code, "") + c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) + return nil + } + } + c.handleClose = h +} + +// PingHandler returns the current ping handler +func (c *Conn) PingHandler() func(appData string) error { + return c.handlePing +} + +// SetPingHandler sets the handler for ping messages received from the peer. +// The appData argument to h is the PING message application data. The default +// ping handler sends a pong to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// ping messages as described in the section on Control Messages above. +func (c *Conn) SetPingHandler(h func(appData string) error) { + if h == nil { + h = func(message string) error { + err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) + if err == ErrCloseSent { + return nil + } else if e, ok := err.(net.Error); ok && e.Temporary() { + return nil + } + return err + } + } + c.handlePing = h +} + +// PongHandler returns the current pong handler +func (c *Conn) PongHandler() func(appData string) error { + return c.handlePong +} + +// SetPongHandler sets the handler for pong messages received from the peer. +// The appData argument to h is the PONG message application data. The default +// pong handler does nothing. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// pong messages as described in the section on Control Messages above. +func (c *Conn) SetPongHandler(h func(appData string) error) { + if h == nil { + h = func(string) error { return nil } + } + c.handlePong = h +} + +// UnderlyingConn returns the internal net.Conn. This can be used to further +// modifications to connection specific flags. +func (c *Conn) UnderlyingConn() net.Conn { + return c.conn +} + +// EnableWriteCompression enables and disables write compression of +// subsequent text and binary messages. This function is a noop if +// compression was not negotiated with the peer. +func (c *Conn) EnableWriteCompression(enable bool) { + c.enableWriteCompression = enable +} + +// SetCompressionLevel sets the flate compression level for subsequent text and +// binary messages. This function is a noop if compression was not negotiated +// with the peer. See the compress/flate package for a description of +// compression levels. +func (c *Conn) SetCompressionLevel(level int) error { + if !isValidCompressionLevel(level) { + return errors.New("websocket: invalid compression level") + } + c.compressionLevel = level + return nil +} + +// FormatCloseMessage formats closeCode and text as a WebSocket close message. +// An empty message is returned for code CloseNoStatusReceived. +func FormatCloseMessage(closeCode int, text string) []byte { + if closeCode == CloseNoStatusReceived { + // Return empty message because it's illegal to send + // CloseNoStatusReceived. Return non-nil value in case application + // checks for nil. + return []byte{} + } + buf := make([]byte, 2+len(text)) + binary.BigEndian.PutUint16(buf, uint16(closeCode)) + copy(buf[2:], text) + return buf +} diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go new file mode 100644 index 00000000000..a509a21f87a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package websocket + +import "net" + +func (c *Conn) writeBufs(bufs ...[]byte) error { + b := net.Buffers(bufs) + _, err := b.WriteTo(c.conn) + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go new file mode 100644 index 00000000000..37edaff5a57 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go @@ -0,0 +1,18 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package websocket + +func (c *Conn) writeBufs(bufs ...[]byte) error { + for _, buf := range bufs { + if len(buf) > 0 { + if _, err := c.conn.Write(buf); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go new file mode 100644 index 00000000000..c6f4df8960f --- /dev/null +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -0,0 +1,227 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package websocket implements the WebSocket protocol defined in RFC 6455. +// +// Overview +// +// The Conn type represents a WebSocket connection. A server application calls +// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: +// +// var upgrader = websocket.Upgrader{ +// ReadBufferSize: 1024, +// WriteBufferSize: 1024, +// } +// +// func handler(w http.ResponseWriter, r *http.Request) { +// conn, err := upgrader.Upgrade(w, r, nil) +// if err != nil { +// log.Println(err) +// return +// } +// ... Use conn to send and receive messages. +// } +// +// Call the connection's WriteMessage and ReadMessage methods to send and +// receive messages as a slice of bytes. This snippet of code shows how to echo +// messages using these methods: +// +// for { +// messageType, p, err := conn.ReadMessage() +// if err != nil { +// log.Println(err) +// return +// } +// if err := conn.WriteMessage(messageType, p); err != nil { +// log.Println(err) +// return +// } +// } +// +// In above snippet of code, p is a []byte and messageType is an int with value +// websocket.BinaryMessage or websocket.TextMessage. +// +// An application can also send and receive messages using the io.WriteCloser +// and io.Reader interfaces. To send a message, call the connection NextWriter +// method to get an io.WriteCloser, write the message to the writer and close +// the writer when done. To receive a message, call the connection NextReader +// method to get an io.Reader and read until io.EOF is returned. This snippet +// shows how to echo messages using the NextWriter and NextReader methods: +// +// for { +// messageType, r, err := conn.NextReader() +// if err != nil { +// return +// } +// w, err := conn.NextWriter(messageType) +// if err != nil { +// return err +// } +// if _, err := io.Copy(w, r); err != nil { +// return err +// } +// if err := w.Close(); err != nil { +// return err +// } +// } +// +// Data Messages +// +// The WebSocket protocol distinguishes between text and binary data messages. +// Text messages are interpreted as UTF-8 encoded text. The interpretation of +// binary messages is left to the application. +// +// This package uses the TextMessage and BinaryMessage integer constants to +// identify the two data message types. The ReadMessage and NextReader methods +// return the type of the received message. The messageType argument to the +// WriteMessage and NextWriter methods specifies the type of a sent message. +// +// It is the application's responsibility to ensure that text messages are +// valid UTF-8 encoded text. +// +// Control Messages +// +// The WebSocket protocol defines three types of control messages: close, ping +// and pong. Call the connection WriteControl, WriteMessage or NextWriter +// methods to send a control message to the peer. +// +// Connections handle received close messages by calling the handler function +// set with the SetCloseHandler method and by returning a *CloseError from the +// NextReader, ReadMessage or the message Read method. The default close +// handler sends a close message to the peer. +// +// Connections handle received ping messages by calling the handler function +// set with the SetPingHandler method. The default ping handler sends a pong +// message to the peer. +// +// Connections handle received pong messages by calling the handler function +// set with the SetPongHandler method. The default pong handler does nothing. +// If an application sends ping messages, then the application should set a +// pong handler to receive the corresponding pong. +// +// The control message handler functions are called from the NextReader, +// ReadMessage and message reader Read methods. The default close and ping +// handlers can block these methods for a short time when the handler writes to +// the connection. +// +// The application must read the connection to process close, ping and pong +// messages sent from the peer. If the application is not otherwise interested +// in messages from the peer, then the application should start a goroutine to +// read and discard messages from the peer. A simple example is: +// +// func readLoop(c *websocket.Conn) { +// for { +// if _, _, err := c.NextReader(); err != nil { +// c.Close() +// break +// } +// } +// } +// +// Concurrency +// +// Connections support one concurrent reader and one concurrent writer. +// +// Applications are responsible for ensuring that no more than one goroutine +// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, +// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and +// that no more than one goroutine calls the read methods (NextReader, +// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) +// concurrently. +// +// The Close and WriteControl methods can be called concurrently with all other +// methods. +// +// Origin Considerations +// +// Web browsers allow Javascript applications to open a WebSocket connection to +// any host. It's up to the server to enforce an origin policy using the Origin +// request header sent by the browser. +// +// The Upgrader calls the function specified in the CheckOrigin field to check +// the origin. If the CheckOrigin function returns false, then the Upgrade +// method fails the WebSocket handshake with HTTP status 403. +// +// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail +// the handshake if the Origin request header is present and the Origin host is +// not equal to the Host request header. +// +// The deprecated package-level Upgrade function does not perform origin +// checking. The application is responsible for checking the Origin header +// before calling the Upgrade function. +// +// Buffers +// +// Connections buffer network input and output to reduce the number +// of system calls when reading or writing messages. +// +// Write buffers are also used for constructing WebSocket frames. See RFC 6455, +// Section 5 for a discussion of message framing. A WebSocket frame header is +// written to the network each time a write buffer is flushed to the network. +// Decreasing the size of the write buffer can increase the amount of framing +// overhead on the connection. +// +// The buffer sizes in bytes are specified by the ReadBufferSize and +// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default +// size of 4096 when a buffer size field is set to zero. The Upgrader reuses +// buffers created by the HTTP server when a buffer size field is set to zero. +// The HTTP server buffers have a size of 4096 at the time of this writing. +// +// The buffer sizes do not limit the size of a message that can be read or +// written by a connection. +// +// Buffers are held for the lifetime of the connection by default. If the +// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the +// write buffer only when writing a message. +// +// Applications should tune the buffer sizes to balance memory use and +// performance. Increasing the buffer size uses more memory, but can reduce the +// number of system calls to read or write the network. In the case of writing, +// increasing the buffer size can reduce the number of frame headers written to +// the network. +// +// Some guidelines for setting buffer parameters are: +// +// Limit the buffer sizes to the maximum expected message size. Buffers larger +// than the largest message do not provide any benefit. +// +// Depending on the distribution of message sizes, setting the buffer size to +// to a value less than the maximum expected message size can greatly reduce +// memory use with a small impact on performance. Here's an example: If 99% of +// the messages are smaller than 256 bytes and the maximum message size is 512 +// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls +// than a buffer size of 512 bytes. The memory savings is 50%. +// +// A write buffer pool is useful when the application has a modest number +// writes over a large number of connections. when buffers are pooled, a larger +// buffer size has a reduced impact on total memory use and has the benefit of +// reducing system calls and frame overhead. +// +// Compression EXPERIMENTAL +// +// Per message compression extensions (RFC 7692) are experimentally supported +// by this package in a limited capacity. Setting the EnableCompression option +// to true in Dialer or Upgrader will attempt to negotiate per message deflate +// support. +// +// var upgrader = websocket.Upgrader{ +// EnableCompression: true, +// } +// +// If compression was successfully negotiated with the connection's peer, any +// message received in compressed form will be automatically decompressed. +// All Read methods will return uncompressed bytes. +// +// Per message compression of messages written to a connection can be enabled +// or disabled by calling the corresponding Conn method: +// +// conn.EnableWriteCompression(false) +// +// Currently this package does not support compression with "context takeover". +// This means that messages must be compressed and decompressed in isolation, +// without retaining sliding window or dictionary state across messages. For +// more details refer to RFC 7692. +// +// Use of compression is experimental and may result in decreased performance. +package websocket diff --git a/vendor/github.com/gorilla/websocket/go.mod b/vendor/github.com/gorilla/websocket/go.mod new file mode 100644 index 00000000000..1a7afd5028a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/go.mod @@ -0,0 +1,3 @@ +module github.com/gorilla/websocket + +go 1.12 diff --git a/vendor/github.com/gorilla/websocket/go.sum b/vendor/github.com/gorilla/websocket/go.sum new file mode 100644 index 00000000000..cf4fbbaa07a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/go.sum @@ -0,0 +1,2 @@ +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= diff --git a/vendor/github.com/gorilla/websocket/join.go b/vendor/github.com/gorilla/websocket/join.go new file mode 100644 index 00000000000..c64f8c82901 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/join.go @@ -0,0 +1,42 @@ +// Copyright 2019 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "io" + "strings" +) + +// JoinMessages concatenates received messages to create a single io.Reader. +// The string term is appended to each message. The returned reader does not +// support concurrent calls to the Read method. +func JoinMessages(c *Conn, term string) io.Reader { + return &joinReader{c: c, term: term} +} + +type joinReader struct { + c *Conn + term string + r io.Reader +} + +func (r *joinReader) Read(p []byte) (int, error) { + if r.r == nil { + var err error + _, r.r, err = r.c.NextReader() + if err != nil { + return 0, err + } + if r.term != "" { + r.r = io.MultiReader(r.r, strings.NewReader(r.term)) + } + } + n, err := r.r.Read(p) + if err == io.EOF { + err = nil + r.r = nil + } + return n, err +} diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go new file mode 100644 index 00000000000..dc2c1f6415f --- /dev/null +++ b/vendor/github.com/gorilla/websocket/json.go @@ -0,0 +1,60 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "encoding/json" + "io" +) + +// WriteJSON writes the JSON encoding of v as a message. +// +// Deprecated: Use c.WriteJSON instead. +func WriteJSON(c *Conn, v interface{}) error { + return c.WriteJSON(v) +} + +// WriteJSON writes the JSON encoding of v as a message. +// +// See the documentation for encoding/json Marshal for details about the +// conversion of Go values to JSON. +func (c *Conn) WriteJSON(v interface{}) error { + w, err := c.NextWriter(TextMessage) + if err != nil { + return err + } + err1 := json.NewEncoder(w).Encode(v) + err2 := w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// Deprecated: Use c.ReadJSON instead. +func ReadJSON(c *Conn, v interface{}) error { + return c.ReadJSON(v) +} + +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// See the documentation for the encoding/json Unmarshal function for details +// about the conversion of JSON to a Go value. +func (c *Conn) ReadJSON(v interface{}) error { + _, r, err := c.NextReader() + if err != nil { + return err + } + err = json.NewDecoder(r).Decode(v) + if err == io.EOF { + // One value is expected in the message. + err = io.ErrUnexpectedEOF + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go new file mode 100644 index 00000000000..577fce9efd7 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +// +build !appengine + +package websocket + +import "unsafe" + +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +func maskBytes(key [4]byte, pos int, b []byte) int { + // Mask one byte at a time for small buffers. + if len(b) < 2*wordSize { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 + } + + // Mask one byte at a time to word boundary. + if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { + n = wordSize - n + for i := range b[:n] { + b[i] ^= key[pos&3] + pos++ + } + b = b[n:] + } + + // Create aligned word size key. + var k [wordSize]byte + for i := range k { + k[i] = key[(pos+i)&3] + } + kw := *(*uintptr)(unsafe.Pointer(&k)) + + // Mask one word at a time. + n := (len(b) / wordSize) * wordSize + for i := 0; i < n; i += wordSize { + *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw + } + + // Mask one byte at a time for remaining bytes. + b = b[n:] + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go new file mode 100644 index 00000000000..2aac060e52e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask_safe.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +// +build appengine + +package websocket + +func maskBytes(key [4]byte, pos int, b []byte) int { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go new file mode 100644 index 00000000000..74ec565d2c3 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/prepared.go @@ -0,0 +1,102 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "net" + "sync" + "time" +) + +// PreparedMessage caches on the wire representations of a message payload. +// Use PreparedMessage to efficiently send a message payload to multiple +// connections. PreparedMessage is especially useful when compression is used +// because the CPU and memory expensive compression operation can be executed +// once for a given set of compression options. +type PreparedMessage struct { + messageType int + data []byte + mu sync.Mutex + frames map[prepareKey]*preparedFrame +} + +// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. +type prepareKey struct { + isServer bool + compress bool + compressionLevel int +} + +// preparedFrame contains data in wire representation. +type preparedFrame struct { + once sync.Once + data []byte +} + +// NewPreparedMessage returns an initialized PreparedMessage. You can then send +// it to connection using WritePreparedMessage method. Valid wire +// representation will be calculated lazily only once for a set of current +// connection options. +func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { + pm := &PreparedMessage{ + messageType: messageType, + frames: make(map[prepareKey]*preparedFrame), + data: data, + } + + // Prepare a plain server frame. + _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) + if err != nil { + return nil, err + } + + // To protect against caller modifying the data argument, remember the data + // copied to the plain server frame. + pm.data = frameData[len(frameData)-len(data):] + return pm, nil +} + +func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { + pm.mu.Lock() + frame, ok := pm.frames[key] + if !ok { + frame = &preparedFrame{} + pm.frames[key] = frame + } + pm.mu.Unlock() + + var err error + frame.once.Do(func() { + // Prepare a frame using a 'fake' connection. + // TODO: Refactor code in conn.go to allow more direct construction of + // the frame. + mu := make(chan bool, 1) + mu <- true + var nc prepareConn + c := &Conn{ + conn: &nc, + mu: mu, + isServer: key.isServer, + compressionLevel: key.compressionLevel, + enableWriteCompression: true, + writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), + } + if key.compress { + c.newCompressionWriter = compressNoContextTakeover + } + err = c.WriteMessage(pm.messageType, pm.data) + frame.data = nc.buf.Bytes() + }) + return pm.messageType, frame.data, err +} + +type prepareConn struct { + buf bytes.Buffer + net.Conn +} + +func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } +func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go new file mode 100644 index 00000000000..e87a8c9f0c9 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/proxy.go @@ -0,0 +1,77 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "encoding/base64" + "errors" + "net" + "net/http" + "net/url" + "strings" +) + +type netDialerFunc func(network, addr string) (net.Conn, error) + +func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { + return fn(network, addr) +} + +func init() { + proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { + return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil + }) +} + +type httpProxyDialer struct { + proxyURL *url.URL + forwardDial func(network, addr string) (net.Conn, error) +} + +func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { + hostPort, _ := hostPortNoPort(hpd.proxyURL) + conn, err := hpd.forwardDial(network, hostPort) + if err != nil { + return nil, err + } + + connectHeader := make(http.Header) + if user := hpd.proxyURL.User; user != nil { + proxyUser := user.Username() + if proxyPassword, passwordSet := user.Password(); passwordSet { + credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) + connectHeader.Set("Proxy-Authorization", "Basic "+credential) + } + } + + connectReq := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: addr}, + Host: addr, + Header: connectHeader, + } + + if err := connectReq.Write(conn); err != nil { + conn.Close() + return nil, err + } + + // Read response. It's OK to use and discard buffered reader here becaue + // the remote server does not speak until spoken to. + br := bufio.NewReader(conn) + resp, err := http.ReadResponse(br, connectReq) + if err != nil { + conn.Close() + return nil, err + } + + if resp.StatusCode != 200 { + conn.Close() + f := strings.SplitN(resp.Status, " ", 2) + return nil, errors.New(f[1]) + } + return conn, nil +} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go new file mode 100644 index 00000000000..887d558918c --- /dev/null +++ b/vendor/github.com/gorilla/websocket/server.go @@ -0,0 +1,363 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "errors" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +// HandshakeError describes an error with the handshake from the peer. +type HandshakeError struct { + message string +} + +func (e HandshakeError) Error() string { return e.message } + +// Upgrader specifies parameters for upgrading an HTTP connection to a +// WebSocket connection. +type Upgrader struct { + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer + // size is zero, then buffers allocated by the HTTP server are used. The + // I/O buffer sizes do not limit the size of the messages that can be sent + // or received. + ReadBufferSize, WriteBufferSize int + + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + + // Subprotocols specifies the server's supported protocols in order of + // preference. If this field is not nil, then the Upgrade method negotiates a + // subprotocol by selecting the first match in this list with a protocol + // requested by the client. If there's no match, then no protocol is + // negotiated (the Sec-Websocket-Protocol header is not included in the + // handshake response). + Subprotocols []string + + // Error specifies the function for generating HTTP error responses. If Error + // is nil, then http.Error is used to generate the HTTP response. + Error func(w http.ResponseWriter, r *http.Request, status int, reason error) + + // CheckOrigin returns true if the request Origin header is acceptable. If + // CheckOrigin is nil, then a safe default is used: return false if the + // Origin request header is present and the origin host is not equal to + // request Host header. + // + // A CheckOrigin function should carefully validate the request origin to + // prevent cross-site request forgery. + CheckOrigin func(r *http.Request) bool + + // EnableCompression specify if the server should attempt to negotiate per + // message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool +} + +func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { + err := HandshakeError{reason} + if u.Error != nil { + u.Error(w, r, status, err) + } else { + w.Header().Set("Sec-Websocket-Version", "13") + http.Error(w, http.StatusText(status), status) + } + return nil, err +} + +// checkSameOrigin returns true if the origin is not set or is equal to the request host. +func checkSameOrigin(r *http.Request) bool { + origin := r.Header["Origin"] + if len(origin) == 0 { + return true + } + u, err := url.Parse(origin[0]) + if err != nil { + return false + } + return equalASCIIFold(u.Host, r.Host) +} + +func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { + if u.Subprotocols != nil { + clientProtocols := Subprotocols(r) + for _, serverProtocol := range u.Subprotocols { + for _, clientProtocol := range clientProtocols { + if clientProtocol == serverProtocol { + return clientProtocol + } + } + } + } else if responseHeader != nil { + return responseHeader.Get("Sec-Websocket-Protocol") + } + return "" +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// application negotiated subprotocol (Sec-WebSocket-Protocol). +// +// If the upgrade fails, then Upgrade replies to the client with an HTTP error +// response. +func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { + const badHandshake = "websocket: the client is not using the websocket protocol: " + + if !tokenListContainsValue(r.Header, "Connection", "upgrade") { + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") + } + + if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") + } + + if r.Method != "GET" { + return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") + } + + if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") + } + + if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") + } + + checkOrigin := u.CheckOrigin + if checkOrigin == nil { + checkOrigin = checkSameOrigin + } + if !checkOrigin(r) { + return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") + } + + challengeKey := r.Header.Get("Sec-Websocket-Key") + if challengeKey == "" { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank") + } + + subprotocol := u.selectSubprotocol(r, responseHeader) + + // Negotiate PMCE + var compress bool + if u.EnableCompression { + for _, ext := range parseExtensions(r.Header) { + if ext[""] != "permessage-deflate" { + continue + } + compress = true + break + } + } + + h, ok := w.(http.Hijacker) + if !ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") + } + var brw *bufio.ReadWriter + netConn, brw, err := h.Hijack() + if err != nil { + return u.returnError(w, r, http.StatusInternalServerError, err.Error()) + } + + if brw.Reader.Buffered() > 0 { + netConn.Close() + return nil, errors.New("websocket: client sent data before handshake is complete") + } + + var br *bufio.Reader + if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { + // Reuse hijacked buffered reader as connection reader. + br = brw.Reader + } + + buf := bufioWriterBuffer(netConn, brw.Writer) + + var writeBuf []byte + if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { + // Reuse hijacked write buffer as connection buffer. + writeBuf = buf + } + + c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf) + c.subprotocol = subprotocol + + if compress { + c.newCompressionWriter = compressNoContextTakeover + c.newDecompressionReader = decompressNoContextTakeover + } + + // Use larger of hijacked buffer and connection write buffer for header. + p := buf + if len(c.writeBuf) > len(p) { + p = c.writeBuf + } + p = p[:0] + + p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) + p = append(p, computeAcceptKey(challengeKey)...) + p = append(p, "\r\n"...) + if c.subprotocol != "" { + p = append(p, "Sec-WebSocket-Protocol: "...) + p = append(p, c.subprotocol...) + p = append(p, "\r\n"...) + } + if compress { + p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) + } + for k, vs := range responseHeader { + if k == "Sec-Websocket-Protocol" { + continue + } + for _, v := range vs { + p = append(p, k...) + p = append(p, ": "...) + for i := 0; i < len(v); i++ { + b := v[i] + if b <= 31 { + // prevent response splitting. + b = ' ' + } + p = append(p, b) + } + p = append(p, "\r\n"...) + } + } + p = append(p, "\r\n"...) + + // Clear deadlines set by HTTP server. + netConn.SetDeadline(time.Time{}) + + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) + } + if _, err = netConn.Write(p); err != nil { + netConn.Close() + return nil, err + } + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Time{}) + } + + return c, nil +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// Deprecated: Use websocket.Upgrader instead. +// +// Upgrade does not perform origin checking. The application is responsible for +// checking the Origin header before calling Upgrade. An example implementation +// of the same origin policy check is: +// +// if req.Header.Get("Origin") != "http://"+req.Host { +// http.Error(w, "Origin not allowed", http.StatusForbidden) +// return +// } +// +// If the endpoint supports subprotocols, then the application is responsible +// for negotiating the protocol used on the connection. Use the Subprotocols() +// function to get the subprotocols requested by the client. Use the +// Sec-Websocket-Protocol response header to specify the subprotocol selected +// by the application. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// negotiated subprotocol (Sec-Websocket-Protocol). +// +// The connection buffers IO to the underlying network connection. The +// readBufSize and writeBufSize parameters specify the size of the buffers to +// use. Messages can be larger than the buffers. +// +// If the request is not a valid WebSocket handshake, then Upgrade returns an +// error of type HandshakeError. Applications should handle this error by +// replying to the client with an HTTP error response. +func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) { + u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize} + u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { + // don't return errors to maintain backwards compatibility + } + u.CheckOrigin = func(r *http.Request) bool { + // allow all connections by default + return true + } + return u.Upgrade(w, r, responseHeader) +} + +// Subprotocols returns the subprotocols requested by the client in the +// Sec-Websocket-Protocol header. +func Subprotocols(r *http.Request) []string { + h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol")) + if h == "" { + return nil + } + protocols := strings.Split(h, ",") + for i := range protocols { + protocols[i] = strings.TrimSpace(protocols[i]) + } + return protocols +} + +// IsWebSocketUpgrade returns true if the client requested upgrade to the +// WebSocket protocol. +func IsWebSocketUpgrade(r *http.Request) bool { + return tokenListContainsValue(r.Header, "Connection", "upgrade") && + tokenListContainsValue(r.Header, "Upgrade", "websocket") +} + +// bufioReaderSize size returns the size of a bufio.Reader. +func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { + // This code assumes that peek on a reset reader returns + // bufio.Reader.buf[:0]. + // TODO: Use bufio.Reader.Size() after Go 1.10 + br.Reset(originalReader) + if p, err := br.Peek(0); err == nil { + return cap(p) + } + return 0 +} + +// writeHook is an io.Writer that records the last slice passed to it vio +// io.Writer.Write. +type writeHook struct { + p []byte +} + +func (wh *writeHook) Write(p []byte) (int, error) { + wh.p = p + return len(p), nil +} + +// bufioWriterBuffer grabs the buffer from a bufio.Writer. +func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { + // This code assumes that bufio.Writer.buf[:1] is passed to the + // bufio.Writer's underlying writer. + var wh writeHook + bw.Reset(&wh) + bw.WriteByte(0) + bw.Flush() + + bw.Reset(originalWriter) + + return wh.p[:cap(wh.p)] +} diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go new file mode 100644 index 00000000000..834f122a00d --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace.go @@ -0,0 +1,19 @@ +// +build go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + if trace.TLSHandshakeStart != nil { + trace.TLSHandshakeStart() + } + err := doHandshake(tlsConn, cfg) + if trace.TLSHandshakeDone != nil { + trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go new file mode 100644 index 00000000000..77d05a0b574 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace_17.go @@ -0,0 +1,12 @@ +// +build !go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + return doHandshake(tlsConn, cfg) +} diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go new file mode 100644 index 00000000000..7bf2f66c674 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/util.go @@ -0,0 +1,283 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "io" + "net/http" + "strings" + "unicode/utf8" +) + +var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") + +func computeAcceptKey(challengeKey string) string { + h := sha1.New() + h.Write([]byte(challengeKey)) + h.Write(keyGUID) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func generateChallengeKey() (string, error) { + p := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, p); err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(p), nil +} + +// Token octets per RFC 2616. +var isTokenOctet = [256]bool{ + '!': true, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '*': true, + '+': true, + '-': true, + '.': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'W': true, + 'V': true, + 'X': true, + 'Y': true, + 'Z': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '|': true, + '~': true, +} + +// skipSpace returns a slice of the string s with all leading RFC 2616 linear +// whitespace removed. +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if b := s[i]; b != ' ' && b != '\t' { + break + } + } + return s[i:] +} + +// nextToken returns the leading RFC 2616 token of s and the string following +// the token. +func nextToken(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + if !isTokenOctet[s[i]] { + break + } + } + return s[:i], s[i:] +} + +// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616 +// and the string following the token or quoted string. +func nextTokenOrQuoted(s string) (value string, rest string) { + if !strings.HasPrefix(s, "\"") { + return nextToken(s) + } + s = s[1:] + for i := 0; i < len(s); i++ { + switch s[i] { + case '"': + return s[:i], s[i+1:] + case '\\': + p := make([]byte, len(s)-1) + j := copy(p, s[:i]) + escape := true + for i = i + 1; i < len(s); i++ { + b := s[i] + switch { + case escape: + escape = false + p[j] = b + j++ + case b == '\\': + escape = true + case b == '"': + return string(p[:j]), s[i+1:] + default: + p[j] = b + j++ + } + } + return "", "" + } + } + return "", "" +} + +// equalASCIIFold returns true if s is equal to t with ASCII case folding as +// defined in RFC 4790. +func equalASCIIFold(s, t string) bool { + for s != "" && t != "" { + sr, size := utf8.DecodeRuneInString(s) + s = s[size:] + tr, size := utf8.DecodeRuneInString(t) + t = t[size:] + if sr == tr { + continue + } + if 'A' <= sr && sr <= 'Z' { + sr = sr + 'a' - 'A' + } + if 'A' <= tr && tr <= 'Z' { + tr = tr + 'a' - 'A' + } + if sr != tr { + return false + } + } + return s == t +} + +// tokenListContainsValue returns true if the 1#token header with the given +// name contains a token equal to value with ASCII case folding. +func tokenListContainsValue(header http.Header, name string, value string) bool { +headers: + for _, s := range header[name] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + s = skipSpace(s) + if s != "" && s[0] != ',' { + continue headers + } + if equalASCIIFold(t, value) { + return true + } + if s == "" { + continue headers + } + s = s[1:] + } + } + return false +} + +// parseExtensions parses WebSocket extensions from a header. +func parseExtensions(header http.Header) []map[string]string { + // From RFC 6455: + // + // Sec-WebSocket-Extensions = extension-list + // extension-list = 1#extension + // extension = extension-token *( ";" extension-param ) + // extension-token = registered-token + // registered-token = token + // extension-param = token [ "=" (token | quoted-string) ] + // ;When using the quoted-string syntax variant, the value + // ;after quoted-string unescaping MUST conform to the + // ;'token' ABNF. + + var result []map[string]string +headers: + for _, s := range header["Sec-Websocket-Extensions"] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + ext := map[string]string{"": t} + for { + s = skipSpace(s) + if !strings.HasPrefix(s, ";") { + break + } + var k string + k, s = nextToken(skipSpace(s[1:])) + if k == "" { + continue headers + } + s = skipSpace(s) + var v string + if strings.HasPrefix(s, "=") { + v, s = nextTokenOrQuoted(skipSpace(s[1:])) + s = skipSpace(s) + } + if s != "" && s[0] != ',' && s[0] != ';' { + continue headers + } + ext[k] = v + } + if s != "" && s[0] != ',' { + continue headers + } + result = append(result, ext) + if s == "" { + continue headers + } + s = s[1:] + } + } + return result +} diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go new file mode 100644 index 00000000000..2e668f6b882 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/x_net_proxy.go @@ -0,0 +1,473 @@ +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. +//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy + +// Package proxy provides support for a variety of protocols to proxy network +// data. +// + +package websocket + +import ( + "errors" + "io" + "net" + "net/url" + "os" + "strconv" + "strings" + "sync" +) + +type proxy_direct struct{} + +// Direct is a direct proxy: one that makes network connections directly. +var proxy_Direct = proxy_direct{} + +func (proxy_direct) Dial(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} + +// A PerHost directs connections to a default Dialer unless the host name +// requested matches one of a number of exceptions. +type proxy_PerHost struct { + def, bypass proxy_Dialer + + bypassNetworks []*net.IPNet + bypassIPs []net.IP + bypassZones []string + bypassHosts []string +} + +// NewPerHost returns a PerHost Dialer that directs connections to either +// defaultDialer or bypass, depending on whether the connection matches one of +// the configured rules. +func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { + return &proxy_PerHost{ + def: defaultDialer, + bypass: bypass, + } +} + +// Dial connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + return p.dialerForRequest(host).Dial(network, addr) +} + +func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { + if ip := net.ParseIP(host); ip != nil { + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass + } + } + for _, bypassIP := range p.bypassIPs { + if bypassIP.Equal(ip) { + return p.bypass + } + } + return p.def + } + + for _, zone := range p.bypassZones { + if strings.HasSuffix(host, zone) { + return p.bypass + } + if host == zone[1:] { + // For a zone ".example.com", we match "example.com" + // too. + return p.bypass + } + } + for _, bypassHost := range p.bypassHosts { + if bypassHost == host { + return p.bypass + } + } + return p.def +} + +// AddFromString parses a string that contains comma-separated values +// specifying hosts that should use the bypass proxy. Each value is either an +// IP address, a CIDR range, a zone (*.example.com) or a host name +// (localhost). A best effort is made to parse the string and errors are +// ignored. +func (p *proxy_PerHost) AddFromString(s string) { + hosts := strings.Split(s, ",") + for _, host := range hosts { + host = strings.TrimSpace(host) + if len(host) == 0 { + continue + } + if strings.Contains(host, "/") { + // We assume that it's a CIDR address like 127.0.0.0/8 + if _, net, err := net.ParseCIDR(host); err == nil { + p.AddNetwork(net) + } + continue + } + if ip := net.ParseIP(host); ip != nil { + p.AddIP(ip) + continue + } + if strings.HasPrefix(host, "*.") { + p.AddZone(host[1:]) + continue + } + p.AddHost(host) + } +} + +// AddIP specifies an IP address that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match an IP. +func (p *proxy_PerHost) AddIP(ip net.IP) { + p.bypassIPs = append(p.bypassIPs, ip) +} + +// AddNetwork specifies an IP range that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match. +func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { + p.bypassNetworks = append(p.bypassNetworks, net) +} + +// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of +// "example.com" matches "example.com" and all of its subdomains. +func (p *proxy_PerHost) AddZone(zone string) { + if strings.HasSuffix(zone, ".") { + zone = zone[:len(zone)-1] + } + if !strings.HasPrefix(zone, ".") { + zone = "." + zone + } + p.bypassZones = append(p.bypassZones, zone) +} + +// AddHost specifies a host name that will use the bypass proxy. +func (p *proxy_PerHost) AddHost(host string) { + if strings.HasSuffix(host, ".") { + host = host[:len(host)-1] + } + p.bypassHosts = append(p.bypassHosts, host) +} + +// A Dialer is a means to establish a connection. +type proxy_Dialer interface { + // Dial connects to the given address via the proxy. + Dial(network, addr string) (c net.Conn, err error) +} + +// Auth contains authentication parameters that specific Dialers may require. +type proxy_Auth struct { + User, Password string +} + +// FromEnvironment returns the dialer specified by the proxy related variables in +// the environment. +func proxy_FromEnvironment() proxy_Dialer { + allProxy := proxy_allProxyEnv.Get() + if len(allProxy) == 0 { + return proxy_Direct + } + + proxyURL, err := url.Parse(allProxy) + if err != nil { + return proxy_Direct + } + proxy, err := proxy_FromURL(proxyURL, proxy_Direct) + if err != nil { + return proxy_Direct + } + + noProxy := proxy_noProxyEnv.Get() + if len(noProxy) == 0 { + return proxy + } + + perHost := proxy_NewPerHost(proxy, proxy_Direct) + perHost.AddFromString(noProxy) + return perHost +} + +// proxySchemes is a map from URL schemes to a function that creates a Dialer +// from a URL with such a scheme. +var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) + +// RegisterDialerType takes a URL scheme and a function to generate Dialers from +// a URL with that scheme and a forwarding Dialer. Registered schemes are used +// by FromURL. +func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { + if proxy_proxySchemes == nil { + proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) + } + proxy_proxySchemes[scheme] = f +} + +// FromURL returns a Dialer given a URL specification and an underlying +// Dialer for it to make network requests. +func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { + var auth *proxy_Auth + if u.User != nil { + auth = new(proxy_Auth) + auth.User = u.User.Username() + if p, ok := u.User.Password(); ok { + auth.Password = p + } + } + + switch u.Scheme { + case "socks5": + return proxy_SOCKS5("tcp", u.Host, auth, forward) + } + + // If the scheme doesn't match any of the built-in schemes, see if it + // was registered by another package. + if proxy_proxySchemes != nil { + if f, ok := proxy_proxySchemes[u.Scheme]; ok { + return f(u, forward) + } + } + + return nil, errors.New("proxy: unknown scheme: " + u.Scheme) +} + +var ( + proxy_allProxyEnv = &proxy_envOnce{ + names: []string{"ALL_PROXY", "all_proxy"}, + } + proxy_noProxyEnv = &proxy_envOnce{ + names: []string{"NO_PROXY", "no_proxy"}, + } +) + +// envOnce looks up an environment variable (optionally by multiple +// names) once. It mitigates expensive lookups on some platforms +// (e.g. Windows). +// (Borrowed from net/http/transport.go) +type proxy_envOnce struct { + names []string + once sync.Once + val string +} + +func (e *proxy_envOnce) Get() string { + e.once.Do(e.init) + return e.val +} + +func (e *proxy_envOnce) init() { + for _, n := range e.names { + e.val = os.Getenv(n) + if e.val != "" { + return + } + } +} + +// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address +// with an optional username and password. See RFC 1928 and RFC 1929. +func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { + s := &proxy_socks5{ + network: network, + addr: addr, + forward: forward, + } + if auth != nil { + s.user = auth.User + s.password = auth.Password + } + + return s, nil +} + +type proxy_socks5 struct { + user, password string + network, addr string + forward proxy_Dialer +} + +const proxy_socks5Version = 5 + +const ( + proxy_socks5AuthNone = 0 + proxy_socks5AuthPassword = 2 +) + +const proxy_socks5Connect = 1 + +const ( + proxy_socks5IP4 = 1 + proxy_socks5Domain = 3 + proxy_socks5IP6 = 4 +) + +var proxy_socks5Errors = []string{ + "", + "general failure", + "connection forbidden", + "network unreachable", + "host unreachable", + "connection refused", + "TTL expired", + "command not supported", + "address type not supported", +} + +// Dial connects to the address addr on the given network via the SOCKS5 proxy. +func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { + switch network { + case "tcp", "tcp6", "tcp4": + default: + return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) + } + + conn, err := s.forward.Dial(s.network, s.addr) + if err != nil { + return nil, err + } + if err := s.connect(conn, addr); err != nil { + conn.Close() + return nil, err + } + return conn, nil +} + +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *proxy_socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) + if err != nil { + return err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return errors.New("proxy: failed to parse port number: " + portStr) + } + if port < 1 || port > 0xffff { + return errors.New("proxy: port number out of range: " + portStr) + } + + // the size here is just an estimate + buf := make([]byte, 0, 6+len(host)) + + buf = append(buf, proxy_socks5Version) + if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { + buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) + } else { + buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) + } + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + if buf[0] != 5 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + } + if buf[1] == 0xff { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + } + + // See RFC 1929 + if buf[1] == proxy_socks5AuthPassword { + buf = buf[:0] + buf = append(buf, 1 /* password protocol version */) + buf = append(buf, uint8(len(s.user))) + buf = append(buf, s.user...) + buf = append(buf, uint8(len(s.password))) + buf = append(buf, s.password...) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if buf[1] != 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + } + } + + buf = buf[:0] + buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) + + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + buf = append(buf, proxy_socks5IP4) + ip = ip4 + } else { + buf = append(buf, proxy_socks5IP6) + } + buf = append(buf, ip...) + } else { + if len(host) > 255 { + return errors.New("proxy: destination host name too long: " + host) + } + buf = append(buf, proxy_socks5Domain) + buf = append(buf, byte(len(host))) + buf = append(buf, host...) + } + buf = append(buf, byte(port>>8), byte(port)) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:4]); err != nil { + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + failure := "unknown error" + if int(buf[1]) < len(proxy_socks5Errors) { + failure = proxy_socks5Errors[buf[1]] + } + + if len(failure) > 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + } + + bytesToDiscard := 0 + switch buf[3] { + case proxy_socks5IP4: + bytesToDiscard = net.IPv4len + case proxy_socks5IP6: + bytesToDiscard = net.IPv6len + case proxy_socks5Domain: + _, err := io.ReadFull(conn, buf[:1]) + if err != nil { + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + bytesToDiscard = int(buf[0]) + default: + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + } + + if cap(buf) < bytesToDiscard { + buf = make([]byte, bytesToDiscard) + } else { + buf = buf[:bytesToDiscard] + } + if _, err := io.ReadFull(conn, buf); err != nil { + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + // Also need to discard the port number + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + return nil +} diff --git a/vendor/google.golang.org/appengine/datastore/datastore.go b/vendor/google.golang.org/appengine/datastore/datastore.go new file mode 100644 index 00000000000..576bc50132a --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/datastore.go @@ -0,0 +1,407 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + "fmt" + "reflect" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine" + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +var ( + // ErrInvalidEntityType is returned when functions like Get or Next are + // passed a dst or src argument of invalid type. + ErrInvalidEntityType = errors.New("datastore: invalid entity type") + // ErrInvalidKey is returned when an invalid key is presented. + ErrInvalidKey = errors.New("datastore: invalid key") + // ErrNoSuchEntity is returned when no entity was found for a given key. + ErrNoSuchEntity = errors.New("datastore: no such entity") +) + +// ErrFieldMismatch is returned when a field is to be loaded into a different +// type than the one it was stored from, or when a field is missing or +// unexported in the destination struct. +// StructType is the type of the struct pointed to by the destination argument +// passed to Get or to Iterator.Next. +type ErrFieldMismatch struct { + StructType reflect.Type + FieldName string + Reason string +} + +func (e *ErrFieldMismatch) Error() string { + return fmt.Sprintf("datastore: cannot load field %q into a %q: %s", + e.FieldName, e.StructType, e.Reason) +} + +// protoToKey converts a Reference proto to a *Key. If the key is invalid, +// protoToKey will return the invalid key along with ErrInvalidKey. +func protoToKey(r *pb.Reference) (k *Key, err error) { + appID := r.GetApp() + namespace := r.GetNameSpace() + for _, e := range r.Path.Element { + k = &Key{ + kind: e.GetType(), + stringID: e.GetName(), + intID: e.GetId(), + parent: k, + appID: appID, + namespace: namespace, + } + if !k.valid() { + return k, ErrInvalidKey + } + } + return +} + +// keyToProto converts a *Key to a Reference proto. +func keyToProto(defaultAppID string, k *Key) *pb.Reference { + appID := k.appID + if appID == "" { + appID = defaultAppID + } + n := 0 + for i := k; i != nil; i = i.parent { + n++ + } + e := make([]*pb.Path_Element, n) + for i := k; i != nil; i = i.parent { + n-- + e[n] = &pb.Path_Element{ + Type: &i.kind, + } + // At most one of {Name,Id} should be set. + // Neither will be set for incomplete keys. + if i.stringID != "" { + e[n].Name = &i.stringID + } else if i.intID != 0 { + e[n].Id = &i.intID + } + } + var namespace *string + if k.namespace != "" { + namespace = proto.String(k.namespace) + } + return &pb.Reference{ + App: proto.String(appID), + NameSpace: namespace, + Path: &pb.Path{ + Element: e, + }, + } +} + +// multiKeyToProto is a batch version of keyToProto. +func multiKeyToProto(appID string, key []*Key) []*pb.Reference { + ret := make([]*pb.Reference, len(key)) + for i, k := range key { + ret[i] = keyToProto(appID, k) + } + return ret +} + +// multiValid is a batch version of Key.valid. It returns an error, not a +// []bool. +func multiValid(key []*Key) error { + invalid := false + for _, k := range key { + if !k.valid() { + invalid = true + break + } + } + if !invalid { + return nil + } + err := make(appengine.MultiError, len(key)) + for i, k := range key { + if !k.valid() { + err[i] = ErrInvalidKey + } + } + return err +} + +// It's unfortunate that the two semantically equivalent concepts pb.Reference +// and pb.PropertyValue_ReferenceValue aren't the same type. For example, the +// two have different protobuf field numbers. + +// referenceValueToKey is the same as protoToKey except the input is a +// PropertyValue_ReferenceValue instead of a Reference. +func referenceValueToKey(r *pb.PropertyValue_ReferenceValue) (k *Key, err error) { + appID := r.GetApp() + namespace := r.GetNameSpace() + for _, e := range r.Pathelement { + k = &Key{ + kind: e.GetType(), + stringID: e.GetName(), + intID: e.GetId(), + parent: k, + appID: appID, + namespace: namespace, + } + if !k.valid() { + return nil, ErrInvalidKey + } + } + return +} + +// keyToReferenceValue is the same as keyToProto except the output is a +// PropertyValue_ReferenceValue instead of a Reference. +func keyToReferenceValue(defaultAppID string, k *Key) *pb.PropertyValue_ReferenceValue { + ref := keyToProto(defaultAppID, k) + pe := make([]*pb.PropertyValue_ReferenceValue_PathElement, len(ref.Path.Element)) + for i, e := range ref.Path.Element { + pe[i] = &pb.PropertyValue_ReferenceValue_PathElement{ + Type: e.Type, + Id: e.Id, + Name: e.Name, + } + } + return &pb.PropertyValue_ReferenceValue{ + App: ref.App, + NameSpace: ref.NameSpace, + Pathelement: pe, + } +} + +type multiArgType int + +const ( + multiArgTypeInvalid multiArgType = iota + multiArgTypePropertyLoadSaver + multiArgTypeStruct + multiArgTypeStructPtr + multiArgTypeInterface +) + +// checkMultiArg checks that v has type []S, []*S, []I, or []P, for some struct +// type S, for some interface type I, or some non-interface non-pointer type P +// such that P or *P implements PropertyLoadSaver. +// +// It returns what category the slice's elements are, and the reflect.Type +// that represents S, I or P. +// +// As a special case, PropertyList is an invalid type for v. +func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) { + if v.Kind() != reflect.Slice { + return multiArgTypeInvalid, nil + } + if v.Type() == typeOfPropertyList { + return multiArgTypeInvalid, nil + } + elemType = v.Type().Elem() + if reflect.PtrTo(elemType).Implements(typeOfPropertyLoadSaver) { + return multiArgTypePropertyLoadSaver, elemType + } + switch elemType.Kind() { + case reflect.Struct: + return multiArgTypeStruct, elemType + case reflect.Interface: + return multiArgTypeInterface, elemType + case reflect.Ptr: + elemType = elemType.Elem() + if elemType.Kind() == reflect.Struct { + return multiArgTypeStructPtr, elemType + } + } + return multiArgTypeInvalid, nil +} + +// Get loads the entity stored for k into dst, which must be a struct pointer +// or implement PropertyLoadSaver. If there is no such entity for the key, Get +// returns ErrNoSuchEntity. +// +// The values of dst's unmatched struct fields are not modified, and matching +// slice-typed fields are not reset before appending to them. In particular, it +// is recommended to pass a pointer to a zero valued struct on each Get call. +// +// ErrFieldMismatch is returned when a field is to be loaded into a different +// type than the one it was stored from, or when a field is missing or +// unexported in the destination struct. ErrFieldMismatch is only returned if +// dst is a struct pointer. +func Get(c context.Context, key *Key, dst interface{}) error { + if dst == nil { // GetMulti catches nil interface; we need to catch nil ptr here + return ErrInvalidEntityType + } + err := GetMulti(c, []*Key{key}, []interface{}{dst}) + if me, ok := err.(appengine.MultiError); ok { + return me[0] + } + return err +} + +// GetMulti is a batch version of Get. +// +// dst must be a []S, []*S, []I or []P, for some struct type S, some interface +// type I, or some non-interface non-pointer type P such that P or *P +// implements PropertyLoadSaver. If an []I, each element must be a valid dst +// for Get: it must be a struct pointer or implement PropertyLoadSaver. +// +// As a special case, PropertyList is an invalid type for dst, even though a +// PropertyList is a slice of structs. It is treated as invalid to avoid being +// mistakenly passed when []PropertyList was intended. +func GetMulti(c context.Context, key []*Key, dst interface{}) error { + v := reflect.ValueOf(dst) + multiArgType, _ := checkMultiArg(v) + if multiArgType == multiArgTypeInvalid { + return errors.New("datastore: dst has invalid type") + } + if len(key) != v.Len() { + return errors.New("datastore: key and dst slices have different length") + } + if len(key) == 0 { + return nil + } + if err := multiValid(key); err != nil { + return err + } + req := &pb.GetRequest{ + Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key), + } + res := &pb.GetResponse{} + if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil { + return err + } + if len(key) != len(res.Entity) { + return errors.New("datastore: internal error: server returned the wrong number of entities") + } + multiErr, any := make(appengine.MultiError, len(key)), false + for i, e := range res.Entity { + if e.Entity == nil { + multiErr[i] = ErrNoSuchEntity + } else { + elem := v.Index(i) + if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { + elem = elem.Addr() + } + if multiArgType == multiArgTypeStructPtr && elem.IsNil() { + elem.Set(reflect.New(elem.Type().Elem())) + } + multiErr[i] = loadEntity(elem.Interface(), e.Entity) + } + if multiErr[i] != nil { + any = true + } + } + if any { + return multiErr + } + return nil +} + +// Put saves the entity src into the datastore with key k. src must be a struct +// pointer or implement PropertyLoadSaver; if a struct pointer then any +// unexported fields of that struct will be skipped. If k is an incomplete key, +// the returned key will be a unique key generated by the datastore. +func Put(c context.Context, key *Key, src interface{}) (*Key, error) { + k, err := PutMulti(c, []*Key{key}, []interface{}{src}) + if err != nil { + if me, ok := err.(appengine.MultiError); ok { + return nil, me[0] + } + return nil, err + } + return k[0], nil +} + +// PutMulti is a batch version of Put. +// +// src must satisfy the same conditions as the dst argument to GetMulti. +func PutMulti(c context.Context, key []*Key, src interface{}) ([]*Key, error) { + v := reflect.ValueOf(src) + multiArgType, _ := checkMultiArg(v) + if multiArgType == multiArgTypeInvalid { + return nil, errors.New("datastore: src has invalid type") + } + if len(key) != v.Len() { + return nil, errors.New("datastore: key and src slices have different length") + } + if len(key) == 0 { + return nil, nil + } + appID := internal.FullyQualifiedAppID(c) + if err := multiValid(key); err != nil { + return nil, err + } + req := &pb.PutRequest{} + for i := range key { + elem := v.Index(i) + if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { + elem = elem.Addr() + } + sProto, err := saveEntity(appID, key[i], elem.Interface()) + if err != nil { + return nil, err + } + req.Entity = append(req.Entity, sProto) + } + res := &pb.PutResponse{} + if err := internal.Call(c, "datastore_v3", "Put", req, res); err != nil { + return nil, err + } + if len(key) != len(res.Key) { + return nil, errors.New("datastore: internal error: server returned the wrong number of keys") + } + ret := make([]*Key, len(key)) + for i := range ret { + var err error + ret[i], err = protoToKey(res.Key[i]) + if err != nil || ret[i].Incomplete() { + return nil, errors.New("datastore: internal error: server returned an invalid key") + } + } + return ret, nil +} + +// Delete deletes the entity for the given key. +func Delete(c context.Context, key *Key) error { + err := DeleteMulti(c, []*Key{key}) + if me, ok := err.(appengine.MultiError); ok { + return me[0] + } + return err +} + +// DeleteMulti is a batch version of Delete. +func DeleteMulti(c context.Context, key []*Key) error { + if len(key) == 0 { + return nil + } + if err := multiValid(key); err != nil { + return err + } + req := &pb.DeleteRequest{ + Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key), + } + res := &pb.DeleteResponse{} + return internal.Call(c, "datastore_v3", "Delete", req, res) +} + +func namespaceMod(m proto.Message, namespace string) { + // pb.Query is the only type that has a name_space field. + // All other namespace support in datastore is in the keys. + switch m := m.(type) { + case *pb.Query: + if m.NameSpace == nil { + m.NameSpace = &namespace + } + } +} + +func init() { + internal.NamespaceMods["datastore_v3"] = namespaceMod + internal.RegisterErrorCodeMap("datastore_v3", pb.Error_ErrorCode_name) + internal.RegisterTimeoutErrorCode("datastore_v3", int32(pb.Error_TIMEOUT)) +} diff --git a/vendor/google.golang.org/appengine/datastore/doc.go b/vendor/google.golang.org/appengine/datastore/doc.go new file mode 100644 index 00000000000..85616cf2741 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/doc.go @@ -0,0 +1,361 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +/* +Package datastore provides a client for App Engine's datastore service. + + +Basic Operations + +Entities are the unit of storage and are associated with a key. A key +consists of an optional parent key, a string application ID, a string kind +(also known as an entity type), and either a StringID or an IntID. A +StringID is also known as an entity name or key name. + +It is valid to create a key with a zero StringID and a zero IntID; this is +called an incomplete key, and does not refer to any saved entity. Putting an +entity into the datastore under an incomplete key will cause a unique key +to be generated for that entity, with a non-zero IntID. + +An entity's contents are a mapping from case-sensitive field names to values. +Valid value types are: + - signed integers (int, int8, int16, int32 and int64), + - bool, + - string, + - float32 and float64, + - []byte (up to 1 megabyte in length), + - any type whose underlying type is one of the above predeclared types, + - ByteString, + - *Key, + - time.Time (stored with microsecond precision), + - appengine.BlobKey, + - appengine.GeoPoint, + - structs whose fields are all valid value types, + - slices of any of the above. + +Slices of structs are valid, as are structs that contain slices. However, if +one struct contains another, then at most one of those can be repeated. This +disqualifies recursively defined struct types: any struct T that (directly or +indirectly) contains a []T. + +The Get and Put functions load and save an entity's contents. An entity's +contents are typically represented by a struct pointer. + +Example code: + + type Entity struct { + Value string + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + + k := datastore.NewKey(ctx, "Entity", "stringID", 0, nil) + e := new(Entity) + if err := datastore.Get(ctx, k, e); err != nil { + http.Error(w, err.Error(), 500) + return + } + + old := e.Value + e.Value = r.URL.Path + + if _, err := datastore.Put(ctx, k, e); err != nil { + http.Error(w, err.Error(), 500) + return + } + + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + fmt.Fprintf(w, "old=%q\nnew=%q\n", old, e.Value) + } + +GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and +Delete functions. They take a []*Key instead of a *Key, and may return an +appengine.MultiError when encountering partial failure. + + +Properties + +An entity's contents can be represented by a variety of types. These are +typically struct pointers, but can also be any type that implements the +PropertyLoadSaver interface. If using a struct pointer, you do not have to +explicitly implement the PropertyLoadSaver interface; the datastore will +automatically convert via reflection. If a struct pointer does implement that +interface then those methods will be used in preference to the default +behavior for struct pointers. Struct pointers are more strongly typed and are +easier to use; PropertyLoadSavers are more flexible. + +The actual types passed do not have to match between Get and Put calls or even +across different calls to datastore. It is valid to put a *PropertyList and +get that same entity as a *myStruct, or put a *myStruct0 and get a *myStruct1. +Conceptually, any entity is saved as a sequence of properties, and is loaded +into the destination value on a property-by-property basis. When loading into +a struct pointer, an entity that cannot be completely represented (such as a +missing field) will result in an ErrFieldMismatch error but it is up to the +caller whether this error is fatal, recoverable or ignorable. + +By default, for struct pointers, all properties are potentially indexed, and +the property name is the same as the field name (and hence must start with an +upper case letter). + +Fields may have a `datastore:"name,options"` tag. The tag name is the +property name, which must be one or more valid Go identifiers joined by ".", +but may start with a lower case letter. An empty tag name means to just use the +field name. A "-" tag name means that the datastore will ignore that field. + +The only valid options are "omitempty" and "noindex". + +If the options include "omitempty" and the value of the field is empty, then the field will be omitted on Save. +The empty values are false, 0, any nil interface value, and any array, slice, map, or string of length zero. +Struct field values will never be empty. + +If options include "noindex" then the field will not be indexed. All fields are indexed +by default. Strings or byte slices longer than 1500 bytes cannot be indexed; +fields used to store long strings and byte slices must be tagged with "noindex" +or they will cause Put operations to fail. + +To use multiple options together, separate them by a comma. +The order does not matter. + +If the options is "" then the comma may be omitted. + +Example code: + + // A and B are renamed to a and b. + // A, C and J are not indexed. + // D's tag is equivalent to having no tag at all (E). + // I is ignored entirely by the datastore. + // J has tag information for both the datastore and json packages. + type TaggedStruct struct { + A int `datastore:"a,noindex"` + B int `datastore:"b"` + C int `datastore:",noindex"` + D int `datastore:""` + E int + I int `datastore:"-"` + J int `datastore:",noindex" json:"j"` + } + + +Structured Properties + +If the struct pointed to contains other structs, then the nested or embedded +structs are flattened. For example, given these definitions: + + type Inner1 struct { + W int32 + X string + } + + type Inner2 struct { + Y float64 + } + + type Inner3 struct { + Z bool + } + + type Outer struct { + A int16 + I []Inner1 + J Inner2 + Inner3 + } + +then an Outer's properties would be equivalent to those of: + + type OuterEquivalent struct { + A int16 + IDotW []int32 `datastore:"I.W"` + IDotX []string `datastore:"I.X"` + JDotY float64 `datastore:"J.Y"` + Z bool + } + +If Outer's embedded Inner3 field was tagged as `datastore:"Foo"` then the +equivalent field would instead be: FooDotZ bool `datastore:"Foo.Z"`. + +If an outer struct is tagged "noindex" then all of its implicit flattened +fields are effectively "noindex". + + +The PropertyLoadSaver Interface + +An entity's contents can also be represented by any type that implements the +PropertyLoadSaver interface. This type may be a struct pointer, but it does +not have to be. The datastore package will call Load when getting the entity's +contents, and Save when putting the entity's contents. +Possible uses include deriving non-stored fields, verifying fields, or indexing +a field only if its value is positive. + +Example code: + + type CustomPropsExample struct { + I, J int + // Sum is not stored, but should always be equal to I + J. + Sum int `datastore:"-"` + } + + func (x *CustomPropsExample) Load(ps []datastore.Property) error { + // Load I and J as usual. + if err := datastore.LoadStruct(x, ps); err != nil { + return err + } + // Derive the Sum field. + x.Sum = x.I + x.J + return nil + } + + func (x *CustomPropsExample) Save() ([]datastore.Property, error) { + // Validate the Sum field. + if x.Sum != x.I + x.J { + return nil, errors.New("CustomPropsExample has inconsistent sum") + } + // Save I and J as usual. The code below is equivalent to calling + // "return datastore.SaveStruct(x)", but is done manually for + // demonstration purposes. + return []datastore.Property{ + { + Name: "I", + Value: int64(x.I), + }, + { + Name: "J", + Value: int64(x.J), + }, + }, nil + } + +The *PropertyList type implements PropertyLoadSaver, and can therefore hold an +arbitrary entity's contents. + + +Queries + +Queries retrieve entities based on their properties or key's ancestry. Running +a query yields an iterator of results: either keys or (key, entity) pairs. +Queries are re-usable and it is safe to call Query.Run from concurrent +goroutines. Iterators are not safe for concurrent use. + +Queries are immutable, and are either created by calling NewQuery, or derived +from an existing query by calling a method like Filter or Order that returns a +new query value. A query is typically constructed by calling NewQuery followed +by a chain of zero or more such methods. These methods are: + - Ancestor and Filter constrain the entities returned by running a query. + - Order affects the order in which they are returned. + - Project constrains the fields returned. + - Distinct de-duplicates projected entities. + - KeysOnly makes the iterator return only keys, not (key, entity) pairs. + - Start, End, Offset and Limit define which sub-sequence of matching entities + to return. Start and End take cursors, Offset and Limit take integers. Start + and Offset affect the first result, End and Limit affect the last result. + If both Start and Offset are set, then the offset is relative to Start. + If both End and Limit are set, then the earliest constraint wins. Limit is + relative to Start+Offset, not relative to End. As a special case, a + negative limit means unlimited. + +Example code: + + type Widget struct { + Description string + Price int + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + q := datastore.NewQuery("Widget"). + Filter("Price <", 1000). + Order("-Price") + b := new(bytes.Buffer) + for t := q.Run(ctx); ; { + var x Widget + key, err := t.Next(&x) + if err == datastore.Done { + break + } + if err != nil { + serveError(ctx, w, err) + return + } + fmt.Fprintf(b, "Key=%v\nWidget=%#v\n\n", key, x) + } + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + io.Copy(w, b) + } + + +Transactions + +RunInTransaction runs a function in a transaction. + +Example code: + + type Counter struct { + Count int + } + + func inc(ctx context.Context, key *datastore.Key) (int, error) { + var x Counter + if err := datastore.Get(ctx, key, &x); err != nil && err != datastore.ErrNoSuchEntity { + return 0, err + } + x.Count++ + if _, err := datastore.Put(ctx, key, &x); err != nil { + return 0, err + } + return x.Count, nil + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + var count int + err := datastore.RunInTransaction(ctx, func(ctx context.Context) error { + var err1 error + count, err1 = inc(ctx, datastore.NewKey(ctx, "Counter", "singleton", 0, nil)) + return err1 + }, nil) + if err != nil { + serveError(ctx, w, err) + return + } + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + fmt.Fprintf(w, "Count=%d", count) + } + + +Metadata + +The datastore package provides access to some of App Engine's datastore +metadata. This metadata includes information about the entity groups, +namespaces, entity kinds, and properties in the datastore, as well as the +property representations for each property. + +Example code: + + func handle(w http.ResponseWriter, r *http.Request) { + // Print all the kinds in the datastore, with all the indexed + // properties (and their representations) for each. + ctx := appengine.NewContext(r) + + kinds, err := datastore.Kinds(ctx) + if err != nil { + serveError(ctx, w, err) + return + } + + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + for _, kind := range kinds { + fmt.Fprintf(w, "%s:\n", kind) + props, err := datastore.KindProperties(ctx, kind) + if err != nil { + fmt.Fprintln(w, "\t(unable to retrieve properties)") + continue + } + for p, rep := range props { + fmt.Fprintf(w, "\t-%s (%s)\n", p, strings.Join(rep, ", ")) + } + } + } +*/ +package datastore // import "google.golang.org/appengine/datastore" diff --git a/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go b/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go new file mode 100644 index 00000000000..643d4049c6b --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go @@ -0,0 +1,120 @@ +// Copyright 2019 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// Package cloudpb is a subset of types and functions, copied from cloud.google.com/go/datastore. +// +// They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package. +package cloudkey + +import ( + "encoding/base64" + "errors" + "strings" + + "github.com/golang/protobuf/proto" + cloudpb "google.golang.org/appengine/datastore/internal/cloudpb" +) + +///////////////////////////////////////////////////////////////////// +// Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/datastore.go +///////////////////////////////////////////////////////////////////// + +var ( + // ErrInvalidKey is returned when an invalid key is presented. + ErrInvalidKey = errors.New("datastore: invalid key") +) + +///////////////////////////////////////////////////////////////////// +// Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/key.go +///////////////////////////////////////////////////////////////////// + +// Key represents the datastore key for a stored entity. +type Key struct { + // Kind cannot be empty. + Kind string + // Either ID or Name must be zero for the Key to be valid. + // If both are zero, the Key is incomplete. + ID int64 + Name string + // Parent must either be a complete Key or nil. + Parent *Key + + // Namespace provides the ability to partition your data for multiple + // tenants. In most cases, it is not necessary to specify a namespace. + // See docs on datastore multitenancy for details: + // https://cloud.google.com/datastore/docs/concepts/multitenancy + Namespace string +} + +// DecodeKey decodes a key from the opaque representation returned by Encode. +func DecodeKey(encoded string) (*Key, error) { + // Re-add padding. + if m := len(encoded) % 4; m != 0 { + encoded += strings.Repeat("=", 4-m) + } + + b, err := base64.URLEncoding.DecodeString(encoded) + if err != nil { + return nil, err + } + + pKey := new(cloudpb.Key) + if err := proto.Unmarshal(b, pKey); err != nil { + return nil, err + } + return protoToKey(pKey) +} + +// valid returns whether the key is valid. +func (k *Key) valid() bool { + if k == nil { + return false + } + for ; k != nil; k = k.Parent { + if k.Kind == "" { + return false + } + if k.Name != "" && k.ID != 0 { + return false + } + if k.Parent != nil { + if k.Parent.Incomplete() { + return false + } + if k.Parent.Namespace != k.Namespace { + return false + } + } + } + return true +} + +// Incomplete reports whether the key does not refer to a stored entity. +func (k *Key) Incomplete() bool { + return k.Name == "" && k.ID == 0 +} + +// protoToKey decodes a protocol buffer representation of a key into an +// equivalent *Key object. If the key is invalid, protoToKey will return the +// invalid key along with ErrInvalidKey. +func protoToKey(p *cloudpb.Key) (*Key, error) { + var key *Key + var namespace string + if partition := p.PartitionId; partition != nil { + namespace = partition.NamespaceId + } + for _, el := range p.Path { + key = &Key{ + Namespace: namespace, + Kind: el.Kind, + ID: el.GetId(), + Name: el.GetName(), + Parent: key, + } + } + if !key.valid() { // Also detects key == nil. + return key, ErrInvalidKey + } + return key, nil +} diff --git a/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go b/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go new file mode 100644 index 00000000000..af8195f3f8d --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go @@ -0,0 +1,344 @@ +// Copyright 2019 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// Package cloudpb is a subset of protobufs, copied from google.golang.org/genproto/googleapis/datastore/v1. +// +// They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package. +package cloudpb + +import ( + "fmt" + + "github.com/golang/protobuf/proto" +) + +// A partition ID identifies a grouping of entities. The grouping is always +// by project and namespace, however the namespace ID may be empty. +// +// A partition ID contains several dimensions: +// project ID and namespace ID. +// +// Partition dimensions: +// +// - May be `""`. +// - Must be valid UTF-8 bytes. +// - Must have values that match regex `[A-Za-z\d\.\-_]{1,100}` +// If the value of any dimension matches regex `__.*__`, the partition is +// reserved/read-only. +// A reserved/read-only partition ID is forbidden in certain documented +// contexts. +// +// Foreign partition IDs (in which the project ID does +// not match the context project ID ) are discouraged. +// Reads and writes of foreign partition IDs may fail if the project is not in +// an active state. +type PartitionId struct { + // The ID of the project to which the entities belong. + ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + // If not empty, the ID of the namespace to which the entities belong. + NamespaceId string `protobuf:"bytes,4,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PartitionId) Reset() { *m = PartitionId{} } +func (m *PartitionId) String() string { return proto.CompactTextString(m) } +func (*PartitionId) ProtoMessage() {} +func (*PartitionId) Descriptor() ([]byte, []int) { + return fileDescriptor_entity_096a297364b049a5, []int{0} +} +func (m *PartitionId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PartitionId.Unmarshal(m, b) +} +func (m *PartitionId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PartitionId.Marshal(b, m, deterministic) +} +func (dst *PartitionId) XXX_Merge(src proto.Message) { + xxx_messageInfo_PartitionId.Merge(dst, src) +} +func (m *PartitionId) XXX_Size() int { + return xxx_messageInfo_PartitionId.Size(m) +} +func (m *PartitionId) XXX_DiscardUnknown() { + xxx_messageInfo_PartitionId.DiscardUnknown(m) +} + +var xxx_messageInfo_PartitionId proto.InternalMessageInfo + +func (m *PartitionId) GetProjectId() string { + if m != nil { + return m.ProjectId + } + return "" +} + +func (m *PartitionId) GetNamespaceId() string { + if m != nil { + return m.NamespaceId + } + return "" +} + +// A unique identifier for an entity. +// If a key's partition ID or any of its path kinds or names are +// reserved/read-only, the key is reserved/read-only. +// A reserved/read-only key is forbidden in certain documented contexts. +type Key struct { + // Entities are partitioned into subsets, currently identified by a project + // ID and namespace ID. + // Queries are scoped to a single partition. + PartitionId *PartitionId `protobuf:"bytes,1,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"` + // The entity path. + // An entity path consists of one or more elements composed of a kind and a + // string or numerical identifier, which identify entities. The first + // element identifies a _root entity_, the second element identifies + // a _child_ of the root entity, the third element identifies a child of the + // second entity, and so forth. The entities identified by all prefixes of + // the path are called the element's _ancestors_. + // + // An entity path is always fully complete: *all* of the entity's ancestors + // are required to be in the path along with the entity identifier itself. + // The only exception is that in some documented cases, the identifier in the + // last path element (for the entity) itself may be omitted. For example, + // the last path element of the key of `Mutation.insert` may have no + // identifier. + // + // A path can never be empty, and a path can have at most 100 elements. + Path []*Key_PathElement `protobuf:"bytes,2,rep,name=path,proto3" json:"path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Key) Reset() { *m = Key{} } +func (m *Key) String() string { return proto.CompactTextString(m) } +func (*Key) ProtoMessage() {} +func (*Key) Descriptor() ([]byte, []int) { + return fileDescriptor_entity_096a297364b049a5, []int{1} +} +func (m *Key) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Key.Unmarshal(m, b) +} +func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Key.Marshal(b, m, deterministic) +} +func (dst *Key) XXX_Merge(src proto.Message) { + xxx_messageInfo_Key.Merge(dst, src) +} +func (m *Key) XXX_Size() int { + return xxx_messageInfo_Key.Size(m) +} +func (m *Key) XXX_DiscardUnknown() { + xxx_messageInfo_Key.DiscardUnknown(m) +} + +// A (kind, ID/name) pair used to construct a key path. +// +// If either name or ID is set, the element is complete. +// If neither is set, the element is incomplete. +type Key_PathElement struct { + // The kind of the entity. + // A kind matching regex `__.*__` is reserved/read-only. + // A kind must not contain more than 1500 bytes when UTF-8 encoded. + // Cannot be `""`. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // The type of ID. + // + // Types that are valid to be assigned to IdType: + // *Key_PathElement_Id + // *Key_PathElement_Name + IdType isKey_PathElement_IdType `protobuf_oneof:"id_type"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Key_PathElement) Reset() { *m = Key_PathElement{} } +func (m *Key_PathElement) String() string { return proto.CompactTextString(m) } +func (*Key_PathElement) ProtoMessage() {} +func (*Key_PathElement) Descriptor() ([]byte, []int) { + return fileDescriptor_entity_096a297364b049a5, []int{1, 0} +} +func (m *Key_PathElement) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Key_PathElement.Unmarshal(m, b) +} +func (m *Key_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Key_PathElement.Marshal(b, m, deterministic) +} +func (dst *Key_PathElement) XXX_Merge(src proto.Message) { + xxx_messageInfo_Key_PathElement.Merge(dst, src) +} +func (m *Key_PathElement) XXX_Size() int { + return xxx_messageInfo_Key_PathElement.Size(m) +} +func (m *Key_PathElement) XXX_DiscardUnknown() { + xxx_messageInfo_Key_PathElement.DiscardUnknown(m) +} + +var xxx_messageInfo_Key_PathElement proto.InternalMessageInfo + +func (m *Key_PathElement) GetKind() string { + if m != nil { + return m.Kind + } + return "" +} + +type isKey_PathElement_IdType interface { + isKey_PathElement_IdType() +} + +type Key_PathElement_Id struct { + Id int64 `protobuf:"varint,2,opt,name=id,proto3,oneof"` +} + +type Key_PathElement_Name struct { + Name string `protobuf:"bytes,3,opt,name=name,proto3,oneof"` +} + +func (*Key_PathElement_Id) isKey_PathElement_IdType() {} + +func (*Key_PathElement_Name) isKey_PathElement_IdType() {} + +func (m *Key_PathElement) GetIdType() isKey_PathElement_IdType { + if m != nil { + return m.IdType + } + return nil +} + +func (m *Key_PathElement) GetId() int64 { + if x, ok := m.GetIdType().(*Key_PathElement_Id); ok { + return x.Id + } + return 0 +} + +func (m *Key_PathElement) GetName() string { + if x, ok := m.GetIdType().(*Key_PathElement_Name); ok { + return x.Name + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Key_PathElement) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Key_PathElement_OneofMarshaler, _Key_PathElement_OneofUnmarshaler, _Key_PathElement_OneofSizer, []interface{}{ + (*Key_PathElement_Id)(nil), + (*Key_PathElement_Name)(nil), + } +} + +func _Key_PathElement_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Key_PathElement) + // id_type + switch x := m.IdType.(type) { + case *Key_PathElement_Id: + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Id)) + case *Key_PathElement_Name: + b.EncodeVarint(3<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Name) + case nil: + default: + return fmt.Errorf("Key_PathElement.IdType has unexpected type %T", x) + } + return nil +} + +func _Key_PathElement_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Key_PathElement) + switch tag { + case 2: // id_type.id + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.IdType = &Key_PathElement_Id{int64(x)} + return true, err + case 3: // id_type.name + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.IdType = &Key_PathElement_Name{x} + return true, err + default: + return false, nil + } +} + +func _Key_PathElement_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Key_PathElement) + // id_type + switch x := m.IdType.(type) { + case *Key_PathElement_Id: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(x.Id)) + case *Key_PathElement_Name: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Name))) + n += len(x.Name) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +var fileDescriptor_entity_096a297364b049a5 = []byte{ + // 780 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xff, 0x6e, 0xdc, 0x44, + 0x10, 0xc7, 0xed, 0xbb, 0x5c, 0x1a, 0x8f, 0xdd, 0xa4, 0x6c, 0x2a, 0x61, 0x02, 0x28, 0x26, 0x80, + 0x74, 0x02, 0xc9, 0x6e, 0xc2, 0x1f, 0x54, 0x14, 0xa4, 0x72, 0x25, 0xe0, 0x28, 0x15, 0x9c, 0x56, + 0x55, 0x24, 0x50, 0xa4, 0xd3, 0xde, 0x79, 0xeb, 0x2e, 0x67, 0xef, 0x5a, 0xf6, 0x3a, 0xaa, 0xdf, + 0x05, 0xf1, 0x00, 0x3c, 0x0a, 0x8f, 0x80, 0x78, 0x18, 0xb4, 0x3f, 0xec, 0x0b, 0xed, 0x35, 0xff, + 0x79, 0x67, 0x3e, 0xdf, 0xd9, 0xef, 0xec, 0xce, 0x1a, 0xa2, 0x5c, 0x88, 0xbc, 0xa0, 0x49, 0x46, + 0x24, 0x69, 0xa4, 0xa8, 0x69, 0x72, 0x73, 0x9a, 0x50, 0x2e, 0x99, 0xec, 0xe2, 0xaa, 0x16, 0x52, + 0xa0, 0x43, 0x43, 0xc4, 0x03, 0x11, 0xdf, 0x9c, 0x1e, 0x7d, 0x64, 0x65, 0xa4, 0x62, 0x09, 0xe1, + 0x5c, 0x48, 0x22, 0x99, 0xe0, 0x8d, 0x91, 0x0c, 0x59, 0xbd, 0x5a, 0xb6, 0x2f, 0x93, 0x46, 0xd6, + 0xed, 0x4a, 0xda, 0xec, 0xf1, 0x9b, 0x59, 0xc9, 0x4a, 0xda, 0x48, 0x52, 0x56, 0x16, 0x08, 0x2d, + 0x20, 0xbb, 0x8a, 0x26, 0x05, 0x91, 0x05, 0xcf, 0x4d, 0xe6, 0xe4, 0x17, 0xf0, 0xe7, 0xa4, 0x96, + 0x4c, 0x6d, 0x76, 0x91, 0xa1, 0x8f, 0x01, 0xaa, 0x5a, 0xfc, 0x4e, 0x57, 0x72, 0xc1, 0xb2, 0x70, + 0x14, 0xb9, 0x53, 0x0f, 0x7b, 0x36, 0x72, 0x91, 0xa1, 0x4f, 0x20, 0xe0, 0xa4, 0xa4, 0x4d, 0x45, + 0x56, 0x54, 0x01, 0x3b, 0x1a, 0xf0, 0x87, 0xd8, 0x45, 0x76, 0xf2, 0x8f, 0x0b, 0xe3, 0x4b, 0xda, + 0xa1, 0x67, 0x10, 0x54, 0x7d, 0x61, 0x85, 0xba, 0x91, 0x3b, 0xf5, 0xcf, 0xa2, 0x78, 0x4b, 0xef, + 0xf1, 0x2d, 0x07, 0xd8, 0xaf, 0x6e, 0xd9, 0x79, 0x0c, 0x3b, 0x15, 0x91, 0xaf, 0xc2, 0x51, 0x34, + 0x9e, 0xfa, 0x67, 0x9f, 0x6d, 0x15, 0x5f, 0xd2, 0x2e, 0x9e, 0x13, 0xf9, 0xea, 0xbc, 0xa0, 0x25, + 0xe5, 0x12, 0x6b, 0xc5, 0xd1, 0x0b, 0xd5, 0xd7, 0x10, 0x44, 0x08, 0x76, 0xd6, 0x8c, 0x1b, 0x17, + 0x1e, 0xd6, 0xdf, 0xe8, 0x01, 0x8c, 0x6c, 0x8f, 0xe3, 0xd4, 0xc1, 0x23, 0x96, 0xa1, 0x87, 0xb0, + 0xa3, 0x5a, 0x09, 0xc7, 0x8a, 0x4a, 0x1d, 0xac, 0x57, 0x33, 0x0f, 0xee, 0xb1, 0x6c, 0xa1, 0x8e, + 0xee, 0xe4, 0x29, 0xc0, 0xf7, 0x75, 0x4d, 0xba, 0x2b, 0x52, 0xb4, 0x14, 0x9d, 0xc1, 0xee, 0x8d, + 0xfa, 0x68, 0x42, 0x57, 0xfb, 0x3b, 0xda, 0xea, 0x4f, 0xb3, 0xd8, 0x92, 0x27, 0x7f, 0x4c, 0x60, + 0x62, 0xd4, 0x4f, 0x00, 0x78, 0x5b, 0x14, 0x0b, 0x9d, 0x08, 0xfd, 0xc8, 0x9d, 0xee, 0x6f, 0x2a, + 0xf4, 0x37, 0x19, 0xff, 0xdc, 0x16, 0x85, 0xe6, 0x53, 0x07, 0x7b, 0xbc, 0x5f, 0xa0, 0xcf, 0xe1, + 0xfe, 0x52, 0x88, 0x82, 0x12, 0x6e, 0xf5, 0xaa, 0xb1, 0xbd, 0xd4, 0xc1, 0x81, 0x0d, 0x0f, 0x18, + 0xe3, 0x92, 0xe6, 0xb4, 0xb6, 0x58, 0xdf, 0x6d, 0x60, 0xc3, 0x06, 0xfb, 0x14, 0x82, 0x4c, 0xb4, + 0xcb, 0x82, 0x5a, 0x4a, 0xf5, 0xef, 0xa6, 0x0e, 0xf6, 0x4d, 0xd4, 0x40, 0xe7, 0x70, 0x30, 0x8c, + 0x95, 0xe5, 0x40, 0xdf, 0xe9, 0xdb, 0xa6, 0x5f, 0xf4, 0x5c, 0xea, 0xe0, 0xfd, 0x41, 0x64, 0xca, + 0x7c, 0x0d, 0xde, 0x9a, 0x76, 0xb6, 0xc0, 0x44, 0x17, 0x08, 0xdf, 0x75, 0xaf, 0xa9, 0x83, 0xf7, + 0xd6, 0xb4, 0x1b, 0x4c, 0x36, 0xb2, 0x66, 0x3c, 0xb7, 0xda, 0xf7, 0xec, 0x25, 0xf9, 0x26, 0x6a, + 0xa0, 0x63, 0x80, 0x65, 0x21, 0x96, 0x16, 0x41, 0x91, 0x3b, 0x0d, 0xd4, 0xc1, 0xa9, 0x98, 0x01, + 0xbe, 0x83, 0x83, 0x9c, 0x8a, 0x45, 0x25, 0x18, 0x97, 0x96, 0xda, 0xd3, 0x26, 0x0e, 0x7b, 0x13, + 0xea, 0xa2, 0xe3, 0xe7, 0x44, 0x3e, 0xe7, 0x79, 0xea, 0xe0, 0xfb, 0x39, 0x15, 0x73, 0x05, 0x1b, + 0xf9, 0x53, 0x08, 0xcc, 0x53, 0xb6, 0xda, 0x5d, 0xad, 0xfd, 0x70, 0x6b, 0x03, 0xe7, 0x1a, 0x54, + 0x0e, 0x8d, 0xc4, 0x54, 0x98, 0x81, 0x4f, 0xd4, 0x08, 0xd9, 0x02, 0x9e, 0x2e, 0x70, 0xbc, 0xb5, + 0xc0, 0x66, 0xd4, 0x52, 0x07, 0x03, 0xd9, 0x0c, 0x5e, 0x08, 0xf7, 0x4a, 0x4a, 0x38, 0xe3, 0x79, + 0xb8, 0x1f, 0xb9, 0xd3, 0x09, 0xee, 0x97, 0xe8, 0x11, 0x3c, 0xa4, 0xaf, 0x57, 0x45, 0x9b, 0xd1, + 0xc5, 0xcb, 0x5a, 0x94, 0x0b, 0xc6, 0x33, 0xfa, 0x9a, 0x36, 0xe1, 0xa1, 0x1a, 0x0f, 0x8c, 0x6c, + 0xee, 0xc7, 0x5a, 0x94, 0x17, 0x26, 0x33, 0x0b, 0x00, 0xb4, 0x13, 0x33, 0xe0, 0xff, 0xba, 0xb0, + 0x6b, 0x7c, 0xa3, 0x2f, 0x60, 0xbc, 0xa6, 0x9d, 0x7d, 0xb7, 0xef, 0xbc, 0x22, 0xac, 0x20, 0x74, + 0xa9, 0x7f, 0x1b, 0x15, 0xad, 0x25, 0xa3, 0x4d, 0x38, 0xd6, 0xaf, 0xe1, 0xcb, 0x3b, 0x0e, 0x25, + 0x9e, 0x0f, 0xf4, 0x39, 0x97, 0x75, 0x87, 0x6f, 0xc9, 0x8f, 0x7e, 0x85, 0x83, 0x37, 0xd2, 0xe8, + 0xc1, 0xc6, 0x8b, 0x67, 0x76, 0x7c, 0x04, 0x93, 0xcd, 0x44, 0xdf, 0xfd, 0xf4, 0x0c, 0xf8, 0xcd, + 0xe8, 0xb1, 0x3b, 0xfb, 0xd3, 0x85, 0xf7, 0x57, 0xa2, 0xdc, 0x06, 0xcf, 0x7c, 0x63, 0x6d, 0xae, + 0x86, 0x78, 0xee, 0xfe, 0xf6, 0xad, 0x65, 0x72, 0x51, 0x10, 0x9e, 0xc7, 0xa2, 0xce, 0x93, 0x9c, + 0x72, 0x3d, 0xe2, 0x89, 0x49, 0x91, 0x8a, 0x35, 0xff, 0xfb, 0xcb, 0x3f, 0x19, 0x16, 0x7f, 0x8d, + 0x3e, 0xf8, 0xc9, 0xc8, 0x9f, 0x15, 0xa2, 0xcd, 0xe2, 0x1f, 0x86, 0x8d, 0xae, 0x4e, 0xff, 0xee, + 0x73, 0xd7, 0x3a, 0x77, 0x3d, 0xe4, 0xae, 0xaf, 0x4e, 0x97, 0xbb, 0x7a, 0x83, 0xaf, 0xfe, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xf3, 0xdd, 0x11, 0x96, 0x45, 0x06, 0x00, 0x00, +} + +var xxx_messageInfo_Key proto.InternalMessageInfo diff --git a/vendor/google.golang.org/appengine/datastore/key.go b/vendor/google.golang.org/appengine/datastore/key.go new file mode 100644 index 00000000000..fd598dc9657 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/key.go @@ -0,0 +1,400 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "bytes" + "encoding/base64" + "encoding/gob" + "errors" + "fmt" + "strconv" + "strings" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +type KeyRangeCollisionError struct { + start int64 + end int64 +} + +func (e *KeyRangeCollisionError) Error() string { + return fmt.Sprintf("datastore: Collision when attempting to allocate range [%d, %d]", + e.start, e.end) +} + +type KeyRangeContentionError struct { + start int64 + end int64 +} + +func (e *KeyRangeContentionError) Error() string { + return fmt.Sprintf("datastore: Contention when attempting to allocate range [%d, %d]", + e.start, e.end) +} + +// Key represents the datastore key for a stored entity, and is immutable. +type Key struct { + kind string + stringID string + intID int64 + parent *Key + appID string + namespace string +} + +// Kind returns the key's kind (also known as entity type). +func (k *Key) Kind() string { + return k.kind +} + +// StringID returns the key's string ID (also known as an entity name or key +// name), which may be "". +func (k *Key) StringID() string { + return k.stringID +} + +// IntID returns the key's integer ID, which may be 0. +func (k *Key) IntID() int64 { + return k.intID +} + +// Parent returns the key's parent key, which may be nil. +func (k *Key) Parent() *Key { + return k.parent +} + +// AppID returns the key's application ID. +func (k *Key) AppID() string { + return k.appID +} + +// Namespace returns the key's namespace. +func (k *Key) Namespace() string { + return k.namespace +} + +// Incomplete returns whether the key does not refer to a stored entity. +// In particular, whether the key has a zero StringID and a zero IntID. +func (k *Key) Incomplete() bool { + return k.stringID == "" && k.intID == 0 +} + +// valid returns whether the key is valid. +func (k *Key) valid() bool { + if k == nil { + return false + } + for ; k != nil; k = k.parent { + if k.kind == "" || k.appID == "" { + return false + } + if k.stringID != "" && k.intID != 0 { + return false + } + if k.parent != nil { + if k.parent.Incomplete() { + return false + } + if k.parent.appID != k.appID || k.parent.namespace != k.namespace { + return false + } + } + } + return true +} + +// Equal returns whether two keys are equal. +func (k *Key) Equal(o *Key) bool { + for k != nil && o != nil { + if k.kind != o.kind || k.stringID != o.stringID || k.intID != o.intID || k.appID != o.appID || k.namespace != o.namespace { + return false + } + k, o = k.parent, o.parent + } + return k == o +} + +// root returns the furthest ancestor of a key, which may be itself. +func (k *Key) root() *Key { + for k.parent != nil { + k = k.parent + } + return k +} + +// marshal marshals the key's string representation to the buffer. +func (k *Key) marshal(b *bytes.Buffer) { + if k.parent != nil { + k.parent.marshal(b) + } + b.WriteByte('/') + b.WriteString(k.kind) + b.WriteByte(',') + if k.stringID != "" { + b.WriteString(k.stringID) + } else { + b.WriteString(strconv.FormatInt(k.intID, 10)) + } +} + +// String returns a string representation of the key. +func (k *Key) String() string { + if k == nil { + return "" + } + b := bytes.NewBuffer(make([]byte, 0, 512)) + k.marshal(b) + return b.String() +} + +type gobKey struct { + Kind string + StringID string + IntID int64 + Parent *gobKey + AppID string + Namespace string +} + +func keyToGobKey(k *Key) *gobKey { + if k == nil { + return nil + } + return &gobKey{ + Kind: k.kind, + StringID: k.stringID, + IntID: k.intID, + Parent: keyToGobKey(k.parent), + AppID: k.appID, + Namespace: k.namespace, + } +} + +func gobKeyToKey(gk *gobKey) *Key { + if gk == nil { + return nil + } + return &Key{ + kind: gk.Kind, + stringID: gk.StringID, + intID: gk.IntID, + parent: gobKeyToKey(gk.Parent), + appID: gk.AppID, + namespace: gk.Namespace, + } +} + +func (k *Key) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + if err := gob.NewEncoder(buf).Encode(keyToGobKey(k)); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (k *Key) GobDecode(buf []byte) error { + gk := new(gobKey) + if err := gob.NewDecoder(bytes.NewBuffer(buf)).Decode(gk); err != nil { + return err + } + *k = *gobKeyToKey(gk) + return nil +} + +func (k *Key) MarshalJSON() ([]byte, error) { + return []byte(`"` + k.Encode() + `"`), nil +} + +func (k *Key) UnmarshalJSON(buf []byte) error { + if len(buf) < 2 || buf[0] != '"' || buf[len(buf)-1] != '"' { + return errors.New("datastore: bad JSON key") + } + k2, err := DecodeKey(string(buf[1 : len(buf)-1])) + if err != nil { + return err + } + *k = *k2 + return nil +} + +// Encode returns an opaque representation of the key +// suitable for use in HTML and URLs. +// This is compatible with the Python and Java runtimes. +func (k *Key) Encode() string { + ref := keyToProto("", k) + + b, err := proto.Marshal(ref) + if err != nil { + panic(err) + } + + // Trailing padding is stripped. + return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") +} + +// DecodeKey decodes a key from the opaque representation returned by Encode. +func DecodeKey(encoded string) (*Key, error) { + // Re-add padding. + if m := len(encoded) % 4; m != 0 { + encoded += strings.Repeat("=", 4-m) + } + + b, err := base64.URLEncoding.DecodeString(encoded) + if err != nil { + return nil, err + } + + ref := new(pb.Reference) + if err := proto.Unmarshal(b, ref); err != nil { + // Couldn't decode it as an App Engine key, try decoding it as a key encoded by cloud.google.com/go/datastore. + if k := decodeCloudKey(encoded); k != nil { + return k, nil + } + return nil, err + } + + return protoToKey(ref) +} + +// NewIncompleteKey creates a new incomplete key. +// kind cannot be empty. +func NewIncompleteKey(c context.Context, kind string, parent *Key) *Key { + return NewKey(c, kind, "", 0, parent) +} + +// NewKey creates a new key. +// kind cannot be empty. +// Either one or both of stringID and intID must be zero. If both are zero, +// the key returned is incomplete. +// parent must either be a complete key or nil. +func NewKey(c context.Context, kind, stringID string, intID int64, parent *Key) *Key { + // If there's a parent key, use its namespace. + // Otherwise, use any namespace attached to the context. + var namespace string + if parent != nil { + namespace = parent.namespace + } else { + namespace = internal.NamespaceFromContext(c) + } + + return &Key{ + kind: kind, + stringID: stringID, + intID: intID, + parent: parent, + appID: internal.FullyQualifiedAppID(c), + namespace: namespace, + } +} + +// AllocateIDs returns a range of n integer IDs with the given kind and parent +// combination. kind cannot be empty; parent may be nil. The IDs in the range +// returned will not be used by the datastore's automatic ID sequence generator +// and may be used with NewKey without conflict. +// +// The range is inclusive at the low end and exclusive at the high end. In +// other words, valid intIDs x satisfy low <= x && x < high. +// +// If no error is returned, low + n == high. +func AllocateIDs(c context.Context, kind string, parent *Key, n int) (low, high int64, err error) { + if kind == "" { + return 0, 0, errors.New("datastore: AllocateIDs given an empty kind") + } + if n < 0 { + return 0, 0, fmt.Errorf("datastore: AllocateIDs given a negative count: %d", n) + } + if n == 0 { + return 0, 0, nil + } + req := &pb.AllocateIdsRequest{ + ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)), + Size: proto.Int64(int64(n)), + } + res := &pb.AllocateIdsResponse{} + if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil { + return 0, 0, err + } + // The protobuf is inclusive at both ends. Idiomatic Go (e.g. slices, for loops) + // is inclusive at the low end and exclusive at the high end, so we add 1. + low = res.GetStart() + high = res.GetEnd() + 1 + if low+int64(n) != high { + return 0, 0, fmt.Errorf("datastore: internal error: could not allocate %d IDs", n) + } + return low, high, nil +} + +// AllocateIDRange allocates a range of IDs with specific endpoints. +// The range is inclusive at both the low and high end. Once these IDs have been +// allocated, you can manually assign them to newly created entities. +// +// The Datastore's automatic ID allocator never assigns a key that has already +// been allocated (either through automatic ID allocation or through an explicit +// AllocateIDs call). As a result, entities written to the given key range will +// never be overwritten. However, writing entities with manually assigned keys in +// this range may overwrite existing entities (or new entities written by a separate +// request), depending on the error returned. +// +// Use this only if you have an existing numeric ID range that you want to reserve +// (for example, bulk loading entities that already have IDs). If you don't care +// about which IDs you receive, use AllocateIDs instead. +// +// AllocateIDRange returns nil if the range is successfully allocated. If one or more +// entities with an ID in the given range already exist, it returns a KeyRangeCollisionError. +// If the Datastore has already cached IDs in this range (e.g. from a previous call to +// AllocateIDRange), it returns a KeyRangeContentionError. Errors of other types indicate +// problems with arguments or an error returned directly from the Datastore. +func AllocateIDRange(c context.Context, kind string, parent *Key, start, end int64) (err error) { + if kind == "" { + return errors.New("datastore: AllocateIDRange given an empty kind") + } + + if start < 1 || end < 1 { + return errors.New("datastore: AllocateIDRange start and end must both be greater than 0") + } + + if start > end { + return errors.New("datastore: AllocateIDRange start must be before end") + } + + req := &pb.AllocateIdsRequest{ + ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)), + Max: proto.Int64(end), + } + res := &pb.AllocateIdsResponse{} + if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil { + return err + } + + // Check for collisions, i.e. existing entities with IDs in this range. + // We could do this before the allocation, but we'd still have to do it + // afterward as well to catch the race condition where an entity is inserted + // after that initial check but before the allocation. Skip the up-front check + // and just do it once. + q := NewQuery(kind).Filter("__key__ >=", NewKey(c, kind, "", start, parent)). + Filter("__key__ <=", NewKey(c, kind, "", end, parent)).KeysOnly().Limit(1) + + keys, err := q.GetAll(c, nil) + if err != nil { + return err + } + if len(keys) != 0 { + return &KeyRangeCollisionError{start: start, end: end} + } + + // Check for a race condition, i.e. cases where the datastore may have + // cached ID batches that contain IDs in this range. + if start < res.GetStart() { + return &KeyRangeContentionError{start: start, end: end} + } + + return nil +} diff --git a/vendor/google.golang.org/appengine/datastore/keycompat.go b/vendor/google.golang.org/appengine/datastore/keycompat.go new file mode 100644 index 00000000000..371a64eeefe --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/keycompat.go @@ -0,0 +1,89 @@ +// Copyright 2019 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "sync" + + "golang.org/x/net/context" + + "google.golang.org/appengine/datastore/internal/cloudkey" + "google.golang.org/appengine/internal" +) + +var keyConversion struct { + mu sync.RWMutex + appID string // read using getKeyConversionAppID +} + +// EnableKeyConversion enables encoded key compatibility with the Cloud +// Datastore client library (cloud.google.com/go/datastore). Encoded keys +// generated by the Cloud Datastore client library will be decoded into App +// Engine datastore keys. +// +// The context provided must be an App Engine context if running in App Engine +// first generation runtime. This can be called in the /_ah/start handler. It is +// safe to call multiple times, and is cheap to call, so can also be inserted as +// middleware. +// +// Enabling key compatibility does not affect the encoding format used by +// Key.Encode, it only expands the type of keys that are able to be decoded with +// DecodeKey. +func EnableKeyConversion(ctx context.Context) { + // Only attempt to set appID if it's unset. + // If already set, ignore. + if getKeyConversionAppID() != "" { + return + } + + keyConversion.mu.Lock() + // Check again to avoid race where another goroutine set appID between the call + // to getKeyConversionAppID above and taking the write lock. + if keyConversion.appID == "" { + keyConversion.appID = internal.FullyQualifiedAppID(ctx) + } + keyConversion.mu.Unlock() +} + +func getKeyConversionAppID() string { + keyConversion.mu.RLock() + appID := keyConversion.appID + keyConversion.mu.RUnlock() + return appID +} + +// decodeCloudKey attempts to decode the given encoded key generated by the +// Cloud Datastore client library (cloud.google.com/go/datastore), returning nil +// if the key couldn't be decoded. +func decodeCloudKey(encoded string) *Key { + appID := getKeyConversionAppID() + if appID == "" { + return nil + } + + k, err := cloudkey.DecodeKey(encoded) + if err != nil { + return nil + } + return convertCloudKey(k, appID) +} + +// convertCloudKey converts a Cloud Datastore key and converts it to an App +// Engine Datastore key. Cloud Datastore keys don't include the project/app ID, +// so we must add it back in. +func convertCloudKey(key *cloudkey.Key, appID string) *Key { + if key == nil { + return nil + } + k := &Key{ + intID: key.ID, + kind: key.Kind, + namespace: key.Namespace, + parent: convertCloudKey(key.Parent, appID), + stringID: key.Name, + appID: appID, + } + return k +} diff --git a/vendor/google.golang.org/appengine/datastore/load.go b/vendor/google.golang.org/appengine/datastore/load.go new file mode 100644 index 00000000000..38a63653979 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/load.go @@ -0,0 +1,429 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "fmt" + "reflect" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/appengine" + pb "google.golang.org/appengine/internal/datastore" +) + +var ( + typeOfBlobKey = reflect.TypeOf(appengine.BlobKey("")) + typeOfByteSlice = reflect.TypeOf([]byte(nil)) + typeOfByteString = reflect.TypeOf(ByteString(nil)) + typeOfGeoPoint = reflect.TypeOf(appengine.GeoPoint{}) + typeOfTime = reflect.TypeOf(time.Time{}) + typeOfKeyPtr = reflect.TypeOf(&Key{}) + typeOfEntityPtr = reflect.TypeOf(&Entity{}) +) + +// typeMismatchReason returns a string explaining why the property p could not +// be stored in an entity field of type v.Type(). +func typeMismatchReason(pValue interface{}, v reflect.Value) string { + entityType := "empty" + switch pValue.(type) { + case int64: + entityType = "int" + case bool: + entityType = "bool" + case string: + entityType = "string" + case float64: + entityType = "float" + case *Key: + entityType = "*datastore.Key" + case time.Time: + entityType = "time.Time" + case appengine.BlobKey: + entityType = "appengine.BlobKey" + case appengine.GeoPoint: + entityType = "appengine.GeoPoint" + case ByteString: + entityType = "datastore.ByteString" + case []byte: + entityType = "[]byte" + } + return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type()) +} + +type propertyLoader struct { + // m holds the number of times a substruct field like "Foo.Bar.Baz" has + // been seen so far. The map is constructed lazily. + m map[string]int +} + +func (l *propertyLoader) load(codec *structCodec, structValue reflect.Value, p Property, requireSlice bool) string { + var v reflect.Value + var sliceIndex int + + name := p.Name + + // If name ends with a '.', the last field is anonymous. + // In this case, strings.Split will give us "" as the + // last element of our fields slice, which will match the "" + // field name in the substruct codec. + fields := strings.Split(name, ".") + + for len(fields) > 0 { + var decoder fieldCodec + var ok bool + + // Cut off the last field (delimited by ".") and find its parent + // in the codec. + // eg. for name "A.B.C.D", split off "A.B.C" and try to + // find a field in the codec with this name. + // Loop again with "A.B", etc. + for i := len(fields); i > 0; i-- { + parent := strings.Join(fields[:i], ".") + decoder, ok = codec.fields[parent] + if ok { + fields = fields[i:] + break + } + } + + // If we never found a matching field in the codec, return + // error message. + if !ok { + return "no such struct field" + } + + v = initField(structValue, decoder.path) + if !v.IsValid() { + return "no such struct field" + } + if !v.CanSet() { + return "cannot set struct field" + } + + if decoder.structCodec != nil { + codec = decoder.structCodec + structValue = v + } + + if v.Kind() == reflect.Slice && v.Type() != typeOfByteSlice { + if l.m == nil { + l.m = make(map[string]int) + } + sliceIndex = l.m[p.Name] + l.m[p.Name] = sliceIndex + 1 + for v.Len() <= sliceIndex { + v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem())) + } + structValue = v.Index(sliceIndex) + requireSlice = false + } + } + + var slice reflect.Value + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + slice = v + v = reflect.New(v.Type().Elem()).Elem() + } else if requireSlice { + return "multiple-valued property requires a slice field type" + } + + // Convert indexValues to a Go value with a meaning derived from the + // destination type. + pValue := p.Value + if iv, ok := pValue.(indexValue); ok { + meaning := pb.Property_NO_MEANING + switch v.Type() { + case typeOfBlobKey: + meaning = pb.Property_BLOBKEY + case typeOfByteSlice: + meaning = pb.Property_BLOB + case typeOfByteString: + meaning = pb.Property_BYTESTRING + case typeOfGeoPoint: + meaning = pb.Property_GEORSS_POINT + case typeOfTime: + meaning = pb.Property_GD_WHEN + case typeOfEntityPtr: + meaning = pb.Property_ENTITY_PROTO + } + var err error + pValue, err = propValue(iv.value, meaning) + if err != nil { + return err.Error() + } + } + + if errReason := setVal(v, pValue); errReason != "" { + // Set the slice back to its zero value. + if slice.IsValid() { + slice.Set(reflect.Zero(slice.Type())) + } + return errReason + } + + if slice.IsValid() { + slice.Index(sliceIndex).Set(v) + } + + return "" +} + +// setVal sets v to the value pValue. +func setVal(v reflect.Value, pValue interface{}) string { + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + x, ok := pValue.(int64) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.OverflowInt(x) { + return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) + } + v.SetInt(x) + case reflect.Bool: + x, ok := pValue.(bool) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.SetBool(x) + case reflect.String: + switch x := pValue.(type) { + case appengine.BlobKey: + v.SetString(string(x)) + case ByteString: + v.SetString(string(x)) + case string: + v.SetString(x) + default: + if pValue != nil { + return typeMismatchReason(pValue, v) + } + } + case reflect.Float32, reflect.Float64: + x, ok := pValue.(float64) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.OverflowFloat(x) { + return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) + } + v.SetFloat(x) + case reflect.Ptr: + x, ok := pValue.(*Key) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if _, ok := v.Interface().(*Key); !ok { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + case reflect.Struct: + switch v.Type() { + case typeOfTime: + x, ok := pValue.(time.Time) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + case typeOfGeoPoint: + x, ok := pValue.(appengine.GeoPoint) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + default: + ent, ok := pValue.(*Entity) + if !ok { + return typeMismatchReason(pValue, v) + } + + // Recursively load nested struct + pls, err := newStructPLS(v.Addr().Interface()) + if err != nil { + return err.Error() + } + + // if ent has a Key value and our struct has a Key field, + // load the Entity's Key value into the Key field on the struct. + if ent.Key != nil && pls.codec.keyField != -1 { + + pls.v.Field(pls.codec.keyField).Set(reflect.ValueOf(ent.Key)) + } + + err = pls.Load(ent.Properties) + if err != nil { + return err.Error() + } + } + case reflect.Slice: + x, ok := pValue.([]byte) + if !ok { + if y, yok := pValue.(ByteString); yok { + x, ok = []byte(y), true + } + } + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.Type().Elem().Kind() != reflect.Uint8 { + return typeMismatchReason(pValue, v) + } + v.SetBytes(x) + default: + return typeMismatchReason(pValue, v) + } + return "" +} + +// initField is similar to reflect's Value.FieldByIndex, in that it +// returns the nested struct field corresponding to index, but it +// initialises any nil pointers encountered when traversing the structure. +func initField(val reflect.Value, index []int) reflect.Value { + for _, i := range index[:len(index)-1] { + val = val.Field(i) + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + } + return val.Field(index[len(index)-1]) +} + +// loadEntity loads an EntityProto into PropertyLoadSaver or struct pointer. +func loadEntity(dst interface{}, src *pb.EntityProto) (err error) { + ent, err := protoToEntity(src) + if err != nil { + return err + } + if e, ok := dst.(PropertyLoadSaver); ok { + return e.Load(ent.Properties) + } + return LoadStruct(dst, ent.Properties) +} + +func (s structPLS) Load(props []Property) error { + var fieldName, reason string + var l propertyLoader + for _, p := range props { + if errStr := l.load(s.codec, s.v, p, p.Multiple); errStr != "" { + // We don't return early, as we try to load as many properties as possible. + // It is valid to load an entity into a struct that cannot fully represent it. + // That case returns an error, but the caller is free to ignore it. + fieldName, reason = p.Name, errStr + } + } + if reason != "" { + return &ErrFieldMismatch{ + StructType: s.v.Type(), + FieldName: fieldName, + Reason: reason, + } + } + return nil +} + +func protoToEntity(src *pb.EntityProto) (*Entity, error) { + props, rawProps := src.Property, src.RawProperty + outProps := make([]Property, 0, len(props)+len(rawProps)) + for { + var ( + x *pb.Property + noIndex bool + ) + if len(props) > 0 { + x, props = props[0], props[1:] + } else if len(rawProps) > 0 { + x, rawProps = rawProps[0], rawProps[1:] + noIndex = true + } else { + break + } + + var value interface{} + if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE { + value = indexValue{x.Value} + } else { + var err error + value, err = propValue(x.Value, x.GetMeaning()) + if err != nil { + return nil, err + } + } + outProps = append(outProps, Property{ + Name: x.GetName(), + Value: value, + NoIndex: noIndex, + Multiple: x.GetMultiple(), + }) + } + + var key *Key + if src.Key != nil { + // Ignore any error, since nested entity values + // are allowed to have an invalid key. + key, _ = protoToKey(src.Key) + } + return &Entity{key, outProps}, nil +} + +// propValue returns a Go value that combines the raw PropertyValue with a +// meaning. For example, an Int64Value with GD_WHEN becomes a time.Time. +func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) { + switch { + case v.Int64Value != nil: + if m == pb.Property_GD_WHEN { + return fromUnixMicro(*v.Int64Value), nil + } else { + return *v.Int64Value, nil + } + case v.BooleanValue != nil: + return *v.BooleanValue, nil + case v.StringValue != nil: + if m == pb.Property_BLOB { + return []byte(*v.StringValue), nil + } else if m == pb.Property_BLOBKEY { + return appengine.BlobKey(*v.StringValue), nil + } else if m == pb.Property_BYTESTRING { + return ByteString(*v.StringValue), nil + } else if m == pb.Property_ENTITY_PROTO { + var ent pb.EntityProto + err := proto.Unmarshal([]byte(*v.StringValue), &ent) + if err != nil { + return nil, err + } + return protoToEntity(&ent) + } else { + return *v.StringValue, nil + } + case v.DoubleValue != nil: + return *v.DoubleValue, nil + case v.Referencevalue != nil: + key, err := referenceValueToKey(v.Referencevalue) + if err != nil { + return nil, err + } + return key, nil + case v.Pointvalue != nil: + // NOTE: Strangely, latitude maps to X, longitude to Y. + return appengine.GeoPoint{Lat: v.Pointvalue.GetX(), Lng: v.Pointvalue.GetY()}, nil + } + return nil, nil +} + +// indexValue is a Property value that is created when entities are loaded from +// an index, such as from a projection query. +// +// Such Property values do not contain all of the metadata required to be +// faithfully represented as a Go value, and are instead represented as an +// opaque indexValue. Load the properties into a concrete struct type (e.g. by +// passing a struct pointer to Iterator.Next) to reconstruct actual Go values +// of type int, string, time.Time, etc. +type indexValue struct { + value *pb.PropertyValue +} diff --git a/vendor/google.golang.org/appengine/datastore/metadata.go b/vendor/google.golang.org/appengine/datastore/metadata.go new file mode 100644 index 00000000000..6acacc3db9a --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/metadata.go @@ -0,0 +1,78 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import "golang.org/x/net/context" + +// Datastore kinds for the metadata entities. +const ( + namespaceKind = "__namespace__" + kindKind = "__kind__" + propertyKind = "__property__" +) + +// Namespaces returns all the datastore namespaces. +func Namespaces(ctx context.Context) ([]string, error) { + // TODO(djd): Support range queries. + q := NewQuery(namespaceKind).KeysOnly() + keys, err := q.GetAll(ctx, nil) + if err != nil { + return nil, err + } + // The empty namespace key uses a numeric ID (==1), but luckily + // the string ID defaults to "" for numeric IDs anyway. + return keyNames(keys), nil +} + +// Kinds returns the names of all the kinds in the current namespace. +func Kinds(ctx context.Context) ([]string, error) { + // TODO(djd): Support range queries. + q := NewQuery(kindKind).KeysOnly() + keys, err := q.GetAll(ctx, nil) + if err != nil { + return nil, err + } + return keyNames(keys), nil +} + +// keyNames returns a slice of the provided keys' names (string IDs). +func keyNames(keys []*Key) []string { + n := make([]string, 0, len(keys)) + for _, k := range keys { + n = append(n, k.StringID()) + } + return n +} + +// KindProperties returns all the indexed properties for the given kind. +// The properties are returned as a map of property names to a slice of the +// representation types. The representation types for the supported Go property +// types are: +// "INT64": signed integers and time.Time +// "DOUBLE": float32 and float64 +// "BOOLEAN": bool +// "STRING": string, []byte and ByteString +// "POINT": appengine.GeoPoint +// "REFERENCE": *Key +// "USER": (not used in the Go runtime) +func KindProperties(ctx context.Context, kind string) (map[string][]string, error) { + // TODO(djd): Support range queries. + kindKey := NewKey(ctx, kindKind, kind, 0, nil) + q := NewQuery(propertyKind).Ancestor(kindKey) + + propMap := map[string][]string{} + props := []struct { + Repr []string `datastore:"property_representation"` + }{} + + keys, err := q.GetAll(ctx, &props) + if err != nil { + return nil, err + } + for i, p := range props { + propMap[keys[i].StringID()] = p.Repr + } + return propMap, nil +} diff --git a/vendor/google.golang.org/appengine/datastore/prop.go b/vendor/google.golang.org/appengine/datastore/prop.go new file mode 100644 index 00000000000..5cb2079d887 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/prop.go @@ -0,0 +1,330 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "fmt" + "reflect" + "strings" + "sync" + "unicode" +) + +// Entities with more than this many indexed properties will not be saved. +const maxIndexedProperties = 20000 + +// []byte fields more than 1 megabyte long will not be loaded or saved. +const maxBlobLen = 1 << 20 + +// Property is a name/value pair plus some metadata. A datastore entity's +// contents are loaded and saved as a sequence of Properties. An entity can +// have multiple Properties with the same name, provided that p.Multiple is +// true on all of that entity's Properties with that name. +type Property struct { + // Name is the property name. + Name string + // Value is the property value. The valid types are: + // - int64 + // - bool + // - string + // - float64 + // - ByteString + // - *Key + // - time.Time + // - appengine.BlobKey + // - appengine.GeoPoint + // - []byte (up to 1 megabyte in length) + // - *Entity (representing a nested struct) + // This set is smaller than the set of valid struct field types that the + // datastore can load and save. A Property Value cannot be a slice (apart + // from []byte); use multiple Properties instead. Also, a Value's type + // must be explicitly on the list above; it is not sufficient for the + // underlying type to be on that list. For example, a Value of "type + // myInt64 int64" is invalid. Smaller-width integers and floats are also + // invalid. Again, this is more restrictive than the set of valid struct + // field types. + // + // A Value will have an opaque type when loading entities from an index, + // such as via a projection query. Load entities into a struct instead + // of a PropertyLoadSaver when using a projection query. + // + // A Value may also be the nil interface value; this is equivalent to + // Python's None but not directly representable by a Go struct. Loading + // a nil-valued property into a struct will set that field to the zero + // value. + Value interface{} + // NoIndex is whether the datastore cannot index this property. + NoIndex bool + // Multiple is whether the entity can have multiple properties with + // the same name. Even if a particular instance only has one property with + // a certain name, Multiple should be true if a struct would best represent + // it as a field of type []T instead of type T. + Multiple bool +} + +// An Entity is the value type for a nested struct. +// This type is only used for a Property's Value. +type Entity struct { + Key *Key + Properties []Property +} + +// ByteString is a short byte slice (up to 1500 bytes) that can be indexed. +type ByteString []byte + +// PropertyLoadSaver can be converted from and to a slice of Properties. +type PropertyLoadSaver interface { + Load([]Property) error + Save() ([]Property, error) +} + +// PropertyList converts a []Property to implement PropertyLoadSaver. +type PropertyList []Property + +var ( + typeOfPropertyLoadSaver = reflect.TypeOf((*PropertyLoadSaver)(nil)).Elem() + typeOfPropertyList = reflect.TypeOf(PropertyList(nil)) +) + +// Load loads all of the provided properties into l. +// It does not first reset *l to an empty slice. +func (l *PropertyList) Load(p []Property) error { + *l = append(*l, p...) + return nil +} + +// Save saves all of l's properties as a slice or Properties. +func (l *PropertyList) Save() ([]Property, error) { + return *l, nil +} + +// validPropertyName returns whether name consists of one or more valid Go +// identifiers joined by ".". +func validPropertyName(name string) bool { + if name == "" { + return false + } + for _, s := range strings.Split(name, ".") { + if s == "" { + return false + } + first := true + for _, c := range s { + if first { + first = false + if c != '_' && !unicode.IsLetter(c) { + return false + } + } else { + if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) { + return false + } + } + } + } + return true +} + +// structCodec describes how to convert a struct to and from a sequence of +// properties. +type structCodec struct { + // fields gives the field codec for the structTag with the given name. + fields map[string]fieldCodec + // hasSlice is whether a struct or any of its nested or embedded structs + // has a slice-typed field (other than []byte). + hasSlice bool + // keyField is the index of a *Key field with structTag __key__. + // This field is not relevant for the top level struct, only for + // nested structs. + keyField int + // complete is whether the structCodec is complete. An incomplete + // structCodec may be encountered when walking a recursive struct. + complete bool +} + +// fieldCodec is a struct field's index and, if that struct field's type is +// itself a struct, that substruct's structCodec. +type fieldCodec struct { + // path is the index path to the field + path []int + noIndex bool + // omitEmpty indicates that the field should be omitted on save + // if empty. + omitEmpty bool + // structCodec is the codec fot the struct field at index 'path', + // or nil if the field is not a struct. + structCodec *structCodec +} + +// structCodecs collects the structCodecs that have already been calculated. +var ( + structCodecsMutex sync.Mutex + structCodecs = make(map[reflect.Type]*structCodec) +) + +// getStructCodec returns the structCodec for the given struct type. +func getStructCodec(t reflect.Type) (*structCodec, error) { + structCodecsMutex.Lock() + defer structCodecsMutex.Unlock() + return getStructCodecLocked(t) +} + +// getStructCodecLocked implements getStructCodec. The structCodecsMutex must +// be held when calling this function. +func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) { + c, ok := structCodecs[t] + if ok { + return c, nil + } + c = &structCodec{ + fields: make(map[string]fieldCodec), + // We initialize keyField to -1 so that the zero-value is not + // misinterpreted as index 0. + keyField: -1, + } + + // Add c to the structCodecs map before we are sure it is good. If t is + // a recursive type, it needs to find the incomplete entry for itself in + // the map. + structCodecs[t] = c + defer func() { + if retErr != nil { + delete(structCodecs, t) + } + }() + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + // Skip unexported fields. + // Note that if f is an anonymous, unexported struct field, + // we will promote its fields. + if f.PkgPath != "" && !f.Anonymous { + continue + } + + tags := strings.Split(f.Tag.Get("datastore"), ",") + name := tags[0] + opts := make(map[string]bool) + for _, t := range tags[1:] { + opts[t] = true + } + switch { + case name == "": + if !f.Anonymous { + name = f.Name + } + case name == "-": + continue + case name == "__key__": + if f.Type != typeOfKeyPtr { + return nil, fmt.Errorf("datastore: __key__ field on struct %v is not a *datastore.Key", t) + } + c.keyField = i + case !validPropertyName(name): + return nil, fmt.Errorf("datastore: struct tag has invalid property name: %q", name) + } + + substructType, fIsSlice := reflect.Type(nil), false + switch f.Type.Kind() { + case reflect.Struct: + substructType = f.Type + case reflect.Slice: + if f.Type.Elem().Kind() == reflect.Struct { + substructType = f.Type.Elem() + } + fIsSlice = f.Type != typeOfByteSlice + c.hasSlice = c.hasSlice || fIsSlice + } + + var sub *structCodec + if substructType != nil && substructType != typeOfTime && substructType != typeOfGeoPoint { + var err error + sub, err = getStructCodecLocked(substructType) + if err != nil { + return nil, err + } + if !sub.complete { + return nil, fmt.Errorf("datastore: recursive struct: field %q", f.Name) + } + if fIsSlice && sub.hasSlice { + return nil, fmt.Errorf( + "datastore: flattening nested structs leads to a slice of slices: field %q", f.Name) + } + c.hasSlice = c.hasSlice || sub.hasSlice + // If f is an anonymous struct field, we promote the substruct's fields up to this level + // in the linked list of struct codecs. + if f.Anonymous { + for subname, subfield := range sub.fields { + if name != "" { + subname = name + "." + subname + } + if _, ok := c.fields[subname]; ok { + return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", subname) + } + c.fields[subname] = fieldCodec{ + path: append([]int{i}, subfield.path...), + noIndex: subfield.noIndex || opts["noindex"], + omitEmpty: subfield.omitEmpty, + structCodec: subfield.structCodec, + } + } + continue + } + } + + if _, ok := c.fields[name]; ok { + return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", name) + } + c.fields[name] = fieldCodec{ + path: []int{i}, + noIndex: opts["noindex"], + omitEmpty: opts["omitempty"], + structCodec: sub, + } + } + c.complete = true + return c, nil +} + +// structPLS adapts a struct to be a PropertyLoadSaver. +type structPLS struct { + v reflect.Value + codec *structCodec +} + +// newStructPLS returns a structPLS, which implements the +// PropertyLoadSaver interface, for the struct pointer p. +func newStructPLS(p interface{}) (*structPLS, error) { + v := reflect.ValueOf(p) + if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { + return nil, ErrInvalidEntityType + } + v = v.Elem() + codec, err := getStructCodec(v.Type()) + if err != nil { + return nil, err + } + return &structPLS{v, codec}, nil +} + +// LoadStruct loads the properties from p to dst. +// dst must be a struct pointer. +func LoadStruct(dst interface{}, p []Property) error { + x, err := newStructPLS(dst) + if err != nil { + return err + } + return x.Load(p) +} + +// SaveStruct returns the properties from src as a slice of Properties. +// src must be a struct pointer. +func SaveStruct(src interface{}) ([]Property, error) { + x, err := newStructPLS(src) + if err != nil { + return nil, err + } + return x.Save() +} diff --git a/vendor/google.golang.org/appengine/datastore/query.go b/vendor/google.golang.org/appengine/datastore/query.go new file mode 100644 index 00000000000..4124534b22f --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/query.go @@ -0,0 +1,774 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "encoding/base64" + "errors" + "fmt" + "math" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +type operator int + +const ( + lessThan operator = iota + lessEq + equal + greaterEq + greaterThan +) + +var operatorToProto = map[operator]*pb.Query_Filter_Operator{ + lessThan: pb.Query_Filter_LESS_THAN.Enum(), + lessEq: pb.Query_Filter_LESS_THAN_OR_EQUAL.Enum(), + equal: pb.Query_Filter_EQUAL.Enum(), + greaterEq: pb.Query_Filter_GREATER_THAN_OR_EQUAL.Enum(), + greaterThan: pb.Query_Filter_GREATER_THAN.Enum(), +} + +// filter is a conditional filter on query results. +type filter struct { + FieldName string + Op operator + Value interface{} +} + +type sortDirection int + +const ( + ascending sortDirection = iota + descending +) + +var sortDirectionToProto = map[sortDirection]*pb.Query_Order_Direction{ + ascending: pb.Query_Order_ASCENDING.Enum(), + descending: pb.Query_Order_DESCENDING.Enum(), +} + +// order is a sort order on query results. +type order struct { + FieldName string + Direction sortDirection +} + +// NewQuery creates a new Query for a specific entity kind. +// +// An empty kind means to return all entities, including entities created and +// managed by other App Engine features, and is called a kindless query. +// Kindless queries cannot include filters or sort orders on property values. +func NewQuery(kind string) *Query { + return &Query{ + kind: kind, + limit: -1, + } +} + +// Query represents a datastore query. +type Query struct { + kind string + ancestor *Key + filter []filter + order []order + projection []string + + distinct bool + distinctOn []string + keysOnly bool + eventual bool + limit int32 + offset int32 + count int32 + start *pb.CompiledCursor + end *pb.CompiledCursor + + err error +} + +func (q *Query) clone() *Query { + x := *q + // Copy the contents of the slice-typed fields to a new backing store. + if len(q.filter) > 0 { + x.filter = make([]filter, len(q.filter)) + copy(x.filter, q.filter) + } + if len(q.order) > 0 { + x.order = make([]order, len(q.order)) + copy(x.order, q.order) + } + return &x +} + +// Ancestor returns a derivative query with an ancestor filter. +// The ancestor should not be nil. +func (q *Query) Ancestor(ancestor *Key) *Query { + q = q.clone() + if ancestor == nil { + q.err = errors.New("datastore: nil query ancestor") + return q + } + q.ancestor = ancestor + return q +} + +// EventualConsistency returns a derivative query that returns eventually +// consistent results. +// It only has an effect on ancestor queries. +func (q *Query) EventualConsistency() *Query { + q = q.clone() + q.eventual = true + return q +} + +// Filter returns a derivative query with a field-based filter. +// The filterStr argument must be a field name followed by optional space, +// followed by an operator, one of ">", "<", ">=", "<=", or "=". +// Fields are compared against the provided value using the operator. +// Multiple filters are AND'ed together. +func (q *Query) Filter(filterStr string, value interface{}) *Query { + q = q.clone() + filterStr = strings.TrimSpace(filterStr) + if len(filterStr) < 1 { + q.err = errors.New("datastore: invalid filter: " + filterStr) + return q + } + f := filter{ + FieldName: strings.TrimRight(filterStr, " ><=!"), + Value: value, + } + switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op { + case "<=": + f.Op = lessEq + case ">=": + f.Op = greaterEq + case "<": + f.Op = lessThan + case ">": + f.Op = greaterThan + case "=": + f.Op = equal + default: + q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr) + return q + } + q.filter = append(q.filter, f) + return q +} + +// Order returns a derivative query with a field-based sort order. Orders are +// applied in the order they are added. The default order is ascending; to sort +// in descending order prefix the fieldName with a minus sign (-). +func (q *Query) Order(fieldName string) *Query { + q = q.clone() + fieldName = strings.TrimSpace(fieldName) + o := order{ + Direction: ascending, + FieldName: fieldName, + } + if strings.HasPrefix(fieldName, "-") { + o.Direction = descending + o.FieldName = strings.TrimSpace(fieldName[1:]) + } else if strings.HasPrefix(fieldName, "+") { + q.err = fmt.Errorf("datastore: invalid order: %q", fieldName) + return q + } + if len(o.FieldName) == 0 { + q.err = errors.New("datastore: empty order") + return q + } + q.order = append(q.order, o) + return q +} + +// Project returns a derivative query that yields only the given fields. It +// cannot be used with KeysOnly. +func (q *Query) Project(fieldNames ...string) *Query { + q = q.clone() + q.projection = append([]string(nil), fieldNames...) + return q +} + +// Distinct returns a derivative query that yields de-duplicated entities with +// respect to the set of projected fields. It is only used for projection +// queries. Distinct cannot be used with DistinctOn. +func (q *Query) Distinct() *Query { + q = q.clone() + q.distinct = true + return q +} + +// DistinctOn returns a derivative query that yields de-duplicated entities with +// respect to the set of the specified fields. It is only used for projection +// queries. The field list should be a subset of the projected field list. +// DistinctOn cannot be used with Distinct. +func (q *Query) DistinctOn(fieldNames ...string) *Query { + q = q.clone() + q.distinctOn = fieldNames + return q +} + +// KeysOnly returns a derivative query that yields only keys, not keys and +// entities. It cannot be used with projection queries. +func (q *Query) KeysOnly() *Query { + q = q.clone() + q.keysOnly = true + return q +} + +// Limit returns a derivative query that has a limit on the number of results +// returned. A negative value means unlimited. +func (q *Query) Limit(limit int) *Query { + q = q.clone() + if limit < math.MinInt32 || limit > math.MaxInt32 { + q.err = errors.New("datastore: query limit overflow") + return q + } + q.limit = int32(limit) + return q +} + +// Offset returns a derivative query that has an offset of how many keys to +// skip over before returning results. A negative value is invalid. +func (q *Query) Offset(offset int) *Query { + q = q.clone() + if offset < 0 { + q.err = errors.New("datastore: negative query offset") + return q + } + if offset > math.MaxInt32 { + q.err = errors.New("datastore: query offset overflow") + return q + } + q.offset = int32(offset) + return q +} + +// BatchSize returns a derivative query to fetch the supplied number of results +// at once. This value should be greater than zero, and equal to or less than +// the Limit. +func (q *Query) BatchSize(size int) *Query { + q = q.clone() + if size <= 0 || size > math.MaxInt32 { + q.err = errors.New("datastore: query batch size overflow") + return q + } + q.count = int32(size) + return q +} + +// Start returns a derivative query with the given start point. +func (q *Query) Start(c Cursor) *Query { + q = q.clone() + if c.cc == nil { + q.err = errors.New("datastore: invalid cursor") + return q + } + q.start = c.cc + return q +} + +// End returns a derivative query with the given end point. +func (q *Query) End(c Cursor) *Query { + q = q.clone() + if c.cc == nil { + q.err = errors.New("datastore: invalid cursor") + return q + } + q.end = c.cc + return q +} + +// toProto converts the query to a protocol buffer. +func (q *Query) toProto(dst *pb.Query, appID string) error { + if len(q.projection) != 0 && q.keysOnly { + return errors.New("datastore: query cannot both project and be keys-only") + } + if len(q.distinctOn) != 0 && q.distinct { + return errors.New("datastore: query cannot be both distinct and distinct-on") + } + dst.Reset() + dst.App = proto.String(appID) + if q.kind != "" { + dst.Kind = proto.String(q.kind) + } + if q.ancestor != nil { + dst.Ancestor = keyToProto(appID, q.ancestor) + if q.eventual { + dst.Strong = proto.Bool(false) + } + } + if q.projection != nil { + dst.PropertyName = q.projection + if len(q.distinctOn) != 0 { + dst.GroupByPropertyName = q.distinctOn + } + if q.distinct { + dst.GroupByPropertyName = q.projection + } + } + if q.keysOnly { + dst.KeysOnly = proto.Bool(true) + dst.RequirePerfectPlan = proto.Bool(true) + } + for _, qf := range q.filter { + if qf.FieldName == "" { + return errors.New("datastore: empty query filter field name") + } + p, errStr := valueToProto(appID, qf.FieldName, reflect.ValueOf(qf.Value), false) + if errStr != "" { + return errors.New("datastore: bad query filter value type: " + errStr) + } + xf := &pb.Query_Filter{ + Op: operatorToProto[qf.Op], + Property: []*pb.Property{p}, + } + if xf.Op == nil { + return errors.New("datastore: unknown query filter operator") + } + dst.Filter = append(dst.Filter, xf) + } + for _, qo := range q.order { + if qo.FieldName == "" { + return errors.New("datastore: empty query order field name") + } + xo := &pb.Query_Order{ + Property: proto.String(qo.FieldName), + Direction: sortDirectionToProto[qo.Direction], + } + if xo.Direction == nil { + return errors.New("datastore: unknown query order direction") + } + dst.Order = append(dst.Order, xo) + } + if q.limit >= 0 { + dst.Limit = proto.Int32(q.limit) + } + if q.offset != 0 { + dst.Offset = proto.Int32(q.offset) + } + if q.count != 0 { + dst.Count = proto.Int32(q.count) + } + dst.CompiledCursor = q.start + dst.EndCompiledCursor = q.end + dst.Compile = proto.Bool(true) + return nil +} + +// Count returns the number of results for the query. +// +// The running time and number of API calls made by Count scale linearly with +// the sum of the query's offset and limit. Unless the result count is +// expected to be small, it is best to specify a limit; otherwise Count will +// continue until it finishes counting or the provided context expires. +func (q *Query) Count(c context.Context) (int, error) { + // Check that the query is well-formed. + if q.err != nil { + return 0, q.err + } + + // Run a copy of the query, with keysOnly true (if we're not a projection, + // since the two are incompatible), and an adjusted offset. We also set the + // limit to zero, as we don't want any actual entity data, just the number + // of skipped results. + newQ := q.clone() + newQ.keysOnly = len(newQ.projection) == 0 + newQ.limit = 0 + if q.limit < 0 { + // If the original query was unlimited, set the new query's offset to maximum. + newQ.offset = math.MaxInt32 + } else { + newQ.offset = q.offset + q.limit + if newQ.offset < 0 { + // Do the best we can, in the presence of overflow. + newQ.offset = math.MaxInt32 + } + } + req := &pb.Query{} + if err := newQ.toProto(req, internal.FullyQualifiedAppID(c)); err != nil { + return 0, err + } + res := &pb.QueryResult{} + if err := internal.Call(c, "datastore_v3", "RunQuery", req, res); err != nil { + return 0, err + } + + // n is the count we will return. For example, suppose that our original + // query had an offset of 4 and a limit of 2008: the count will be 2008, + // provided that there are at least 2012 matching entities. However, the + // RPCs will only skip 1000 results at a time. The RPC sequence is: + // call RunQuery with (offset, limit) = (2012, 0) // 2012 == newQ.offset + // response has (skippedResults, moreResults) = (1000, true) + // n += 1000 // n == 1000 + // call Next with (offset, limit) = (1012, 0) // 1012 == newQ.offset - n + // response has (skippedResults, moreResults) = (1000, true) + // n += 1000 // n == 2000 + // call Next with (offset, limit) = (12, 0) // 12 == newQ.offset - n + // response has (skippedResults, moreResults) = (12, false) + // n += 12 // n == 2012 + // // exit the loop + // n -= 4 // n == 2008 + var n int32 + for { + // The QueryResult should have no actual entity data, just skipped results. + if len(res.Result) != 0 { + return 0, errors.New("datastore: internal error: Count request returned too much data") + } + n += res.GetSkippedResults() + if !res.GetMoreResults() { + break + } + if err := callNext(c, res, newQ.offset-n, q.count); err != nil { + return 0, err + } + } + n -= q.offset + if n < 0 { + // If the offset was greater than the number of matching entities, + // return 0 instead of negative. + n = 0 + } + return int(n), nil +} + +// callNext issues a datastore_v3/Next RPC to advance a cursor, such as that +// returned by a query with more results. +func callNext(c context.Context, res *pb.QueryResult, offset, count int32) error { + if res.Cursor == nil { + return errors.New("datastore: internal error: server did not return a cursor") + } + req := &pb.NextRequest{ + Cursor: res.Cursor, + } + if count >= 0 { + req.Count = proto.Int32(count) + } + if offset != 0 { + req.Offset = proto.Int32(offset) + } + if res.CompiledCursor != nil { + req.Compile = proto.Bool(true) + } + res.Reset() + return internal.Call(c, "datastore_v3", "Next", req, res) +} + +// GetAll runs the query in the given context and returns all keys that match +// that query, as well as appending the values to dst. +// +// dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non- +// interface, non-pointer type P such that P or *P implements PropertyLoadSaver. +// +// As a special case, *PropertyList is an invalid type for dst, even though a +// PropertyList is a slice of structs. It is treated as invalid to avoid being +// mistakenly passed when *[]PropertyList was intended. +// +// The keys returned by GetAll will be in a 1-1 correspondence with the entities +// added to dst. +// +// If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys. +// +// The running time and number of API calls made by GetAll scale linearly with +// the sum of the query's offset and limit. Unless the result count is +// expected to be small, it is best to specify a limit; otherwise GetAll will +// continue until it finishes collecting results or the provided context +// expires. +func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) { + var ( + dv reflect.Value + mat multiArgType + elemType reflect.Type + errFieldMismatch error + ) + if !q.keysOnly { + dv = reflect.ValueOf(dst) + if dv.Kind() != reflect.Ptr || dv.IsNil() { + return nil, ErrInvalidEntityType + } + dv = dv.Elem() + mat, elemType = checkMultiArg(dv) + if mat == multiArgTypeInvalid || mat == multiArgTypeInterface { + return nil, ErrInvalidEntityType + } + } + + var keys []*Key + for t := q.Run(c); ; { + k, e, err := t.next() + if err == Done { + break + } + if err != nil { + return keys, err + } + if !q.keysOnly { + ev := reflect.New(elemType) + if elemType.Kind() == reflect.Map { + // This is a special case. The zero values of a map type are + // not immediately useful; they have to be make'd. + // + // Funcs and channels are similar, in that a zero value is not useful, + // but even a freshly make'd channel isn't useful: there's no fixed + // channel buffer size that is always going to be large enough, and + // there's no goroutine to drain the other end. Theoretically, these + // types could be supported, for example by sniffing for a constructor + // method or requiring prior registration, but for now it's not a + // frequent enough concern to be worth it. Programmers can work around + // it by explicitly using Iterator.Next instead of the Query.GetAll + // convenience method. + x := reflect.MakeMap(elemType) + ev.Elem().Set(x) + } + if err = loadEntity(ev.Interface(), e); err != nil { + if _, ok := err.(*ErrFieldMismatch); ok { + // We continue loading entities even in the face of field mismatch errors. + // If we encounter any other error, that other error is returned. Otherwise, + // an ErrFieldMismatch is returned. + errFieldMismatch = err + } else { + return keys, err + } + } + if mat != multiArgTypeStructPtr { + ev = ev.Elem() + } + dv.Set(reflect.Append(dv, ev)) + } + keys = append(keys, k) + } + return keys, errFieldMismatch +} + +// Run runs the query in the given context. +func (q *Query) Run(c context.Context) *Iterator { + if q.err != nil { + return &Iterator{err: q.err} + } + t := &Iterator{ + c: c, + limit: q.limit, + count: q.count, + q: q, + prevCC: q.start, + } + var req pb.Query + if err := q.toProto(&req, internal.FullyQualifiedAppID(c)); err != nil { + t.err = err + return t + } + if err := internal.Call(c, "datastore_v3", "RunQuery", &req, &t.res); err != nil { + t.err = err + return t + } + offset := q.offset - t.res.GetSkippedResults() + var count int32 + if t.count > 0 && (t.limit < 0 || t.count < t.limit) { + count = t.count + } else { + count = t.limit + } + for offset > 0 && t.res.GetMoreResults() { + t.prevCC = t.res.CompiledCursor + if err := callNext(t.c, &t.res, offset, count); err != nil { + t.err = err + break + } + skip := t.res.GetSkippedResults() + if skip < 0 { + t.err = errors.New("datastore: internal error: negative number of skipped_results") + break + } + offset -= skip + } + if offset < 0 { + t.err = errors.New("datastore: internal error: query offset was overshot") + } + return t +} + +// Iterator is the result of running a query. +type Iterator struct { + c context.Context + err error + // res is the result of the most recent RunQuery or Next API call. + res pb.QueryResult + // i is how many elements of res.Result we have iterated over. + i int + // limit is the limit on the number of results this iterator should return. + // A negative value means unlimited. + limit int32 + // count is the number of results this iterator should fetch at once. This + // should be equal to or greater than zero. + count int32 + // q is the original query which yielded this iterator. + q *Query + // prevCC is the compiled cursor that marks the end of the previous batch + // of results. + prevCC *pb.CompiledCursor +} + +// Done is returned when a query iteration has completed. +var Done = errors.New("datastore: query has no more results") + +// Next returns the key of the next result. When there are no more results, +// Done is returned as the error. +// +// If the query is not keys only and dst is non-nil, it also loads the entity +// stored for that key into the struct pointer or PropertyLoadSaver dst, with +// the same semantics and possible errors as for the Get function. +func (t *Iterator) Next(dst interface{}) (*Key, error) { + k, e, err := t.next() + if err != nil { + return nil, err + } + if dst != nil && !t.q.keysOnly { + err = loadEntity(dst, e) + } + return k, err +} + +func (t *Iterator) next() (*Key, *pb.EntityProto, error) { + if t.err != nil { + return nil, nil, t.err + } + + // Issue datastore_v3/Next RPCs as necessary. + for t.i == len(t.res.Result) { + if !t.res.GetMoreResults() { + t.err = Done + return nil, nil, t.err + } + t.prevCC = t.res.CompiledCursor + var count int32 + if t.count > 0 && (t.limit < 0 || t.count < t.limit) { + count = t.count + } else { + count = t.limit + } + if err := callNext(t.c, &t.res, 0, count); err != nil { + t.err = err + return nil, nil, t.err + } + if t.res.GetSkippedResults() != 0 { + t.err = errors.New("datastore: internal error: iterator has skipped results") + return nil, nil, t.err + } + t.i = 0 + if t.limit >= 0 { + t.limit -= int32(len(t.res.Result)) + if t.limit < 0 { + t.err = errors.New("datastore: internal error: query returned more results than the limit") + return nil, nil, t.err + } + } + } + + // Extract the key from the t.i'th element of t.res.Result. + e := t.res.Result[t.i] + t.i++ + if e.Key == nil { + return nil, nil, errors.New("datastore: internal error: server did not return a key") + } + k, err := protoToKey(e.Key) + if err != nil || k.Incomplete() { + return nil, nil, errors.New("datastore: internal error: server returned an invalid key") + } + return k, e, nil +} + +// Cursor returns a cursor for the iterator's current location. +func (t *Iterator) Cursor() (Cursor, error) { + if t.err != nil && t.err != Done { + return Cursor{}, t.err + } + // If we are at either end of the current batch of results, + // return the compiled cursor at that end. + skipped := t.res.GetSkippedResults() + if t.i == 0 && skipped == 0 { + if t.prevCC == nil { + // A nil pointer (of type *pb.CompiledCursor) means no constraint: + // passing it as the end cursor of a new query means unlimited results + // (glossing over the integer limit parameter for now). + // A non-nil pointer to an empty pb.CompiledCursor means the start: + // passing it as the end cursor of a new query means 0 results. + // If prevCC was nil, then the original query had no start cursor, but + // Iterator.Cursor should return "the start" instead of unlimited. + return Cursor{&zeroCC}, nil + } + return Cursor{t.prevCC}, nil + } + if t.i == len(t.res.Result) { + return Cursor{t.res.CompiledCursor}, nil + } + // Otherwise, re-run the query offset to this iterator's position, starting from + // the most recent compiled cursor. This is done on a best-effort basis, as it + // is racy; if a concurrent process has added or removed entities, then the + // cursor returned may be inconsistent. + q := t.q.clone() + q.start = t.prevCC + q.offset = skipped + int32(t.i) + q.limit = 0 + q.keysOnly = len(q.projection) == 0 + t1 := q.Run(t.c) + _, _, err := t1.next() + if err != Done { + if err == nil { + err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results") + } + return Cursor{}, err + } + return Cursor{t1.res.CompiledCursor}, nil +} + +var zeroCC pb.CompiledCursor + +// Cursor is an iterator's position. It can be converted to and from an opaque +// string. A cursor can be used from different HTTP requests, but only with a +// query with the same kind, ancestor, filter and order constraints. +type Cursor struct { + cc *pb.CompiledCursor +} + +// String returns a base-64 string representation of a cursor. +func (c Cursor) String() string { + if c.cc == nil { + return "" + } + b, err := proto.Marshal(c.cc) + if err != nil { + // The only way to construct a Cursor with a non-nil cc field is to + // unmarshal from the byte representation. We panic if the unmarshal + // succeeds but the marshaling of the unchanged protobuf value fails. + panic(fmt.Sprintf("datastore: internal error: malformed cursor: %v", err)) + } + return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") +} + +// Decode decodes a cursor from its base-64 string representation. +func DecodeCursor(s string) (Cursor, error) { + if s == "" { + return Cursor{&zeroCC}, nil + } + if n := len(s) % 4; n != 0 { + s += strings.Repeat("=", 4-n) + } + b, err := base64.URLEncoding.DecodeString(s) + if err != nil { + return Cursor{}, err + } + cc := &pb.CompiledCursor{} + if err := proto.Unmarshal(b, cc); err != nil { + return Cursor{}, err + } + return Cursor{cc}, nil +} diff --git a/vendor/google.golang.org/appengine/datastore/save.go b/vendor/google.golang.org/appengine/datastore/save.go new file mode 100644 index 00000000000..7b045a59556 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/save.go @@ -0,0 +1,333 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + "fmt" + "math" + "reflect" + "time" + + "github.com/golang/protobuf/proto" + + "google.golang.org/appengine" + pb "google.golang.org/appengine/internal/datastore" +) + +func toUnixMicro(t time.Time) int64 { + // We cannot use t.UnixNano() / 1e3 because we want to handle times more than + // 2^63 nanoseconds (which is about 292 years) away from 1970, and those cannot + // be represented in the numerator of a single int64 divide. + return t.Unix()*1e6 + int64(t.Nanosecond()/1e3) +} + +func fromUnixMicro(t int64) time.Time { + return time.Unix(t/1e6, (t%1e6)*1e3).UTC() +} + +var ( + minTime = time.Unix(int64(math.MinInt64)/1e6, (int64(math.MinInt64)%1e6)*1e3) + maxTime = time.Unix(int64(math.MaxInt64)/1e6, (int64(math.MaxInt64)%1e6)*1e3) +) + +// valueToProto converts a named value to a newly allocated Property. +// The returned error string is empty on success. +func valueToProto(defaultAppID, name string, v reflect.Value, multiple bool) (p *pb.Property, errStr string) { + var ( + pv pb.PropertyValue + unsupported bool + ) + switch v.Kind() { + case reflect.Invalid: + // No-op. + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + pv.Int64Value = proto.Int64(v.Int()) + case reflect.Bool: + pv.BooleanValue = proto.Bool(v.Bool()) + case reflect.String: + pv.StringValue = proto.String(v.String()) + case reflect.Float32, reflect.Float64: + pv.DoubleValue = proto.Float64(v.Float()) + case reflect.Ptr: + if k, ok := v.Interface().(*Key); ok { + if k != nil { + pv.Referencevalue = keyToReferenceValue(defaultAppID, k) + } + } else { + unsupported = true + } + case reflect.Struct: + switch t := v.Interface().(type) { + case time.Time: + if t.Before(minTime) || t.After(maxTime) { + return nil, "time value out of range" + } + pv.Int64Value = proto.Int64(toUnixMicro(t)) + case appengine.GeoPoint: + if !t.Valid() { + return nil, "invalid GeoPoint value" + } + // NOTE: Strangely, latitude maps to X, longitude to Y. + pv.Pointvalue = &pb.PropertyValue_PointValue{X: &t.Lat, Y: &t.Lng} + default: + unsupported = true + } + case reflect.Slice: + if b, ok := v.Interface().([]byte); ok { + pv.StringValue = proto.String(string(b)) + } else { + // nvToProto should already catch slice values. + // If we get here, we have a slice of slice values. + unsupported = true + } + default: + unsupported = true + } + if unsupported { + return nil, "unsupported datastore value type: " + v.Type().String() + } + p = &pb.Property{ + Name: proto.String(name), + Value: &pv, + Multiple: proto.Bool(multiple), + } + if v.IsValid() { + switch v.Interface().(type) { + case []byte: + p.Meaning = pb.Property_BLOB.Enum() + case ByteString: + p.Meaning = pb.Property_BYTESTRING.Enum() + case appengine.BlobKey: + p.Meaning = pb.Property_BLOBKEY.Enum() + case time.Time: + p.Meaning = pb.Property_GD_WHEN.Enum() + case appengine.GeoPoint: + p.Meaning = pb.Property_GEORSS_POINT.Enum() + } + } + return p, "" +} + +type saveOpts struct { + noIndex bool + multiple bool + omitEmpty bool +} + +// saveEntity saves an EntityProto into a PropertyLoadSaver or struct pointer. +func saveEntity(defaultAppID string, key *Key, src interface{}) (*pb.EntityProto, error) { + var err error + var props []Property + if e, ok := src.(PropertyLoadSaver); ok { + props, err = e.Save() + } else { + props, err = SaveStruct(src) + } + if err != nil { + return nil, err + } + return propertiesToProto(defaultAppID, key, props) +} + +func saveStructProperty(props *[]Property, name string, opts saveOpts, v reflect.Value) error { + if opts.omitEmpty && isEmptyValue(v) { + return nil + } + p := Property{ + Name: name, + NoIndex: opts.noIndex, + Multiple: opts.multiple, + } + switch x := v.Interface().(type) { + case *Key: + p.Value = x + case time.Time: + p.Value = x + case appengine.BlobKey: + p.Value = x + case appengine.GeoPoint: + p.Value = x + case ByteString: + p.Value = x + default: + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p.Value = v.Int() + case reflect.Bool: + p.Value = v.Bool() + case reflect.String: + p.Value = v.String() + case reflect.Float32, reflect.Float64: + p.Value = v.Float() + case reflect.Slice: + if v.Type().Elem().Kind() == reflect.Uint8 { + p.NoIndex = true + p.Value = v.Bytes() + } + case reflect.Struct: + if !v.CanAddr() { + return fmt.Errorf("datastore: unsupported struct field: value is unaddressable") + } + sub, err := newStructPLS(v.Addr().Interface()) + if err != nil { + return fmt.Errorf("datastore: unsupported struct field: %v", err) + } + return sub.save(props, name+".", opts) + } + } + if p.Value == nil { + return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type()) + } + *props = append(*props, p) + return nil +} + +func (s structPLS) Save() ([]Property, error) { + var props []Property + if err := s.save(&props, "", saveOpts{}); err != nil { + return nil, err + } + return props, nil +} + +func (s structPLS) save(props *[]Property, prefix string, opts saveOpts) error { + for name, f := range s.codec.fields { + name = prefix + name + v := s.v.FieldByIndex(f.path) + if !v.IsValid() || !v.CanSet() { + continue + } + var opts1 saveOpts + opts1.noIndex = opts.noIndex || f.noIndex + opts1.multiple = opts.multiple + opts1.omitEmpty = f.omitEmpty // don't propagate + // For slice fields that aren't []byte, save each element. + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + opts1.multiple = true + for j := 0; j < v.Len(); j++ { + if err := saveStructProperty(props, name, opts1, v.Index(j)); err != nil { + return err + } + } + continue + } + // Otherwise, save the field itself. + if err := saveStructProperty(props, name, opts1, v); err != nil { + return err + } + } + return nil +} + +func propertiesToProto(defaultAppID string, key *Key, props []Property) (*pb.EntityProto, error) { + e := &pb.EntityProto{ + Key: keyToProto(defaultAppID, key), + } + if key.parent == nil { + e.EntityGroup = &pb.Path{} + } else { + e.EntityGroup = keyToProto(defaultAppID, key.root()).Path + } + prevMultiple := make(map[string]bool) + + for _, p := range props { + if pm, ok := prevMultiple[p.Name]; ok { + if !pm || !p.Multiple { + return nil, fmt.Errorf("datastore: multiple Properties with Name %q, but Multiple is false", p.Name) + } + } else { + prevMultiple[p.Name] = p.Multiple + } + + x := &pb.Property{ + Name: proto.String(p.Name), + Value: new(pb.PropertyValue), + Multiple: proto.Bool(p.Multiple), + } + switch v := p.Value.(type) { + case int64: + x.Value.Int64Value = proto.Int64(v) + case bool: + x.Value.BooleanValue = proto.Bool(v) + case string: + x.Value.StringValue = proto.String(v) + if p.NoIndex { + x.Meaning = pb.Property_TEXT.Enum() + } + case float64: + x.Value.DoubleValue = proto.Float64(v) + case *Key: + if v != nil { + x.Value.Referencevalue = keyToReferenceValue(defaultAppID, v) + } + case time.Time: + if v.Before(minTime) || v.After(maxTime) { + return nil, fmt.Errorf("datastore: time value out of range") + } + x.Value.Int64Value = proto.Int64(toUnixMicro(v)) + x.Meaning = pb.Property_GD_WHEN.Enum() + case appengine.BlobKey: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BLOBKEY.Enum() + case appengine.GeoPoint: + if !v.Valid() { + return nil, fmt.Errorf("datastore: invalid GeoPoint value") + } + // NOTE: Strangely, latitude maps to X, longitude to Y. + x.Value.Pointvalue = &pb.PropertyValue_PointValue{X: &v.Lat, Y: &v.Lng} + x.Meaning = pb.Property_GEORSS_POINT.Enum() + case []byte: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BLOB.Enum() + if !p.NoIndex { + return nil, fmt.Errorf("datastore: cannot index a []byte valued Property with Name %q", p.Name) + } + case ByteString: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BYTESTRING.Enum() + default: + if p.Value != nil { + return nil, fmt.Errorf("datastore: invalid Value type for a Property with Name %q", p.Name) + } + } + + if p.NoIndex { + e.RawProperty = append(e.RawProperty, x) + } else { + e.Property = append(e.Property, x) + if len(e.Property) > maxIndexedProperties { + return nil, errors.New("datastore: too many indexed properties") + } + } + } + return e, nil +} + +// isEmptyValue is taken from the encoding/json package in the standard library. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + // TODO(perfomance): Only reflect.String needed, other property types are not supported (copy/paste from json package) + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + // TODO(perfomance): Uint* are unsupported property types - should be removed (copy/paste from json package) + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Struct: + switch x := v.Interface().(type) { + case time.Time: + return x.IsZero() + } + } + return false +} diff --git a/vendor/google.golang.org/appengine/datastore/transaction.go b/vendor/google.golang.org/appengine/datastore/transaction.go new file mode 100644 index 00000000000..2ae8428f856 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/transaction.go @@ -0,0 +1,96 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +func init() { + internal.RegisterTransactionSetter(func(x *pb.Query, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.GetRequest, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.PutRequest, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.DeleteRequest, t *pb.Transaction) { + x.Transaction = t + }) +} + +// ErrConcurrentTransaction is returned when a transaction is rolled back due +// to a conflict with a concurrent transaction. +var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction") + +// RunInTransaction runs f in a transaction. It calls f with a transaction +// context tc that f should use for all App Engine operations. +// +// If f returns nil, RunInTransaction attempts to commit the transaction, +// returning nil if it succeeds. If the commit fails due to a conflicting +// transaction, RunInTransaction retries f, each time with a new transaction +// context. It gives up and returns ErrConcurrentTransaction after three +// failed attempts. The number of attempts can be configured by specifying +// TransactionOptions.Attempts. +// +// If f returns non-nil, then any datastore changes will not be applied and +// RunInTransaction returns that same error. The function f is not retried. +// +// Note that when f returns, the transaction is not yet committed. Calling code +// must be careful not to assume that any of f's changes have been committed +// until RunInTransaction returns nil. +// +// Since f may be called multiple times, f should usually be idempotent. +// datastore.Get is not idempotent when unmarshaling slice fields. +// +// Nested transactions are not supported; c may not be a transaction context. +func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error { + xg := false + if opts != nil { + xg = opts.XG + } + readOnly := false + if opts != nil { + readOnly = opts.ReadOnly + } + attempts := 3 + if opts != nil && opts.Attempts > 0 { + attempts = opts.Attempts + } + var t *pb.Transaction + var err error + for i := 0; i < attempts; i++ { + if t, err = internal.RunTransactionOnce(c, f, xg, readOnly, t); err != internal.ErrConcurrentTransaction { + return err + } + } + return ErrConcurrentTransaction +} + +// TransactionOptions are the options for running a transaction. +type TransactionOptions struct { + // XG is whether the transaction can cross multiple entity groups. In + // comparison, a single group transaction is one where all datastore keys + // used have the same root key. Note that cross group transactions do not + // have the same behavior as single group transactions. In particular, it + // is much more likely to see partially applied transactions in different + // entity groups, in global queries. + // It is valid to set XG to true even if the transaction is within a + // single entity group. + XG bool + // Attempts controls the number of retries to perform when commits fail + // due to a conflicting transaction. If omitted, it defaults to 3. + Attempts int + // ReadOnly controls whether the transaction is a read only transaction. + // Read only transactions are potentially more efficient. + ReadOnly bool +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/LICENSE b/vendor/gopkg.in/vmihailenco/msgpack.v2/LICENSE new file mode 100644 index 00000000000..bafc76b689c --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 The msgpack for Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/Makefile b/vendor/gopkg.in/vmihailenco/msgpack.v2/Makefile new file mode 100644 index 00000000000..b62ae6a46e3 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/Makefile @@ -0,0 +1,5 @@ +all: + go test ./... + env GOOS=linux GOARCH=386 go test ./... + go test ./... -short -race + go vet diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/README.md b/vendor/gopkg.in/vmihailenco/msgpack.v2/README.md new file mode 100644 index 00000000000..12985b29d06 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/README.md @@ -0,0 +1,69 @@ +# MessagePack encoding for Golang + +[![Build Status](https://travis-ci.org/vmihailenco/msgpack.svg?branch=v2)](https://travis-ci.org/vmihailenco/msgpack) +[![GoDoc](https://godoc.org/github.com/vmihailenco/msgpack?status.svg)](https://godoc.org/github.com/vmihailenco/msgpack) + +Supports: +- Primitives, arrays, maps, structs, time.Time and interface{}. +- Appengine *datastore.Key and datastore.Cursor. +- [CustomEncoder](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#example-CustomEncoder)/CustomDecoder interfaces for custom encoding. +- [Extensions](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#example-RegisterExt) to encode type information. +- Renaming fields via `msgpack:"my_field_name"`. +- Inlining struct fields via `msgpack:",inline"`. +- Omitting empty fields via `msgpack:",omitempty"`. +- [Map keys sorting](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#Encoder.SortMapKeys). +- Encoding/decoding all [structs as arrays](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#Encoder.StructAsArray) or [individual structs](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#example-Marshal--AsArray). +- Simple but very fast and efficient [queries](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#example-Decoder-Query). + +API docs: https://godoc.org/gopkg.in/vmihailenco/msgpack.v2. +Examples: https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#pkg-examples. + +## Installation + +Install: + +```shell +go get gopkg.in/vmihailenco/msgpack.v2 +``` + +## Quickstart + +```go +func ExampleMarshal() { + type Item struct { + Foo string + } + + b, err := msgpack.Marshal(&Item{Foo: "bar"}) + if err != nil { + panic(err) + } + + var item Item + err = msgpack.Unmarshal(b, &item) + if err != nil { + panic(err) + } + fmt.Println(item.Foo) + // Output: bar +} +``` + +## Benchmark + +``` +BenchmarkStructVmihailencoMsgpack-4 200000 12814 ns/op 2128 B/op 26 allocs/op +BenchmarkStructUgorjiGoMsgpack-4 100000 17678 ns/op 3616 B/op 70 allocs/op +BenchmarkStructUgorjiGoCodec-4 100000 19053 ns/op 7346 B/op 23 allocs/op +BenchmarkStructJSON-4 20000 69438 ns/op 7864 B/op 26 allocs/op +BenchmarkStructGOB-4 10000 104331 ns/op 14664 B/op 278 allocs/op +``` + +## Howto + +Please go through [examples](https://godoc.org/gopkg.in/vmihailenco/msgpack.v2#pkg-examples) to get an idea how to use this package. + +## See also + +- [Golang PostgreSQL ORM](https://github.com/go-pg/pg) +- [Golang message task queue](https://github.com/go-msgqueue/msgqueue) diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/appengine.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/appengine.go new file mode 100644 index 00000000000..43614247fc5 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/appengine.go @@ -0,0 +1,69 @@ +// +build appengine + +package msgpack + +import ( + "reflect" + + ds "google.golang.org/appengine/datastore" +) + +var ( + keyPtrType = reflect.TypeOf((*ds.Key)(nil)) + cursorType = reflect.TypeOf((*ds.Cursor)(nil)).Elem() +) + +func init() { + Register(keyPtrType, encodeDatastoreKeyValue, decodeDatastoreKeyValue) + Register(cursorType, encodeDatastoreCursorValue, decodeDatastoreCursorValue) +} + +func EncodeDatastoreKey(e *Encoder, key *ds.Key) error { + if key == nil { + return e.EncodeNil() + } + return e.EncodeString(key.Encode()) +} + +func encodeDatastoreKeyValue(e *Encoder, v reflect.Value) error { + key := v.Interface().(*ds.Key) + return EncodeDatastoreKey(e, key) +} + +func DecodeDatastoreKey(d *Decoder) (*ds.Key, error) { + v, err := d.DecodeString() + if err != nil { + return nil, err + } + if v == "" { + return nil, nil + } + return ds.DecodeKey(v) +} + +func decodeDatastoreKeyValue(d *Decoder, v reflect.Value) error { + key, err := DecodeDatastoreKey(d) + if err != nil { + return err + } + v.Set(reflect.ValueOf(key)) + return nil +} + +func encodeDatastoreCursorValue(e *Encoder, v reflect.Value) error { + cursor := v.Interface().(ds.Cursor) + return e.Encode(cursor.String()) +} + +func decodeDatastoreCursorValue(d *Decoder, v reflect.Value) error { + s, err := d.DecodeString() + if err != nil { + return err + } + cursor, err := ds.DecodeCursor(s) + if err != nil { + return err + } + v.Set(reflect.ValueOf(cursor)) + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/codes/codes.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/codes/codes.go new file mode 100644 index 00000000000..b2b12074ee0 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/codes/codes.go @@ -0,0 +1,76 @@ +package codes + +var ( + PosFixedNumHigh byte = 0x7f + NegFixedNumLow byte = 0xe0 + + Nil byte = 0xc0 + + False byte = 0xc2 + True byte = 0xc3 + + Float byte = 0xca + Double byte = 0xcb + + Uint8 byte = 0xcc + Uint16 byte = 0xcd + Uint32 byte = 0xce + Uint64 byte = 0xcf + + Int8 byte = 0xd0 + Int16 byte = 0xd1 + Int32 byte = 0xd2 + Int64 byte = 0xd3 + + FixedStrLow byte = 0xa0 + FixedStrHigh byte = 0xbf + FixedStrMask byte = 0x1f + Str8 byte = 0xd9 + Str16 byte = 0xda + Str32 byte = 0xdb + + Bin8 byte = 0xc4 + Bin16 byte = 0xc5 + Bin32 byte = 0xc6 + + FixedArrayLow byte = 0x90 + FixedArrayHigh byte = 0x9f + FixedArrayMask byte = 0xf + Array16 byte = 0xdc + Array32 byte = 0xdd + + FixedMapLow byte = 0x80 + FixedMapHigh byte = 0x8f + FixedMapMask byte = 0xf + Map16 byte = 0xde + Map32 byte = 0xdf + + FixExt1 byte = 0xd4 + FixExt2 byte = 0xd5 + FixExt4 byte = 0xd6 + FixExt8 byte = 0xd7 + FixExt16 byte = 0xd8 + Ext8 byte = 0xc7 + Ext16 byte = 0xc8 + Ext32 byte = 0xc9 +) + +func IsFixedNum(c byte) bool { + return c <= PosFixedNumHigh || c >= NegFixedNumLow +} + +func IsFixedMap(c byte) bool { + return c >= FixedMapLow && c <= FixedMapHigh +} + +func IsFixedArray(c byte) bool { + return c >= FixedArrayLow && c <= FixedArrayHigh +} + +func IsFixedString(c byte) bool { + return c >= FixedStrLow && c <= FixedStrHigh +} + +func IsExt(c byte) bool { + return (c >= FixExt1 && c <= FixExt16) || (c >= Ext8 && c <= Ext32) +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode.go new file mode 100644 index 00000000000..7e11b40d415 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode.go @@ -0,0 +1,425 @@ +package msgpack + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "reflect" + "time" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +const bytesAllocLimit = 1024 * 1024 // 1mb + +type bufReader interface { + Read([]byte) (int, error) + ReadByte() (byte, error) + UnreadByte() error +} + +func newBufReader(r io.Reader) bufReader { + if br, ok := r.(bufReader); ok { + return br + } + return bufio.NewReader(r) +} + +func makeBuffer() []byte { + return make([]byte, 0, 64) +} + +// Unmarshal decodes the MessagePack-encoded data and stores the result +// in the value pointed to by v. +func Unmarshal(data []byte, v ...interface{}) error { + return NewDecoder(bytes.NewReader(data)).Decode(v...) +} + +type Decoder struct { + DecodeMapFunc func(*Decoder) (interface{}, error) + + r bufReader + buf []byte + + extLen int + rec []byte // accumulates read data if not nil +} + +func NewDecoder(r io.Reader) *Decoder { + return &Decoder{ + DecodeMapFunc: decodeMap, + + r: newBufReader(r), + buf: makeBuffer(), + } +} + +func (d *Decoder) Reset(r io.Reader) error { + d.r = newBufReader(r) + return nil +} + +func (d *Decoder) Decode(v ...interface{}) error { + for _, vv := range v { + if err := d.decode(vv); err != nil { + return err + } + } + return nil +} + +func (d *Decoder) decode(dst interface{}) error { + var err error + switch v := dst.(type) { + case *string: + if v != nil { + *v, err = d.DecodeString() + return err + } + case *[]byte: + if v != nil { + return d.decodeBytesPtr(v) + } + case *int: + if v != nil { + *v, err = d.DecodeInt() + return err + } + case *int8: + if v != nil { + *v, err = d.DecodeInt8() + return err + } + case *int16: + if v != nil { + *v, err = d.DecodeInt16() + return err + } + case *int32: + if v != nil { + *v, err = d.DecodeInt32() + return err + } + case *int64: + if v != nil { + *v, err = d.DecodeInt64() + return err + } + case *uint: + if v != nil { + *v, err = d.DecodeUint() + return err + } + case *uint8: + if v != nil { + *v, err = d.DecodeUint8() + return err + } + case *uint16: + if v != nil { + *v, err = d.DecodeUint16() + return err + } + case *uint32: + if v != nil { + *v, err = d.DecodeUint32() + return err + } + case *uint64: + if v != nil { + *v, err = d.DecodeUint64() + return err + } + case *bool: + if v != nil { + *v, err = d.DecodeBool() + return err + } + case *float32: + if v != nil { + *v, err = d.DecodeFloat32() + return err + } + case *float64: + if v != nil { + *v, err = d.DecodeFloat64() + return err + } + case *[]string: + return d.decodeStringSlicePtr(v) + case *map[string]string: + return d.decodeMapStringStringPtr(v) + case *map[string]interface{}: + return d.decodeMapStringInterfacePtr(v) + case *time.Duration: + if v != nil { + vv, err := d.DecodeInt64() + *v = time.Duration(vv) + return err + } + case *time.Time: + if v != nil { + *v, err = d.DecodeTime() + return err + } + } + + v := reflect.ValueOf(dst) + if !v.IsValid() { + return errors.New("msgpack: Decode(nil)") + } + if v.Kind() != reflect.Ptr { + return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst) + } + v = v.Elem() + if !v.IsValid() { + return fmt.Errorf("msgpack: Decode(nonsettable %T)", dst) + } + return d.DecodeValue(v) +} + +func (d *Decoder) DecodeValue(v reflect.Value) error { + decode := getDecoder(v.Type()) + return decode(d, v) +} + +func (d *Decoder) DecodeNil() error { + c, err := d.readByte() + if err != nil { + return err + } + if c != codes.Nil { + return fmt.Errorf("msgpack: invalid code %x decoding nil", c) + } + return nil +} + +func (d *Decoder) DecodeBool() (bool, error) { + c, err := d.readByte() + if err != nil { + return false, err + } + return d.bool(c) +} + +func (d *Decoder) bool(c byte) (bool, error) { + if c == codes.False { + return false, nil + } + if c == codes.True { + return true, nil + } + return false, fmt.Errorf("msgpack: invalid code %x decoding bool", c) +} + +func (d *Decoder) interfaceValue(v reflect.Value) error { + vv, err := d.DecodeInterface() + if err != nil { + return err + } + if vv != nil { + if v.Type() == errorType { + if vv, ok := vv.(string); ok { + v.Set(reflect.ValueOf(errors.New(vv))) + return nil + } + } + + v.Set(reflect.ValueOf(vv)) + } + return nil +} + +// DecodeInterface decodes value into interface. Possible value types are: +// - nil, +// - bool, +// - int64 for negative numbers, +// - uint64 for positive numbers, +// - float32 and float64, +// - string, +// - slices of any of the above, +// - maps of any of the above. +func (d *Decoder) DecodeInterface() (interface{}, error) { + c, err := d.readByte() + if err != nil { + return nil, err + } + + if codes.IsFixedNum(c) { + if int8(c) < 0 { + return d.int(c) + } + return d.uint(c) + } + if codes.IsFixedMap(c) { + d.r.UnreadByte() + return d.DecodeMap() + } + if codes.IsFixedArray(c) { + return d.decodeSlice(c) + } + if codes.IsFixedString(c) { + return d.string(c) + } + + switch c { + case codes.Nil: + return nil, nil + case codes.False, codes.True: + return d.bool(c) + case codes.Float: + return d.float32(c) + case codes.Double: + return d.float64(c) + case codes.Uint8, codes.Uint16, codes.Uint32, codes.Uint64: + return d.uint(c) + case codes.Int8, codes.Int16, codes.Int32, codes.Int64: + return d.int(c) + case codes.Bin8, codes.Bin16, codes.Bin32: + return d.bytes(c, nil) + case codes.Str8, codes.Str16, codes.Str32: + return d.string(c) + case codes.Array16, codes.Array32: + return d.decodeSlice(c) + case codes.Map16, codes.Map32: + d.r.UnreadByte() + return d.DecodeMap() + case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16, + codes.Ext8, codes.Ext16, codes.Ext32: + return d.ext(c) + } + + return 0, fmt.Errorf("msgpack: unknown code %x decoding interface{}", c) +} + +// Skip skips next value. +func (d *Decoder) Skip() error { + c, err := d.readByte() + if err != nil { + return err + } + + if codes.IsFixedNum(c) { + return nil + } else if codes.IsFixedMap(c) { + return d.skipMap(c) + } else if codes.IsFixedArray(c) { + return d.skipSlice(c) + } else if codes.IsFixedString(c) { + return d.skipBytes(c) + } + + switch c { + case codes.Nil, codes.False, codes.True: + return nil + case codes.Uint8, codes.Int8: + return d.skipN(1) + case codes.Uint16, codes.Int16: + return d.skipN(2) + case codes.Uint32, codes.Int32, codes.Float: + return d.skipN(4) + case codes.Uint64, codes.Int64, codes.Double: + return d.skipN(8) + case codes.Bin8, codes.Bin16, codes.Bin32: + return d.skipBytes(c) + case codes.Str8, codes.Str16, codes.Str32: + return d.skipBytes(c) + case codes.Array16, codes.Array32: + return d.skipSlice(c) + case codes.Map16, codes.Map32: + return d.skipMap(c) + case codes.FixExt1, codes.FixExt2, codes.FixExt4, codes.FixExt8, codes.FixExt16, codes.Ext8, codes.Ext16, codes.Ext32: + return d.skipExt(c) + } + + return fmt.Errorf("msgpack: unknown code %x", c) +} + +// peekCode returns next MessagePack code. See +// https://github.com/msgpack/msgpack/blob/master/spec.md#formats for details. +func (d *Decoder) PeekCode() (code byte, err error) { + code, err = d.r.ReadByte() + if err != nil { + return 0, err + } + return code, d.r.UnreadByte() +} + +func (d *Decoder) hasNilCode() bool { + code, err := d.PeekCode() + return err == nil && code == codes.Nil +} + +func (d *Decoder) readByte() (byte, error) { + c, err := d.r.ReadByte() + if err != nil { + return 0, err + } + if d.rec != nil { + d.rec = append(d.rec, c) + } + return c, nil +} + +func (d *Decoder) readFull(b []byte) error { + _, err := io.ReadFull(d.r, b) + if err != nil { + return err + } + if d.rec != nil { + d.rec = append(d.rec, b...) + } + return nil +} + +func (d *Decoder) readN(n int) ([]byte, error) { + buf, err := readN(d.r, d.buf, n) + if err != nil { + return nil, err + } + d.buf = buf + if d.rec != nil { + d.rec = append(d.rec, buf...) + } + return buf, nil +} + +func readN(r io.Reader, b []byte, n int) ([]byte, error) { + if n == 0 && b == nil { + return make([]byte, 0), nil + } + + if cap(b) >= n { + b = b[:n] + _, err := io.ReadFull(r, b) + return b, err + } + b = b[:cap(b)] + + pos := 0 + for len(b) < n { + diff := n - len(b) + if diff > bytesAllocLimit { + diff = bytesAllocLimit + } + b = append(b, make([]byte, diff)...) + + _, err := io.ReadFull(r, b[pos:]) + if err != nil { + return nil, err + } + + pos = len(b) + } + + return b, nil +} + +func min(a, b int) int { + if a <= b { + return a + } + return b +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_map.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_map.go new file mode 100644 index 00000000000..21c97978d5d --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_map.go @@ -0,0 +1,265 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +const mapElemsAllocLimit = 1e4 + +var mapStringStringPtrType = reflect.TypeOf((*map[string]string)(nil)) +var mapStringStringType = mapStringStringPtrType.Elem() + +var mapStringInterfacePtrType = reflect.TypeOf((*map[string]interface{})(nil)) +var mapStringInterfaceType = mapStringInterfacePtrType.Elem() + +func decodeMapValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + + typ := v.Type() + if n == -1 { + v.Set(reflect.Zero(typ)) + return nil + } + + if v.IsNil() { + v.Set(reflect.MakeMap(typ)) + } + keyType := typ.Key() + valueType := typ.Elem() + + for i := 0; i < n; i++ { + mk := reflect.New(keyType).Elem() + if err := d.DecodeValue(mk); err != nil { + return err + } + + mv := reflect.New(valueType).Elem() + if err := d.DecodeValue(mv); err != nil { + return err + } + + v.SetMapIndex(mk, mv) + } + + return nil +} +func decodeMap(d *Decoder) (interface{}, error) { + n, err := d.DecodeMapLen() + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + + m := make(map[interface{}]interface{}, min(n, mapElemsAllocLimit)) + for i := 0; i < n; i++ { + mk, err := d.DecodeInterface() + if err != nil { + return nil, err + } + mv, err := d.DecodeInterface() + if err != nil { + return nil, err + } + m[mk] = mv + } + return m, nil +} + +func (d *Decoder) DecodeMapLen() (int, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + + if codes.IsExt(c) { + if err = d.skipExtHeader(c); err != nil { + return 0, err + } + + c, err = d.readByte() + if err != nil { + return 0, err + } + } + + return d.mapLen(c) +} + +func (d *Decoder) mapLen(c byte) (int, error) { + if c == codes.Nil { + return -1, nil + } + if c >= codes.FixedMapLow && c <= codes.FixedMapHigh { + return int(c & codes.FixedMapMask), nil + } + if c == codes.Map16 { + n, err := d.uint16() + return int(n), err + } + if c == codes.Map32 { + n, err := d.uint32() + return int(n), err + } + return 0, fmt.Errorf("msgpack: invalid code %x decoding map length", c) +} + +func decodeMapStringStringValue(d *Decoder, v reflect.Value) error { + mptr := v.Addr().Convert(mapStringStringPtrType).Interface().(*map[string]string) + return d.decodeMapStringStringPtr(mptr) +} + +func (d *Decoder) decodeMapStringStringPtr(ptr *map[string]string) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + if n == -1 { + *ptr = nil + return nil + } + + m := *ptr + if m == nil { + *ptr = make(map[string]string, min(n, mapElemsAllocLimit)) + m = *ptr + } + + for i := 0; i < n; i++ { + mk, err := d.DecodeString() + if err != nil { + return err + } + mv, err := d.DecodeString() + if err != nil { + return err + } + m[mk] = mv + } + + return nil +} + +func decodeMapStringInterfaceValue(d *Decoder, v reflect.Value) error { + ptr := v.Addr().Convert(mapStringInterfacePtrType).Interface().(*map[string]interface{}) + return d.decodeMapStringInterfacePtr(ptr) +} + +func (d *Decoder) decodeMapStringInterfacePtr(ptr *map[string]interface{}) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + if n == -1 { + *ptr = nil + return nil + } + + m := *ptr + if m == nil { + *ptr = make(map[string]interface{}, min(n, mapElemsAllocLimit)) + m = *ptr + } + + for i := 0; i < n; i++ { + mk, err := d.DecodeString() + if err != nil { + return err + } + mv, err := d.DecodeInterface() + if err != nil { + return err + } + m[mk] = mv + } + + return nil +} + +func (d *Decoder) DecodeMap() (interface{}, error) { + return d.DecodeMapFunc(d) +} + +func (d *Decoder) skipMap(c byte) error { + n, err := d.mapLen(c) + if err != nil { + return err + } + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + if err := d.Skip(); err != nil { + return err + } + } + return nil +} + +func decodeStructValue(d *Decoder, strct reflect.Value) error { + c, err := d.readByte() + if err != nil { + return err + } + + var isArray bool + + n, err := d.mapLen(c) + if err != nil { + var err2 error + n, err2 = d.arrayLen(c) + if err2 != nil { + return err + } + isArray = true + } + if n == -1 { + strct.Set(reflect.Zero(strct.Type())) + return nil + } + + fields := structs.Fields(strct.Type()) + + if isArray { + for i, f := range fields.List { + if i >= n { + break + } + if err := f.DecodeValue(d, strct); err != nil { + return err + } + } + // Skip extra values. + for i := len(fields.List); i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + } + return nil + } + + for i := 0; i < n; i++ { + name, err := d.DecodeString() + if err != nil { + return err + } + if f := fields.Table[name]; f != nil { + if err := f.DecodeValue(d, strct); err != nil { + return err + } + } else { + if err := d.Skip(); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_number.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_number.go new file mode 100644 index 00000000000..587634161c1 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_number.go @@ -0,0 +1,270 @@ +package msgpack + +import ( + "fmt" + "math" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +func (d *Decoder) skipN(n int) error { + _, err := d.readN(n) + return err +} + +func (d *Decoder) uint8() (uint8, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return uint8(c), nil +} + +func (d *Decoder) uint16() (uint16, error) { + b, err := d.readN(2) + if err != nil { + return 0, err + } + return (uint16(b[0]) << 8) | uint16(b[1]), nil +} + +func (d *Decoder) uint32() (uint32, error) { + b, err := d.readN(4) + if err != nil { + return 0, err + } + n := (uint32(b[0]) << 24) | + (uint32(b[1]) << 16) | + (uint32(b[2]) << 8) | + uint32(b[3]) + return n, nil +} + +func (d *Decoder) uint64() (uint64, error) { + b, err := d.readN(8) + if err != nil { + return 0, err + } + n := (uint64(b[0]) << 56) | + (uint64(b[1]) << 48) | + (uint64(b[2]) << 40) | + (uint64(b[3]) << 32) | + (uint64(b[4]) << 24) | + (uint64(b[5]) << 16) | + (uint64(b[6]) << 8) | + uint64(b[7]) + return n, nil +} + +func (d *Decoder) DecodeUint64() (uint64, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.uint(c) +} + +func (d *Decoder) uint(c byte) (uint64, error) { + if c == codes.Nil { + return 0, nil + } + if codes.IsFixedNum(c) { + return uint64(int8(c)), nil + } + switch c { + case codes.Uint8: + n, err := d.uint8() + return uint64(n), err + case codes.Int8: + n, err := d.uint8() + return uint64(int8(n)), err + case codes.Uint16: + n, err := d.uint16() + return uint64(n), err + case codes.Int16: + n, err := d.uint16() + return uint64(int16(n)), err + case codes.Uint32: + n, err := d.uint32() + return uint64(n), err + case codes.Int32: + n, err := d.uint32() + return uint64(int32(n)), err + case codes.Uint64, codes.Int64: + return d.uint64() + } + return 0, fmt.Errorf("msgpack: invalid code %x decoding uint64", c) +} + +func (d *Decoder) DecodeInt64() (int64, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.int(c) +} + +func (d *Decoder) int(c byte) (int64, error) { + if c == codes.Nil { + return 0, nil + } + if codes.IsFixedNum(c) { + return int64(int8(c)), nil + } + switch c { + case codes.Uint8: + n, err := d.uint8() + return int64(n), err + case codes.Int8: + n, err := d.uint8() + return int64(int8(n)), err + case codes.Uint16: + n, err := d.uint16() + return int64(n), err + case codes.Int16: + n, err := d.uint16() + return int64(int16(n)), err + case codes.Uint32: + n, err := d.uint32() + return int64(n), err + case codes.Int32: + n, err := d.uint32() + return int64(int32(n)), err + case codes.Uint64, codes.Int64: + n, err := d.uint64() + return int64(n), err + } + return 0, fmt.Errorf("msgpack: invalid code %x decoding int64", c) +} + +func (d *Decoder) DecodeFloat32() (float32, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.float32(c) +} + +func (d *Decoder) float32(c byte) (float32, error) { + if c == codes.Float { + n, err := d.uint32() + if err != nil { + return 0, err + } + return math.Float32frombits(n), nil + } + + n, err := d.int(c) + if err != nil { + return 0, fmt.Errorf("msgpack: invalid code %x decoding float32", c) + } + return float32(n), nil +} + +func (d *Decoder) DecodeFloat64() (float64, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.float64(c) +} + +func (d *Decoder) float64(c byte) (float64, error) { + switch c { + case codes.Float: + n, err := d.float32(c) + if err != nil { + return 0, err + } + return float64(n), nil + case codes.Double: + n, err := d.uint64() + if err != nil { + return 0, err + } + return math.Float64frombits(n), nil + } + + n, err := d.int(c) + if err != nil { + return 0, fmt.Errorf("msgpack: invalid code %x decoding float32", c) + } + return float64(n), nil +} + +func (d *Decoder) DecodeUint() (uint, error) { + n, err := d.DecodeUint64() + return uint(n), err +} + +func (d *Decoder) DecodeUint8() (uint8, error) { + n, err := d.DecodeUint64() + return uint8(n), err +} + +func (d *Decoder) DecodeUint16() (uint16, error) { + n, err := d.DecodeUint64() + return uint16(n), err +} + +func (d *Decoder) DecodeUint32() (uint32, error) { + n, err := d.DecodeUint64() + return uint32(n), err +} + +func (d *Decoder) DecodeInt() (int, error) { + n, err := d.DecodeInt64() + return int(n), err +} + +func (d *Decoder) DecodeInt8() (int8, error) { + n, err := d.DecodeInt64() + return int8(n), err +} + +func (d *Decoder) DecodeInt16() (int16, error) { + n, err := d.DecodeInt64() + return int16(n), err +} + +func (d *Decoder) DecodeInt32() (int32, error) { + n, err := d.DecodeInt64() + return int32(n), err +} + +func decodeFloat32Value(d *Decoder, v reflect.Value) error { + f, err := d.DecodeFloat32() + if err != nil { + return err + } + v.SetFloat(float64(f)) + return nil +} + +func decodeFloat64Value(d *Decoder, v reflect.Value) error { + f, err := d.DecodeFloat64() + if err != nil { + return err + } + v.SetFloat(f) + return nil +} + +func decodeInt64Value(d *Decoder, v reflect.Value) error { + n, err := d.DecodeInt64() + if err != nil { + return err + } + v.SetInt(n) + return nil +} + +func decodeUint64Value(d *Decoder, v reflect.Value) error { + n, err := d.DecodeUint64() + if err != nil { + return err + } + v.SetUint(n) + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_query.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_query.go new file mode 100644 index 00000000000..18d9d89b938 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_query.go @@ -0,0 +1,158 @@ +package msgpack + +import ( + "fmt" + "strconv" + "strings" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +type queryResult struct { + query string + key string + hasAsterisk bool + + values []interface{} +} + +func (q *queryResult) nextKey() { + ind := strings.IndexByte(q.query, '.') + if ind == -1 { + q.key = q.query + q.query = "" + return + } + q.key = q.query[:ind] + q.query = q.query[ind+1:] +} + +// Query extracts data specified by the query from the msgpack stream skipping +// any other data. Query consists of map keys and array indexes separated with dot, +// e.g. key1.0.key2. +func (d *Decoder) Query(query string) ([]interface{}, error) { + res := queryResult{ + query: query, + } + if err := d.query(&res); err != nil { + return nil, err + } + return res.values, nil +} + +func (d *Decoder) query(q *queryResult) error { + q.nextKey() + if q.key == "" { + v, err := d.DecodeInterface() + if err != nil { + return err + } + q.values = append(q.values, v) + return nil + } + + code, err := d.PeekCode() + if err != nil { + return err + } + + switch { + case code == codes.Map16 || code == codes.Map32 || codes.IsFixedMap(code): + err = d.queryMapKey(q) + case code == codes.Array16 || code == codes.Array32 || codes.IsFixedArray(code): + err = d.queryArrayIndex(q) + default: + err = fmt.Errorf("msgpack: unsupported code=%x decoding key=%q", code, q.key) + } + return err +} + +func (d *Decoder) queryMapKey(q *queryResult) error { + n, err := d.DecodeMapLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + for i := 0; i < n; i++ { + k, err := d.bytesNoCopy() + if err != nil { + return err + } + + if string(k) == q.key { + if err := d.query(q); err != nil { + return err + } + if q.hasAsterisk { + return d.skipNext((n - i - 1) * 2) + } + return nil + } + + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) queryArrayIndex(q *queryResult) error { + n, err := d.DecodeSliceLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + if q.key == "*" { + q.hasAsterisk = true + + query := q.query + for i := 0; i < n; i++ { + q.query = query + if err := d.query(q); err != nil { + return err + } + } + + q.hasAsterisk = false + return nil + } + + ind, err := strconv.Atoi(q.key) + if err != nil { + return err + } + + for i := 0; i < n; i++ { + if i == ind { + if err := d.query(q); err != nil { + return err + } + if q.hasAsterisk { + return d.skipNext(n - i - 1) + } + return nil + } + + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) skipNext(n int) error { + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + } + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_slice.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_slice.go new file mode 100644 index 00000000000..61e3da2bd44 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_slice.go @@ -0,0 +1,197 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +const sliceElemsAllocLimit = 1e4 + +var sliceStringPtrType = reflect.TypeOf((*[]string)(nil)) + +// Deprecated. Use DecodeArrayLen instead. +func (d *Decoder) DecodeSliceLen() (int, error) { + return d.DecodeArrayLen() +} + +func (d *Decoder) DecodeArrayLen() (int, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.arrayLen(c) +} + +func (d *Decoder) arrayLen(c byte) (int, error) { + if c == codes.Nil { + return -1, nil + } else if c >= codes.FixedArrayLow && c <= codes.FixedArrayHigh { + return int(c & codes.FixedArrayMask), nil + } + switch c { + case codes.Array16: + n, err := d.uint16() + return int(n), err + case codes.Array32: + n, err := d.uint32() + return int(n), err + } + return 0, fmt.Errorf("msgpack: invalid code %x decoding array length", c) +} + +func decodeStringSliceValue(d *Decoder, v reflect.Value) error { + ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string) + return d.decodeStringSlicePtr(ptr) +} + +func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + if n == -1 { + return nil + } + + ss := setStringsCap(*ptr, n) + for i := 0; i < n; i++ { + s, err := d.DecodeString() + if err != nil { + return err + } + ss = append(ss, s) + } + *ptr = ss + + return nil +} + +func setStringsCap(s []string, n int) []string { + if n > sliceElemsAllocLimit { + n = sliceElemsAllocLimit + } + + if s == nil { + return make([]string, 0, n) + } + + if cap(s) >= n { + return s[:0] + } + + s = s[:cap(s)] + s = append(s, make([]string, n-len(s))...) + return s[:0] +} + +func decodeSliceValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + + if n == -1 { + v.Set(reflect.Zero(v.Type())) + return nil + } + if n == 0 && v.IsNil() { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + return nil + } + + if v.Cap() >= n { + v.Set(v.Slice(0, n)) + } else if v.Len() < v.Cap() { + v.Set(v.Slice(0, v.Cap())) + } + + for i := 0; i < n; i++ { + if i >= v.Len() { + v.Set(growSliceValue(v, n)) + } + sv := v.Index(i) + if err := d.DecodeValue(sv); err != nil { + return err + } + } + + return nil +} + +func growSliceValue(v reflect.Value, n int) reflect.Value { + diff := n - v.Len() + if diff > sliceElemsAllocLimit { + diff = sliceElemsAllocLimit + } + v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff)) + return v +} + +func decodeArrayValue(d *Decoder, v reflect.Value) error { + n, err := d.DecodeArrayLen() + if err != nil { + return err + } + + if n == -1 { + return nil + } + + if n > v.Len() { + return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) + } + for i := 0; i < n; i++ { + sv := v.Index(i) + if err := d.DecodeValue(sv); err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) DecodeSlice() ([]interface{}, error) { + c, err := d.readByte() + if err != nil { + return nil, err + } + return d.decodeSlice(c) +} + +func (d *Decoder) decodeSlice(c byte) ([]interface{}, error) { + n, err := d.arrayLen(c) + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + + s := make([]interface{}, 0, min(n, sliceElemsAllocLimit)) + for i := 0; i < n; i++ { + v, err := d.DecodeInterface() + if err != nil { + return nil, err + } + s = append(s, v) + } + + return s, nil +} + +func (d *Decoder) skipSlice(c byte) error { + n, err := d.arrayLen(c) + if err != nil { + return err + } + + for i := 0; i < n; i++ { + if err := d.Skip(); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_string.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_string.go new file mode 100644 index 00000000000..17c1b6118ed --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_string.go @@ -0,0 +1,168 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +func (d *Decoder) bytesLen(c byte) (int, error) { + if c == codes.Nil { + return -1, nil + } else if codes.IsFixedString(c) { + return int(c & codes.FixedStrMask), nil + } + switch c { + case codes.Str8, codes.Bin8: + n, err := d.uint8() + return int(n), err + case codes.Str16, codes.Bin16: + n, err := d.uint16() + return int(n), err + case codes.Str32, codes.Bin32: + n, err := d.uint32() + return int(n), err + } + return 0, fmt.Errorf("msgpack: invalid code %x decoding bytes length", c) +} + +func (d *Decoder) DecodeString() (string, error) { + c, err := d.readByte() + if err != nil { + return "", err + } + return d.string(c) +} + +func (d *Decoder) string(c byte) (string, error) { + n, err := d.bytesLen(c) + if err != nil { + return "", err + } + if n == -1 { + return "", nil + } + b, err := d.readN(n) + return string(b), err +} + +func decodeStringValue(d *Decoder, v reflect.Value) error { + s, err := d.DecodeString() + if err != nil { + return err + } + v.SetString(s) + return nil +} + +func (d *Decoder) DecodeBytesLen() (int, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.bytesLen(c) +} + +func (d *Decoder) DecodeBytes() ([]byte, error) { + c, err := d.readByte() + if err != nil { + return nil, err + } + return d.bytes(c, nil) +} + +func (d *Decoder) bytes(c byte, b []byte) ([]byte, error) { + n, err := d.bytesLen(c) + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + return readN(d.r, b, n) +} + +func (d *Decoder) bytesNoCopy() ([]byte, error) { + c, err := d.readByte() + if err != nil { + return nil, err + } + n, err := d.bytesLen(c) + if err != nil { + return nil, err + } + if n == -1 { + return nil, nil + } + return d.readN(n) +} + +func (d *Decoder) decodeBytesPtr(ptr *[]byte) error { + c, err := d.readByte() + if err != nil { + return err + } + return d.bytesPtr(c, ptr) +} + +func (d *Decoder) bytesPtr(c byte, ptr *[]byte) error { + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n == -1 { + *ptr = nil + return nil + } + + *ptr, err = readN(d.r, *ptr, n) + return err +} + +func (d *Decoder) skipBytes(c byte) error { + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n == -1 { + return nil + } + return d.skipN(n) +} + +func decodeBytesValue(d *Decoder, v reflect.Value) error { + c, err := d.readByte() + if err != nil { + return err + } + + b, err := d.bytes(c, v.Bytes()) + if err != nil { + return err + } + v.SetBytes(b) + + return nil +} + +func decodeByteArrayValue(d *Decoder, v reflect.Value) error { + c, err := d.readByte() + if err != nil { + return err + } + + n, err := d.bytesLen(c) + if err != nil { + return err + } + if n == -1 { + return nil + } + if n > v.Len() { + return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n) + } + + b := v.Slice(0, n).Bytes() + return d.readFull(b) +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_value.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_value.go new file mode 100644 index 00000000000..e239296238f --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/decode_value.go @@ -0,0 +1,248 @@ +package msgpack + +import ( + "fmt" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +var interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() +var stringType = reflect.TypeOf((*string)(nil)).Elem() + +var valueDecoders []decoderFunc + +func init() { + valueDecoders = []decoderFunc{ + reflect.Bool: decodeBoolValue, + reflect.Int: decodeInt64Value, + reflect.Int8: decodeInt64Value, + reflect.Int16: decodeInt64Value, + reflect.Int32: decodeInt64Value, + reflect.Int64: decodeInt64Value, + reflect.Uint: decodeUint64Value, + reflect.Uint8: decodeUint64Value, + reflect.Uint16: decodeUint64Value, + reflect.Uint32: decodeUint64Value, + reflect.Uint64: decodeUint64Value, + reflect.Float32: decodeFloat32Value, + reflect.Float64: decodeFloat64Value, + reflect.Complex64: decodeUnsupportedValue, + reflect.Complex128: decodeUnsupportedValue, + reflect.Array: decodeArrayValue, + reflect.Chan: decodeUnsupportedValue, + reflect.Func: decodeUnsupportedValue, + reflect.Interface: decodeInterfaceValue, + reflect.Map: decodeMapValue, + reflect.Ptr: decodeUnsupportedValue, + reflect.Slice: decodeSliceValue, + reflect.String: decodeStringValue, + reflect.Struct: decodeStructValue, + reflect.UnsafePointer: decodeUnsupportedValue, + } +} + +func getDecoder(typ reflect.Type) decoderFunc { + kind := typ.Kind() + + if decoder, ok := typDecMap[typ]; ok { + return decoder + } + + if typ.Implements(customDecoderType) { + return decodeCustomValue + } + if typ.Implements(unmarshalerType) { + return unmarshalValue + } + + // Addressable struct field value. + if kind != reflect.Ptr { + ptr := reflect.PtrTo(typ) + if ptr.Implements(customDecoderType) { + return decodeCustomValueAddr + } + if ptr.Implements(unmarshalerType) { + return unmarshalValueAddr + } + } + + switch kind { + case reflect.Ptr: + return ptrDecoderFunc(typ) + case reflect.Slice: + elem := typ.Elem() + switch elem.Kind() { + case reflect.Uint8: + return decodeBytesValue + } + switch elem { + case stringType: + return decodeStringSliceValue + } + case reflect.Array: + if typ.Elem().Kind() == reflect.Uint8 { + return decodeByteArrayValue + } + case reflect.Map: + if typ.Key() == stringType { + switch typ.Elem() { + case stringType: + return decodeMapStringStringValue + case interfaceType: + return decodeMapStringInterfaceValue + } + } + } + return valueDecoders[kind] +} + +func ptrDecoderFunc(typ reflect.Type) decoderFunc { + decoder := getDecoder(typ.Elem()) + return func(d *Decoder, v reflect.Value) error { + if d.hasNilCode() { + v.Set(reflect.Zero(v.Type())) + return d.DecodeNil() + } + if v.IsNil() { + if !v.CanSet() { + return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) + } + v.Set(reflect.New(v.Type().Elem())) + } + return decoder(d, v.Elem()) + } +} + +func decodeCustomValueAddr(d *Decoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) + } + return decodeCustomValue(d, v.Addr()) +} + +func decodeCustomValue(d *Decoder, v reflect.Value) error { + c, err := d.PeekCode() + if err != nil { + return err + } + + if codes.IsExt(c) { + c, err = d.readByte() + if err != nil { + return err + } + + _, err = d.parseExtLen(c) + if err != nil { + return err + } + + _, err = d.readByte() + if err != nil { + return err + } + + c, err = d.PeekCode() + if err != nil { + return err + } + } + + if c == codes.Nil { + // TODO: set nil + return d.DecodeNil() + } + + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + + decoder := v.Interface().(CustomDecoder) + return decoder.DecodeMsgpack(d) +} + +func unmarshalValueAddr(d *Decoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Decode(nonsettable %T)", v.Interface()) + } + return unmarshalValue(d, v.Addr()) +} + +func unmarshalValue(d *Decoder, v reflect.Value) error { + c, err := d.PeekCode() + if err != nil { + return err + } + + if codes.IsExt(c) { + c, err = d.readByte() + if err != nil { + return err + } + + extLen, err := d.parseExtLen(c) + if err != nil { + return err + } + d.extLen = extLen + + _, err = d.readByte() + if err != nil { + return err + } + + c, err = d.PeekCode() + if err != nil { + return err + } + } + + if c == codes.Nil { + // TODO: set nil + return d.DecodeNil() + } + + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + + if d.extLen != 0 { + b, err := d.readN(d.extLen) + d.extLen = 0 + if err != nil { + return err + } + d.rec = b + } else { + d.rec = makeBuffer() + if err := d.Skip(); err != nil { + return err + } + } + + unmarshaler := v.Interface().(Unmarshaler) + err = unmarshaler.UnmarshalMsgpack(d.rec) + d.rec = nil + return err +} + +func decodeBoolValue(d *Decoder, v reflect.Value) error { + flag, err := d.DecodeBool() + if err != nil { + return err + } + v.SetBool(flag) + return nil +} + +func decodeInterfaceValue(d *Decoder, v reflect.Value) error { + if v.IsNil() { + return d.interfaceValue(v) + } + return d.DecodeValue(v.Elem()) +} + +func decodeUnsupportedValue(d *Decoder, v reflect.Value) error { + return fmt.Errorf("msgpack: Decode(unsupported %s)", v.Type()) +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/encode.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode.go new file mode 100644 index 00000000000..ad10f2e9a6f --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode.go @@ -0,0 +1,144 @@ +package msgpack + +import ( + "bytes" + "io" + "reflect" + "time" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +type writer interface { + io.Writer + WriteByte(byte) error + WriteString(string) (int, error) +} + +type byteWriter struct { + io.Writer +} + +func (w byteWriter) WriteByte(b byte) error { + _, err := w.Write([]byte{b}) + return err +} + +func (w byteWriter) WriteString(s string) (int, error) { + return w.Write([]byte(s)) +} + +// Marshal returns the MessagePack encoding of v. +func Marshal(v ...interface{}) ([]byte, error) { + var buf bytes.Buffer + err := NewEncoder(&buf).Encode(v...) + return buf.Bytes(), err +} + +type Encoder struct { + w writer + buf []byte + + sortMapKeys bool + structAsArray bool +} + +func NewEncoder(w io.Writer) *Encoder { + bw, ok := w.(writer) + if !ok { + bw = byteWriter{Writer: w} + } + return &Encoder{ + w: bw, + buf: make([]byte, 9), + } +} + +// SortMapKeys causes the Encoder to encode map keys in increasing order. +// Supported map types are: +// - map[string]string +// - map[string]interface{} +func (e *Encoder) SortMapKeys(v bool) *Encoder { + e.sortMapKeys = v + return e +} + +// StructAsArray causes the Encoder to encode Go structs as MessagePack arrays. +func (e *Encoder) StructAsArray(v bool) *Encoder { + e.structAsArray = v + return e +} + +func (e *Encoder) Encode(v ...interface{}) error { + for _, vv := range v { + if err := e.encode(vv); err != nil { + return err + } + } + return nil +} + +func (e *Encoder) encode(v interface{}) error { + switch v := v.(type) { + case nil: + return e.EncodeNil() + case string: + return e.EncodeString(v) + case []byte: + return e.EncodeBytes(v) + case int: + return e.EncodeInt64(int64(v)) + case int64: + return e.EncodeInt64(v) + case uint: + return e.EncodeUint64(uint64(v)) + case uint64: + return e.EncodeUint64(v) + case bool: + return e.EncodeBool(v) + case float32: + return e.EncodeFloat32(v) + case float64: + return e.EncodeFloat64(v) + case time.Duration: + return e.EncodeInt64(int64(v)) + case time.Time: + return e.EncodeTime(v) + } + return e.EncodeValue(reflect.ValueOf(v)) +} + +func (e *Encoder) EncodeValue(v reflect.Value) error { + encode := getEncoder(v.Type()) + return encode(e, v) +} + +func (e *Encoder) EncodeNil() error { + return e.w.WriteByte(codes.Nil) +} + +func (e *Encoder) EncodeBool(value bool) error { + if value { + return e.w.WriteByte(codes.True) + } + return e.w.WriteByte(codes.False) +} + +func (e *Encoder) write(b []byte) error { + _, err := e.w.Write(b) + if err != nil { + return err + } + return nil +} + +func (e *Encoder) writeString(s string) error { + n, err := e.w.WriteString(s) + if err != nil { + return err + } + if n < len(s) { + return io.ErrShortWrite + } + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_map.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_map.go new file mode 100644 index 00000000000..c9544ccfae2 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_map.go @@ -0,0 +1,166 @@ +package msgpack + +import ( + "reflect" + "sort" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +func encodeMapValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + for _, key := range v.MapKeys() { + if err := e.EncodeValue(key); err != nil { + return err + } + if err := e.EncodeValue(v.MapIndex(key)); err != nil { + return err + } + } + + return nil +} + +func encodeMapStringStringValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + m := v.Convert(mapStringStringType).Interface().(map[string]string) + if e.sortMapKeys { + return e.encodeSortedMapStringString(m) + } + + for mk, mv := range m { + if err := e.EncodeString(mk); err != nil { + return err + } + if err := e.EncodeString(mv); err != nil { + return err + } + } + + return nil +} + +func encodeMapStringInterfaceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + + if err := e.EncodeMapLen(v.Len()); err != nil { + return err + } + + m := v.Convert(mapStringInterfaceType).Interface().(map[string]interface{}) + if e.sortMapKeys { + return e.encodeSortedMapStringInterface(m) + } + + for mk, mv := range m { + if err := e.EncodeString(mk); err != nil { + return err + } + if err := e.Encode(mv); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) encodeSortedMapStringString(m map[string]string) error { + keys := make([]string, 0, len(m)) + for k, _ := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + err := e.EncodeString(k) + if err != nil { + return err + } + if err = e.EncodeString(m[k]); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) encodeSortedMapStringInterface(m map[string]interface{}) error { + keys := make([]string, 0, len(m)) + for k, _ := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + err := e.EncodeString(k) + if err != nil { + return err + } + if err = e.Encode(m[k]); err != nil { + return err + } + } + + return nil +} + +func (e *Encoder) EncodeMapLen(l int) error { + if l < 16 { + return e.w.WriteByte(codes.FixedMapLow | byte(l)) + } + if l < 65536 { + return e.write2(codes.Map16, uint64(l)) + } + return e.write4(codes.Map32, uint32(l)) +} + +func encodeStructValue(e *Encoder, strct reflect.Value) error { + structFields := structs.Fields(strct.Type()) + if e.structAsArray || structFields.asArray { + return encodeStructValueAsArray(e, strct, structFields.List) + } + fields := structFields.OmitEmpty(strct) + + if err := e.EncodeMapLen(len(fields)); err != nil { + return err + } + + for _, f := range fields { + if err := e.EncodeString(f.name); err != nil { + return err + } + if err := f.EncodeValue(e, strct); err != nil { + return err + } + } + + return nil +} + +func encodeStructValueAsArray(e *Encoder, strct reflect.Value, fields []*field) error { + if err := e.EncodeArrayLen(len(fields)); err != nil { + return err + } + for _, f := range fields { + if err := f.EncodeValue(e, strct); err != nil { + return err + } + } + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_number.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_number.go new file mode 100644 index 00000000000..347f56ca5d4 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_number.go @@ -0,0 +1,138 @@ +package msgpack + +import ( + "math" + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +func (e *Encoder) EncodeUint(v uint) error { + return e.EncodeUint64(uint64(v)) +} + +func (e *Encoder) EncodeUint8(v uint8) error { + return e.EncodeUint64(uint64(v)) +} + +func (e *Encoder) EncodeUint16(v uint16) error { + return e.EncodeUint64(uint64(v)) +} + +func (e *Encoder) EncodeUint32(v uint32) error { + return e.EncodeUint64(uint64(v)) +} + +func (e *Encoder) EncodeUint64(v uint64) error { + if v <= math.MaxInt8 { + return e.w.WriteByte(byte(v)) + } + if v <= math.MaxUint8 { + return e.write1(codes.Uint8, v) + } + if v <= math.MaxUint16 { + return e.write2(codes.Uint16, v) + } + if v <= math.MaxUint32 { + return e.write4(codes.Uint32, uint32(v)) + } + return e.write8(codes.Uint64, v) +} + +func (e *Encoder) EncodeInt(v int) error { + return e.EncodeInt64(int64(v)) +} + +func (e *Encoder) EncodeInt8(v int8) error { + return e.EncodeInt64(int64(v)) +} + +func (e *Encoder) EncodeInt16(v int16) error { + return e.EncodeInt64(int64(v)) +} + +func (e *Encoder) EncodeInt32(v int32) error { + return e.EncodeInt64(int64(v)) +} + +func (e *Encoder) EncodeInt64(v int64) error { + if v >= 0 { + return e.EncodeUint64(uint64(v)) + } + if v >= int64(int8(codes.NegFixedNumLow)) { + return e.w.WriteByte(byte(v)) + } + if v >= math.MinInt8 { + return e.write1(codes.Int8, uint64(v)) + } + if v >= math.MinInt16 { + return e.write2(codes.Int16, uint64(v)) + } + if v >= math.MinInt32 { + return e.write4(codes.Int32, uint32(v)) + } + return e.write8(codes.Int64, uint64(v)) +} + +func (e *Encoder) EncodeFloat32(n float32) error { + return e.write4(codes.Float, math.Float32bits(n)) +} + +func (e *Encoder) EncodeFloat64(n float64) error { + return e.write8(codes.Double, math.Float64bits(n)) +} + +func (e *Encoder) write1(code byte, n uint64) error { + e.buf = e.buf[:2] + e.buf[0] = code + e.buf[1] = byte(n) + return e.write(e.buf) +} + +func (e *Encoder) write2(code byte, n uint64) error { + e.buf = e.buf[:3] + e.buf[0] = code + e.buf[1] = byte(n >> 8) + e.buf[2] = byte(n) + return e.write(e.buf) +} + +func (e *Encoder) write4(code byte, n uint32) error { + e.buf = e.buf[:5] + e.buf[0] = code + e.buf[1] = byte(n >> 24) + e.buf[2] = byte(n >> 16) + e.buf[3] = byte(n >> 8) + e.buf[4] = byte(n) + return e.write(e.buf) +} + +func (e *Encoder) write8(code byte, n uint64) error { + e.buf = e.buf[:9] + e.buf[0] = code + e.buf[1] = byte(n >> 56) + e.buf[2] = byte(n >> 48) + e.buf[3] = byte(n >> 40) + e.buf[4] = byte(n >> 32) + e.buf[5] = byte(n >> 24) + e.buf[6] = byte(n >> 16) + e.buf[7] = byte(n >> 8) + e.buf[8] = byte(n) + return e.write(e.buf) +} + +func encodeInt64Value(e *Encoder, v reflect.Value) error { + return e.EncodeInt64(v.Int()) +} + +func encodeUint64Value(e *Encoder, v reflect.Value) error { + return e.EncodeUint64(v.Uint()) +} + +func encodeFloat32Value(e *Encoder, v reflect.Value) error { + return e.EncodeFloat32(float32(v.Float())) +} + +func encodeFloat64Value(e *Encoder, v reflect.Value) error { + return e.EncodeFloat64(v.Float()) +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_slice.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_slice.go new file mode 100644 index 00000000000..0a4e37d986f --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_slice.go @@ -0,0 +1,120 @@ +package msgpack + +import ( + "reflect" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +func encodeStringValue(e *Encoder, v reflect.Value) error { + return e.EncodeString(v.String()) +} + +func encodeByteSliceValue(e *Encoder, v reflect.Value) error { + return e.EncodeBytes(v.Bytes()) +} + +func encodeByteArrayValue(e *Encoder, v reflect.Value) error { + if err := e.EncodeBytesLen(v.Len()); err != nil { + return err + } + + if v.CanAddr() { + b := v.Slice(0, v.Len()).Bytes() + return e.write(b) + } + + b := make([]byte, v.Len()) + reflect.Copy(reflect.ValueOf(b), v) + return e.write(b) +} + +func (e *Encoder) EncodeBytesLen(l int) error { + if l < 256 { + return e.write1(codes.Bin8, uint64(l)) + } + if l < 65536 { + return e.write2(codes.Bin16, uint64(l)) + } + return e.write4(codes.Bin32, uint32(l)) +} + +func (e *Encoder) encodeStrLen(l int) error { + if l < 32 { + return e.w.WriteByte(codes.FixedStrLow | uint8(l)) + } + if l < 256 { + return e.write1(codes.Str8, uint64(l)) + } + if l < 65536 { + return e.write2(codes.Str16, uint64(l)) + } + return e.write4(codes.Str32, uint32(l)) +} + +func (e *Encoder) EncodeString(v string) error { + if err := e.encodeStrLen(len(v)); err != nil { + return err + } + return e.writeString(v) +} + +func (e *Encoder) EncodeBytes(v []byte) error { + if v == nil { + return e.EncodeNil() + } + if err := e.EncodeBytesLen(len(v)); err != nil { + return err + } + return e.write(v) +} + +func (e *Encoder) EncodeArrayLen(l int) error { + if l < 16 { + return e.w.WriteByte(codes.FixedArrayLow | byte(l)) + } + if l < 65536 { + return e.write2(codes.Array16, uint64(l)) + } + return e.write4(codes.Array32, uint32(l)) +} + +// Deprecated. Use EncodeArrayLen instead. +func (e *Encoder) EncodeSliceLen(l int) error { + return e.EncodeArrayLen(l) +} + +func (e *Encoder) encodeStringSlice(s []string) error { + if s == nil { + return e.EncodeNil() + } + if err := e.EncodeArrayLen(len(s)); err != nil { + return err + } + for _, v := range s { + if err := e.EncodeString(v); err != nil { + return err + } + } + return nil +} + +func encodeSliceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return encodeArrayValue(e, v) +} + +func encodeArrayValue(e *Encoder, v reflect.Value) error { + l := v.Len() + if err := e.EncodeSliceLen(l); err != nil { + return err + } + for i := 0; i < l; i++ { + if err := e.EncodeValue(v.Index(i)); err != nil { + return err + } + } + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_value.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_value.go new file mode 100644 index 00000000000..2f5a3509a85 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/encode_value.go @@ -0,0 +1,167 @@ +package msgpack + +import ( + "fmt" + "reflect" +) + +var valueEncoders []encoderFunc + +func init() { + valueEncoders = []encoderFunc{ + reflect.Bool: encodeBoolValue, + reflect.Int: encodeInt64Value, + reflect.Int8: encodeInt64Value, + reflect.Int16: encodeInt64Value, + reflect.Int32: encodeInt64Value, + reflect.Int64: encodeInt64Value, + reflect.Uint: encodeUint64Value, + reflect.Uint8: encodeUint64Value, + reflect.Uint16: encodeUint64Value, + reflect.Uint32: encodeUint64Value, + reflect.Uint64: encodeUint64Value, + reflect.Float32: encodeFloat32Value, + reflect.Float64: encodeFloat64Value, + reflect.Complex64: encodeUnsupportedValue, + reflect.Complex128: encodeUnsupportedValue, + reflect.Array: encodeArrayValue, + reflect.Chan: encodeUnsupportedValue, + reflect.Func: encodeUnsupportedValue, + reflect.Interface: encodeInterfaceValue, + reflect.Map: encodeMapValue, + reflect.Ptr: encodeUnsupportedValue, + reflect.Slice: encodeSliceValue, + reflect.String: encodeStringValue, + reflect.Struct: encodeStructValue, + reflect.UnsafePointer: encodeUnsupportedValue, + } +} + +func getEncoder(typ reflect.Type) encoderFunc { + if encoder, ok := typEncMap[typ]; ok { + return encoder + } + + if typ.Implements(customEncoderType) { + return encodeCustomValue + } + if typ.Implements(marshalerType) { + return marshalValue + } + + kind := typ.Kind() + + // Addressable struct field value. + if kind != reflect.Ptr { + ptr := reflect.PtrTo(typ) + if ptr.Implements(customEncoderType) { + return encodeCustomValuePtr + } + if ptr.Implements(marshalerType) { + return marshalValuePtr + } + } + + if typ == errorType { + return encodeErrorValue + } + + switch kind { + case reflect.Ptr: + return ptrEncoderFunc(typ) + case reflect.Slice: + if typ.Elem().Kind() == reflect.Uint8 { + return encodeByteSliceValue + } + case reflect.Array: + if typ.Elem().Kind() == reflect.Uint8 { + return encodeByteArrayValue + } + case reflect.Map: + if typ.Key() == stringType { + switch typ.Elem() { + case stringType: + return encodeMapStringStringValue + case interfaceType: + return encodeMapStringInterfaceValue + } + } + } + return valueEncoders[kind] +} + +func ptrEncoderFunc(typ reflect.Type) encoderFunc { + encoder := getEncoder(typ.Elem()) + return func(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return encoder(e, v.Elem()) + } +} + +func encodeCustomValuePtr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + encoder := v.Addr().Interface().(CustomEncoder) + return encoder.EncodeMsgpack(e) +} + +func encodeCustomValue(e *Encoder, v reflect.Value) error { + switch v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + if v.IsNil() { + return e.EncodeNil() + } + } + + encoder := v.Interface().(CustomEncoder) + return encoder.EncodeMsgpack(e) +} + +func marshalValuePtr(e *Encoder, v reflect.Value) error { + if !v.CanAddr() { + return fmt.Errorf("msgpack: Encode(non-addressable %T)", v.Interface()) + } + return marshalValue(e, v.Addr()) +} + +func marshalValue(e *Encoder, v reflect.Value) error { + switch v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + if v.IsNil() { + return e.EncodeNil() + } + } + + marshaler := v.Interface().(Marshaler) + b, err := marshaler.MarshalMsgpack() + if err != nil { + return err + } + _, err = e.w.Write(b) + return err +} + +func encodeBoolValue(e *Encoder, v reflect.Value) error { + return e.EncodeBool(v.Bool()) +} + +func encodeInterfaceValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return e.EncodeValue(v.Elem()) +} + +func encodeErrorValue(e *Encoder, v reflect.Value) error { + if v.IsNil() { + return e.EncodeNil() + } + return e.EncodeString(v.Interface().(error).Error()) +} + +func encodeUnsupportedValue(e *Encoder, v reflect.Value) error { + return fmt.Errorf("msgpack: Encode(unsupported %s)", v.Type()) +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/ext.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/ext.go new file mode 100644 index 00000000000..37ae53dd303 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/ext.go @@ -0,0 +1,200 @@ +package msgpack + +import ( + "bytes" + "fmt" + "reflect" + "sync" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +var extTypes []reflect.Type + +var bufferPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +// RegisterExt records a type, identified by a value for that type, +// under the provided id. That id will identify the concrete type of a value +// sent or received as an interface variable. Only types that will be +// transferred as implementations of interface values need to be registered. +// Expecting to be used only during initialization, it panics if the mapping +// between types and ids is not a bijection. +func RegisterExt(id int8, value interface{}) { + if diff := int(id) - len(extTypes) + 1; diff > 0 { + extTypes = append(extTypes, make([]reflect.Type, diff)...) + } + + if extTypes[id] != nil { + panic(fmt.Errorf("msgpack: ext with id=%d is already registered", id)) + } + + typ := reflect.TypeOf(value) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + ptr := reflect.PtrTo(typ) + + extTypes[id] = typ + decoder := getDecoder(typ) + Register(ptr, makeExtEncoder(id, getEncoder(ptr)), decoder) + Register(typ, makeExtEncoder(id, getEncoder(typ)), decoder) +} + +func makeExtEncoder(id int8, enc encoderFunc) encoderFunc { + return func(e *Encoder, v reflect.Value) error { + buf := bufferPool.Get().(*bytes.Buffer) + defer bufferPool.Put(buf) + buf.Reset() + + oldw := e.w + e.w = buf + err := enc(e, v) + e.w = oldw + + if err != nil { + return err + } + + if err := e.encodeExtLen(buf.Len()); err != nil { + return err + } + if err := e.w.WriteByte(byte(id)); err != nil { + return err + } + return e.write(buf.Bytes()) + } +} + +func (e *Encoder) encodeExtLen(l int) error { + switch l { + case 1: + return e.w.WriteByte(codes.FixExt1) + case 2: + return e.w.WriteByte(codes.FixExt2) + case 4: + return e.w.WriteByte(codes.FixExt4) + case 8: + return e.w.WriteByte(codes.FixExt8) + case 16: + return e.w.WriteByte(codes.FixExt16) + } + if l < 256 { + return e.write1(codes.Ext8, uint64(l)) + } + if l < 65536 { + return e.write2(codes.Ext16, uint64(l)) + } + return e.write4(codes.Ext32, uint32(l)) +} + +func (d *Decoder) decodeExtLen() (int, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.parseExtLen(c) +} + +func (d *Decoder) parseExtLen(c byte) (int, error) { + switch c { + case codes.FixExt1: + return 1, nil + case codes.FixExt2: + return 2, nil + case codes.FixExt4: + return 4, nil + case codes.FixExt8: + return 8, nil + case codes.FixExt16: + return 16, nil + case codes.Ext8: + n, err := d.uint8() + return int(n), err + case codes.Ext16: + n, err := d.uint16() + return int(n), err + case codes.Ext32: + n, err := d.uint32() + return int(n), err + default: + return 0, fmt.Errorf("msgpack: invalid code %x decoding ext length", c) + } +} + +func (d *Decoder) decodeExt() (interface{}, error) { + c, err := d.readByte() + if err != nil { + return 0, err + } + return d.ext(c) +} + +func (d *Decoder) ext(c byte) (interface{}, error) { + extLen, err := d.parseExtLen(c) + if err != nil { + return nil, err + } + // Save for later use. + d.extLen = extLen + + extId, err := d.readByte() + if err != nil { + return nil, err + } + + if int(extId) >= len(extTypes) { + return nil, fmt.Errorf("msgpack: unregistered ext id=%d", extId) + } + + typ := extTypes[extId] + if typ == nil { + return nil, fmt.Errorf("msgpack: unregistered ext id=%d", extId) + } + + v := reflect.New(typ).Elem() + if err := d.DecodeValue(v); err != nil { + return nil, err + } + + return v.Interface(), nil +} + +func (d *Decoder) skipExt(c byte) error { + n, err := d.parseExtLen(c) + if err != nil { + return err + } + return d.skipN(n) +} + +func (d *Decoder) skipExtHeader(c byte) error { + // Read ext type. + _, err := d.readByte() + if err != nil { + return err + } + // Read ext body len. + for i := 0; i < extHeaderLen(c); i++ { + _, err := d.readByte() + if err != nil { + return err + } + } + return nil +} + +func extHeaderLen(c byte) int { + switch c { + case codes.Ext8: + return 1 + case codes.Ext16: + return 2 + case codes.Ext32: + return 4 + } + return 0 +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/msgpack.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/msgpack.go new file mode 100644 index 00000000000..dbb53161a2c --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/msgpack.go @@ -0,0 +1,19 @@ +package msgpack // import "gopkg.in/vmihailenco/msgpack.v2" + +// Deprecated. Use CustomEncoder. +type Marshaler interface { + MarshalMsgpack() ([]byte, error) +} + +// Deprecated. Use CustomDecoder. +type Unmarshaler interface { + UnmarshalMsgpack([]byte) error +} + +type CustomEncoder interface { + EncodeMsgpack(*Encoder) error +} + +type CustomDecoder interface { + DecodeMsgpack(*Decoder) error +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/tags.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/tags.go new file mode 100644 index 00000000000..7377f115944 --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/tags.go @@ -0,0 +1,44 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package msgpack + +import ( + "strings" +) + +// tagOptions is the string following a comma in a struct field's "json" +// tag, or the empty string. It does not include the leading comma. +type tagOptions string + +// parseTag splits a struct field's json tag into its name and +// comma-separated options. +func parseTag(tag string) (string, tagOptions) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tagOptions(tag[idx+1:]) + } + return tag, tagOptions("") +} + +// Contains reports whether a comma-separated list of options +// contains a particular substr flag. substr must be surrounded by a +// string boundary or commas. +func (o tagOptions) Contains(optionName string) bool { + if len(o) == 0 { + return false + } + s := string(o) + for s != "" { + var next string + i := strings.IndexRune(s, ',') + if i >= 0 { + s, next = s[:i], s[i+1:] + } + if s == optionName { + return true + } + s = next + } + return false +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/time.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/time.go new file mode 100644 index 00000000000..8728894e6af --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/time.go @@ -0,0 +1,59 @@ +package msgpack + +import ( + "fmt" + "reflect" + "time" + + "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() + +func init() { + Register(timeType, encodeTimeValue, decodeTimeValue) +} + +func (e *Encoder) EncodeTime(tm time.Time) error { + if err := e.w.WriteByte(codes.FixedArrayLow | 2); err != nil { + return err + } + if err := e.EncodeInt64(tm.Unix()); err != nil { + return err + } + return e.EncodeInt(tm.Nanosecond()) +} + +func (d *Decoder) DecodeTime() (time.Time, error) { + b, err := d.readByte() + if err != nil { + return time.Time{}, err + } + if b != 0x92 { + return time.Time{}, fmt.Errorf("msgpack: invalid code %x decoding time", b) + } + + sec, err := d.DecodeInt64() + if err != nil { + return time.Time{}, err + } + nsec, err := d.DecodeInt64() + if err != nil { + return time.Time{}, err + } + return time.Unix(sec, nsec), nil +} + +func encodeTimeValue(e *Encoder, v reflect.Value) error { + tm := v.Interface().(time.Time) + return e.EncodeTime(tm) +} + +func decodeTimeValue(d *Decoder, v reflect.Value) error { + tm, err := d.DecodeTime() + if err != nil { + return err + } + v.Set(reflect.ValueOf(tm)) + return nil +} diff --git a/vendor/gopkg.in/vmihailenco/msgpack.v2/types.go b/vendor/gopkg.in/vmihailenco/msgpack.v2/types.go new file mode 100644 index 00000000000..f1770b8c5ba --- /dev/null +++ b/vendor/gopkg.in/vmihailenco/msgpack.v2/types.go @@ -0,0 +1,214 @@ +package msgpack + +import ( + "reflect" + "sync" +) + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +var customEncoderType = reflect.TypeOf((*CustomEncoder)(nil)).Elem() +var customDecoderType = reflect.TypeOf((*CustomDecoder)(nil)).Elem() + +var marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() +var unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + +type encoderFunc func(*Encoder, reflect.Value) error +type decoderFunc func(*Decoder, reflect.Value) error + +var typEncMap = make(map[reflect.Type]encoderFunc) +var typDecMap = make(map[reflect.Type]decoderFunc) + +// Register registers encoder and decoder functions for a type. +// In most cases you should prefer implementing CustomEncoder and +// CustomDecoder interfaces. +func Register(typ reflect.Type, enc encoderFunc, dec decoderFunc) { + if enc != nil { + typEncMap[typ] = enc + } + if dec != nil { + typDecMap[typ] = dec + } +} + +//------------------------------------------------------------------------------ + +var structs = newStructCache() + +type structCache struct { + l sync.RWMutex + m map[reflect.Type]*fields +} + +func newStructCache() *structCache { + return &structCache{ + m: make(map[reflect.Type]*fields), + } +} + +func (m *structCache) Fields(typ reflect.Type) *fields { + m.l.RLock() + fs, ok := m.m[typ] + m.l.RUnlock() + if !ok { + m.l.Lock() + fs, ok = m.m[typ] + if !ok { + fs = getFields(typ) + m.m[typ] = fs + } + m.l.Unlock() + } + + return fs +} + +//------------------------------------------------------------------------------ + +type field struct { + name string + index []int + omitEmpty bool + + encoder encoderFunc + decoder decoderFunc +} + +func (f *field) value(strct reflect.Value) reflect.Value { + return strct.FieldByIndex(f.index) +} + +func (f *field) Omit(strct reflect.Value) bool { + return f.omitEmpty && isEmptyValue(f.value(strct)) +} + +func (f *field) EncodeValue(e *Encoder, strct reflect.Value) error { + return f.encoder(e, f.value(strct)) +} + +func (f *field) DecodeValue(d *Decoder, strct reflect.Value) error { + return f.decoder(d, f.value(strct)) +} + +//------------------------------------------------------------------------------ + +type fields struct { + List []*field + Table map[string]*field + + asArray bool + omitEmpty bool +} + +func newFields(numField int) *fields { + return &fields{ + List: make([]*field, 0, numField), + Table: make(map[string]*field, numField), + } +} + +func (fs *fields) Len() int { + return len(fs.List) +} + +func (fs *fields) Add(field *field) { + fs.List = append(fs.List, field) + fs.Table[field.name] = field + if field.omitEmpty { + fs.omitEmpty = field.omitEmpty + } +} + +func (fs *fields) OmitEmpty(strct reflect.Value) []*field { + if !fs.omitEmpty { + return fs.List + } + + fields := make([]*field, 0, fs.Len()) + for _, f := range fs.List { + if !f.Omit(strct) { + fields = append(fields, f) + } + } + return fields +} + +func getFields(typ reflect.Type) *fields { + numField := typ.NumField() + fs := newFields(numField) + + var omitEmpty bool + for i := 0; i < numField; i++ { + f := typ.Field(i) + + name, opt := parseTag(f.Tag.Get("msgpack")) + if name == "-" { + continue + } + + if f.Name == "_msgpack" { + if opt.Contains("asArray") { + fs.asArray = true + } + if opt.Contains("omitempty") { + omitEmpty = true + } + } + + if f.PkgPath != "" && !f.Anonymous { + continue + } + + if opt.Contains("inline") { + inlineFields(fs, f) + continue + } + + if name == "" { + name = f.Name + } + field := field{ + name: name, + index: f.Index, + omitEmpty: omitEmpty || opt.Contains("omitempty"), + encoder: getEncoder(f.Type), + decoder: getDecoder(f.Type), + } + fs.Add(&field) + } + return fs +} + +func inlineFields(fs *fields, f reflect.StructField) { + typ := f.Type + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + inlinedFields := getFields(typ).List + for _, field := range inlinedFields { + if _, ok := fs.Table[field.name]; ok { + // Don't overwrite shadowed fields. + continue + } + field.index = append(f.Index, field.index...) + fs.Add(field) + } +} + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 4dca573df82..395b96aa5bc 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -2864,6 +2864,18 @@ "revision": "44cc805cf13205b55f69e14bcb69867d1ae92f98", "revisionTime": "2016-08-05T00:47:13Z" }, + { + "checksumSHA1": "OSx+nvOfDkLfsBTZmsDUD2xw1gw=", + "path": "github.com/eclipse/paho.mqtt.golang", + "revision": "0d940dd29fd24f905cd16b28b1209b4977b97e1a", + "revisionTime": "2020-01-21T10:57:43Z" + }, + { + "checksumSHA1": "59nucqU3g1fgFTJiaIoxtKHYGmE=", + "path": "github.com/eclipse/paho.mqtt.golang/packets", + "revision": "0d940dd29fd24f905cd16b28b1209b4977b97e1a", + "revisionTime": "2020-01-21T10:57:43Z" + }, { "checksumSHA1": "Tt1KFInyaxjtvhGI75+crc75n/Q=", "path": "github.com/elastic/ecs/code/go/ecs", @@ -3755,6 +3767,12 @@ "revision": "d520615e531a6bf3fb69406b9eba718261285ec8", "revisionTime": "2016-12-05T14:13:22Z" }, + { + "checksumSHA1": "ajAqUByI39Sfm99F/ZNOguPP3Mk=", + "path": "github.com/gorilla/websocket", + "revision": "c3e18be99d19e6b3e8f1559eea2c161a665c4b6b", + "revisionTime": "2019-08-25T01:20:11Z" + }, { "checksumSHA1": "dF75743hHL364Dx3HKdZbBBFrpE=", "path": "github.com/grpc-ecosystem/go-grpc-prometheus", @@ -5742,12 +5760,6 @@ "version": "v0.7.0", "versionExact": "v0.7.0" }, - { - "path": "google.golang.org/api/internal/gensupport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, { "checksumSHA1": "I4Oe5Q+AuaxmN3duL38r2evqGKk=", "path": "google.golang.org/api/internal/gensupport", @@ -5756,6 +5768,12 @@ "version": "v0.14.0", "versionExact": "v0.14.0" }, + { + "path": "google.golang.org/api/internal/gensupport", + "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", + "version": "v0.7.0", + "versionExact": "v0.7.0" + }, { "checksumSHA1": "nN+zggDyWr8HPYzwltMkzJJr1Jc=", "path": "google.golang.org/api/internal/third_party/uritemplates", @@ -5844,6 +5862,30 @@ "version": "v1.6.5", "versionExact": "v1.6.5" }, + { + "checksumSHA1": "5XkGWfndn+Th+AOFw9u7xLO8Qp8=", + "path": "google.golang.org/appengine/datastore", + "revision": "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880", + "revisionTime": "2019-06-06T17:30:15Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "BmZtAIDebUf0ivXIeQ33/3H4094=", + "path": "google.golang.org/appengine/datastore/internal/cloudkey", + "revision": "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880", + "revisionTime": "2019-06-06T17:30:15Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, + { + "checksumSHA1": "mqxlap2M+qVsEvWvXZ4hOfwLVvw=", + "path": "google.golang.org/appengine/datastore/internal/cloudpb", + "revision": "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880", + "revisionTime": "2019-06-06T17:30:15Z", + "version": "v1.6.1", + "versionExact": "v1.6.1" + }, { "checksumSHA1": "/R9+Y0jX9ijye8Ea6oh/RBwOOg4=", "path": "google.golang.org/appengine/internal", @@ -6655,6 +6697,18 @@ "revision": "3f83fa5005286a7fe593b055f0d7771a7dce4655", "revisionTime": "2016-08-18T02:01:20Z" }, + { + "checksumSHA1": "9zWLKf1I9P/EOJFQwdlf0oWBWdU=", + "path": "gopkg.in/vmihailenco/msgpack.v2", + "revision": "f4f8982de4ef0de18be76456617cc3f5d8d8141e", + "revisionTime": "2017-05-02T10:41:14Z" + }, + { + "checksumSHA1": "KqVHe5SB85yaDcseNq2CogozjRk=", + "path": "gopkg.in/vmihailenco/msgpack.v2/codes", + "revision": "f4f8982de4ef0de18be76456617cc3f5d8d8141e", + "revisionTime": "2017-05-02T10:41:14Z" + }, { "checksumSHA1": "ZSWoOPUNRr5+3dhkLK3C4cZAQPk=", "path": "gopkg.in/yaml.v2", From 05855fdbb8c42a28fe630e7ae0778aad99dce494 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Fri, 31 Jan 2020 09:13:48 +0100 Subject: [PATCH 37/37] Detect Eclipse Public License --- NOTICE.txt | 156 +++++++++++++++++++++++++++++++++++ dev-tools/generate_notice.py | 10 ++- 2 files changed, 164 insertions(+), 2 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 5e3a26acd96..df155af2a02 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1255,6 +1255,99 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------- +Dependency: github.com/eclipse/paho.mqtt.golang +Revision: 0d940dd29fd24f905cd16b28b1209b4977b97e1a +License type (autodetected): EPL-1.0 +./vendor/github.com/eclipse/paho.mqtt.golang/LICENSE: +-------------------------------------------------------------------- +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. +-------------------------------------------------------------------- Dependency: github.com/elastic/ecs Version: v1.4.0 Revision: cc4b36eebec29975f57cd0475c3987c9bde5c15a @@ -2697,6 +2790,35 @@ License type (autodetected): Apache-2.0 Apache License 2.0 +-------------------------------------------------------------------- +Dependency: github.com/gorilla/websocket +Revision: c3e18be99d19e6b3e8f1559eea2c161a665c4b6b +License type (autodetected): BSD-2-Clause +./vendor/github.com/gorilla/websocket/LICENSE: +-------------------------------------------------------------------- +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -------------------------------------------------------------------- Dependency: github.com/grpc-ecosystem/go-grpc-prometheus Revision: ae0d8660c5f2108ca70a3776dbe0fb53cf79f1da @@ -6688,6 +6810,40 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------- +Dependency: gopkg.in/vmihailenco/msgpack.v2 +Revision: f4f8982de4ef0de18be76456617cc3f5d8d8141e +License type (autodetected): BSD-3-Clause +./vendor/gopkg.in/vmihailenco/msgpack.v2/LICENSE: +-------------------------------------------------------------------- +Copyright (c) 2013 The msgpack for Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -------------------------------------------------------------------- Dependency: gopkg.in/yaml.v2 Revision: 5420a8b6744d3b0345ab293f6fcba19c978f1183 diff --git a/dev-tools/generate_notice.py b/dev-tools/generate_notice.py index 645b7ad65ff..ba6d65f0d0c 100644 --- a/dev-tools/generate_notice.py +++ b/dev-tools/generate_notice.py @@ -309,6 +309,10 @@ def create_notice(filename, beat, copyright, vendor_dirs, csvfile, overrides=Non "Creative Commons Attribution-ShareAlike 4.0 International" ] +ECLIPSE_PUBLIC_LICENSE_TITLES = [ + "Eclipse Public License - v 1.0" +] + LGPL_3_LICENSE_TITLE = [ "GNU LESSER GENERAL PUBLIC LICENSE Version 3" ] @@ -348,16 +352,18 @@ def detect_license_summary(content): return "LGPL-3.0" if any(sentence in content[0:1500] for sentence in UNIVERSAL_PERMISSIVE_LICENSE_TITLES): return "UPL-1.0" - + if any(sentence in content[0:1500] for sentence in ECLIPSE_PUBLIC_LICENSE_TITLES): + return "EPL-1.0" return "UNKNOWN" ACCEPTED_LICENSES = [ "Apache-2.0", - "MIT", "BSD-4-Clause", "BSD-3-Clause", "BSD-2-Clause", + "EPL-1.0", + "MIT", "MPL-2.0", "UPL-1.0", ]

      *YV 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ν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¨UGe1anD#`wQ@0$KauR!IBRoQCZ5XXsBZxfB(9- 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%0D;KX1e@|qJC1cs7~!=+ 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 a|HohWS!DmNn{i7RfWXt$&t;ucLK6Ukr5C9H literal 0 HcmV?d00001 diff --git a/metricbeat/docs/images/metricbeat-ibmmq-subscriptions.png b/metricbeat/docs/images/metricbeat-ibmmq-subscriptions.png new file mode 100644 index 0000000000000000000000000000000000000000..44c8f14a90031f6258497f9a853b5033050fa3fe GIT binary patch literal 528065 zcmeEuRZv~qmiER21d@>8?ykYz*|@s~w;kL)Sc1E|1$XzLf#5E|-QDe9IrnxybyxNI zPe1k(QpJ+F=N#j+!8Zjt2^1t8BoGLMA_*2%0=^J|K!}2`;DO(efAMk$frvnoqCzUJ zdWTDJj#FAK@T-{AGwWKvmzI|D8(Ugh(1X`|vwMM`whXpby~i+i`qO>9uqk54wkXE|8KGWMp68~#rj)|b!!2Y_oA9?f~8WZAXs=3)X@QzEgbm8G`yN# zWmf^zo?4Ok6i*-YLjGWdId9r3H{0UuwYlf?mL>t&2J=6w`~T#~|2Oq|HMq0lo#6dI zBB@FvlP&gI&{)y><7V{f>Hk8jxUGZ55`=!+WP=?r5_>t@%<_Xb1-U}cVA7w5^YW0H zq17k!W<};e7VZKh(;SJ#{eeZ?Q9L`zPJvno%{UB=&lsUISMhHw=YRc*8Xs;CV89~~ zBogcS*FMun%=^`ED1NtHNoP7V^bCx1=+5Z7hvDJ<)5dX&3;VneQp(esUsYkeS+Px@ zcCdEYex=6emiPF?AcN(J_#Q`JIPjkQb(i-`M5TTQ@x*M!psQtHMCjf;@*|qj2GKtS zAe}2Tr?c=;Bym!qr$?cWs1= zslUd~6@9~xcP;bJ?h7C^1J%_EWTHS>0+~lHv+d>;V=6rTPifKwg2-|>-XW-3L4Cy8%in@t>R~l)V{=^bEC>Vnl#9E ziwaG29Z@Is(qROW?0d?SsWUi3q<%5L=HAvF4 z_j(6p&Yf4hBI4p0@vl^^c@{N22u3YJ0HE)$S)#m0pMlg!{~TX9zsSt?)%$eHSGW|c z6BLosr2n9hb_8@*@V~6g&c0c$!8Eu?z=t|7*2sRXRd4=UebyCffiVyFNQFBlYC=R`AdPFo{|O;-^}a53 zpC3)QSh?k%QTyFqBr1^@RTAEsN8EjWX5GJ^7dIg8h0*K1z3qpwSHG{kBGhg8NxXj- zetk!d2Kfh->k$pQWBt(wk+AM)3}v=_Ss~2cc=QVfJr1eFb*Xc*Zi_R_FZI&CZF-*g z>!QiLp0J|#-UDwZ2yq4Nr3f*jgVf=LgR2j6o=U}uuRu(`#&<};aWA9I9j-b^uqvzP z!xFdmN4QFq;r_OApP-vtCZ31p9U9#(>U+It;~2xi(a*;QlMOa2b~8J81pJp`KcMg4 z^10Uvayd{UJ&r&lpc4Gp=$9XoBbM16D^$uy6Mk7=S@AaWkO+I)=#S)dKP2>gxJQRW z-WIt%UBe%T_&%&Yuyz{%UJLFF#bm6qSrH_O40X9!AokhV5ZdT667(`ua^+6Oz z4KdrW2{tjc`ySaQOCpt{Oq7$7 zGWfO0R&m|w8CS(+Jf*yxigU?ol($d6TrEcOM>CZ{#r;G|`OHu2JwAg=HD4H+8V6e$3ml!@pXo1&+#H4dZ%%F!7nzP^d0fIoUJ~K zcs|}D4k(j}Rg-;Fthbij9Ex7r&wK70URa;#rNxM}+wF7~{ra|1Ff@)lo^e&ZT&Mdk zH1TZZs0Ex(!^L6@{;u=ucauGl=@6E)ex@($~K5xi}`9ftLMdru-; z9A{giLNE|ZiPH7%IZd~>*m2&{_2xL;UdhYdMd->h{w3}GX7Yd4^#0o(z4`{@Hh%j> zdbd!j&Ryyj+|l^v5PcUku}#0o>^O&2$B0N=rr&azSR8QK4;LjIhzyhX?(?g3nh~3` zxqvB{)vq8W(VOVb?~JD9*`z`J4V+c)XxeGpKMaM+Gw1RQ@%Q!1OXgx8ji2;=+V~uBXG=xwW0Ec zan*@F|K^-)w4)6Q$Fgz^qfb>Mk;8lVB3}?2oS$1DyZ?Zj@@hy@QbSA_rCKx`4NfwK z3`vG#pC7;Fvg^!n zCPM10RK+5X(+>$wCQM40#vPg!A7CEp=X9xuCYoHs@B+}tLl*dgj`{94ROF<6>P2aKE8ofTpZzC? zX|i~&dx~{rami54`V0+sVL0Zy?Bli7hK$LOZQ&py$Yj&5leBJe8+pC5x8P9vw@|_D zBCL1(-3uDGJYsF2I$@5M+a|y^$MQ zqk9BlyHAAyE9#^Xt8&I|ExNS2Uts+C5C#+IUN@YRzok(rB=X?Nfq{?0%QkO{Tty{X zYJYicv*II6GQ0bAAB}j7G6#i7@>O4%5?6jj<)>~E)#49>9rSQf3$>p^wucXq1Fcu8 zaAB4tu)>)ep~0jQ;lV1}G5Jcp)wYClJY($DxiTMI2w9c(M1+y7)EMmNdY%Nxee>Gd zmB=l3oJH#BJkId31t)ywW8cQc^-nPrK#|SY`} zFJmT?X^uJF9o$~1Q6p%PN#}Zdwd7jHhd4Jhd|z8Z6GRLBMA~n-5mbgGZPH+mHP(^HCkkb0 zG}^+!x$+$f=TP1fFUdnd?)O|0uN|vW9{4&|{ORHiEphXH9ZvDdGO_l@98uDJZd2p_8!d;b#jfn?D~3q9;?pn`StK#v zJ2olfX*G&uexGMF7s6Y^;XZuV>%+k2GNq<d*y|XdugG zr5y&*dvhomWvx5-=EU)6c?1;WM?(Y!U<*pg7>%X7rw_cf%8+((O;KCp%CG7 z+2iRpU#UJM_=-KS(?_vcQE&z#2Vd+kuJ;T~&b31t6a$l-tP+VneYt(cnO|JBK_VJ3 z>+5*QP&a2W8wnW8#wYwzPwD$1?L^t5;$hUf!Fh=y>^#YU6}ISBt=^it$0hvx?-NW$ z-5=}Zv}fzR(z#~F)8}{2>RJ!UJ6JmX2~r{7<i2)a%b;2!j3GtN9t-wt(SBJl0U8nzX5hrG*li_G|Boy zLVQr{(>01*WCqD&^oA?ju(mECvk|xF6<#3YCvTNAM9w!@f-JC6wVvm{j;z?N``bk* zr>0>%>Lfg88~qfV4;fw)am^?%YTLp`>9sxiw!G0NQtGh26>zrOH&&C<>W^D}#y3>Ik!Ek!7%J84>M?0nJ}9KrqN zTme)9?&3>Yp+53ZGg4=|i<`N?(8TfDX!lu4=O%VSDf63sM`bIgp8`i*!+znw={brVnOqR{1>Il_Vuw zz_*2lfz^Y>_u*PJ#Q7oUQr%t#nVH_bK6{`TH3>p-8f;=}9RprBHsPY$S1av5<@;X` zfrR&=Ud@1FwtGl_d-+B}TGkI*ZU(h>^wLk;b&5L2s2%_g!{wWYkX~bpE|)&7O7t^{ zfek=62IE>383dg6&@Lx;>u0fMQI=BUxng1oG8WOa9;N|rDoTV+E$+^@kUdBA0Z@8l z_t4>Sd%5?~us1AXiaIt&!SA;%OOcupweRI>HX(z4%ePWr=20Oe8kYtB;xRno5Zla+EKVP z9v?XQ4Bqa<3jKFHYOnL8l0U#*Y}dLyPc$9+tY32Jw0I*&5(sp+xDdXjw=~X^iH3!{ z*b=QRR2=F%J>Q}&U2K)s)XxFy^@L%=@W1GN8SO~4TbX@xw$UdPPGho$Gpax?6G1ww z+;_KortJB2k3t25yiCFv6$P8I=dG>pw^((tMtp z>FtH1PvNKr1E|ya@OLP3A_MJoOpbU&*yY|N31ngFXBssri6~P=nlZJnVZm#5tztZ4+(xqjFkXdh zCHheBh*v~nAs-MI8_KKP!mkhKBl(|#lEQx|fh=C0MRw;Gbs>v+c6_xqvlH7_H|H4$ zC-Xu3Qn`FVS*}%GrVp@ezAE|de7ub(C6@>Kr&15z_9Z$5Fb`KM*Rhq!4L6=!7m5kn z!#E`N#uqNx0ZGm$%in9iq0>^}OjVR+MCOAgVkzb0%>xTwgI@PW| zV)tui`q&*UpltaZ^SOR)tTG}Nf>w`XP=%&eBCD}r96gTCr92%K_-^}>&A55;dT)Xx zy;Xq4toC+<$9A>SUPg2CDT>w%^$&@Yh)C-MxY!>#35UJV-*In3a8Yep+MfSjtjlaP zgHQe0@n8HYP^IXc%Y^{oZX%7gYf)sHhH;F_NYu&{96XVo?H*4ana98DFn1XB`iwgI z1$Pyswo(r@Kjvywbz%71u`nGqsZ{7`7STA~ovWttZ}``ky{ImCQ!5uJESpJQP7BfN zBxmW#OJjQE?6A`5)@v=X4ot$_U2Ijk>;H5Kn>lLk+9^H8`Bm-o%W{h+xi$6sXo|m$ zeml*<#m=Zdz#TOX52j0IlXz^Ro6C&9HJ8zWeeC2!u_aa;mZRHc0bt?&Eyln(Ih#lzX~u;CRy^O zsc!1>$%$6*H@Q-o9U|7LL+iZ1%Uvif{=6{XYiqQh*5Z9sbl3F0%JaONP^+Nl_j)(6e&eLu9`j;4ddo<&R2f<+UT3?Ef(Di_>KJJd}w z@d;q7HZ~D+WDD7Oq#@ zWxY@2;IUi>WHRZrvGwbV#B#&4>MOOI#B`kLk`T|PYV0GQy?qp!%}I* zQN72}LfISC;W&e6I{8fg{#$B?)AMPo(2YW!Y%x$*wOb1$NdbL>&opJ2 zkL@KJ16 z<%!9Z8nmo7yCu!w)7-}8Ud`@|k*}r+j#n_XGI@W19Vt-a8~2kfK-5nAaZxlRGkpTi zL$;!!7}M*{h=H{hvtnh>MhjqQ2LIn4+G(8h5Ltho1k`nA`?pe$uN()i6^$qik5aK)R&pvx!$z|2II z4xtzH@`T?){XvNGcdsFKO(deLJps|O3=+S#@PkC{*FP+H9&XP_i>Ix>0>GN8MEV2c z>qy0IKS~Mss6#|%t?EXX7pP)YjsRBN#L+H18t{LmFQAT}golmp$KN`%p(G3r)j6nl0Qmhw=rM=&jn-Mq5Qf7qehl2F81)R_6 zFc@^rMDahGI`)KNpt~Fk^z=t&#zD}?a27g{bIgmQTYX-j_~2c!;1baq`^3Vq#%(XQ z@mn8Gh2}X_&&hUYs+!ziLqL*UvYFnGNS?J+(eYlH0zMWWs;g9*Byj~}s`mP+pL#=a zac{f`vBRbB2_`y1HE*S^ak)MR;bg^BDhkgwzIxC8nt=CIxu4<*^>7KQ%CMKI+Wqnt zF(@L#)Ug!&j)cf={r2?2!_bi+eSuxPd5U`KsSb*)%s(x%-EycemKdj8RS+JY#IO@B6}Yt;U-hbeW&XYwoq4`BXJ|QPxAr| z=5jFU2IT&@>xFNVGq$a56r@%OGSBdT@l?PM&`NJDJJIiA(yQT(rf{OUidq1-1*f)06#{A7HN(RZd{JBZpOk?^?|B?LZiS*ScdC=a^ zwRE+Tc=O1uufPMJ+f25nYB7s;nJj;##7>W4_a)1I3-PtwiE#Q#Fx=XlAY;v_UsZrJ z!L-Ck1w{tYFMz^6>as^Fv8?n5v?~YK32KZd> z2Axvj<7pBCA3B$Xyl=FSh~^*o<1chu$B^yTd)RSG*z-t61M68*^JBF*eF_xG(*fvV zWxMm-=8HkkQ=H0287Axp?RM0>lv;0I;k|4r&<|)T;fU{@1c-=!jT{}&sSU=Qj{Xpl zh-XI&(ye!mXpU52ww%fF@3?6@taKhWB$G-KT$)`TRV->$Ep|k|!kQ`0kjyU@mt81) zlEx}m`0=>EQV$Ilx;tiaTcD%UYSiJ1@a!wsv~Yc)-f43t6%U_@*O_5FFCkOR!D_!q z)mxdS#at+@G?@)F`+I)fBQZ2_d`D#;n`06JyUqN!1bUoo6XfnU!UweInn)D$B8&pg zO9fu)IvviFrPVPvhj*tLZEw+O9{Ev8g! zttC;0Lk8trhwEanlKp=0nu=k>_GI!M+Ih4XMJ6g9yHJ@{9IpilYq2(*9b0T{e)Cii zy+_>je2uZ-FN(TphY9#7W0N!u=J8?+$Q7@NC)(E-lja*Va6Y+aj#%iIgm6n@%?Z({ zfeV(1t5layJImdcE9Y;3Myl899*hwA9Q;aKpY3F|>#V;3ZK8OZiViMHrep~Gvk-v10AR&FUh#RAOy#-1sd>dp z>E=%4!@uN35qq+wm&s}Z?`%D*YgWWE-e!fcwK5V-LSq!)JJDm2?5ba)#%3b?;PbL1 zG>oGfZ&eJj;{NnJp4)Fe*H|~+^8(1Aq=3ildVh%hhXtvYprH3k#nXjErxar@jDdgLFgl&PjvEFt z%@`F<=(Y2D-QK=?xFPIHs%p-PgoR0<%P4!~NsE1-BVNZihBF0jO1xE9OR6-VP6b5}#{%?_c zlOL_vQHT!(p*wkd8r6>R)mp`F@r?T7C^rDUeS9RyRWj**fNY0-6DJoL=AJD*1&9&7 zHue`U+*wBdk`lWyW}wI!^}h&x9|;15KBxWuJxDuR^SoTkCMSUqb=e;S5>AwZM6*g7 z>NL6I10Us&XBdg8?5}OJr2~U4LJ2;j`mD{En|zd`O)7ycwr4CD3_1lt0(nmn5UY4I z?F7KZ%hJAS=k)GUU{(;8%9qBFm}B}>`O^8RRHshPtK(-)9psl~-F+0hZysS5UW@1% z$=A2U(0|k}CGt?})Wb60yp!*mllOr45@nwu5t*(aHDn1R7fTr~-rm|2zwPIBlhQ8l z<@GeyXrY~ZQKni$gM>a9JPPDkPIB&$Uw5Dp$GdI2$_j1%3_8(UhzbdlUA|jtt``Bs zgtO}<9y;Cjg+irxi><6I9eM4WgNSqwCWBSmx^HdqYsSHD7l{VfT)p#C|Vasm$M}C!SNIPa*QCFO}-NJ6$sp|A9Ms zBO}N!(I1`}hED4Q<r?hnT{Rk3sf>;}U<67QSG}CKrqi`>rsvV*l&j1D$#3-d~`Y7pS~Y^>U+q zx}}N|OxiTey5a=&XZjy_MZS)ka~5PWZ!yCU_9(tuVkRH1{PGH`rtvvGG}mYdX?9DQ zHPmVJl)YOt0?Ug|KeDuxdR$!Nn~v)HsZhs~xJ1x>eadx@vH%syUNrxVVNRc~N-SUa zDk9+&n}_>{ccpmrumW<1A$1&eHnN&UV#)019}azTd#iZoT{hea53M|(^L zp(k-e5~cy1!|zg}q<$nqaSoW_bA|F--bYg+D8%RtafBQF;Y^mK=!tpfF?0p-+?Ob_ zlycIAeMUV*PKF)zB7lpuM%ri4-3PI}Fp=ISG8x$3G+jKRp&cIu>_uRnRheVdm{cePdwsrHp*%_=Ki^9 zU)1w%j2!SnxWvhJzU~tf{Jvr1P74s_cDD8(N@hty5dk1F4cW_56Y{9!$2eyeJI|wH za?|%4JkI+?L85u*3h61+3MCQ5aD;K7iRGnKCfn0jcwC-3*#6pE=U8(U-^UyCyL9Kz zr>74%3~vSVn^W4GlPs84C-P~fqC`59)EKIqATpWVZVul`jo>#%0|1L<^Oi+ZKLbTN z6jnOq1C4Kv7&5W$0;}n)$TeaFC?;Pp)UzJkDevR8Ik!;EwJ;{yC$qYO4CpFfg@1jzqGyYXn_$y?=NqN@7UjQ%wt)RH) zxrm_h+P#{ywWg)SH=>A)Cby5Ko#4)Q{B}g&lCoD6z*QGo zq}ftGJYFjaQ}@jRG@wMD!l3)G`cqLiY5vj+BksWBph>IQI{ut6wi@;l-{L+(z|Okj zUdHioLK-D=dpHqUnb&FM-BqZ?sl`FU^jCb^f@-(9pH*|W8!a6=q4Rpmt2m71!w>S% zu@;jBY74NN4pW!U$sA@lET*g~p!l6q%kXBi#QO}j{Hjb!B7i<4WLKrOHZb$_1M>HLnrT{E?O zFriEev)7j;f%DJquf5R8C$plxz4lqDt6cqN<=a|;+EnB-+*kN}$rY_hhV{UC?E_7( z^w;$&T^|}tK~w^zH-cb0*X$~*rx_j4W+S>P^%k_WcP_*LphJ8PBb**xXIMB@ zNJfKG%r~^CO9u$ZkDPD0_ryA!7pIYjOlE5|Y1|%q^Xj<($04Vf`XiiwGJ&u{c<(h z^f-i?b&9%dY4s-zd5$>q{YYWJ>NWy>JB<3#EOvCFuTC~ss2^JRn4t0kkz1Ke_UY(! zYIXKjCVC!zh=_msHIqJgog;>1aG11)#blcV6c^_&^?N;zN0MOG=z`&eq7u}@l@Rbd zluvQKa$gc7*ll$D8tsPtjR)(2z=-j#`IhT~o!9*(V*a3tstEB61-{Si>AUw7a)C0& z31Y>#`LeN6cMX4bXdSi%B|4bfWiL15qPA!w4oRZgac_Cn)K#ow5^x8ZEY4-Ne)J=QTW>?8)3goKn z(Xfm3+zXkXDBtBrs?j^4-^##%>-i;QVZ@d8N|ZfBwi-%i%X5Xg)%M*|;p2?`>p(H2 z?L3zU0)095SL^=BoGa05dvmt3>~WAri>a8|Nck2o~n4mLWJm{Z1GkO&2b< zsD?|z0-@cxz8(0;>vfM8naS6Gh3hgE6L3rO~}= z5$Z7no1G2>rpilFztV@+vjnuw3gQY@V<5$}ll7<+e*I+c{g*%)R1TfOu0Z~8A!TIVl46pkmED+@Uah={0E=*D&R1^hBA)7XkpNd_{N^Jv< zXV)oVrJ5|*W$Y+K=u}a&RIezeEBoAEtKN*mBV5J@_4GueN0Eqye6>fnEL1J8omGdQ zD72#mf)Bdb%99jVy9>En9mQME=d>( z@bteRD$zq`%iHE$R+$I{+zrp3*~(Bq;6dd90yU|p>yp`*y__=JoHhxWZsO`pSS%?F z+ApuMC#XkL>cl)4ElXnNAD+j8LI&gL{Q%imV`&;V<^eYg8g4fkTpp-pi;jwsRj$#P z6L~X%)Fz0#E$X;}ENv&&ft)iob7AjD`%C(#;q7aQ(XG(4WdvGkGl_+oGV040TkoWq zy!x#3zm@rx<@5i`&U0LI(2T&J&ky>(0&pV|F{gM|6YR}pTy)x9e%d@KEx-Yof-Lx^ z@9|jwTx}Q6RyyKTE7STOhn*mXJ2LLget*M7^DvU$@am)Ki0Xaxj$wa&-79pd8+{+8 zpt)Zje&;rB9TnPbqDuvYq5nGd=CoE8{RM5GmAp0SE>G4`4iZSbJ=O949U~ctz+3pl z7GQHgu*UwkV%d*Hf5|-Cm}meJtYW50Z|e`>=?$`Kl%@oo;KKmq=@XsHHsSiKcc z2D?Q5fc&SRU5dvABqDVBINZ7t)mrZ3MVAw!AyHlGCgD5#tmQ}|<(&+Xv%O!KoIDa; zjcY+tj0xN+{2quS`mM#*IQ*5khJ8#jrwMi;X9C|}0s{)H>1Uw9Y$XXIXI*!6$J`cu zo;pp=((~-5=8U;yrF*D=UbNA*Wi@Ci0T-3g?upz1#LMZWM9IReybL`A306A+kctK2 zaqKRNHH+__E>*;CbKj@dBsGeYI@lZXiPLfj{1lH>)0gOekH)}WrNMD=p-TTg$^8q4UmR-Jnnw38yxr( zu|D6lu%2s#lZbfERqL&sIU7YKl0+x*LZ^Ph%I}(5>+WZoF#3YC84W2wxA>#$!0>3Z zmx-ovR>iNXC)-b}L=yYo=K%hq6xFY2Ao|p9McFK^nmA31LG%8U5%Bf4LxuGZNiqR_7&3KrRs;T|Ty4+>+h_PPwu812>DWF*g-9fMF!6+zwEG zHn{LSiI>jUMRye`Nw`nU!Vtq(2hnq9E%R%@?zns=(yp?9T47EzJ z#!TU0ibZec*@k$QE%C1(>QVvD1b-$&!J(!9qJq_2Ds zwwA2!`Ri0=CA#A1wO!afD2xN^qC&2DJ)a1El-c7u#k2cCP`Rq=0M*uwJd< zzFh0px%2gfrRTBMe7MBswq|9A%&3~uDKIhe_D3o`LvVB^)R1|d_UVAI`1VTnaQ)73 z?0aR3NYxqb2kY9IqP>qiKFhC-!4)OWMNghqiv`#zY-}p&lQ(8Z3*751{uc2cpFAo| zQb$g?9x7O15$y+^F3&S69?RZ%xXGnNkV~smA4vV>eFar&`1&=${C~CM5~X|wf_uI$ zAXyXU9ksM@@2m4=(#&(LUYDaM5)<=amQmSdx@=C2I;_61aU~Q0wvX?r_QHHKTr8z3Y4mdttpFLTDM>HTJ5M3^1H%}|Bi1Bb}$0Lo1z*Fp^*W{=u>Gx zEIqs3`{?u_8u|S7GH6oEvvjzt&?MycoGL_%E!(G_83EXF@u3ev^|a`n#$8Xl%DWKd z6^CUDKJ%WY?PfnNs=<*>4pKrDm4Ed4fhLn$UNS}UYk5h@e(JV{o)ZRqzcI)*-)KP_ z6v+fTzeJPR-|5ZQ6nuR5A6bBS3P3+fVPC?%z@$@+NM}*Cr_<(@V7q_3L+*i`#l)+1 zd)U9oU~vFVXP5s%Hd9v{-KUf<>Bl?43AHh1zH$rldOM?_Y;g1!%bKiK580LP3zcDe zoS%QU0{O_4l9ELFbbla3LF)j}2d`Bjg$C{X45aq1;?s zRB7wS&{L-W%;ko2#B<5yVft`M_yx$T(H@Y4cK9nB7W$?ZJI)RotZ1*`fQI5_-YqPP zGb{4oO#jK9PqqYSKN12Q()||y>yK*1W0F)F{EWuYL~AMWp>dXwVQoi+nZ1$-)rx6_ zr^Cvt$2qGZ=fB5{Ct?3Y--dxmMLDO}Hr{W9YvEoblWEg7_cuL&EDJyGWP#k*xctYPYCZkC`Fou%&nH9WvEWfXi_{P!L;|=L-1^yh*!AifG z=6DgA|0r?VBg`qdQd#R@O!qT^FuI$YYj7z0377_Ws{{li2?am8Y~x*xvSXn%$A+~(R#6*pNe2{9gx5wbYm1t~?8VvpxkU3u&tb|kK{ z*)-W7#)w_yx|=M8wtB2YyWXt%E0LQmxaty(EU>t*(>=P}_*J_dRxaDx+4TX&?O6V( zty7}8B1x`-pAI;l7jeBWJe(?8Hx5#RS=wWfi9FZ=^Iq^ji23!&Y#Rz1d6>-#=U>^2 zF&L4=&-c`R(X0dOoz&Jzf&wKA`2J{uG2a%@X{J?ZM=p;hQ4rT#azrR~!Gaiw5FqcR zd)H6~QtD@Do1!66>dm&;xOYy^R8e?Uf>;i3g4UW3qm^pxwbn(>3R%`$>RrgQ(53{$ zehXUlq+`-qUitR*{rw1ht!%~a=E1fs-IZdK_nRZ>-TDouYuzR20qmcDhkPP+M5i~7 z&JrC^5>q77Cm@qcd;9G@dCvx=ykcF-n)~A*fT@Ck(E?gkN8=)es@L#V?NdNhLb8R; zilfu0_Iq`tN;i;QM$fzN4I~`(cyebO&v)Q4@vw!B%F~A!WC7z0Q9DJhk|Lcl+T{Ie zAj$g)xq?}>!)S<-*LUZ(0@t%gpTWD@&(pA1`!hYju)%ni9WC3dBz_Ssx+I?NLvN&S zpqS^Zg{W}YwV8_XKwp4g7Q~ldKFFtU2f`scbbs&Q5dJow#o!RfPxHj>$qx9qChB#e2I>4WQaoVKe>?w2@)pBLMmPz?K~R9zfJL6R$Wg5}?P{Vdhm zy`L6#H9ybP@-NggYiKRL45v0wsdXu+R$Ij0o6pX;3b=jFXPE{D!s0&%q3(T$?GE|C z2FoZ5^SNMInKDu=;Oo0b9+X~9n#uvRB+$e?N-DEqUU`aXT4Pm}TQ}0sA9!sxtUO}@ zBUj*Gb@&5iJ^&8dKn>O=L{9QjxX# zw>H-iVg0w}#Qi!XiSo`dXJmp=FFFCcefWzw3xeftB{Mjkg4|Rl-S?-!cFLj$M6bg; zcc|$Skkl|fS7XRjH`qwjKWxE(89sFxbx+)VO%qj*7VY4DzJ)@U$M4A>&3wEnL??$g zHTxAjmQ5!QebwM^VEy)wng$!yrP~~G(%rw7TaihE!Qf06kj#TlsG9~u{}U8*1eyq< zZ>jRS5$ffT%(>m2EDN_RD+^PpvSwDHQXV?w25S@=jb=-k|Lg#e>(0%IfWcNXJ*W41 zS~a(F5UcsDFeZhqBS^CNHOk(~{61f;-6DbYqMP7+c^NCK^`#2$rAKM$4c71Xin&@1 zaaqx@5yr{=ng2^B&2i)Yg3mKVHtT|C4l>l%LEa>(Va@$b9gWq^5Hd*r3{rdN`#o!A1Z_Bl_T*|=? zkL%q4Ew&Q)pODV1wYe&<$ZGi+>*RQYK>pLh6R`G`(9F|5R9<$s_#gSW*53-ovzry+R7%p(KlDecs3z)4SB;KlIG}&i*@bW=w*Z3}^?i9eX&a)LZE-Ga?$Z;w~ zdh%s-YGuv1_tz}tmW3;OcNdth569`}Wg>B(R%Pt|f<{|H_$-+*!O_B2K@%;}g#xtb00|ommCk8q8NacZqNfCEl3H4|rT|%+)or}CJ&));<@PBD%HF1P(33oAQtXi#|zX~-_x%w$X&JAyhf`GYQP9RCa9&M$r{8iZNDWu|t zVEv+O@%D1F=$-baB!O$HraC%hB{B?nM&#oTqi*jI*RLrl(SK*G1}5GY4E?y$cKL8` z*Zt5rFI<;~%kk2EThuJs@R!==(k<$w-_hUbc|>8@_ce$Pdoo$K>kXkmj#cKn!FwS3 zWbjz%J=lSdFBrq`;cV%*IpFyIsxCC_Q)lHjDL6{apzD(_b5)M2$hAN6z5ra^yKE4{ zrrU^e)NoB{DPXL&C^pwYTX&!Z(t>KRp{DyaN9bq}(3e_~!e9ltud#BjdF)ht*v#$z z3T-wi%om`DC!-24GJHPN0OA!wMGMBwj}G^Ez?5Qcxw9x}Z@gyK_52aVP&^cNc21H0 z9@f-E0S4Ue9T`RgGVfnyb3m&$`Pljk@+bMAWe!8Qzz<~8QHpW^@rs2^KI63#lq4?u zq}&%q#cC>E@z*Ryh(CKQv>^xV=H+Uk(WlerL5G~}%w>{}R zHww9Gq;;cW$Zb$PcjrEZs^7n9p@`}?39pO*fz$d(oR9CUX02IqJx1^}!=()1 z)q&Ezu2Q0@kCJbWFi|i2k=1HJL3c|ZBq>a*TEd|~ua`FnNMJE<_Q?3v@2E+}Pb5^Qn~Wn>y>K z1SOJ9jpce!n*5HX80`c~<+Q_GwFUWl&o_wUi{x&8jyC?)g5%MIT#*{N^dDHXQdfdW zte6w<$E|Z%f*+ppP}Xk~hwi*5FFesZdQe$5`GqkmCK_AJ3*>o4u2RBP-b}i9DgcqG zwv6YtOJM%MLYRMbZ_W$uHvH#`4yqL8g!{nE`vH(x55x=Kx%Y9QZpA95+rYt2#%%OWH&gTZELHY0ex0Y3# zcYme6uQTLLwKUJOOcCU@(DEHnNzQ_ui0)ItK|jutTB~}oEhH7Qmk02g=x9oFYa?Z8j~qn z&(+=B;;`?MY4yC5(kw$EYID64xWr}A(`5XV6n(rjO!I1~-Gk7GVqYnBZ!%A`pS@W! z251~HG~l-8T2^Gm;gl9UejxeS&sG+9c{q>!8jD|%Z|k}YhsdaTN*sPPqa)zql{{O| zbb*^Lo3+!`0=?_Vn5+z=b~O`?I#YQX(GHixF-uy9tLo85CMdGK?^Y*kx0hR?6Y@od za0c9j@P^H_VEKXyZ!^4$08^;v7(_a%CjFBeu%R7F3j43DicxMjT@2y?zd%8@+T0aPNY<^!Ir88$m{ z7`Fx3@>KgiNv<9pszvW@WQWOoc~CUzqIq8IVIFv9l`$VEDa-YBI(}i{tz@JR zCZMc2O%#MqLK22dX4foNVOk{yGH?9-^9hK%=4 zbxh9f5kJTqNh5%I z>giz*5I3&XI8P~Eqp-g6;Hwbc!#WMNaP2bVd0?0^7nb|Z!{?>)v@V(AJ3|<3zUdiSxfSE`6tt0X^YYFyh&+230ckSTKAI?XtvS9d@q*D;z4#HqUP{aPzneM+&W>!2f?GSAQ)?^!50h@6t&S_3`oPxyx2mqCIv?=1;` zF~<*EZ)+#;Ia4{n zfjI09h4|I(y-K(!zgHU>0M;tnut^jHm77nGx6-@ayBnU&aw^1@Jlu|@)+~w-&yBds1wUJh zoM?#sW>GF>7G(qdS?bXgASKe$m_?xDE_c~1mnO>yWVhk;qUYJkd7S-eQftZo^(caW zVQ~CFI;V+C^|jv;7kZE^$b0faR$h-Eg^+c~psh1PT_$)bw8-E8g&1~C5Wm#A?vw00 zr|)8=q->f4ix#`1;cS{L1Sr3b9Xp>6=M&TOvY3JqnME;wquH^AYY>O)G+@*@Q(|E! zi?v>rD_zM&S}}O)of6}$nKU@SeAOe3+;=6&*`ySkc-fmb`3&_17!_V48H2wY^jTlY zO1MXPf#$duH}lxNJTEGTk>@)CbwM>|c{Hg;I#Z5_`Dyh@s{(>h^E$~+}?=NUc z>DbGsx8pGI;099MA-mh8=F#^JF5nT>&X27(2)G{^iEMgj>N+6@uCXdU(gd0i-lC3) zt%Rgg}A))^cP!&w+{V3=7aB^);HF*SI4j47)Mi85kv2>xld` zSak(RfrJFWLznSmi#32QLI!$=#jhccw-zK`8|t~NX?5n=-5$Xig4)4e9cK4&dI!0g zX}G-Jo))^}`+_yonDz5BKx*N1qbi9t%NDmOfGIYX(}Omw_-!c^MdJ1!KCcG`@T7A% zTi(PL2~!qD;qAS{Uy^yhU;j}_oJk1{b=f6TE;Ou=5KVoXy1m$YF;Cp_xQ#W#-pK-X zE0l6n4GOd@?oyVUbzLzxH&5OZw0l861@BM#r0zY$F;$IxjsEyS+Jr@)g*N?haL^8% z<1>8vV#a7#t^Fab-9g$41$cF?QAz9|8Gu(iwC(L8&7!df(N9-_S>c|S3ntCzdC*j9v_5f-Esg42#?x-Ft*DoK- z=-4GR&}bjcX3)Mi!)@F1ASuh=#z0TT%Qa$4K0^20=w!QU44=&&izPcBdf&QS`{ppj z^Ys+#SzwUgdK+UiN=j(iv_^YjF^Aga@&4hv=p3b}TT)kv#lxs{KCoqNbf%TSY6FLJ zyi0*v(t+4+g&WInBjQju5N7)%5*Iic4*yf9(?Vd`ovQB}1eFle_%=$iru3UBWqevU z-{MmXJ!la2N&_0pscwop9CS?$&cUd}%immP4EiCt*KK-VX*HH^AY?+per}t$z(5eF z69Pr8=z)j}RzSrfzk1Je_d-TT?^E_2Z3KgP^%Dzy2*nqFybK`pQ7@V;F zQu4&scBUGi<2biE3#KJ}Q<#n@2V=z!pDn0q(7DJm%*Fpw`||o!6%R!TpVM7NGUa3u zn=*>fW==f~%R-GlF6z#R7H^eieM{#(;DCt1DjCp0G6uRTs+MQ0V?EhuFk=gJ`VjmU zqxT+-SDA;-4EfWBIYFhTAD@ym8)e50*wl&^0dt~qfkQm6c=`AudG1zi^ z;I{I)t9RcMJ_bfHdi6=~>xOlynNKwG7(Xx@xsfrT45Sf>JjL&UXkM2(IJuKSneat# zWLIG*po!aJ>!4>W`)i^W!x`YF#O0y76rCiXFOkY#6yw?P!*e=fE~BiI;hC8wXltL0 z_iJuYQq_rKnu4V{MLhQm)XkcA$`x=#Q7c(S(of>51(dBneBn1u+$u2JVrKp5BNxP+gre|bK^**K(&>YH<7Gms7DWF$MOX<^v_tIf0 z#p;h90^Du@j+`=C@1Wik^qE)_7)*aGefUsHg~f*>!zS!H-Dt5UZo*JbN3>4xN&l?3 zZ4V zm)pnmM!=$=!yf!C7@8(eRg^97T2<$U$^5_@RKb=}f^t3!W__t4U!6|=NNf%v(`lj{ z5)3!;;-%J7J15(Xpn6vJJ?n6$V*jX5u4&E z9phbY7mw|LhKFK>7u#Nv8~R{+4-k9UT)vTtiDkukDQ&? zP|yUmf!iSC7P0}UkS4UE*V)M>Lwl1HyIsx}qZ}!i<~78>+K4Bb_tt5rx2ChLhDjqq z`PNs#jq!{Eb!B;%C$G=P8GtpW5BnPms9fjqjDkzN4!@3j!XzI~Z8X8dmZx%DW4!Gk z3r6-Bm~H;;$LO83;*g^1>Bhcc(JAA8QI}8!&bkMVJ(ZT+^8>9=^|1WBvdq;XrX*`B zPh_3mT0_6#sOHsg&4Eqz&y>q!FH`Mi^$2N_Rwo_}Rtg*|81-H=S3({D+veAjnSAg<2WZP*BaPPz<+$#k>G`E?1fu=luh;_6VDq2HVQh`uVP*xYrGDF zYL_Mv^Tj?hYAciIFQkM)!w^RYU7M9-d=4c-ovD>sG)=&ck8bmQcY}ugMD}@3AB?9y zx)Y+A=&G8qq{mD{Yb10WJesQ3MYhq1*x;$HaJiWDW89`@N~lj@J(}#nN28(=Zl9(( zS`9W3BO>i>uF}yMKbyv!JViHHRP-pfbs@Pzxu6U)xo;pmUe?t?*{;lSAeANmOs-Xq zu{a8X>80ooevzi%xX)z6P?A+M1J)w$&%8CZ)#)u5b};nG*$@UfTD-WDMq~vt^Ah21 z-fTB{sEkEz=w+a=GZJvt4x#xs;PCqxD9nmyK3EJrie@{OFU zJSWNFn)$b#`+aPK!I+~lkMZsp_Pd8W!tUJq1{bp#*7g=n!g60k^Ju4mD6LlA)=LLI z$S`O?^G{Of(FbcgmDyD`t1#-wlX8Nno%Pg)f=gDN;XZ;&f_sHMn=dJp4G^ZnxaTfh zxj`rHi}NQBe*Le-KTTuP-i9fO?e)a(_IYZIN3BYwfew6k4}Z+&GN-x;&AOv!ctS?1 ztm4MqG6+n*e?GC_Y`NU#GG&`GQBuz)FDJf|2s28(lyY@Wcmdxhx&)wdU7WMi`mbd9yym*5h1=$T!N0-L~r%j0`r3qEs{QJ7O^F zNv4)#O!@TYl6sv)Q#ClYMEhoiSVGdQ>|~P_lQmo+zZ=$acol1+pL`Fk%wm^aCN-P_#eePQjvq%t{uDd|2C@Lqnl8dvNKZ?RNCcFht)YRu7o zo+<$|)I{k>?kGvv)zE2qKukJ>EcH?<#gXhe30kiQf&@bZR0E)+{q^CGOk#&GlzLJz zasc{%I%rLUL8C$$22`MT@fg4Ydl~V(?C$F;w_3+&6HnUnK83sQz&pQO3{KZ7Nxis3 zn(N>9scOSWSC?dGsW+J6F`(6*WC9lA9$`%I4OW<-uo@maUh}kDD{Y2jPJYXT{>2Ek zkfO_S@eA(IcO_nD(s&-prUj7x z$rJ_8EAdd=+_f_G9+RcQi4SjuA`v;RNPkRSoPGm9lc4nZd1)gb0#R41{CiPvt)j{+ z3N(v?THaiiLT&63LYC&M_;ud@NR~BJj*{6H8iyFcD9(Q+NO3hl^E-uz$!nIH4<6-R(3Fqu8Q3IdYzWn$vd)C)#VCn9ef|=I-~y-)kpFK$Fh~f zdp^^%`Vq*^J9#*Ypqj@3`nu_S(oD3Cjo^ zKN3>e*O%d7EOVLH;dUjmwb|_zmGh6emHvf}(D3kVMFk(FFOTHNhk`nz!m%ZC#Iw3y z=|Y7JPt|bnh<@MQzomdhzWApZEVfS=+0lh{HKTYWpMN{Wxg!tIY&8GNMAWpS&+$?X zB%EP9`fYe|-O={AMFs)osHP*e`VHL7Vw=hKQOL2Bb@`M_%u=1jUjD&$uyVV}w{Gl3 zq&_Hh)+}y3Uj~C^Jk&>}RYFxseQ{Lx3ZSYdz4jXxQQ{^SmpJq(hRrzwHVlN@j?Oz` zDdMTcbv;8|vFO;!bK#e9&!yS;EkNAm8xK45M(p>;OrdY|iFgd41OznDKFNNoGUnq{W-s zB~%=#`eH`V7F^VKq^j2Ycuocs7)m&q6}i$qG$gPRW4;jfZYOd57^8_iu|Fgc=Fvm% zS=MH8;NWJiYGq^{BOE!#--|2YJ;Asc-qWrWxwOAd(*#9C?$}!4(_!GSnhsxFjKgfs zCA=HjH5V>Kj1}#@{AzJAf+F42=r5S-U-oAaApU6v`C>`rkIqu%PNG>LSDFKBu@<b+R6$Uh+v6de4=MrVC|fF`Nt#z_gg`Yve| zef>sT#jh6J=g!G0UHZ%0=J0z2!TNNBgb&jV`5@gtN?ZWkl;c(r5rpRa1jdbIpL|ZB>bKp@1G|~R%QiV@g;%I+ za4R^jCPNSY|;PXH3f+eRxXm}VA&+M1x^l1+G6!W`Yh2DcmLd_{zC@)i$B*p zV0|2DXB0S_ZiR!k)O+H&xXqqm1+slaxD9G0&L4GtmN;(=c+@f=d^VY~so@w8lCes& zbjPPNcy%mje?kB$c31)lIOsj?R%cxMh>R;iezJzK44xHLJSBwWl9*vH6dKX!C?;c}Ag z%s?xm%17Z4YW2Y7&R^u_&x^_@eueb`D~G(kLU&)g>fv=t>|+s#vAZD;pDmQbaM~H$ zxI3dt`uQ~e0b2DE`|J&JU#qKNSjdqX!bsvISLDP!#4unDAG(F!Ix{W&`U8B?*qw#} zcS5@RoUDOFhVFbPO%`B7M#G8csPR$-6bY@Qf*}sEMudD&kg;4tby z9<*fZ@uP3-%)!>8hH(FRGym@YSeX8@+1FR;7NMYRXWYi-SBA&tlhJMteT8n`6Or1Q zy0Kb;O6^i*?l~M~dPuPS*YD5EfN6^R4^zDkYrg()di2+v*3S#k4g7`45$9wN_xkm4 zSo?=L;y0Rbh@S;_IT&sN6)|N0sg`Hrw4%RI5fBmlsS&@>9+bS zd^hm^U8?g>R1=@Wze2a@8v0+N{3HthCCb0h)&COZzeM>-NB+d<{XZ%x8R^j31jASu z{c_5mZ2r%F@_R&lL!50ShKu9u*8UgLU!;3l`D&}Ye3X%~?4`3@p`pgD0%--O)#c$?`tEiX;t-*rtOlaRG?k6TCm71!y$*^hQ z14cBHfKCU++xK;<)2%gbiLl)d92(71QB_Us2<`5c&!|j~Dlb=Vl_k#0OwXKQ3x8GM1fN3s>|Z`a%pt8TYR zH)!BfsdSp?E*~l{=W$b4RlSuZx5)yef$ybmGtOnCr{`WFHPw>rj?HBXk9K7_{|_Jf z*97`^vgi=Y?nsY{bQjPt`emd)amn?n8DimJ3z|=#w;0Y=bictmVLq{~VJcV4lIN+e zscN{Fn|p7f>7F8QR!c@^ZL0lCbA6*XGN)Di((d@n{0kHI z7g+I;!msd-6fu1kFL^qHS+u$+8>l#!CGbv+)L>8yqh($O!!vbFeJZJ}MTyMJO_f_b z@^7B3a1s-)+-0Uc%MSms6hCLJXNsCYRVE9a=S=B=0Zfbq_pJ# z3u|yCle>C>kBt#YR`P6xB8T*MiLdDO$P>pA)ajPH-2o8b#;%Mz1w8IYl!>>k3C7{+$HybdOKz zpT;glcDKq+JkONJ&Eyp}&xsdPyrXeKsPi|i%7rlrzb6j4tAsJHWr)=Z_m5 zx|dC_CH#XW|B`zD8&Uk!=^DPM7%&iAr5hcMU;mrDxl+l2i<>!Cm1-vW_XL+N2MCb` z7e~m>wD><>_8ViQ^Bt)l8@B%6_W8%F|N7yFx;PGNPV!$yOa8}S8K?))FEeY5hwePCzp0l+3gS3<&P6#Bf76eD z%>&q{B*-iM_mt2zZ$BefDleTXb7_!{ zW9?#H_V&Z=-FB_B~!kC}z{z}U}d`@SaRh)`ElHRWxHkcX4g%0TrHm^UT3 zNUQLH`F>iQS({}|GtF>ZNwKr9kC=l~D1EF680$5C*q2N;S|r(MKR5eMa8Q#ce-4Xm z5rVRN*5_;p2ylR0zFoo>*_#u;O3(lxIcNDv^_H+c)=)Y=|wdo{IDoz?FPov>8l8{ zZ!~szIS364Ma~H44T(oqQOp*oH41xLih!)_vuxxd7D)lIR9c@>_b|i(&K7+rd|aWd zsga&2T?SijwjcA$pb+^wc}_NNMwk`+3fo|rq?}r<7BW$4p0z)f1~xiE2Ton@nMgAt zNcBCV1bB6vdV-19=9eSHnk`_`sWqjPd>p+r`aXw4HqEG^JQe_*ls{x{560QLF>(h~xEg?zW<4Kgv+0&U-wGPF zA0DP{cRdm1s(>X36NVa5SGZ@j;L}yD>1tkxh%6m9fzeJ`r$9-><%LqJUYR=C8c`Vt zYZlwaS`&%CtTr8da3(M1M*&zz-H9%G-;r*TU2cIC42QcAOP-QfK&F$1W2#Vzrd6IJ)3aa3(8NPtJjM|Nj3TekpN({!QXVf5YYC(Uk88YYpc z3A33GInP(9X$A;b?XeG1TF$Z!FgKlsN&8)E&}8C>rTaSM$`Ed5L#)N~CkGbKEA7;h zHPt3uE5IuPLEVnbqhj(3-{wCARxAY8EVaFNjFnE}lPX(`*eE-UpeftQH5{z-PGalS z(B4JPiYZNcK5pC^{NlD&q&z>!Z!TjGR5ri}+^woIgqG08!bSG^FnCV;6fI{M`A%&6 zz-)?f6z+^M_CC6EvpEGJG8|i|P3;Ofuy5R+JC1*7Zs~*^;ozejx$i zRSH-wuLxUVhn|n)r9RO32c{Aso_4k(sM+b|fnvqUjut(_0G0FgV}kx($fuelgL5J1 zq33Jdl`_+=ecv_V=-+z*II6C%Ouh#Nz+q`|8#_}A)d9BD-`K%L-W>buv-E~uKH$d9 zmg)Eh&d;4T2AKG$$M0W~Ors~rEa(pTp9kM~1 zk}v2pW*FBZD%=re*BkgAmYh;u(e=65zT<>aGyh7ocdF9i3pt_e(915t_uspOpRcBf zz|&gv3|(Etx}qSY@M*MC{S>({L8wBreqFkXb0;&xZF0sgD~SX2VnM(e_90XMNBeI3``Ku z5$&I*2n&ZHTu?iM*u(MEZ#b&AI2zDdLS#)lZ4E5^sztQuQ-Byb}_qu`?jg0`2i4by-blBvpiA)Bc(rg?>&P*+2*V(`U`_P~ zT_e~_aeZ{CO+EpAuTlBK>rLB-Ze|_nFT-a{pVic!ytOH~@RsdfRu7og<-XYw^N2CTh{eIKC9Soi`~sIX_$YBayRWh7T8@SeW>wlY<8v1 z=5oj3ds_;OXJOv8sI{F_2M%RVRdj`*GS}x*wZy_;AW+eySh1M(uz-F4+(n-btqXLK zetn0d%?VFcBrm0Ub2NKwj0?cWpbIUmI|VlL*(NnXcU`E|*Q;L`_;{i8c#9Qo`PRaB zQ}UBR6Nv2+J8L3{&yP23m~fD1+_(dV#uDP3lGEjWP>>;QzHb*GrGOOPPiI~@)CnH8 zH9s*?$(Yg!=qumTi9X#nn3!d{F08*aYT($yvSNaFwW4nM%Gr7o?*CErxsS% zX)>O^tl!LgVF1#c+_&iin-$xiEwnSM9>wTv_hiVGYxK}=X4}W|3(3dBO~z0AC)xQH9SvYfRSbMh z%YjZ;tlsZZ2p0q1UrwsJXs@oZpq&LZF$ldS?VaH43Sgn+b<%b7I_qIMsgeLlQ4@X!RMTCi@qM zynQM)hptK?!L(_~#Y07%HpK6(g&z=oPN;D*rE)l|eNq)82b#U>zqgXSp{J@zVt$ON zdU7$0L1eRGp*rX^Y6tFiWeZHhBGzkn^H^7qzlVlB6A{!;WK)k9;-ovZI81Kd9h)C~#YTs zGVHHq(g?dg=^<{WZB_EE<*sK(R;Tq%%6(2k!I;=sDZqC#JP)m~O^mQ)79{jJc&9kD zsdDJ9OA$BA%?dtQMz0`w-#uI1w#ZvQ4IuW9Fgup6qwmg9a)%|JlMS59^YP>@_H>t? zv{q$Yo4+e#-uEGfF>CAn``K{hj2?}yTz<-o_fh=vY~C?1oqM5o3iD`bb7kwtC%jem z$iCnVERUEY4RA_fUs>zd?avC^7OQ(xWZ_F<*?G8`!bb5oJC89jPVsVdYyKs6M8ct~ zG5*p~G7e!>o`AW3?YxIaXWHL@SwWeO9Rs1Zt?jLKqW_6_{dsD0<0g<&ukn1nPRIBO zkd^N9q@$wsE*3;E&?tnC%#Jk)seTRbh23<&1|=2KEf&Au+tQ5Q|yO$cRNp8n3r zig0__T~AGN6Bk+5ymJl&Wez+B+OfhDM#}bWw>bsOaHX@;IDuQKISx zkPlF?=P8~IGpPd#E8RurvwGivfdJn4s#cbFWa5)6@Nn~UkL-@0)sXRiv@#f$ufZb!*G=g% z}f{`?c)8=tkm}J)&)5<@q;G5M7bHI;?XQNbrv>OKsP?Re>m{!dpi3 z>XB&;Hp)jS#7IoVa1PN+yOEj~QMpf6E@|z9?T)n{iEr7XHVfWxoiT}8h;CrY_7-#O z=qtkn@Q%Kw5RL%2-q(QXeR8p)vzeR8gn$G6lm=xsa146}O(2XUpThKQzAl#i5`C z2;-q?l?GLc3@xQ^I6RqXQtRnvIDFMH)Z!YrfJC2auuEBr?UV9W(4h zmflsOjl68%2)vk*;MFzS8$jEyA6TyJPmm&$G+T9mC~)`0XOY+~Y&=sr*~emU?$ZlT zRaSVWPpsDSu4WyO@bWhNu1qJiqu6Mj42*`jE=&VHd1@BZm0AWyDhYy6i3Kg0s)OfC zdP6S5l8O11;&rl;h-#?GAi}l<@-c79&&!si3iI(%>w8yauHE=Ht*~F9D#6@Pu~;B~ z2d}U})HpDGuQaYEuY_ za+@u?{SrQl+U=n81=I*2RvpA7qlazG*LZk14!4(9`s-@JNg>162mlu;jVeSt8&8M3 z_PdGgb`%OMhjV6U)XztRE<}6Fj0t>MTU9wH+glouc(#-!!URaQsopF#)UDwRb&{@A zHq}=bpdwa@>Jxs;UMhPP2q}njkdWuun6-hB=>apa;;8$8vi7;FL< zVi*%QI`p?3;e)~bO!`oL@9}K=`P9~7$?`WG{L~E^RAnZ6^ttS`Zk&D1@RZ$n=lj0V zHc@YVQ@yN|rcb_9)}D-pb0>jIJ2z{;Z}Q?6C-${hrBs}^9laPan^?wj!VC5|cKuRV zsj8tE4upzTMGEcilM#C*MdeQF7CWAp<@zY&o|SQ=51)uB1|;csE~x{6%~g|dZy)P79$&A2 zoB>R`F{Bqg>UK=suN+=-yfEt2fTQ{*e*MXruwgn*01{ZidGJ1?ue)+lmPA8W&P6U$a|$<&h%4~(!{5h?|XPm`q;Mj3Hgr+R=$@Z zLjnz?_k#GvbjhalkDMg0E25fC)5Z?m#g>wO;2vp8cD#n<%^EG^qwUd^VSEmZzSBz> z6Go5}HxnYd_dMCn(|t4#_@HxHigaOI-dCs30ekZs-1#NG>UubN^CC815b!N$dk+I}QR~Oe^lEAD)NhEADUeIxK7T_tBcLt6s_q|U{ zXA8J_f&nvDQMyzzxOAOPF}a$hy8cI=)9d>xxU6~)@y<1hdaE?@m`VWgi;_NSJ4Ak9 zm}8n5z~0luYKHr1l?#|`rg9ubPz$0IjdTEckKq8`kVR=IH`NRvVkW3iPiR3JV5c)B z5`e42IyZN|705Bhd}>D55v)3Uq55nx059YYjy*5ibdGtscAav!S3#m{7-nR?e&M!D*pERt*~JqM#KO*1=y`xyI&^$_II zRUFsxv|fZ!hXHZy9p+g;W-Brg_&x+~&l>gz+Czx;Uq zKKnvMxe-wb$YbZAn?uqnxy3nLF-&bEG2T`Smz5B|Na1YZ1Ho+oETPl>gq#KLr}#b9 zRI*=LysS=1RckX{d9bQTG~}%-(T6kgR7IEIfO}Fyn-<*K2=1MJVr6e1(Jo z)Zgfq_T*VkGeRrv*_T?>QoAjLoiI=T@SWoP6gni=Zf6C|t{Ep?Q-M_W5d%^>`-QG4 z{^f%g@G%l`kE0a9t+uH}g!}hc%qgfe`qJSyR7Dw8hkk3b;CmmP1L6l}e;d%SV8;z_ zW*daEOi0**s~)6VAo5waKgf-RV2TGgEPOHOl7z#-aAwoVu4&9u96JphAriUw^Q!K z#u&LmL>~l+^*$bj3ze|?Mh7GK`xP{7P=H>9db%2}xtJbW%@gjE(U4L#TZXEMAhMzJ z`S!F~Qx_wyZasOxbT*E}{E~~34+8uM-*DsRa4#1T*xW|Bgbqs9YYhq>mT-0&86FCF zH`f8;8;Z44G`h_RegN8^u2jB;7_RGfOZ9ZMT>~%H?jAaJUJu3(zgLnRX<)Drd0wWS z{Ia$7y1dcech9Zyw(ZZ~kl`?)BNPiE*9dcbsh5VO^>)VgOHR40tj=bLo|Cnfz6}V~ zylt=RY&tcE$O2BTpqcno!tYb-X*~{6sOp4>xJ&fJL+$}^D!YdZYY7k#>H^l$UTC+3 zGsp3_%pOY9E%a*;w>>az0wX7C2w9CenH~WqIh}XAI8mV+Dc$T#FF;IQwRF{xwS?U~ zjDHa+D!Iz>4RkR){7D${xS{cCPp{F;Lm-{|{t}8k#eK^HD@@=7o*JIi>Yh(iQ+r(G z{5LxYU4l=MT7g7Uc7=I-h&RV6s6J!94owA=Y|ZL89m5xZ^af|VL?6K3CTzV^ZdHWM zf?w&oPsb);RvlBIx5ectELZoEav1ZgrT|TgtXkV@x;(TW)vdk&uJv5vE1z0@Ru2Epx1Bejju&is#$2I0XeRHWqN$uR!lvLbx zn_<|u?mJ*dSmr?s25IJDw}GST^6LA5O4GuUnri?bah8G@bvrCAkpkA()OfBB)Ld># zC73PpnalfRn+$xCkx=$qh}%8t)Zz00cJSK)u$*ncC$$8ppbCGW!6?=Sd5?jn7Zr_=RU8|AB@i0UD`<()5-KI6ZJ?kTeBmapMGg5+v!Zg}`P6M1*>(2Qc!Ri0 zAXE_NwI&@HTSmNqw@UJMjn+Z}dGL@;7ov|EMy+NE0VIMP@C~JfR>xh)joT)C%Q`FL z47F9moT*>+g~L4)5NP&75hTmMg$8M(X6laJ(%vJSWSWF=nP1 zyYCWXSQFK)(k12twv;v#At0a&JsG^qWjPqMo7e>wErMQHe|)BB!&f{5z%eP>HES>P z0_B&%X;ZH4*PRce6dnn70zo~=ea=AmY+BMKx=6}q_SX-3sl~gCA4FeUJq4Nl^mfBT zfzn{$Flh&oU4LLfhj%nNvJxK^*gP|)e%Zrop1BOh%lV?3IVQqovQ#TNT3Uq9Uh{Y* zAupls_qdN6J;od#v6dXNWd*>GK8lG^G)Wg!lx931>t-?GflezV$Gdaebkf@gy>R|8 zE|8m>cW&`7i{L!tk-FADJ6*sqE@{jl`NkK*6h%7#5 z2_U}TUX|`jOm0M%jytO(S=iWu@YGJBkCO*PiFw+n4s~()Fz+9|6ZW607T8mA0LBs< z2v-Nj<=hKsFiO1X3gPFUN!9lu0@s^Y5hq+-(O}Jc>$nR*z*sRBLPf@K(Mzu3{dS|E zOS{XrhnMb$YJv1`@I!PAo7mh#HYQkYPxf6BUKzCS0CmU-sGIRlD~A6`!COW|bTTvP z3|i?FVVxWSfJ3UBHNC^hf_`U1z$9AMutM$Vi*(wx*#ImHE{L{$3crDNLEMl*R%Sau z0mo``pbUKrih{Pa0tu3E$QpT98W$9__k3xuJblamQp9h5Z2P5mm(@JHhJq|bxH7cW zl}sD%wtlAih`6u#!l`hHH9vu`zl6t4M}Qajt3$m{HofYb00$#S zYxSP{*?5Z`+9jbNfWBu{?{S3(|UJL`8aWt#1?y#!%A^Q`JnXQIvYa}(v<&xKy2k9&7crQiB zcX!WMLYj2*9?9DvP$hP@M3-%NKMrvKj0duuc9gAq(-`kWnGy8BVs4wK&E?my*Tr_T zUY+U{y4KQuO_6BT%OJ0~TRG+OqUC#rw@&-LC8Jid){W`1*7+}Y`3vr-XiatDI$w-PbigcGTE1MbzT>M7D_j4y$j1@m;&Tu>VgH>L z`gS$n3X#~#9~_1B;+`29z!_4Y?Fmm2D>96m*&q5wn5*hn+`LnI*4Do&U=pFKoI4Xh zBHu2|0;QmxlReFB2ifiEQxx^$dmD|_|ms1Pn zyC(ZAGjVyyqA0Ys`$)~&>}cHhQ`4$yhs5MQ!r#vLx7#;dFLJQ%ie`*#OfR37A?Ut!Tg? zFc5Ae$mHi7Z&xhR2lM)Y(^yqc=iTBIjadl3;-y-vQGF{ZRw$hJVc z*4lZ^qrGBfgD|b!WUX2bc}>Q<7^Pehf0jaeLtGag zS9-`)`fMdXzR5yr7dc2@?_5abW!Y?KW$S(t8N+2WyB*))rcnsXQMM{n5CacLl;-T%+ zp`Znq->Y}EC8FF#PTqqnwNr^1mfjIdh1}CDCA4kg?Hd6`g%_@Rz?~L44ZU zXH2g6`giJ_ji%x|04;gL3pCG`@&5sHR$e`AD=7Jui5}BJi?;sq*O|a5PP_%2Lj!Ai{f>30_V@8l%$&Yi12|lsQYDm>TFJDU!(l zRFR6*KF*_Ovu8g8gm7Ls-o%{Lmnlih{X_c2HT?9Oe0pQn?V%yzddz)&8jh3n;&d|S zWb7vSZAIMC$(2mL(L^1`yz}S39Zx{VDhOHd9SuT){tuG=lQKHv{aC%k0fR#s4alav zAx30~XSaXaJ&!(}7Sf1v)^YT%x>)zSbiOM*Y2w9f^muf1(cVUkFS#|ckEQe@??>B-l7{gcTRX8aZCB+RSl4WzI3uXCmWj09&+CMnGPAE zbf3jbTqho3to{?H{)L&(RiM-2e|0DZ;aK@HzJbPk(Y~DVlUw>YcdpI@JGq$(rBVU9 zO%N&0K7}mzt>n4G7{xzcydVU$^B%+2Xl;OaLcBq|Vbjm_IY-EURHzPb%I#(Rz*6@& z0u^+DFyM3=5^eC|iRH!24owMF+`Mn!^(N7vbpT>XiD|6=pHy1(r> zORLx(a|njm+lKwbBs%ObJ04G9n9Dfr<8}i2c1;MVWj%*FPTtp21ezw>c~@i(Q4b9!!#!hoL_zESx}6b4@XqEv4Ei!uzj znURr0%O2H#?3u)9zs_P<8YeGn20t4_t4-3Qs!kE`ALa049i44#xwe7sErWh=DVL&v zKaQWsm3z(B5DUF&rl6ppbS|j~b@A@j^u=-oTJ0rOZdaQ_--oWTx<9e)U+A~E!qs2x zR?Uxm-eyi1l7F`E!%qV7L+cm2#T~qjqiR{m#u{o12g1sZ0j>+%^rg#Cv{VCMyNY`B zF=Xy85HHl~NKnt6|MprptmoN(RI}LG=m1OE(Fc5%6_}V&#++N80%WW7%ILM0|D^HK z!O7z?3!{H}1qdGBm0oqHdIOlq03!wHe^iD58^q;!&F>KqVzIr|__{#m^(;Z=Shs#3 z*YtUDu*#pK)E_zg^k+`JTYV-O7i0kAlSe9oOoN{5+HjwA+g2Y|4F+F9K2+*M0V~S z9i6ZGm4b*)u7l4H!w;&Q*8h`c<(}^d8F%LmmJ2}K{z&_sNLb6|SogM)EGyclBun*V z#D8uuS8shCCD3o~FHxv}P>lvd9*niH{A6V;YQ>9ZA$*PIxS1XCg8t(4KypU>h3$v^ zHL=p3yWslkr#=_e!fG)}zO_WQOs*kI^g*$fK(uI#$>PwAO>>qUpX zld3sU00-~r;ks~D0!U$QXwrw904|4S%W7rvzpC=Ts)~-4sF?-a#eTo}t_f77$rvM+ zV&W{R$FXuKe-m@p$ATkW9bupp}xB| z-8}S}xmTac$K!>=(R83E0RZtk_4c-nZE1Rm*M)I@{PRG5GlBS2jCwKNCzJRiC%fpO z98E*}XGK<8FpL;Gvo8__VrT#V7<=oOy80z*xKJqW?(SBsxVyVsu~Hn0%K?hJySuwP zEyba@6u08;&UrV_y*J;Re93!nvi~6D1hUWGGru)!t(mdS{{Ql`E&w8d_e!$3k`az9 zX`mc9mt4mKqAX3agmw>R+!Xg}kFX{_jp{ca%7-grU z$0!<1GMbi^O|6DF$9PRF@c_EHo_WfI(XIT-)oUjkM=D9-kc-h}zPoeABm^1*V4r zO=h>5xU+S(@@-~4^xtq^kE&WX;!vjdN?yIsa3>4C37281aDAm0%(X#H$@+iuFUlX^ zux$lT_XPOsczx>z(6l#qfUup!Bj;q*>~c0*UnjL^T)!^r|w0pCe0_L8JvI!ADmg(jQ-uGoZ&RJ&<78=dkBJmy{qHm!1HYez>14g(YL0}kye6v` zM$!r;f%{%&W`vs^PsCx{rqVB&lD9u| zgtqr@fZ40NtknXbkWs<2SW-oszluqy9xE7mGQ*AM@;TfqK*wdx5Uy_3CkM-}Y?eML zENY^kFDN2$Q?^axh!+Ou_Bm|pk+5{U3wIPQq&hrs;_tt2Yi6Q(2Y%Fu!z2u%Afr@hwM(N|xUrdBFHEQ8#j_P}6E%?>}C(SEC=#U>y`w;q9PhT~_$E-{9 z)v#9B@)Qx_xBBh$zD7O8;t=r{Use4uf1Np0(J4JTYxDN|RbH;k*O#&=g>>VJ8)H}R*|1LyVS%)OOpIF5;ZsmUtb{i6H#R}E9@ ziT;_A?$GVyNV;tpYp(suFequi|9+X^e%AmC2p=`26fWp3V~KE1s8f59ic5erjZ~GY zZ$kGXvsUHETcpU}KQY9t<*(LXaUWbU>!S$HZA=qy7BZ` z?%%8JJu2fDcD7eK<1d7mivQGDA1Xs}6Z*gfNtHVz*%PakNjeZ$qF!Bis4$cmgr=Ds` zbyra?o#iy;pKjYOCJ9S9NXiXTsI@Mykk|Jiqi6MP*H=ovr@BD|p}!ZJ3(XlcO@BU9 z)ep5dF~l+(=<0>fB)@$(gyDXgXEnFZ^wbEkx;WASmQ0rwQ_=HT?x9&YAcxmY0*%j< zP_jD>G$|@^_#ia8uu^H6$74-L;2kLY5&P15e;F{m`7I0!!P%Xudazq_2hWR{zVWZ|w5fMmP;do)G z;@wR?64*Tdiu#-?up!>d{_P|@bpeKix*w%GJeq29960~;B@{PLqxZiax+n0^d6g`r zg()B>a(aIB4YNDkPogyqoI^=V#Slx?tOckqtCy+en_c9eUtIKuC0NWJ0ZT-F2ErAf za#h=g9IN^jPW`A)rzJy0M~6f^7@U9Nm(7eQmNe}0iDD-5+PF2KQnm1hf>W*&)uEJ2 zRzHoI@tvQo)<6pQaMLub1|MtFD`5(RJPgf0A-@_~23dGYHDhWO@mxRJ(dqs1{EXp) zN|byZs!8E1XT$c-QI!3zlVGbYX-LW}HKhSf(e%EHzfyGzLXKz3Kh@p0GdUD(0=-`& z7evT3*O4C~3w>+&#rk<@s+cR-$Fgaex3~v;ceIizIQyfC5a{$xe(i13WGqjykUrw0 zUgEvxFy76@zoQcq#aZzsX^ShTnAO1uT34)wO!=c2iY52_$B++Nx|!Xn6kS(Id+pkT zg@pJr&vOb!poJb~_(5n_q)mSq>GAaCn&^;8LlJjhgr7dh z(}5azk6O-n{fNAfWhV?UD210lDa3KAeF(_r_uLAAjsX9tSg`+l)7e%Jh~;3*$>mfH zXlQ9x>&|_q|Naie3jal`mE3Q*|6$;~;;!Lh;#;yMX+7wc{X{V+ZQi9?$h#PC{5gy8 z19?$w?8G0p9lQ_rt>Fz5FGX3Xv@cw>jQZQW1kTg=J>)U)xpN58bRT|uO8-EEg(aIB!@F`g6WRaX#@jOn7waDopt2V-;C?frl>Rz>Ytd+X zm9RuaCTg`>T#zpG`Lq4AGT-x%ow1Ix-(Ofa7*K66kZqVAUszUr&tXBHuEOYCzxLzj zXD>LH7 zSaxX1PeW0aWd>*qIu|N`1buNrnJlvNUmi!X2bIM`(w9G?jOI*baz>P-mrv-lc_PU0{HOAO`@`#~0d zg*>DEZN+0urZ81z&f6fO4EfAf78?C8?=gm2+!BQn4KP1n&bqtEeO+vvc~A^ z9d2i2HvOX&((Kg8K?w<$A73@mp{3VHq#JT5g(3gzl?bsMwsDAap&u?!*N?9Hoe`-REuVyiM4ij*R| zUPjCN;Sm>OB3Oh1^`cO9m~3l8E5&7}K_M#Y6lgBegs=%C3So(6%m$!mY=ylnwy#dc z0i9p(y3iXbJFoZZV7_)A=5s90<>8il7RUFT-Cjz}tHZ@{x`-BR*Ia?ZeX}rQvmG@*OdT^*=`LMGZO^Apv24~5iWMg{j6Srg#*1TM z_ul3EzHT<3dnsVc0YW4Tp%SGNf?PaLcWpuc*>2hP`wzBgx$B0>k|TH?Va^$H0jB*7PCRy zTt;~-W80UW7qiuW7FsyA+GuHp)8&-REMboR;{|vYB>y$}-s*OSb)CW^zxB`pK2|K1>rM|_4?4VjP%!I%F#^tC{bUa#Gxq3ARXM40(yfGdS}>KWK+r*iP&j`52uSt z=v8&E7TC;&V%N;1BqQ--viNR?I@_Fz^Of@;HQj)FJ?M`}X?6H1_Zs?Dp-insqv}yOc6MTKJ$mrCsF|>V;&F6X?+;Yc6DHn&xl+N`tih#@UxKD>83Huv0%5C5UV^(5e~ zYT5mIpA{9|Kaox?*L`@4R;w6us~_Qoz^)uk#b>a(tJU*?J{vapV!Pn;&*xIrGXF?j zjOLo+LsYLo@pYw4ZYmHgEIhDDjd&=B1%+Ot{Oc4<2Or5Ww1jx=;+59MZkAU)Rd_7s zMiTwP_nsahwqm7_o_R(t9(eL_-QT)My`Z&Jg6>+#LNmJf?dg6wZr=;^YNNa4iJ(dy z_5#lvdQAyUbo1L&Fb)bae_+nKwGOrQJY%U&SG~+d;<=o+5egwUrNQ$-$(JuZ1-{h} z1QXubWKmN19Cq49C-LspFBgOO4?6s#swIj+2{cOEf9fzUJJNZasGq0Xsiuq6@)bg_ z4{xk91wqJMcJ9BP+PO?RT8H*@(%7g}Dz(uv0<(=54cotANktP50?RbdkJJ7Hq~HSY zyyV=-I)z#>B6g3=0dc{|G#GQal)llF8pKEXfdTb;3qnR- z$@g!^C9QD1Pwadnqn{+zv~fxbiWMWbt;SD^RoOiCTeHojYQ76p1398eqrQC={+r^Cw%t+`au&QOmFypgv^N7^tWH=B&O>c z9rs`MOQc16%14=;AJA*t^c8Ul&RM9oVP6$wFa}u9B_fMnMfiISjr{(S;M)8+5&Qgc zi<^(kHPy|(!Obvl=x>2$^tagz6+g_IF`{w_CTMAsc&$=+m$DOHD$2A}N;|NDWPy*; zvKK*$5gq+Vf7E69Ll8Svu*G9v`ZxMdTcpgL*HXdv%=ddOTWHv1a2Hc34T@W@A*7hn z$?r;nlNM&zOEF2|20Lzu$|O0{Ki22SsKhl9c|Y9}4Jf6B0Q+n+7|F#IgdjfZ zX~e&;J|P<~SNm%C_G+RJF5-2yw}eRHOAMFG5wsllz6OMUYqTEJOzrv{Btj&r&td88 z+ZR?4n!@-%XE?;?cE4Ck1cFeVusiwaxCEKd4IejKW19}N;*QcAST9aT|Mvp(t;!1X zz+z5p=%;i|a6B|}kl4E0lyY!>?V0HRbjf1CU~)2CUtqooBi z9TifG>f=-aCpLWp1EdjzI{CDEjlWGxP36Xux!u%9>up{nl87V>SG!}`ZEz6U?eq+tA5pa_bsmWZYPcrM|6zO*LQB z`}tMAP>F>8+ob*Wcvi>PI6+1Lgd$PMXi5&s;IQ=rmRRTrWCJ&x z#DHybd{5WvDe=(5VS~@n%3`%p`Grl%dqFBHtu&m0Xq2+Q-w?dArm?&x&z7qo8FbvlJ*ZK~h#X8)A=yx{ zA#1L40EiieS{NeUC4eHIBnwYP1s?~`_1&H!F4+ESd2zw2T%OsdD@aN*?SrmYc;b5) zoxRW~&0E;mz^~=b$o&>%u`-jUB_b6xUdf_$m3bgur#-CVlg_ZFlpM1CD~r%j5dvNu zDZ4IOA*Z_)$vp+FsLq9&qjiP}Wk|g+UOJ?v*c6HwhLA`b2uB{Y#k9w~5h@ zno101MhA3FMtycU(6%>nzo&qY;^mnV<_YIBKT7TX*_%MGab$&EnV&&9rjrv7=u!~75!D}*TCoBgM@1tb&1VbhP?z&XX zsmEh&b|j`ig${XPfR@%^qyBkoSVWGM=uZ3Gd7nv5P6@hDd1wr)du=gc%gj!uD~FaA z6~Ee;!dMLIg}%)5m}w6^GV#jkJ0MLc9uJvdr#g(2wzCV1r8S1+zwr1%I*Z4f%b-fl z^<3b&b?s64Xq^Btf;k*dZaLl83O;9rgiM5~N4-NlSjP&(2vYp9j}RLuO?N&+Qv_NF zyuYTy&3^cnCo$uBnSQPoT9_^5Th>gqBt!e`y;YEmm0xt4rAOg3Fgf$h8In>(Ia6~J zd{J;sqfnmc4&Dq9$s+gtTWjcAH+$)0V(?#K|Jw&p@u1}4Kz0w^gLerrTNhI1U5Yl3 z`$jY&i@WT%s}!~ZTRgwK^r;FGzWv7PyjmgQkt9xB{C!#67j6_$UW`eaR$Pohx=4^V zwB$vbf8qdI*PU*p_+FDB><(E7Y?}nuGi%mw13TD6kLH~1V5XWd6HH$i-}*{w`ss=a8r!#jgj>W z(nRN|j;7EWLM2c~1w}+Ocq#zT7xnXgL`k5uR4Cd9q+^PLA%W(mdEs8(1IuWcuO!CXV0EKpg_ zH;3g8+}9_L7Qb1lkj`O%H5*01hloY*ZNX8QP(0Qbe3P+r6IT#C6skK<4Z4U4t*0a} z2=f|cH?sRN3}=YLLg0NiCSjey<0bg2-=%1)85$T*qZHiHa*7YT`$ay7l%n{61~>?} zUKijZ`tDS`v1MrXJAe&rn2?9@`_>1l{hNe?(7-kIkApre$R#pT7s!O|`Acst=34(s zd`CyV{aHcCQVcR$(GQaHNb>9cT^j52Ab;rCSBZHKlZ>P)$U^XrT#yD)L|GK9ql!wG zH2)kMRsXnP(cH7?8jFgj=RO3-;~LyW67ypM>aN*-13`=+t&>E%S@#UD$Ds}wX!3vhpNl{7Il9!FYm+(GsH$ItgXyz9uJmTROHWU ziLw-4%`O~W#U;4=!-HU0gmO2JF}QaK@cV$`$nyS?0k;kuJtaIpo{p*K8C=gvvs8bA z97<>nA4?u$9a+X%4<)^K_E2V2FA;T_ufg-{W9k{CAekiz)tF<9>H%w=PPeqh?XDOq z{upmiK#bus5gZ+TpA@9HIznu<$NE4fG{Y>bgF@`Pxr$_|IRA%@!}Q7WI<(E4Jtp0t z3NAaDrxl+1EnkI0az_&??<~}pN}U$yl5xYtoS70AsdeI>a+eOGe z$enrYe#DS;qS57(krlAAZcgL?U1Ij~E!|DA+beR|Uk4oaq-LV|lW*>21~E9UJ~bao zmAEpg^RZ4fnA}L}w-(acN(k{bp=8xg5>oZO=#orOB)Gqd-Qk-@<>eBnt%=91ZhG!kEHWJHMDk7`++Tv-Sf;Xx1N~G+-29ojmV| zD(&pfgmQ5X=gZ188OTo?ZI^X^pRE)Lq;pz^{;4yS%UGyc|2&o&#{HaA59~zwUCuTV z$NVic`Hg85@N|vqeYYtlJ!J9FqSJT>)FrdkGur7pEU_r2QYZpm$ z+C9jR*9UfRIb*)J$8C|!1sFmvOWmA@3t*8|DazZu$c&E~QP1S$wccQmN0VLLdYK%H zez&uP;ZvR>5*@c(0(H|fW1xip<{AiGZr%$Y3pGggOVSi9C{e55rV4$1vP=|)P8FXM zByHPYE>!0}#rD7>R~)Hb>rkvBPG7-${7w>+EC{(b048R#by(>zNU*CTU$==~RhZ`V zw?@Tl?~)6Fc{eKROPy!g<4fZg+M9l%-tM0-$=WQefKLh}?A(sDoKGkZOAUNR!-F7sdLc$#|!PcGD$`B|~3k zffP!Ts8ZdaQXw$Sz2G;CtQmb=kIyQ7fG1F{`ggwsk68P6p=Mywt1DwUXA6R`Umj7| zQ3C*aOv0J4@{l%4`o~W=Wk0jkcPIBvwB;Vfk`o#@tS|TPkKlRyG_)b&L)ZS^h^955 z4O6)?V#=I^`yZ@KR;qhyd@LNTVZWhmUh^zkvbWZP;zTHp%Q5Ok5Wn;Z$Nr%{a*PiH zR3Q|%Dd0T4aiJ&;L%|Ql02TsNCQ`$gEUW9>T3a{Tt?wST@WZ3zOUmOAUYjqUepKef zNNV{@O}n%CzLZIQZ9VR^^78$AC!NFJ{p`JbCr}>^`?9Xq(<@4czR|ueb?*z$Y9(dl zciqSGjyNFk9ZT_a)+SaQUC|}DuUoFWlz*agXvBs}B~}DN6;s&tFEzQGA7!_nf)>4K z!uza<0-N!_A8BtijRj35fN%M96D3<`9mG+aJ3iaKM zS~%u#tdPATCVebQ8e1x|8{;vHLECp=(&T7<8e3sPT!1qM&Et(iRuh!lDV?u(hx0ui zPlI`KPsF|?IplO5hQ;P)+y|x}afWG@r`r=gL_$^_LwcRcSWNDN`0jUfrjL!lc+RTf z*lI(qYSYbWA#>KL7BWyrDGO73dmxLLl!AtYxM}chd|akDkaR#=#klx$HRgTCoeLU_ zI^B|nEUJ?jRk|FZ@lP31|5Z78`+%@I`XtWd^Ax`jHgRV}K+KvnPPv7m|L;}V@{A^h zhntOl7_*0Z53x*Y{z60Mj1_y1Bg#)6J+bEgUxMvKOWqB0NHPVA%p=BXzM&EPrAD&v zH8F2!M8NCTbibCheg=akO0tcus26(ja?iE(0Hi1RXR%Xd@vof%a0g8+*<;zDX*C-cgzyDmc4``D zbp6bLZ1dH6FnSf2$I9Qv?YMQbR9jGevck!8cg#b2BOMi}<74CEDrH1TozFLnkN-5` z0M)m@K6d$PC+5l>DD}^);>@u53?;@60G|0iWh7!D&iKD%}5PZ%g0aMYx*9+-8R##_h zT~bNqd2#-|;StWkKtT6bE+YJuLYuRAoV~Cj(uI!|@1sB~lA#$#7%lr!_2E(ntC@tC zj|@}y=}t0{(Gb&oG`X2qb*W0vt=8$zkWk169mup&kJkfU7&iqNCu>c^KL(2xd^CfU zcC(EhCm=R!y5Gq}I64f$KxC0a5WFPHUFqBR7R$f)I=w8|{6d5A^>)jLvN#%Ou`?Z$SbV3xag}_p+ z68doLaeKJ2V`CN?})_MvG5{|_IH7d*S>Qhww z7t86w-rThjI2iH+K!I(s3GIcJmzvY9H(?q#Qdg9ExJlU^O5qC`{*v=3IH;Cm!A5DA zt-rW&Tp8Ftk3)(?GD|ev6PP(yBQ6i+a>S=<2v2Y@tV)um^gnQ^!jP;%e%+IUi4%q| zqvRu6`jlD`-`i=?bn3K*}n9nojICFjwTExMQVO#_ywB1 zq;dg;=6w3=E#esul&B9-pKO=l(ag6Fn+S%o7+^*c>B8DwtOig#hg)^k7rsXa#qfBlONgsY!=bX7ypvG!`ZosBf z#U<`!q(}GC9!ajCKVmc}=Ps7VE16%beh>VQvL>%u& zHA|eXc+pba{7DdmhB5v9XnQG$E^~Z$IMeVx-kZmJF`KuEaT|O=p~(z>UoxIKxGfb! zHqb5EG(v08UMRwDzuw&+XG*ivgx()69BO7Gqm=Xbd56Th*7)U1L%+CLVLE38g<)rF zvpN#!Lg~-G!6TN-*&+!|G(#Lh^mB`p0HxR2+Iw6!=f=)gx#gUxW`(bf)GwDNh|7&9 zfkz9SJ3B^8-h1g6P`A&nbU-0&`EqjH!xzn{bko1p``A8$KZL(*qxMT2G? ztsk-sH4r=J17M7iF=cX7tE^)*(lA)D8MigjoRb03jEzOkoo=f*J3&y0RE=Qp(YHML zFpZznJzCj$TZB9I9n1i~$?LX&5=2A9x_o-Fi51IZE}C{mf*YykiIypkg^m_oU#NO) z)P*8m-<_wDb+{)TjkJmgmO}IH^PXRmn>b%MkmA1M_ZCU-em9&5E4N-U$8Ojqh{!+nz@$lvEgFW}PB&@KjG_ts(Km~JD=Q$k zkKe#V9w*u{@k5!Sa5%{v#+eREKc?Y(n1IuqNe~?r$qW%6UBhj@^EVBlb;AY8?Tlel z#*m>T?dBBQlU(Lcy-1G#N7M1M%Wr>ZC5>$*xXp7cSk9mO z8Sa6g?w4C|0B@RFCNs*IMB=W9G3B!e<4<;A@J|=Ad35YQW9I2v$g7LiF2!F%OS97; zvE!M`%r4lUyW@$_RpvA|O6UO^{(rw5%pd{B2Y~QRv}#lxqDlyFaXzhHd(>p_^0r%P zURT&Yo(nr6mMigwgHQ}dk7EF}>NZ8;BR~~Ue^JCO?5JkI;uZ^|Ha~JP@BnJre8uWB zzDqT~ZqNzT?zll{QpG&3i<*t?Clzzd*})~=LMP;wovGdKUR?=Z?Qknq z)j05t>xKU4b*tWRawxTqD!(_8#cT_JUY)}ZRLfa#UE5&+>IR4H$~!7KY_ZF~1HB9t zWa%FfVPSu44=QbJU&)_Fp>LrZ{3Qbg=kJ5lTYjE&+?g?fiPmf>-DfmNFt6d(lWM4i zg0V=OfC-3Lc7(jGGqnEk-4Vgf9UEIFkG?6P*XzmkPS}+{IPG`N?U~|H$&mJ!@v7kx z1w5yc1ikP51VJA*$8>f!zP-$r8Vle-%h7z8j&c9OEE?P9v+@s3NwQS{F8JXf$(qoQ4hq*yU4$i>%Q^~$%>2!_*IQ(`=mXI8AMsl5bXp}qrj z_qU>Lr|8Yav_77wzvlyS$P-{AGYA{N=u@T7@BU` zT~f)L!T#w(sH9z)+7gFo$1?s($IQz};mp=sVL3gcpPSnkUPb;mZqoTY9HBo8(Lp-A z6tW1Xcm7^3td+A+f`}I=7+_OT6lQ>!o_A7G2H#zw-TI1E_?N2v5$L_qR{PGGkT^vq zh~6#L@=hiv2NlBLygmGvl#-Y@iz@gB=2*x)6MlJ)*9{4iQhgnjx%A$5!BwPw**oG; zxZs)dc4wrs=ie2gzc5IVj%V;r%aTx?jT6R|yn;k{Ayf%1EadTo{@A#|AZF3Nw6qZE zaZmqak@~Ooc7A}cHiYV@mexND9UQ?`J>lj!i9_PH2py)U6VMkD1ZEq>e+uLB!G<1H zdS%zCD~!+5*pER%LEe(jr+hn9Q>SxN>lKSYpmh_Nl)sa?4nBICx(zp3I_7m8~FaQu2|I8Ux!CNv3%N}Lp z3-~@kJ8u1H!PBbnv0d#(FqKqFoC`bCx{PWycuN|;AV zqJ9o}Z-gvbS6%4AfM#F;T8QWNxuTL)ib;o+h7LX+>`x&<%*0pWK?t6os4`qW+KHgQ zN`m!yq_g$5;Lo&qJqw~DCf8MM{~4?zLm}pO{Y93OlFbPokD-8zy?)3R+zU$bwNn?nRwQOe1?Cm86!+W^+g&LaO2;Ao zdUVqmJy~%=U3MkS%;{XMSi5a@soFfsMJCRBeSOk2|`Ki4? zZQnO}shQCJG)A&0Mbzm!u=5`;K;rEjJI&8z;-cAlAo2!EUChXx0@&CJwJA6B-YI(t&D){r1OR4ARwBM+~8sM~(E?`6h~V zE+heNu1cXd8^!@!xNw+aQ9#IKO(q36zr%g-0RI^|WT zg0+|uvY3++`S1+F^+m`p(zMpEy1|He(|W5DLm#iNypVdh&W_6;yLyCnSzg7M7;dF+ z_Aeva2S=-AIqA(vhZcK~;I{e`rtCf-;e}ObRcF`~IhSpvvPqzAXeUGy3q%`s!N|;% z&(Ry-PeM=^q;~n9#pLKVX-RN;x!MO;R8(*(XfwUC0)B{P-%`&r62V4>6iE!YV;8Jjc#Os1{dQ0k762Ni5TCwV}YsG)|&3r zxQjnvZIbXgzPuEPf-a%Z%^JQmrXWp2Ck^v|R0-(QR|ty(ZzZ0274S;*QLjRA>UGk z(}>=^*iDR0OU%*jvjePt$BB5XVIduSY@|KFn^wLqaTn)lLKYercDFvCM;#ZY?q|6@ z#yxlGtR>Q>{!~`Jel`6lNvtf|7Y>tgkA67Kvcpd92$@0~gykClO=Fq7{slW?VgnGo z6O}S>k9-+EwA`!gr4#^6WQuvk{Pvg!%Wx^+OeC{s-U&?b2^bX1BqcLM>;T_JXqeLW zVj+;lNo!TF_I37;$S{+ekHjKNAb63h4O~lSv9;kFYT@V%8A8N&=U_5s$fd|a)`LQWS3OULugETF>+zb}TwX!jsr8em2bs!IU9 zJ%j7jJlWX6;p1ERdi4uF*14C`(LQ{ieY2<=1hakaEBp8RYR4xsmHbJtRAsj#;g896 z@Ox?nqtHDTBN=-_8E?wxgE?zI%(f&3J$MWndVkb7e}6&a;rJcxZj&Ym2}dLO9Nuv& z<5*h8L!C~upvpm2GeXejVr5!_a^qLy3dt$p6y$*b6!@9BQb*sH2d~!rEKcir)5plR z>6+n$fn52t_14SZL2PPy&#Cv>XP|hm zntEfBTDrhUstM=<=hf=^KYWfdwdb8PZ7{qCqS&;d$2B%I^)tJ)!zf-hB(fWxWC>4TDsc`euxkLUsv4L|8e z{!Ww?{of(K*yjM0ZG*3gpYT68)V=$m7~w$4#GN5V3r2BJ^=}wR+=% zKVwG6-PVYc-!dQVmvzQ^GEHMadg7yw%(&hPjR5LdLQ)KpdZUE_C?A&r>jpx$y6AZ ze}|E@2<|?oTCwm0I_@zb$S6m3qh%|b{q(2OZq`R*N5o&jX|mRAX!n{AcXK9BTk-g2 za$q7sN*ai{o}{%j0@y=ewYz3*I%2ZF`0?=9Z`}(1O3nvZzZYN6-n-q!rvYqEIR98g6Sj;3=o7(jiX3$0wwVa$IC}Qp z5GE+KF#-`{x|8H8_ZN<>=#LWA*1N?hEhFS+)*bO%aYr=&iPoD>lZ7#5+dLG$R$9kx z7QAe#kQOwZX_`cJJ>u}I|AMzYeB>&AW|2S`NG>;hu-|&&+1=V>}L?OJ-&^sx7e<Uh5G>-_TM zRPMHcOVH>9gkL8d77C?PLI))x-dpzF=jaT#(_yx4$=e`n$eq7zFV0uD0%NI99i55) zCUbtTwVLDHlBg?^vJ?~~vgN!<4NZ2!;3HEi}8quISHXOWV zihCZVgo2jdJw-I6`5$PV`}sE$c<68OljJ~2ZmVQ2s^lgH$P$(eHYgS{YWh!ys6Zc8 z?EU?@f{pFF z2UYwh0XRUtX}^KK3}EemHm5{jRJNCkM8F4^s1D7npvoI2$(xRmUsk6oI6Z^g>f`wdUGUsx` zf^Phv5dfTox;tNNnZt_cRO!wsJTB&`xxINgu3i^AKhUY+6HD5bPv(+Q%ni{3Nc0ol z&)vhhqpw$TG&=f5eN=+>tL^Vi2NaV%Hp38{(Od!zv>~Q*tX~I!UI{azO$mEmhx3mg zka3w$7$vIeAF0Dle$|M07h=`(IANR2kyx9#Y!4ud1;MYURp}a$7LphY#j~Jcks5Tk z5>+kJ-ub*jK74e$RZj>33HdxjA>lX2x{3<7xQz1RVM$ZIzzPFmwa9kxP1MSKO#GLc zcQUYm1GX(9g}K0ac#9g^z+&7$IAvVG{0YhD8KTR}tszi(zAQqOhMdIZaCXfM55$@e z2q}c0naQ`p_By3^1H)5Tj6{}Qd&*pn5MqI-jvy+6fa`k)soT}FG&7eCfYnmwSMK0j|0C5mP3&G%Q z`8j9|cZOE|dda09dW`pCvhb*>p0YnVyJ)T*pfdc|S!kaoTcK?K`Of00X>MP4nE$8 z$6@dM2ItX5h{a0z-0|V5|(2IOV zwgV`zb(564sF8$91*(33?{=AjBQx_|#Y01Y@LAcXM7dxi6XywurY)DhU}N_YH|mS2 zk)P!EeMP4jm{7lZbheLiCbmR;2mRrL$ygtc`@x;AVU1b?dby90;%m3Zk=^mjUFmZd zU;vejOI_;*(TG9yc)mz3{b3OHyxpRbj8=QbEK_?*9?GJq_@1L>ztX!B#IVE33c=~4 zE|dfVEgk1H(V+R?*;mr2AjtDsn-OjQP$c1?EuoMoqB98MhilHv%C z3OnXT<{UJ~tR$plk^p}d`$xEAuiQ%Z!;&k|D5*U!SAg~WJyu%dzk3bMq^PG^qsm>$ zoe*uy_~;kzY%e03DN)tnw1KMU_b#V3r*a3E*Sr}fovQT9^T7o{GS`P?;>W1uWjDSx;_;MuXr9+xt6bJ=um-#@ z<)=T<(E>go6PHO|qq+d!(zJvlx=WxrUG-aixXZLOv@aa~Zp*%)>vJ)8weAhh?wA2( zLo#D_0KdmKywonAmk+C+*ZnuvBgFN!fWtA=YOa`qSjdz7ANCU9dV?b(BAyw=zW^rf z!RC{WIZpsDdxLWF?7E7rUOU@nlxsixycfzA@QN<}ty>{loyJa`r(M^}dUzyu5x40; zB;ZNd<%y!&<13dkCXvoj7B!&0u4s1pr+aOK4|h!gRRu^d-)_|^Zr>E-PcyFzpT52{ zpd%@y^ci+38hCDP1<74bv)Jn9+v-uJ$4Ngz3SJ=U)OmmZ&b@ygXS%;^QEO!ngtbww zR-psLSSC;ZK3=WyuP^fHmB)hw{G~BEtOY*cKEd8gti*s{aw&9SbO{5vWb5r9oPo&f zQbRyS35$3<3E!J33@bn+7s(RvA_hGotMshrNB*OrhN_?-@XA4cf&F^(YK5|qN-d18 z63ZM_87h9E|IzywR^*EBV76U>*YI`f61mWt529#y9t=6tW1Pb{Hbi{w-5W%{-qq%1 z;frZ2AufBtobvIeR*&;1iW3#|9Z0lY+wTy2$WctWq>c(v6JvPmcsgwIoQXDeN)43- zFg7|;_Mry6L<6PT^4iHx#DLs5uDA(0h=(he@LQpy#z`_!XUM#DQco8idi%y{U^&p3 zH|%pGh#O2uhUZqvH@sQiV!J!Z8e6W}2~1KvUj@MKel)eo9n_dziz&ds zdPzDic$b1wl?B4w$@e+DfAU}yEa@clNi`%I_bk!lK~CGhp#(bh7An{M!O=mA`z0<) zQN7StwOlW#;r<*+#CFi@VUQKphfVAQ7 zgj4hRAiOEqXLkhNk*yc#aN!2s=06)0S|yFS?Y#px#JnoO`B~ z;cvN-Cg|8YIZYj9f$2g=p7`(R|97KSWL&cOTceiTx(*H;H#r2*3A}k#sdH8LIN?(M zB=o5?!vEn)giw|t-~Y|&v^%Wuz<@(m)v*cDp8QAz1VpLt=9c+AsO;N)m6Wbqqx~{` z8oPz4wDia5EbgcvgyeF&u`G71Ab6~g4st^6VMC}}-`UJ%Hv#sB+hHRX6DsT#jx}ET z7C!c^A^m`TcZ9d^!z;A{L9WA3NK}HWiA+n~FGJ+{ zYXeb-a(Stt{_Zfvl1lWw!k7Y#6Bf9Mv)b{s6+ zLu9tV(`MiBWS7I%+V3nbuK3or&4;T!?(22dXRnP|-9PhnF{SThIG(S|Vj|xaM{H1# z!)R3L%B;eg$@~w_npA>WWZAqb4{!KrZ*M#~sw!&leB;4!{B|`%q ztAT?Vi@MV@g%3A@SfpWNZB95QJM>grNz!GiC4m610JQ9@zt~yG=O}`r0k6Ot!snHx zKzDHX7Z&*amMTCt2Bb*IjSS=+d^Rr{k-WK~GF1v<^k064erPLt0N65I38?yJV(Swd zEYc)Lr9kk95J?owkP*rQ4ElTQlTYIb)3oR}%P~0)gLeXJFi;fs?cxp*HK7A82baIN zhPX~^RNSAm=?HxhnGk zkU$9P!>_8A%iIH9HlkvVJB~w-G}aKu={>+rK-2pZ!kj2k{<A!h7KzlC?SND*RW9|#ZRmn-z!qNAMRDc z15_#H!j0dH{c5sXsYiH1p=VKi|KuF(b(pyMSnIV;X0vFFi~rH)JLJQ+0*#0d4z8Ms z?Qcbi<5$c7p*@rGJPNfIc#$0#U+^BnS2Y8m zmT9!WMFHy67;3GgA0^ZWr(MR6sANG^ilK&qv{Ioy|A)Q5j;b=-AAs=@F;Ec&q@+_? zy1QGtK{<3vcUeexr*tFIjS3v;?ozsu&U1J--kEy`X68=(*7vv8`>y*R=kT0o@BQiC z<}w<dkcZKEn}gNSXMw{`r)Y2Q#2yPZV7^>}mx#ojbU*jEpW*(tpP1sF9T ze6{fyS)x$@>0AxV9q6TkyqqHDNAc78)l`)0g$*xk>CxpYtCWDt++ivIQ^p5sd1sfx z>bJ{Kf{~YoX-{xY!!WoB@d zP1HfqPAN;p;Hd8*t8Z&~=lK5D#&@%(h{TC9g=^|PAJpBYV>oq11^s~Z9B}>KfY#UT zs4M%jw`_hP?%sTRB>$k~J1QM*{A=R!2Ru)u{*ua+X#~d1h}wYRmU{m7c4(sMzj~=n z2R_F0ZWeEUcMssvcXQH9G;h7fr9xxA?LpKY%Y`0}K-zzR3~cfpcfZ0t*q3EwGcxZb ziWD?LUzypf*LUv@zdLVYKIy76Z6bL_^GZy_4?}Pg^GjA-Aa(s33tM-iZ#uZ{!~8*^-Ylr{e{L)F3b)E8MLGvnJd~INK3pqP3ED=WQ*}4=g{ffK zQq?CS!ht43`JtV#k~acMBjzKuQlhEv4!^|g53SccUz+~RZoB{DBhRCaRkx$<6ag4P z2%jf!ypIGmU?sJ;&!cG6gFwCs=cpG{DwJAID)0_>kP+#{u{*!{X!}I?%1U1jPp;At zK1d=5z6UT_pSQ;bH3E#wS@#|}tdAjqNOwtW##=j9^CtGIXZF*b9`3GRvQ6AikR$iv zPzjfD(B+5s&s^0+W&H`*=qCDI8kwvt(dl*2eeU83G{7bCfP4TcolZQXE2z&25zq-o z*{}p(F@tV&Qok(WVNgN3pZ}Em=_}#70Fn6z{S+;8+2^KZ+$w@dVOxmaq0~=`ihI&#=EAvzz3cO zt?Mh1gPuqSo$ms{EYV**PTc z*l6Ji8K_$0P+HV`&(zB!aP;l7*dec{FDAVXv1M)Lmk3^3RB|OjjPWp?`rXg|svbA* z+}kl7I;BfIFtHe&C20RE8P|};3UPj1%cD~nLY>;%!djRV`qH64b;%ar`%Z~ypM?jl zzfnXMHF!o1T3I7x9tDN{OJjK`iIDr{I^bH=@^Is>^4g*E?!H7!ec^SlXQIjxMPg#& z>qZheRa|KfG7+iE@xTpG2`2)QBq^%Iwl>r5}bdj<5Cb!9D66o@7$u*H~lW^YEIBe$>C(Qk!T7st; zSP;Sriv%Yas|3JJv!PwN8%3b?w{BSX?*LUz2 z3F=$k`Lqboq~^&LL!g449TK6#pOKfto1vdo3BK+1p!jSyw5+Dw%bP&8SL%*IJnADC z1^JZ2`rD2B)b*8T@Kqc+v!|d)7dfM7L=@2YW*#P zsJ9MwN8dEpY7fyH2s{r5k%HH-ZKH;6&367$3vk4F^NH84eL&h|U60GBK1(sR9~(21lgAv0z&>Ai4JmyI4SCU7E7=kTHKDHXE^p6x`zi zQb|K8oLCul=}E0=$C!61B;atm*xp`VKi$FQMimRjMX4|%lf?M^o(Pt4(-({%`#Mhi ze0$EsZgr|#FH0;4>lKx9eTA{uRn$X_AKZ_^bt`1;T?@br49o-YgEPEUK>-1hfT1oo zkwDuQ+tfJH4zK@G!QtO~4Pt}8w4|IcniRF2?z1R)f3UWWT zQew1*{)FU~hPVML$7JHmXPUMYE8P#0(g_iLt9IrD_w&`Clo%?5c^L4A8J{h~y$sHM zQVq-2kr#mUvWxE^3G;zGXR7C&)WMfuV!#3Kx|97lAhx)}%fEU+l5-v_T!aQ_`mCNX zKoXY7kU|=V1^913dQjEsyds0}Shzd!hq1;ZBx zmWEKE!TF3lzz8tNy#oB_fJC<9EfUZof;i}Q{r=isybx*b15Usk-k}Y32yg?Hur2I8 zw=YrG_zx7jw*PcZeE$gq8}+RRFmy!Du!Qq&B)kt$IW>H^h?oHhx?T5U?%t&z|L#XA zM4(xl_uQn?@ko+aPl6ck?!LIV;YNoa!GI}7u;yd1Cdk^L6LNfdB%Fo<))YPb#@vY{ z3B|>90rKasc(D8kQ8$gty!}^?qQtpGd4~`1Ah=7{F3!R7TK_Tnsm=h<@-sloUvC0h zws|H0R+NDK8Ft|J&n9vIcfbV*{TyI$J`U@As8!m%Kwf}QoNqq;%oLCCY_*miT-@s) zC)w4`*#}UUChlDmOAS(YsMEg;oR?P>yJ;aOT9w>vqFG_^t{`Hjs^Cy%n z6WJ%63za?8zl*%z`SQIme;%@yR(FN)7{hi|{U+8dKm8?HZ2n_5+d3_1xjg)@q7+pd4)8n0q#(HgNW-5*e2-lt=^@p6f|k~J=kSzU-U6RU+Vxl zbZNW4|Iv#KLBrzfj7vRPUr=cGo;wulhKs;OqJPSDrC>_e!YUTXs2Cul*b#t?!hMFG z+IvG*O_b#HdECPP81#3M`ZuKC{}}ZDTMTOch+neTksd*icU%$q+(pUhw>wmln?f;t77c`XCedaD3|@)O(@2(hsAo$07d0&_@L(duw=bi?UVe?=b!rI zML+eR{NE`rYO)ugAo}_9n+PvoJl2P?ba3o7P35YA*-3<9NOp7!LGs8pL_z+y^`H)d z=B@)`KLMD{dHb!ca6H2veYKvKj25wP4FTgB|3WC;zeK->U2wYnI?!>PvZa@7 ztmoW6?4)rfBK})QNCF`8>~`~};K@8@@%)gPYaWCHcmd+XPbkdvXiho!W}x=o{{Bn} z31DBO13|h4mY@2zcrtwcP|5z*w7O?|v$Doj_=|esqS#G>+rO>$Q8AS+od0db@sQ+lFMhh2SF0vg$+&xfhhbT z(yhA!Jy~*xSodC`T=8ai9Y*1*)%iMbHd=%7n9Z-`N@Fs0Gb^6flBL~yhRlaIiP$6V zxxjl|k+4v2^1SM~R4&Bqa8GobTS;ZDEZGT5f)Qx3F>o*1aL(liokMoSU(e zw|He*qNaptGhn|od13rW-?SFCo_|=M`k~n8{60@)bhQ-snxzKgMXXw_;Ss|EGRR~k zhW~4fCEVNOc?9-rSc#maa^b>U3(R%Yu^F;biK!Mkd^v0vGWk@y3dBn!sEIjp z*a|WTWDXf=pT5?SVl5za{nHD$P*KG#cgJ|glqdJfgie-5>fPx(2bW@hclJjEvs)Sh;&GVg&21G#+DdD^VLfr3u_$9wzi8Z z=@OEyo~>!VisSJL$|tDCB?#;A;SbV!@;;G!}abb zOFgerRBO~r7F`IUkDf@%elbB+h;viIwxy;f?n6v}>mbv??{Y9puaL;wPOrQmnJf1@ z*TY=6f6C)tw)rsK7)3+56(-(TS+E0Mn0|V$aC*zsHP-10vWD*A=>ObI0B*8)?0K`a zWzP&k#?&feOGO0%DH#UWu89~HSJ`S}1@bF7#IfT#*vk_R;F?JdQNloLGPZG(VO~Zg z@m4>vL@xUPSv)Rb5EM>@*q|km=X*rp3nD1A+dVal(y*TiVrF6vcT}d2)-df%rfp%f{RJU!b+j`Gb z1SC;|In&uDOkB3*aU{aM23X(dk|X61Q}rtc$5nopXK5QJaEpRZcxD)kU5`-t^@6{L z0dE>_(r?)-mVKS^ZV?>9Qtrt`XcrFn6ps3Xgp3WtLKak1L`6gllt_0*si|_|u<1`Y zv83slxX^mUo9GzgVZn@SVLV52Hb+a}&7D26Up;|%vx6R?z!5fv z-a9u|VT$jn+$aCxy{P@Re1B#sTZYCy+2iS(>3MEvo7cHwAFeA++GQQ->7a&;eSO}R zkR6|9f*KMhB#(W8u>OOgU$*z88bO(wpsXd0qoLa>@R;-Zg&jnM@vmw(ux1R7vV9Y8 zGbwz{5~n}`*ysd-kCcks!XhVrU7X+agd|6T)@>Emx(v_DpQw|VABnv{{ufB&mxV8F zWr5y1H{ROm9$^m-0gl-Yl8m77T7*98(0P($wA`|p=&{XR`M zp3)LtF@bNKxoFZ~$tqL1;Py7Mc~)B@cj`YeoM$Zvit~rwI%fa zBvSlT{+0?7{{*)D{z!m?8OF-x-y^1%_XcbH>RzC~4j|)v0Na+fPKpx={x~^K4Wf)yb79mlibaTg@^y70euaQ;V6<~1PJ zmNy33{|P(+%w*62!!h&ysph{RYW{Ox<9;Q;Yw zsR;n0MYStS&|k;@ueZeCj|hyU&hDuTQ2jHO_|L!%U_7IN>00%;4g;tnf58P(^emPQ>zPYK1!kXbm9uzXzv;$gp~B4s&%-*{ zs$j5Rm{7CyeXWn!d zAniAaTRmY6vg zVMTCU--~FzWAZ|mwU?!DKUZjR3~6}uUdLp!Ur1nw6BK2h!1MzR`qJOM;nji7)f_fQ z(zhH^PA{%;9#=ffvOk7>VVjwt$Xz-5@@*9wq8u&lS(qQdz7S=-1xxT7F^|lcIb+o- zeCJcn^A8aI#NP{%R47g3Y4qfNfCL%^wCb~5Fj2fk7)iK<>`HHmYe4O~p=kll6M1>; zmtBWewflPkyIw$!Q9t-(#NVr_E|R?D73)!g36GAxwRrfS!`jg)oDKHi&U)n@3L zve>g5Z!-Eg%^d>gHh(!k^MYrnjblIEsv#IjS9!Fc+`K|9+t%m$U}wvJnD#d+?hpR; z)B{i#Gv9%S%6PKd%rg7dTz}tSuqA=Blt84m<0y&twVWp}P+OuNIKdN(AYaJ3=W*xe z(O3fqUF^-Gu0{hRB<7&O7y0bed@Kp?nCAW>T(5I!yiQ8`#6#9jJq2=ndhH-EI2_-N z0(R8;>|x7wcT73YLi#JqaZtXux|3U?)$4f_$i8r%YF7Vv!N0oe|L|JlDIqXLJeKD3 zS%aKSw02kfxvK5kWg6MHvmubRnCRK1w7bERj?)<_ZG2}OjBuN+2Mo_A?PvP@>A#E` zwngMHz$Xv%Ca;)v8>JTXPoP=4v(UNh&nCP~ECz@w_RhOAs4}h~&R-4p4W0=JEy_?n zg-)$D$*%5EsZDm*$3M93Xi1=rnJ+0Ri4P1ABV5iuxsdgDj@Xe5m}()-gMeY?O{GIq z;2`Y=Ahg}JQ4$!B1n){;hEzZ;YyqcLA{H-!Kk||RrK8l=(EZ7%~qB-3+Jg+^U z+S`OT)p96PHkpMDgKLA&B$iLdqc?`xUgexZmxe98osI$sM4qygErg&^?fh5kx2eYm{INH@{mmRAYNNzSe zlmT=-!Q!G&yW7jQ^)0#|68f66d8MwpSrisUQ|Ye2|A7&BhxN%(W#iZD^hTR811P3X z8S$NAJ5KJOBGk%^hAWNbs9!x`QL_;K4;B9#p#S|3GBTiv(yP-9sKWELN~f>*WKuuC zb84KjZoG1mc_WV5M8S>I+D1B=k;P?qP2R4r=WuJY1<;4yH%o2EXwqbwSa9xKNXIRy z);7uE;L6;g$Ow(h$eqFgHVRqacKkv~ZVs2#soo0LVZ(xsdeu5CPfyrRX-9DP2xDeP z0$Lu5Cov4B`Z79@Z&TS(p}k}Df%QZ|QHwIYhsJxI&#Y>69<|4P#k2O1{$T=kySfpZ zy$mz+_&Py(xPNP#H0DOJO8yQst1lWS%&W8y38fiGK2sJh>ypTs0Bsd1-G<$F2Qx9Q zQ<9$eo+}H*GYYq}_=cmrO8a$_@?=e^?7Z&R6kxkrRJ(Oa(YqhYtT`QJYpmM!RP)T1 z;;H&?_|t`yOlKd|`^vz#&5tJ%Pf!Bd@!k3GkH5z!SQx?#;tla0-ueeNL;(?iI!naj z76YTNfcwc_(8I!-Y7w)NO}I}J*X*>vo{FMruV1O&x9)&5s`AR+qusZ11a39j-K(xG-NWm#@QEJ8bbb4b3JSS`vNfS{ zH4Y<@wBUw>`$Ao=R1`;#a@yCb9&q?dOMDufgqow{jaTHcw#xFa0O5hfH-EBQ#)6^y z$i;3w0q%BY#b#Mv{EqPNn-D!3KxAl0x!~hbsKbnhC-?nw6th~IqqXk6yk6L!%7V?a zKhJJDQXHE9f_b|jU`oqf@j;+?O#!U^}!V2|&f46iPC zSFBaZf~(1kUf`bLurR1e4%S>@O8)j^^?6#v~de2=JHX))zp1Hy%C13z7cEdjqm-C zFNX2xWpW%=17S$wnh7UL+)UPzZQ*r&^80P#t+#m2xNTrBUX7kiSDiJEIPeGKjPo2V zL~qSf>tuWI@?BZ(;F|VhB5ZAn}Wp)MOXK`!6+&IVyVe=myXDUxx zvMj#H(X}y~j~&?R!I+Y>bta9+UJIou`sC^to<0ak;&2wX4^!a?wz8-A>t4w($_lt< zhgeuYYtCgqVIbG2s_pZta;4u8s?#o~E6Vy8Lv-k}8PBzTLWx{aMF8wBJ2NQN!@Yt3 z-VyhCW4(nIduj%1$kd^oWWMc`V$QU{>V81`0bU5C3i=>zW}mG=JlS=#lvb~b45Q5% z_Od%m?5qSH&szb-X>Z!|xkELA85wzhT<5zq_x4uB^6DsvdzzUg9UI3z56@58ZHd)v z5j@kp|ES^pH^;gMo=)jh@;SI@A*?(nt#*599+Mbvt&QN1IKiO&p4B%Le10#jJZat6 z0~J~Q!Bn4u=Mjlsb}c}$H6<7HEkNt9qyAlLX*>lI%!GGo(fxprbPD@Sry5881C_i* zFi9{cs|@d$`InaB)r}hAvwHVF{j^?)ZV+iGrTX9_3Bl^!ncJqcvrXZ0{uIehoX7jC zcx+mZ_VN9A2fY`3IHxpmj1RkI0- zD%tLY>-Uty*0}b$2nL&htgZI=mW*!g-4f-Qw*@YXweas|$<5`e!LrFG?cFNApLcY+ zr`TQhlGhN^i?X`?HYj+)EUQ;@rJ8AdPzuZNy6bk7%^g~ImRIMayqFCZ*3`CNTt`)q7@#1}DcivMymtC$B)8-5tDPZ-{=GND@dcd|5Rs3I;t5LdB zaa~!C;u-eU9^M=bNi~=H+cpWJqzZ7)TODL}RA|DV4wRV_K!8@o%;Z%ZZ9dd(k}Jd=OmR;->uh0ooSpp%IkVfHsZq(&qA2}If8tsD6HxO&92Lz;T9P>(D zk>28}u4MAVs!cDo206>r?ip<^k;S`Jd6>s}z>y3JJySri0y+ zJcfE}HbTmEg=fui#n6`aVU4M>V9$F#(_5m)F8jB{(duKdsS{Nqm3|mZ+wM08G+L+$ zJRiP?sBVu}i51bpgE-Fe03ej}hGkhp;t}L8b#Ps!YJRFK-H!Vn> zTGR;-h+mA%^ey&R^SSSeGE^Su$(TYNnGB%{6e?sd_EyXJPhlYfWl^fYVB*r@r6LEG zX&uHImQ^Bb7N~jU5B)ovZg@g;&UCP&^iEa3en&VF2W3Me#L}6J&K(}Uy9~riYzehq z=rnH(Zv&iBdp1Y$&45PqxNgin*9omMKLr2{cfKs*YCO%sF5UccaL40_3-X2#k~lJX z$<@CdREY2e@gK(J>`axNsS|>LZ$`-k65Bn~pi|6ccPUhH4#*4N=$0UVfBGuI>&RMJ zU%!b4yK@BLIGEqTs&vqDXnoBw9zbwriEBN_V1nA;nuUuA6nbfnGF?0@9@rIJp^IzD zyS}sKo4Q%elofUOi+p>}sylgZAph{4V9qW1RmDrzXA+*WVc|)9&LvCrO9(7&$7?m4 zkSaxj0uSCF#z`=>X!E+2M`%6#=eSC~yr_Xe)6gOx-WhDSX17d1mfz)DOrTz)A4_=C ze%(s*;mK-p)}AM9t~1r@fbQBP)Z@E_^r@k!`2aAuYNZBO#9Dx=;y`Rok9)bD1degAG{=iHeio=bNc!Kj`l>FR&xy`!sB`qirX!pX3fI{t>7UW@F zb&}Q`+;zVkTU!dkb(gIj>){&R3?Gl9S2Ba%wzlyO6L9{}!7!H(+j1W|Ss>&pe9_5XcH=wAElCvtQo3>~`YtQ!GPbBzVT(oX zr!U!0gV=K0AC)1dhoP{&QzWK#LLGC}%O~U0PU?6w*I5+zCZlL&yU~WW|O#0|b z2X}URa%x*sIR|iA_XCem`AnRjYGG3E;omlLyS17HAG*?etZiTT0AF**z;_qt}w``Zi~MDUy9XU?)v` zB!#9=W!i0b7Nq%)m)fy=4+5ZyZv$N&{GoCar8*IQer;;22f@uC5|=eDiw~b&L41d# z+Z_-I|E^|_&8Kc%JmNf=1lVtk&eN@vnMY>S%po)OFVcOvVabMny4JhDW$ zHfxbhMWv5BA4T~%HkS`Kv!*j>-G4T;sd5Lc+&IaGI5uwkM4f#62q>QLdXFWS_7*bNqQsJQ;5=LJK?s`WgFTJFFXL8)wq@z5w@T$pZn^DG<{!?rFBkJ??VH#rdZ5ZM z+=yqib#U8l4v1mNVsxP?=ik*b|ET9c9cvM$9K;JZ6;%R-2i+iS)rB{PnXei4es@`w ziI~A`m`-omGI4dHULPl$_;=*>pD(EmMh)`U-@T%lILM^ZJ`8W{L*m zPp0WM@QMuDcSz0lxmVk*;?%j&pn)L-;s+0Z_9A;rP8h8x_f$1u*^gu%{-dmqq$V(m zO%CKr1}#qy9U%=cl!B7lv|vtdhiUg{&WhIjOr>E_OkEp+J2;iHC4<@me;=ghM%T|7 zXRAGuMG6!$YA`cixy+?k3IY`Yw^YvVk6Y&2&!_5>WoSE&Q-cB0IPu7%?Dg@SEaY-A z5rz2?&iX~~2Ud{n`2RNNpF2|ChL|8RwU(Zt{S{E481NoVNwM)5)?%2Eatf707?Gr} zUN6Lp*0y;jD-=GLUNP-F+$NSW2{Zjic|_y)0J+!0%R2Fre$G>*g47cO2oc?8wYik6 z>0>1-_50f<$2kcTit!_aU6H4Kze?xY)YO{X{Ij*iEVl5A?Z#6>k5&;}`x@srZ2DJL zY;+?&_r;f&^x|SA7$sE%Rz^$2y6Dg-WF=Mks3H=Sq({py)Rq0^RUXNm8v~CPrn_FiStFYA8oIAYrx80i`J9xwc-kvc`Vfy!@);~x)MIR)g zBc)ZdZ~o;2U2xXD`#=(3$;CZY^q+AGqNM1#n`-yk?@v-1e}u&U0pNcW@IMy#pA7h) z5d5DO_@5g5f4d#vT<9hIOD(|v?>0fFN?Kc+wEQ3+v*ze6;!EM<1u<_2leBSVSbr{x zb&$%u!{dwA_G5yZ9X0G?*HvpFyjX^D;unLd8pIs zEBI3+Q?&ibiG6Lcj4qi+U}8|Ic>+oQ-L0UZRe7Cp>_j=szTz{u8QjDJffo(6h@!^Yx3>DFO|-p=7QBU92T~HI7sv7?-=19tx zLLjfZ{+O;lk+B3@QWf#yy9oJHJiJ9}XtCO9ip5E<1e{Tt;*IEoRjO z5=E)4ps02FjEk#YLD;*^>{tt8v9JZQ3K2M-O<2lcR5tIV0!56f|2*2Z6K(|#yw+^ydwcoqs+E^&2aLnLhV{ZkObBJDc z2qWV8ZCkh)Euy`Y4ATf*eK$yrS!Pevw_4M!`c!sxo>8`n84M*~UcOD85J{!(pcm5w zEo!w`ji!`;F+Vb7Y`(xxsU!njayD_Ya;Z09EQ()o78e^CY=VWZ^vxxzE#bFq=3=}K zO4yB=^{2_Qh}G+JKQNMea>ZS~OsMuwa~U&93&>cK#a!`b}83b;g+ zg!q7tBQlhf$Q?v~K&OvZ9zmo$UoO=}>NJ)@h^?8oTNxozQFHKRK3ei=N*hxZ0AfKZ zjbHO3AM=mjGd>qXE&vP+cS~Pf1Op(I%oeT>w166VzkET=Wy~W`R#IwlCGfl-dB0e6 z8ecu!wJlpdSMs84ycto(k6Prko+!~vN9;o1pj2u#U6_4-__peC<)lk%NO-rja4=%c z;91zH8KYl3$|JKM8+Zu18KmC`?lVrdc0Z8Ee(>PI796UZNvl?(+s$a=Yx)};$b22# zLhC2rQ}<|nyT6|1u3zM)Wcz^BI;fl#q15Nn2JpP!fDO=MZW?nz_@yqvM-$E1yq08I z06`%(AONS`PE}YLp)U*2Mfz>!@JlaJ_m)mE&6tl0xVt_^!6B|r&4MY(FF9me=t9a6 ze9JnBm5Y@*;NoupwF}MSjxqo>V6$p*nNfCp_#v}+N1R|e{aSR5%o?gI%Xy{ORQRdF zgOp@0(aH5|jNZAC(b~jg6x4)ea$!MZ$`#Bfi*piSVfLHMz84oRz5nCXofwX5ndj{x%Yg+=)Tq|MgT_t5<15zY$ zTWYEq5)jkwdzmY7k=Vux`N^M@efr=p=3{p)eZQACOgSWXOiL9Zj9qLT4^u<*;^S@d zDetUt|UqSv`KaK}m--N-bdtT>WGC#&j&rhw_-JIqQtwuW+E4xp6F7;tN*+)S3 zwbjR=o|506EWC1Y;S`zM%;Zz@H-*m^4j1&!?YJcl(3)~pIrI`fti4b9m38V&*8~Tz+htK#bOS=_-I5Gzt9Zs44%Q%=;dC=1vKxLCazn(AYA_P3Pev9+b)di zBG-B!sS$EL8GI)+cuQQOOP+j79Q09fvoj}NS|j#+jo8fCVR^&E{OXH`ddiDtEM1#+ zFBIf;vDgum4SFOl18xE0{RS}?SO~M;smm9CopJ{e2X*lavsi7~9Zr=87rR0l-DrAZ zoWzLe06HGOMa*qW30JxVsSYRtGLn+7Z3pzKNdLuO^JCv+ChZC}333v{w#)zR$x|4% zf&{ey{GZ+%#K?~0sUYS}IAaaQX2yQczJ|XL3AV5Kvxnw085cY(y zi)C^E4EGfO4q(qQY%KvWEI|51`FdiyAL7l3z{bxgd^jY9XPUdK(`+90OCNjdTn|)o zP7*k5XOADkF+d3dzd0u zdWjMAz7GM8Sy7qc?8Cknu3d2~)P~(jir;TaXp#6@mCi$>bv+)a>g)|W%?}RiZSr_x zk6Tp8Xj&GQN5(crMM(i5^*4)IUf&AmBG10?; z^V`~P+jZukOY~!quJOBTY3?Wc7G_W8$}+X|_${i@myt)zRVeEjS|FyEGb?ZMOugF#z_no(jIWYYVp zUSipBQ0E(S9Kf6=WY>Hs*}Ox~s+l%wS2tEnDZ)`%C!WH>EL-;2Ca{9J_nqwVUKO-&%>=Dx>0rJePg!q^)M{N%rN15!@5xUh9ir;XVIDtqwI@oOnuY01EbfDY5NK^^UGIq8JxbSj68*X zWXVn1j5dG1tVZZqt@N3EW4XbntO9n8>>}4(m`1F7s{RD&TRz`yuM$ zz?C-MxkG-o1A83$Tg@2$U=Y4=L%lm>X-HE9455xgAt5H0OTum7`8K!0cmo;tUIVX- zS_!_;Gg|uRL!*l=nzK+Ayvtj)ms`@AD>e!mdlXO!~u+GvNRjp^QosM(Fq-;KQ63FsV z7sAafPl=dB>ES!cGf+Obd>4!PwnmXo-Adqnvg=S>S3$R}!RSFD-q`1M^9GohwQu58 zH~ss&*|`dA0Ze@#adir{C8rrdv$S z?$D^6Wkl&Pwglo0w$*Js{~@eX9K7E&aWG~?2-c=Se1eKU`L&BBN2<#5#e)|~Ry*V0 z>PX_@y32m}eg$WDX^N-oZ1%geTG}y6;@Ocs6wd>rW~~+i<0}8=q^4O*Zo0ABl6qZS zxU|V}s~NxM-MB^Ze2>$~I>F3~(G$Lt-B||fzI2tkAv0rG{0DcbCa*XfOA|>=4cF;Y zv+Z`e`bQY*`k`O=g6D>*tB9a})HDQjsyZCy)0X2nI}Dm;_(BRrg7y}^mFglQBHTM2 zw$|ef8*kaB-KfFoVQSAmUhD6syLvqztzp8wLd||q+0^bENia8t>!$0|kAe0s^KLt5d-Rn^wpFfJH(s}+(m-vW&r}DT>3UabuLA!jM?6jS;Rnai1r41d2TiYIs zm@owEhjmRlPHNUIzdV>$UL-xxYomE>5vQkcYp=WL^GGp$vjg7=(Wt?sz}49#&tUVY zT=+?0&FpM2Ujf}}%;uowY0l)zEC1h43P=(J({ zyFFRilLnrBUy39rs;p|U)0Lj$=3iggL%?3~*`e}g`Z&CP;v#W1yHk^pIPT7-H zh3~&zEeuvKG0fW2wrM4si9V}vt#doiAKMR)SGv@|VJFSA!MrhW9pl;om9J5nmiIw^ zQ(o3azFzmk=BN>jXn)!&S!0#OVr&@jhvmpuitCNBc7E;_7y4-2QHGPRIvNT3EyCxNQwNPOIWQU|ks5ndRl1cCNtM z`?R!@8H@)r&nrkB$J#vYo_{$^fPMxawh+M_^eij0;T4iQoU2Pcpq)o!ca(uU3n?!92%dHqhf18;j-zPfIN8^~kOMcbZx8n0_(?DqTf)`A7rpK~X8)4m30i0Pttoodcq2GDYSZZ+iyQ?_sganHOz>@4zO(X35t zZX7rMC=uqcS)Zp`L3d=nyT-)lrb6FrxajEtTQ3%aGBj{hXXlnHapz~htoSNA?;xXe zN5oc_%`ixPx;8)Rkgh&vpVct_7&Sx(pRG{2XwT0?2vX#;({AaD^+d6Ywz;&fsv^gV zX4s(?FuJOa2ScK5s3(3-UcE#I*l%b3J8P+K$d^Jn3ww*M%26=_Puv>>F2V(Dx}5_? z!`hC1pztWRL~mONg$MOy!}GboC;b!uGdBTSlpFIud?9aEvLDvuPv_PojRy6T$an1f zm1wh@o@Yk#jAb$*w5E$HQ^toJi_IC)+Uo8Dt3@@Oy6iUPW-!1Q;v4n(}JKFzKYj*t)hF%dRqcI9QR~<=C+(zkq*yol||5)=T8(r%)Q8}ilE>QM`keH zU{H_^pR7OGs8O@uyE3SiS5R-ty`6lrGH+Ihm_EnfIyZ5DSWBHpKC7oGmK5o@6-rPz zMc(kD0zO;5TR3nO+(Jr7X23i=BD>*ax6@fMv>H45wHq@Lvu3m0Y;T`yecRt@eQ&sb zdM7-Ol<+~PsnEIHGbTE>)-|ZRdP5M?Uy&WH*|rA`vq-&=kdmo1?&_|iWkw%UD*geE z886G6LqYf?fcab_4t0T+TkE{_2Ekdx2U0Zba4Z2z-dmuSR_|f7j+=ab-B8>$w2=K# zqi#C|A&cNN4|nsA>HZ6#9ei!i>0LEB^^>!iXxA)yGPda|+c~~82=s2?My^e~xoU?R z-K$-}iY1Dv`A@`CiOUpJnpc+Jh{>+Pj(qLFZboNAQQ^mir`k zE6Dv|lDdoIBmg5!!CV`3=)^6);ofnHh#Y5;XVB?%pN!!!WZ3x-cT#hxH#Qz)v5gkO zX#F}pKMQ^$?s9eQG+w53u1tr)0t`%k{_aCO*L5XJB=P2ec|pt0P%zs0AgM;QrFvDR zfLLqX5wDXan5c%fjEs;)bz&`$Z7P6tBZ+VNT{%ONn^kxdMzuphT*dAZBpCXv0Y~L= zIVc2;VR~(G?teV>z&y8GLqN?iBbG$LgKWu1pjA~2*M7H{MJbFcbAP>`g7@%yn$v#l zqK%Fm-3Or5Bk5kMw*|N8;6~WQOIBI_K;rhHbl9^fb;D)QJFQuwToU8!)jH?BH47DM z@PNfJZ>5b=X{V%s%Eg^79_sxuv)}|;v)h)q2jjX>E0081vEhy&qeOR0Esy3wmLN4h zfF`nd+W^p2sjW??PHWc5q9O(TRH>@te}lj+yQR`;t@j2b5)SKIG^=U zoyz`b6WVbFC*ErS7vehCuo3V~Y*1^@{3Y^rs3dhER#C%|;YY4hZurQ{-Ui)Bk$sXg z_eWQ9$hrgC$j{4f^ne?gZCb!C2A^)9^Us~z+{hm-nMtge?o`iU>~E1_oqS|jcVyN3 zPH2|Gl)?ZwOojsyaMph@^&<=4L&4&3rE@c~b>;jLmPg7-U*!1P>RY6#w1>5grd?*| zUu>n)*B>$t;Xkf?8ZSkAg)(PuAg5n%Cf&EU$ZDGWK(R`uoZ5kA*fCLi_?Ea2p34)v z)ghL!gBitc?(h-~9RR5}{O8awp6F}IJ_H`j`=gsFI7KY1S12j7 zIc6Tcw$zC(wNDFV1%wZ8-%0kYlJRQ?fM=;`=Dws(1o zX7Ko?R>X>rP4ikhHXDMol3X&Me)x`eb}VN8-s4+$NvCvHB@Ia0qlQQxA@?Q>2gW*J zaM9;+H27Ol&VnlNHM81|EsYb6q8JC(eV5Ae5AjUbNw1hFbag%tW3WGbr<`}_b}$*? z^wrzPR7(y_FkYX@ZKs#0FzMvrq{U{7XMl*F&Si~5T{r8KnbutPSMIN(;N$iiNe3Gx zyBCVu^!?(c;0Uoa6rzUsaVU=bhyX7*{s>dVo;$Ij0~+4Bq=&`(jUPD(X2R%wEU~tR zm-@3D%Lb(A>u_t%Y>E=r;Vy#)#gh)>>EpG>D`s0CZxEU5_IJ znu-aV-Xh)UrQr&>u4r}emGbeo-8b=;L0QQz<<&Yj@G5ol`JC$1?0Q8YUqWO|175WZ zP}YRF`6R>bjK>z{1UYlM17evVgUTwt$ZT4CU}}}ps(8o1Sw9k*-cbH%PPdo+P}g#J zM_22ORekJ{4hU>-*xw*Zoji;yjrU+;XRB8%S-8Q&z0U!V+Ds?oG0^G{iyGjfW0?Ll zAH+2(lvTCKRwVgdzJ5GwN*J~6o2@XL<}DxJ&*HGhKI`Jz8j814(W953KG0d>&Tb)9;^m-AjPuE&{wEy`Ji;rV|BRz#4T-=p z(G)x7mkq_4C^a^ zO*HyI8z1HsA&rj3v@*IhQVfwjBNcdMKcwC86;Ik!ieGZy`FPogMBRns=p-URb4bT^ zeWfN&|89@k*_yh<9w*2y>Z+L~+XGuiLq$q03uA@a zQdHKcxo=$~A}Ae=4P$A-UQ}L+_JQkOJQ9hvBxham>Jc+Pm9au21AWnk%ceRZ-paeP z(Ltt{CLdZZx&R1zeP+BEt|f=Gt3J{?rOkhgqf5gATQ~UP|C60A)So}>QmeZzGc~2; zGRbFXSM*}sxo=x^6cD%F^6bW3$6?qLuvH3rwoQ^t25lTS)d;`+37(9N7sbb;IlrOL zy_#>D9kuQcPB#NS(CNIwx-WXq7TMdjm+q?z8Y$HbpUg0opSemxiC5oh^2;i)tu!}5 zTTVluA@~@5;~>1r^%yOziP`pm>94nLODt}i2U5toiiaDX_WjwI#cg~$U;gzEr}LR* zy?0cJjS@=%n1Sl!Y~QQP2)AuyG&FKCG?9C#*Q}-P3bA(APa{r3=-YGCAQ5s5j9IXJ z*i=$8j~~jhpCs?K73V?uKxa1f*3GnbdywCQGnJf|AG7(w^*2P6AtJ#H_WBMYItCWb zJ#@#!XI=R&s*%2E#kr&T6Zlfj3)Z~R8rztNd~ST7M>w2|90e16&DK%))8|LYj=`xy zP=)V?S}lmaP+CebTF;GQxR*#7uRPE1*NzB0Tw9o*wG?H@0p?Ptdo zbdzT&l-+*=%A|BK8>QV>r#)RTQq*dG2x+5*nuJsm90vw)b|so-g|cM9BUy%_AA(u2 zc8L@7J#wVGtVq5eKYi?~+L|#a7d(?=%e+*NIpcUV0HNfP-AV7kY`mVn2?H`ksAg(0 zmf_i*|MLQ50Gu+NdD~dp(_$lo z0}qka{N!Adq5G(HpagOJ4<=K6KvLS1V&c-}<}|u!IoE##MZT=(SfUYRsRc~h}VLKM#YM{?7XqGf| zRUamFx={S~XoX{nOGp;1<7(A2Rk=;>_0JjOZf9seZx1p@yZA=ID95b9I$*+7DC8s4 zlADQx2eJlcVDX$Ff!rtLwQE%C6?;|x`OReC`Sq>c`QkR8 ziWDCQ?Sj=h^8DCVmDk$TgMk))cL&X4C3`5fW8MBUCUNL9#|f*3i&&!aCaD@V^QtN7 z1k-)Clof)RVi)?Ms~{SRBaelhZfnQ_};h&j27uds$`#@JIda<7$# z*)h6%(+aqo-9&>Cu`%q`*{ju{eod}PiQILiZ!q#&%OdILS&P|0)?51yl1aAUH%&2IOHRe`LT zNu2MB3F#;Y(v%v=qI)!%Ea&SrIyvSD77u!j@F~7F2J$K{zH|8>$&~evCFee7$!+o# z^vD^TA9;j}Zlx?vdK1Gx(8;D9EY224i5vUdA9(xSYBqvTvPrL0+G<^n7knKx)p#?I z^@g_0x^8H)YVi@p=TD01nEj_gkJXfl2{y}%6f>Xo{a8_Bbvc-c(_+)&$D`S=CPRm; zgRCO=2>ZLOOGsuzt1;6iY^4_WK=hfoYMn^UVWj+!>TR{UAL<0!NMEO~z9Ee= z)|M7QnAx&Khbrzc`E~d};?dDJ=ILbcl!=aYqDZfx)tFe5rwDWGaK!`XdNk!hV87~} zy@5Z084NE3Y8IxK(hBP~u)}^N`##)qV($j>JQ?-|cldVT-I~;3x?s>n zA~)X|&wwYdYoF4GL6;(aEV-?x2)06b+R-o7mwfv8D+aHpv;|DblgSlH4^u#ConQ;& zcGLdWAh!rd7dokYzOXY%TDf7Fv{Svrg*bF_YFxEu+LRB;_kkgUko#fl?DP*xVoK$u3`cLFR#2KDmyQ)fc;MzMM>L`-B*9{L6~Tg>N7poaH_a+;33j?H%q;o8n8jwfl< zR8AebxbSSworx#Zl1!X>Q_)`l{XFOT;Qr;=;$RBQ%x$WoQI)SOKPqZEQ}fdrI!^^yL0e5$$g1;;9H^tdB&iJuT8EE7u_Y!{PZWSCR9P~ z+&CZvoF|DR{=$DV0=_ND%-#tP;TQ)y>Zdv_?x{V`XN;Mys`HnbU+kG>p#+-{5Sxc_ zj43%za3>noQ-NuaW7+B@+c_Ws4H!6ufm6H>L#8;n!`$5TG&nuEhJue7D#--s^d8k2 zwr6h!G8Dxfa~yvwEBymYoyAW+04#?ASVGpLHhW~HHQVE*UK?~fwBe^*dL;R(+*T7d zeR5#<{()w`f*PrAndNb&M6MJlMQXb0Js1au>UK~ax9f~6a>5d|_$r@TJpBV2GucQh zwU*l-Qxq9YX~+F>5-V#7d;>ftD{MRHYC8)i6O)=ORI{FQ&E=tqOZenn~BjFe=9!u^azkT?YhOzdj$5EL+{>PHR z%5WvSbU*EUccBw!T2`{j|?dLKZi`aar)a;z<)OU=GlJI~SXMMr$#=9WhR&$7S zZ(ctbM6@V&z+j)W`@v`bN~ zzW|v{N7`?!#4bBvWy$XQU+1<$*k7PIdki$c0MHCLhDpki*L%kDlxd~6zV997$p3gB zp&7$Ki3b-r$UXb9lI!zO)i> zNY^et>EV*}2Ai|JGoBd>yCO~8+B^-IopP;!J5j_4E`uv-rD{8x&mMTJ)m6LjAn<2S zoo6+R(iB%?Ku4OV%zkCRki8t&wj)@#<{CNxTM9VBoo<_mt-!s)zh_X6)Qo(qZiV)pAawQKq;}GS>hAmmk>yZeA|C1ifcH5i@k0OTPYQ&M{ngjMfTUnp(>vj z`tFPfe@b!llEU1P&(<9qw!)<Sb5D{%L(Tu|S(RZn*OBR~1k8)v<JW%n*0`-k8z~_}ZuQ5a<(srT?)1+eUlTZqNh14>wZx_e83oB@ zU|3dDkXrwUYktz;r&o&ux)4KNA<7|t1_^GT=8dual%l0`8Qd{FbXi7gNSB#o(L<{m zkfWraCilNQp~11?pzK*vI>?!3Y0GSXY&RIaVkn7imNTg>ep1}NNh`f-u*P%y25we( zlC^@8elUM)+c$o)x5uN&kD$5K*W1(Y7W#EXFd@n|K9vV@!)U93G-jOk$A)1l4XYoN}UGZ;q4ae`I^47}7R-Y3MB~V4bJn_j0hgb?q z22I`%Fml>AnZ`@&=F23=EG0beO`5rb;@p%YvFbXGb>HxNv{Kz;yy&hOA2$$fTio0) zn&T*h4>hl*SQ2G^W!^59^&9*tQ1v}-=F6+DxF=6^FML0F_2iW+$`8Pwt`A+{={$Gm z9JR&ei0{;rt&x@|q19c}e{gTO^q62|8RIA%l+9DL5UX4?8Y0KJ zxY(Jl5-1)ev}-luEbiz6b>WV$ZrqmFmq>ORL^-#t{(+}w*=-?S^3q4R5(@PnqkAu^ zhb=h84Hx8N+|zmr_a|+aYDIaEaLf)1BaiK5@8T{^(T4}n--+bm7+K;MD7V2GO{$+E z#R-ampUm}L6A=@kdb3(Kq*f!4_c(+Lld@GuHz{vSF6)*mazfhDY~(93J9Rv^E^(X) z{h7Z0jfV<4rY1a8!iuz;Z-AO{;fUNpzU>^@-kCQHv4^Y0tY?;msTL34F}AI};yikM zp@6l`jXLt0R!P`Rhor99w;6LrZo;972*Z`jRj;=`E>6W_EKjobO?qw)JocrJ*f`3Z zl|Fu}m)bo^kKB9GV{UHN?f5q$>I3Y-LbDxIBInfFiT!_Y5eo$$ee^8s4zm>q2i@^i^$d1S{P zP1Ni@qeXiobT@EsS*sy|rBbD1LWYVDM_p!>B5L7wc{uz$<0tnY10<$;2?2rzIx0jM zMMbJtzsrGH^pvdYd{b97|~xaa}J`3Vj;4=QHoBnw+l&}q?*Fqkv82wqnbRrw-M zgsd$|cyyyqD4Lnyo3vwy_;Pg&WBH?+z{2faIxdS(nOHbaJ7GlV*U>r`1EJ!D$ko05 z?=W4P%oIR{KnSE&|ZNtB9fOg#0N+$-z0l+P}S@(W_fH=veqZ*YY zHvG~zUT9`tia9}McZC6)(N<-Qft^49<%T}xi0H4(SafFlJVIU^XRYGscWE42ZIS+2 za&ps8h#{i15IS#OP(IHj?n)~`%8XsQ8%J9BP*HPHE7B$x$`BDkaWk%+Pq1x0FWC8G z#$U6%KdR$2%p=GLn2u7Tto1C%UIiv_B?X^OCXU4MJ(@oF;Z)H=s0Jb_`ibSAaE#0J zbhkxPo2cIi562>5s{W#@2+#JctIMfviO>$W!55GW2A~$gTz_S3u4f3D=ILC+PB`<+ zK&8qn?>*TmpZPurW$JJ$GK+efF{<3~>EhgwiGK_v*{iDCJB((A7{dy;nxEjQYQ2*y z3iBO!joqGN;x~jpa;)0kAv=oZrlSC+E2-=Q+l%?cwixXzZ+yOftz|My-_<3?n}||! zpKyzP>_i{2v{;WAQ~VpdZc&R#1zP`nx`pbGtX?RrKBMo8{Ee=O@HUT*dl4c)5PaROG{6WN4xs7H>>^y z-%*Z-4<(BnDZN8B4c{~qo4YA$U*BG_Ok5JaNXGo~vez8n%(FI0;VbJ}$f_Pi;CvT5UvRh41a zV&W8IiolF)EE=Q4@T&L0+sEwNNP#-Bb)&?xcm+25yl_$1iXV9@zAO|@rh4~v86-X4twe=#~Rb*O)TDz%T+)l|-H zgNqnYVGN9V8Lsj_EG~o5HdU-#`bI*n(&r9GZ;H1b?w^0Cts(Iez2iKZ1Mz;n#XUT4 z=)mmtmCa|Ld4hFz@JU04TVCyv_e1TMsx~?T3QuV3IX~lkiL#Q1Yw3y%v%*?L!J~uZ zDN)9W?faE{ACqPJox|50SS(cDR-VlG)8Md0U*|ehU(zir@48i?rAlCSsVEDVC+{&> z*Qs|ruANfXldTi;N^;7fj}W;$-%ma=@8C~tfA5Ii<}sm@lThZ-@KTr;j1x5R-w%bk z{@E`cG8V1AU9;YtSPWlwuUoB;EeBLVxV)5}*ht3woQ>-P^noj(LlojMM{o6oRUd=k z`4GewF0&B_^XziNWCi0`|%=)ZI$6_Hg?c}Oq06;Z$@DBG4} zNi=&sa{6M8j_HmaDv`x~ICYXJf`I?DWq+EOK-n>`U3Ke+masl^|yAf zTxrA}gT)>Iiz-|9lo=cNMfrjrjC1#hrB}sg!a?TDi^reocsP{dZgc{_dQY*QflJ>l zwX$w@(f;x!*lT2C*RMilH_})(JObzdZHD*2|1iDgw}-18ZL-?tMu$trgx{Hi=M@tU z%${$aYTnY`BIY%B?-lKOApI77z1h8etWwngOFFy6Cm4L>y*A6xXP)jqbZAeuAp4Bi zEVCYZ=bjZ^-nXpPsRy<^sd!;{!QD9YFLiTfmmUN;2%hdxYt$`=r$#43v-;@#4%byi z%u4{ir#U6_IoN?qT$Z|nyEkhvV%;(-*RJP9$k!mmcO$xAFIM{D6BuEo-!c7?iv((X&rHy5JM@U+_G<@10Q@qtNx^CQkZvSx~U>M?Jx40P$vU`hU)T|PvV zf0>?s%$OtVAIRkH(u4{aurWVok?b-Pd2;K;Q*BiP;2^6#$t}w(T6x`e%}pPQ*J7sCN zT>)**y`x?Ej9suCQ7l#{cq7Ux7w~JkS_p_1GfnchJTK!s-?4yF9pRLx{xUnm49?HP zjq4m;yM4%>mVtgJP^Mf3JyFf!+mQ^eKV;@gg_W3|ywTwra^fMt?d3`|6|h{r1Nw%V zgeu!o+{(CQiA=46=no6&@-=zlK#2+><4*bmB!()gvn8ro^(o@1bj(Azx^Q{reT*`X zz|2eR^RQs{#FH7Yb!1|ik>`G9opI(|TJVo^!o1moQ2yL^m49If z(-mKiOBM6H?J)G`c2pe%L9Z5fv2Nxb@F}#5N3OGi6ocw)zc>{$qG8y;#4FI@uzc=X zqW3blaom2I%+B77n;5&tUg{b1V16<9pk(ue_=AHT=_a^(OBl(U=(>gV?Eb34x>{?7 zh1&x&_BWWkpv8B2HAhp0_uCoO_bX9{%gCi+PXiPQ9a+Yo7q*19oS>t2 z%c-GfO^7S@B?5dVArH49vfGAks+taldwtr)I5I+!c`!jUd1fnuK}+J9mdqcC7hXA; zAdgH}g#5OqbXnZnCl3zua9p)5h_y&^#<)8-eGWYx{cu<9_-ve5&xi_~%NOdrDh<$a zqbYgG0+~GCV`ySskZtkghuZ}w_lIuZO&2Ymbj`dyu@jXl-d`~HxrDpwQ8(9>MDRrp z>@o=N{`(~F(!aq-Pal9u;iqd%1XAxD^j;gM8aS<^`|zAVhS;iA+QV>8Z&KINv?W3& zLES{7VidU(;BgPbX%l?T;6P!2JmiL3q;V(BJt)tarcz#q-)yqAFV`ZNU-!P&KbQ~- z4tB$T>PmEAT$+cl*K$_<`US&Guy`RZaGj+tESJ^7PGB#Qysnwnx{e*wcD$f2e~+AtG6=C1g=+-lD+4$ z5*^orPn&#u1hK2{%PjrkBn+Juo^^Vm3#4-M%BKxjg{SJ zSeFtnX(){5xs64fEu?W*r}$c^izo8S!R)?^_t&P?l^_>S!_(A@r+5YYzI=UaZfZGo3coK+ zS+acMSC!ZGY>Y5P3B@S?gip$04gVXPn;IR)_Wh3jb5(z^=D)s<<1DPmo)mI*LP*e~ zrfTs#jq3iR`*k1wAp*z0Vgn!owrRcIoMECf-Du4B7^*+cM;yqk6GO$eF8h;5@To?m zkkgS{DD2LS!d@501k0t$%Ah){uw>)j%;nTnOZAe<%DQ<;+k#rZ`Za$dV#pkbDBH=n zKsx5dSmM~Og#Qrq=$=5D#l#RQBTsWkEf-O}vprF_VCqmlKsd{lQE z%%1h$nkmZj`D)E%lFjRb%p$k8?|g?2?ovNLEcio3^zzMJsIljJX})2}cFYq^64~5UVZ!@Vda^%)k_%~$m{ zUkjJLuiPz#KkPltYf+@f#CosIN5(p2_Mop3u3Eyuk>z;_ zeXWKL-@rPFrQ;$(&7XZVc8W(miv7CaF$Hl_`{GkyO>N&vtEdF`Eob0d`V>a5+1j~V z*F4PRTaImd;x+BP21+%YYBT)Oaf$dCchb(4*38y-ku~7Cb>!AUwZraY5Ne6V30b)% zv+>4y%z}LcNbEHixuy&L2IiZUJDdj&n%dC#H@Mn58s9J?B#K9NisHT3C9YcSZl6R- z33j^o;6cZ@%dUMf$)Wn7DLs+;+Z`(2y>1Z`8Lk(G48DE?c&xZdB7+xlwA?qa7s_fe zX?REW?kHr)@UW$e0stH=WS|GWT& zicseLLEDGh$f?D)(H+p+a>an}JM@ty!qaQT;BrZ_;&Kxrjb79AGil;q48}`o*|Nh* z5ip_1<=yGrzg*J2paZcsi8!urE}>;jstVZhZQ>|+&l}>hVK&#A3|cOMfz`lsuwa4t z*a>dS-65D!H5t>|ab&_%3ivD20JG#T%asoN4r) ze4VN*f~#-Ni?%F`!Z1Ng!`{S5BX?^y8%6k8HkrLgi57Ex;ka$(ixV_@jQAy?I`$gM zt8RA?n6RT)L~pg%uTa~yD@VQS{IIQ~EzdbYyZA@k^4haAW8pl42ro7HMSo|s)cH&A zk$0?p5voUd(AAu0^^5_S#%~hYJQ%3eYKfp=NMPFH2GaxOuPO4E^{t7sEx zK`O;UQ^51x^8}ui*A?ILoyl?o{;Q)ae1WdZORJyr^rK@he>i{f+LP2f`gX%ypqT!C z#$ATPbvgU_J^Q62Z0X`PR?W>u1RezeWFy0%Z_zlIm2W|9Ss6< zQ~b#@gtv`qpFSuER|9^s$}*0u(X42c7oGd1)@c6g3RX$2AFcn}bOZ+eayU=gW||Gb!sE zvb$NnSz#sI2Wk6J;gc8beS|z(FWz4$&O6MtP#Hf+z;i(ryh!<|Nt*F`<;l@^3%72{ zp0e)a|DBi@4L*D=abX2FKhRzbZ&erUp+QtKZ|ecicBQf+=K6*1l$mSSqHh(XAx%$` z(#42Fb%<=Oa;1{hqeARm0~bV;s8z25%q}#H*~Qq)_?eO0z!u7q5%ND(Sthp&%a zivpKa(;tnmjLa9SHgRz%lk6gSHINh{g{(a|_I=*f)@89q|3)>4iEpdGjj*^^-=x*< zc+eN#LE8o2c2jm4b!yQ%)561%iJ>wA^-Cx_)U7?E%FtCPuxmK-Q_#V%JBtROSJsc| z6@Q{D++UN+YbLb9{C5UPiO3s`=|2N$JGKP^yKd18Rq?i%==rTJta*QW_!6%-VWOF$ z!C*#8=@%~*`l?R-RLJ$pz@FH6_M;P``l+l9(yXqZJ3R=V=tCtPVk|!enVvugLg*gy z9bkx$V`cc?SZM)b<^H|JECzhCTNZjGC$BrzW!AnN$BUQV-4=h|GuAp6QE(TaAgA7nHtUetv4+>X!U3-@s7D<+V#nRB zHC85y@l1EPCwVx(Hk!QPQs+rb*pju4OmTlq7yJz#+G5JhG13_Xv(wx(mKtq=6@3+< zTI^M-Zoe99MDP5-l_2uw7s^?;FriD#h#_Kn3%T&9>wr+B)bhc{FeK}0X!X1_k!v>; zC2j7aOVTX9S#kU(=Dn<&c^T~?`v1Vk_%HZ~T(WDa=PF9FWl;zG;qvxYzgMjvWfktZ zgSv6w?{{Nw0`0(mJfZ9}_5>C%q9Ft%t4E)~TD?yW*I37<{qi1oPm9@-SE6%hhMuJumr;{j6KjQPfFpwBG~1JnC#^5LeoV2+ZYEa4e> zN8GxqY2Nt# z^B@PAOmifw`g^uOTBVJRAI>lqst`^x&$ z#eY6Ad(2p@#ozV9Dva;R9L2Z1uH8=HqG4$NtI7O#QcdyKqwG7e-Qa>l#ebfa>$t<= zQf$5@nSV*fC07NDZ&zGh+@1fMLXKK4Nf@5v@2vdOoH#qJZUg5Paft!ZFuOKDKvq*x zy#6yGIUDkGNpXGZ>O@=R6<0Q2zJ3VT7fGLK75yMCW2|eH9T+dACwUnk1{#bHzyb z$KEQ?4V3WzrR2wq~aaLOA4Yn@(PO8vV)(<$2G|vpWl>| zroxxv)p1mM2(x%SdSJ@7FuEH-7Y$lVtX&miLCHR&@)U7DhwzQqZ*~GQbQ}shB(it7 zfxo;l=zt|#rGGIli~MLyw{og& zp#XG!^gc;L>y^xq-k-v?|6nu$%T7{X2wV4Oze4m8G_bEOF#)SevcVqP-^jNF@TvRN z$`8R>CER{t?Vv&Gu5&Ywive=K0tCNp^qy(*ZXIXkAA^3C1Hw@jb6{(-cd3SKET1y< z(*&{#>7Wgn(yrA7-<78=kiN(MC}k6{H0JXb518HLmW#`I61XnONRE{H_bdoGx93dgU}{G+oqtxY?dp5R+GUV+Gg!!wD)3ao%6e@Dw!4 z4$pD{_49iOB(X}#k%@=VSfmy2dg#>BI%0|Vb2KJO#hWXCYUoECb50NNEih8*ENXQk z%Weg_$}1-OY*?cm015gaHi#whUD7mmXm|LNUSuh{NkkdWrT|83@&@h`8%jFN( zKG;?5i=}3D&98&2-}L-AJ3Kxqw-TV*tMAwhh;6|)%k(Wea1=5eBQ*7a&PMF}P*?fx zs0*EA{*#|R>sn z!_T7Smi1j|tSf^|W%llkpSS@oqr@WlJqsNDGgm96lXcm|4~?03CHOb6*f?jI(EkF zITP)xa#)5l^U$~DO{lSL5X5aH!pr%rrt7=N5tL9Y8r15|alr9AK9;G(;A5O13r393 zMo9_O`1C4cYe_fVK=FO_#Tf{;<_(S4Gkz~cY0L8WS=Mj}0#05`sFO=!)}RJ#+Xg&< zGUMuUCc~2nesSyLoYLqGdBoY3XiU!EK3UY2@ClBlJ*QJZb5ESM_Ju&z-hGOkmsIBq zilppp&q7*-qLbwvJQJwaCjl;&PkQkY%}b{it?EfuDW#4*vf`X#RErfjzbMc~I$W6c zKA2~Jwi@)z`#yQ1ET~V$?6@?k(to@2a#7%}7k|-gUCSl35eJZh5{;BG&7zbgBu3o;A~8s1(nq6PU?c4T<^30>l} z>tuv^y-t$$1`QEozU^` z^w@zqUXUgpzH{#QY$&_A?HEb8#VAAbL|**7(FfnzlNmJ)Crtk7L$a5CUe0aLbm8)( zeWHueWP2a{AWaatouTV8YR57^7wb67{So3@Q0m#tw>6%)6E9UDA7HGCPiW8^m4OsE zVxqoxo#xE48}H6Lz9I7?0b93fDd0sx4DC=xt#+CYeG?htBOYe)q@}#nha_;bMiq2j zf^58iGl9Dzl!XAg)^M4h`TC0VO?)+zJvOZ4MZL=xEUwD)!*pBpfSpuRY;pnTw$;2) zvot9*GdoKzb6NBOjvl;u6(%w`Kj2zfc2?@>C)771_ZKgKdzisG*8pNo9r-OZ*&qwq znCwFMk1}bodHRT>>sE|aN*C|a{39nJdpnn7ZYIYCMAz=154*klqe&xzpAYze9qV7I z-L{u11{vVh#9IAKaRO;(x8pG-x4+&Jp!JV0O(~^OHERxwiqa}z4b-52>H2kGACKU! zy1hDLnG*G(%02wz+=RRB&2(bjL|;50R5HY&dFc;l)WkoaUbU8`L6TN+MZx}0Q+7yi zk46K;dcPRTWQ&1rJ4ddWf7XL+$7A)bsH|?A);D&P9+|)yR#uPi3O^}KPrmE z%FwJB^L*8t`8)#6FfD~U%`m|(iI_)YLHAp)ss}uu$JSy)_zN^(Ee~ElxeY38b!*^& z(Hs!h!;8d1sY5`%*evy_(r*^{8S@gG@=;)%g!*i+QdK+Xf4Y^wV~<~MKyDEs>^^(1 ztQbZYtOISN!Jguy#?GUg$EFyL;FGYeuu4CWN>UMH)w2)&C!Q!i6agP;@ad0{5h62w zL*KjuwM6!N;*o7ZkgfG49?#26MsGoL6{GsDQgr|!e`M94ydQfPm;F`5Zn#(dvE)%_ ziBfg?X}Ii@cgUs!?*MwC4Q`H$;Ys(WZFCAQ-D$izWV%Bk@1l#zpArKSe3wHdf&9Zs zDXBH6xXA4k7ce*nh6Ty_esY!EdyGq-azGuV)@4t6^yMr1o&}mxl*fBq)9S)YVEnOF zM4nb=MB&vH?n~<@hRqssq;%k#Lii9NzNA&^7o`i9FG{Vx#(J2!TMo7jpE@B(OCxJP zy28o%i7uw{{h5X?rwia z3gsB>vv$5ENAB*DK-ZjPWm}0NumuX_a zGmi6TKL@aFW(YswP&Ke~({7>~9u-W6|9%yCf-X|h#YXE}h;gDrd63M`TC`M3)Y~h; z!E}GG+;=vb;j?;kSjkA>>`LB`R@L}*^RYx2T^HH_CQ=5tZ5qDvyuO1mS z?mX#0k%CjeB#y5xgg*x%mXXQlKqc>)6?Q&FG5DG@H^={Ct&T*s`|2%ylNZ&JACvER zS?zKv>2=lcbjegl7-xtlNi0%H688MawI7h^r9e!8+&;igNYa-4_Jtd=UO#ZHRagr-|=qBg+tzN4X@2v%a zSYw%9qKYeL5(vCvF83J?(`TAd_#|H6Fxk-xQ6_nd6VY5nsi6RMH9gzT-szmHEXVp~t>yC+8g0!ue>6_!2 z+;$w3NxtzUmVxE7HzdAWY!(36uy*~ma4W2G-vfKSP0yh@1dnj7sBChFwp`QaDfs^f zWQH*2G~xhzlJ_(F3CU-j+DgnJ-~&|1Y%!cTtXjxU*{ZfN6d~=U{nm6 z8*DxkdXt~t&R1;}^O?6sq>|Aez*J^aGl%)Aa-M_3+|}BnL74xH^3m?MF_H86j7;M5 z0wbRIdG5Z3v_qpAj2l8NLGo*Ge${F75B@`TzjI={{s!hg3+zcQeoC7P@$*QWq`~HP^~kpw}g|uCy8)Zm#BqDjg~2HRV@DFML}YD{Lvx|yUcJ+1vTm8 z95)jf_%1j%MdlG=EbN?KPfOAA1kJ(x8L^<|%$F1zwFjI~>GJjIgRgv4(2hqG_xJ;- zt1!Pers>0Mb83U)%orewW9=&@9irk3 zI3lx4xQKmKz>s?Z;$@YqtZtUPbOYM|%`Il5U-k?BzB+4ENc zQcz*2efw3#0Et=k3!eoNdRaA38+oOQ=b)DfnAC|A+hmKc?%>)?UwgW&-dG1=!>@XH zbbFpS<{cER-a{W@+G=^2l00DS)-|SPC@_a$nPtoYeD)JJl#e8K=UycLmm5`9(o?NK zs5~m@HJ?X_n{1O=5kD6#y=>IO8|Y$)brfSQxw(*tsmrk0*|Juu8(*7h?*-B{<(LbkEW7aqL}m1~iYBL^~LFGRBi!nL{XEcyZ} zr1X%RkuIVeK^t9Icc7-VG9(|(@zPyLbS;g#gka(Ii@aL9t~?_+MATt4vM+^dI)6in z@NPypobe96pnK(pxWju2;ziAO_KX{r&Y?!fSlvYk+>LHwFVuX~*E3o+HY7cuTnK_h z?1d^=0h-K%6EV7%70e()17*zFUYdZoig>*Vbk-+7q1`vluqV-`UhnlY0t@9P6;YQt z9ixtGH}N4qboqU|h3!dn`mHFxtZCKYYtkLdg=k(`Z+3=*{5V{}x8O{8c|z zMK?FgGC}mAnv|dFudg} zpWV{RT?Q8RbhA8xWV@oxZev4v%0@}e(T=q9QK)#pHK_!I-^^aTa)eD@m@vi&yAAh# z7~W8`6CCq4TCBXx55Qngf&(g`)N!m?omS_89Kq`llQYR1jtM@Qk@TmP@gFCsebVk@ zuJa-b1|6I5U(K=l&CF$GO6n-=%onEgUldFBu}g?uD~L^&89Vx!EH_{wZ3n5izzq7p zYl;^h-Tn|ben~2*Iq8z!CM$N(jjwa;QSB?u`VDQMKgAtl;aWQyM)F{Mb* zEBD(q3E+t-25s%FM|2uF>H72P3fQW@9=vAm!W^DrFa@LyOfZ|F9M}!gfMC+T-@16v{uq;5xS9 zMd~8^>$orz)7QqhSq)+Fm0=&CW|9Qrd%y*1DxFcExyt0-WtBF)DcBkPHQj+u)K=?6 z56Dph0w+Z@1Zu1vXD5^Wj8jOF75k5cv_T%4o?Tw&AE@Of_84Q-Vn`^@>r4`r-kJCs z#vLvz)g&!@*9$n|7=wIH{|#|5fTzOW6B~-16mo9VEGEk3%L;EH2K-p10=L4Z7I_P# zRM2E(+py5?J^?5dX0t0L-D~9h9-oBa%RVN;@b0@WJm+G#x?lx>mnt~wxf+Yv7Of)u z8NA$3BRMJDqg5Dn;hKiRovX}dd4Ej|RKAeh#3lZc&il?2Q_QpTul_JN87E2`K7$oG zO~Tg&h%z6L&{MusOyLFp5`23%UqK_)4q=w#L%AS?hHK_l+dKGMG7|QiJy?Nh}VfrHvtWqyxQHvRDa+0i(6A^ z@W$Qz{M5jP#KgdfTPIE%Kh6F^snw*8e0GlTFpVeL2Toctp zNuRFGS<**rRaZ7HiktY4NVBRR%ZHgk_GQY97Z=shR(J6;sX-y2QF_v7I2w4EpGcNpXT?bLDf??_`JF6PnE8_3|a}Gp6>rYEFFDispM{N0PC| zJ}1udfht)Tbr5^p^AKVa>{Yz>AMx zAZF>`N5A`L+qm^I-Q_y-vN{per8)e9ok`rRbU!=;?FEE;oCYM*kTzD;2X!_xp<B3~W#cV$CG+nHH^|>NdvrbI2 z))~S9cKT-CKw_<=pENgN-&)A%mw4JI6g9;JEdv7l+LtzuV8s7<0p?)nU_iV>$re_T zSoIPMkHi>IQ>#^n-Lz4!18H;OBk{h2D6m)E#o1Jjt^H3tgnfJH?a2uQ2e)*`SnjP&OI4>oBxb&EavOrpX|muvca5x3 zEpn2zS<)|0YP*3Kx~TQhyWBPSM|aE^L~lr$TYnd>W!H>uwDsGyL*rIv8{{R~<;gv6FqaUf`IA0Wfa0TLo# z#W%Y?2^RPfN9m#_rUR(2it`^WRWUVUkx6}c{t6JJrk85LP*p9NAj0X(qEEvsWGOWz zuYrYntL_V7l=&`>GF#_NLcsSmKr9})hhZ(OX7lnuur{Ta+n9b#zEXl!<2x{E;uch1 zKBcXzb_Q)WsJ zHI)KP7cnaAu?^v$wa*IKCt*!m=IbVN#E$9Kg}v)5W1kH_sU`Y0_~X;$f;JP$4xn17 zs5lXAe55U_1jeo~Giz5h?17=OzzR#F3JC4!%`-4vq{Esx<54mA9_lA1X7+%KA4Ea> z5f|dlJ@Z_nTES;_ig7_YRo_M{6FlycU+U%);2s=R1{Pcl&&bKl!%~o zupuhVMsG?H0STSZ5>!->Dk9QBM2b`a=}n|bZ&HLn=%I%aAe4}A-$9RMob%{BujhO` zzxi))Ai3|o_gd>(YhCNwybnS-H9{xx0}n#&8%3{{StZuJcyOA-=URm*hhMMdKC6)v zV>;N@Sb3m6rW&rV58BydSv9GYLlkZ4rRwdoOcwC%FI5$fCW`^>YVk$K*?Da8G-uNp z=Fo-b{01qBUL0Ws8dyWKQ5FYNS4QOM<_%J@T|?JZ34P1am3ca)CC!aAPe`DLu#5l| zg4>W|iiJ1lNhQ@?XuDigz4^>YLQC=D5#XJ&fW^f6pcaOrg?bmgotg32$8Cw@Pdle$ zbac{=rq-Xy-&60AKqc}*Nse0*7hVu|m|6yZ!iQI>&5WIg6_ivuP-Pn7G=mgc_K}w3 z>Op__!PZqoV5&l!Y>h1!6r? z?lA?6e@_s<&VoJgh`r+ntAsKcg>v|!}eA8t>tm9@gYtUo0%$(?ibE15KzBESx5L&n+^jJ-tZn_Rh*f zs>SMv!NA$Xbi*((+C~?s!|)7roh-S_+_9lv9yq8J4488j5>2XyuWYUh;*)$ss3RtQgGC1EpqD%6HG}Def=jB~JH32yr$<-_Usi(w6 z9%$PK4YXYc18w&Xp-4pPfMZs%XzQ|$WS?@m5aIXrQZrAZ)^s0gIomXfr*l^2kjOwE zy9lR8Nrx1(YRDjaCXp{2?=qdCX%0x$d}>k4vPbn+IOPMmF^qgC7(>YFsR(4dII{&f zxq{=iz4z|YIeT(7(cLr2KT)Q|h||8Rj(I^dd&pTRsmeEfOqie$;TARH79EN@mzZyD z8X_roL}q5FQH@Gsw5~28f^xg%q@-6-j&ntPmi3tS5#*4>T>r!c{u2_9fXLdp!~#@| zOz6U6oJ5+ee4*`3T8l0;0#FSUGL2re3t_iS$X~u9F`6tTEi~R5(GNrmee#KNlOy!? z{6`qyV3HF2GIt_8@)7as#|Eb!A5HG{tnO=Yqo{DK5wFGY3i{u%?3`bB=EV?1{h-qd z=62#KXwZre-yg_)!%;m<=d_v1drXNd=UCjhsOat1O?$zmhQb;q=|$EJbA(>qq`cXf z=@7ZDr&&TbWH=0r=Zv{I7%@`mA5k1(zRRJZ4i14z5}@l}FcBS=`+)b13A3iufrdp! zhf5qn*$5bEPTyTolkHsRa1&*yOVl!;!7%kb^;rM|oF@Hqyau=XIO%4(pO(|~4@HN0 zpYqe_$4Jemn>3#D6dpb=k#%5`D&km6CN=Zs+fPKc5XIAKGdiuEw=$eakuwi19Y4%5 z=R?bFO*Nl(34L&{{)@X$4y+jpwtzhbsnA?pphjmk1xQ0#Gu-2C*M#@l0D_X7K_h42 z9o?O8?pfRD%qz4!q}B4rXNlN25fk5?}OU8APbj|ZQI`s3O zMozrRV#;xo1EC)0tO@jQiK9&4tSW@@+dk{~Tz1tlz(n4@#}#@dIs>**{Ch_h;kE?Bocr6}e)zm*n1m1u_f zwJVMAM=L}vHjIUfkby<2>Ha z4%GUl*V>e(JJjYyxsUK!y&zF=TFOGw9` za6GDH+Ux%Ysu4F)F$pB*4hUyqL+#J>J`|tJxRvY{Y|*?orJ{m!@dSs5hx)>4^u3_e zWs5+($j~(jZ@Kw&BXDkovi+d$v=xdz`_lQc?5ka3VKi)kcmNr1J;dP@xa*|jn7n$Moy>p({pivd|VQ03z8J;*MsXz9VF>b z+}=aKc>B0Xg8D7-Q2ujUd{dh`8a%lR^FQWNnC_);60f4GG&7??!Z*Q-cQQ%6m{Fj? zn2$uIC^T}vL@uUJC0R93x}8PL<_*4^j>LM4E#ac&!}cNN21khYWlVwP6G0~U0*ebL zUE5T*FiAR&^o}#&h8!Wf<|b#u{8Pr)j=y*WggUp;^T#-a0O&7&$bo{KxX#EzWrFl( zzs?;QchMkQJZPV0$nZ|k;GMET^KB6vpIXS7k-=v(ivmOkmFD%ScU&&iCK3WWVaX~7! z#c-#IUk$~>o?OO}J?^rR&DB-NYjauC-7LVX>ccX6~dGERYkRky($ThrJ~|D>N5@*p$~DPmO;d}YV&;u3aFHm)r| z(R=QgNvEIYwlst<5M50B_@ev;9g)y0uM3p$D7lL-nA7ZT$|sJisU%Oj+S1t{G~iSn z0Hb*m+DeiKWEEZP%L86&AP*;9kWiJ#JbK_l$E^UsT2E1XeLde{zNsa}A>v$0jj&P6 zg}z6rmp3>ce5QVd9!S0OXiN;Z9;=_iAm{Q1lRqxlt2q*9`hbwIec>X5CWbT-vDC{_ zX#>OcqLMZ+T)f2E!Xsf=1d4s^9`wg$M4P!(@u^i>N3|4{QSV-{+9Ga8~@<$#~TODoDOdpt`QfW9U=`27J!=sY|EtSvKuB~AFLmWa?p2}A*+wKYc6a^NoYKc>%Tj)$FS&4TSctn0CGN(YsoA;BPW?hxzQgJJ%$Q@ zSx13mfsvN5=AD~ws7k?P&r^;+hS+2}G`_JOhlvkXvRpPWoY0g}#Ch4uJy{-PTrBbue|o${`RX&Z#1r+b7do`7 zQY|{91ZD}NjkSGY+en8;;`6L`T4-0^%5~tyQK}@B+cjJG-EsoGTY1FNFz5VuJ1!T~ z2$~#$Fc$v94DC#z%TK+Y*gPBjKF_wOdZK zv?#4ni0fGJ`x3=5i?+Fj3rOFQ4|)kn7dAt4_K#*>9RTCNANBAYNP*bwR{FRkI5Fp9 z8!povc=ijuWeX*i#LG`+cnro(hO<4d_6JhaotaAk(g`q1Wa>e5+(tzSN3+9hdm98W_wmj(AtDuBMn(bwn!#E10xN*|4krYd z#{r7YvU~16lXB>q?+)sWd*JL`+O-yRja(aS9@3X1KA52|81EgXk2=lDx873!ou6iC zZ+i}yakJ&~q#5nDsi?52UYz>dwAnn#%o-LyLj^0IR}P%Q_|K z6F;(oYK=d0I6}85LwWO>O?~X3X8Ecu6Qr{*kYT*U@)rks6d0~9P_AKE8+caW#=8Ts z$;+^gH<_S6+UG6B?87WI>uKz|{s6H!18j-N_CJOaUC=4?HOKfqn&@hVY^0u*ElRYMvt&G6P6i3f9L8YdPj5 zG{hGOy~@)jd(0E!vj*r@#^|ljK%?<*wNHZD;c2Y$Rz^8GAcx?}20kl68lE>s6>xND zS(zmS5L{A55_7Hvla6j$+jR1J_qzw?gdI{P)>aR8D?SDpTjIv8_#I^McZ^)+*Eo%P z?_$AAvv&LY3*fSIRsIFdStl=XcRj1h*WnQAp}7F$M8vlH3ynx-S=Q}NMsy-GXw9z_ z(2NuwfrAAAd$|3t-qf^I1zYjq74gJlqOq6oVJWfumKYb7DB^fAMqKSY3AEk8h1MO*rM{gUrzWJ4v z&zIZ>JZrect_?ySpa1sL7n4czWOV}GHF*(dYo4o+-yZtsFTde>`mH3+B?r`FCC#J^ z7*53;;nq?m&oi#9)#u-4Wg?pr8XCsj7J4lthHV7I`?<};4^%|n_`a= zPvT;9y|fvA@C)E5GaiSEA=3YHEZ@CxtUt)@9@JbexqG_h&uh7t>~_bWBXr*;`)~U8 zWP(+Q(T0qLkq7#Qv;Ta-uR55t(g*Wr<=efJ8bge^SVs$zy&yu-rTA` z4b_Y55CzK%anSIitysewgR2Iexwac~A3pjns{`5e@TW&C-5@MAvvh9o@b~GVt~2zA zcD@RE5j*pyKtrtp4CU_wy#QBm<8bm$*<$uT)d@}xY=T(rAqPOwEV1^*rAY0^uBYu1 za>lb8GR<`6!Dr-Z7~%~ZUOsvQ?+`vq%E9IPfXi$bFlAZi+S|ZI#C%=HW$yne%e_WT zu5m=1;HeXe#R{C3|K7w{MaYv1aa_Ypz60JYj!Tz;uIoWCx16sJCU$)X_KlJ`U0>y= zce%)u_6uOhf8z^Qqti`bDy2U}7Y|w+zy{ooVxaks z`TI3|e~eu1D}ZDbx1_LN3pfyQ&V&8}(8C+q4sPVg&Rt#@Ntvz@sRV=V-Hs&Cj;Y|Q z6=ee?@%&N1Y1%un6{-$?{|wIo9s7tSmG%mC@axC^U4ONv;l`Yx&8ZJXSE;?zsW(vZ!Ivn(@j7r<*-hfr!NbNP$<%W z$p1N>(CbwRwEj4%1CRTFQQ~v>0|)agof(KGKvJptPR7wcZ}27L$|72N4lh2a)A`fJ z?IiE9ky(StaJv$y5@%3kN__u{T%OQ_2~t73D@@A~eooRL1p#(v9%H;b#SrX=nk(?)XT6Autc5Z=Yd#5@a^=EH&fni;j|$& zU-br($ZAQN?disPK(|_MG)-QdxZg}=%b!nP!%jkruu+upexDg*=mc7N%4`%m_g$qj z=JeV@Mh}R8_xRv5<)Li{~UJKWbv0fbDg(+ce0O!{b46% zp2t=b1eyUT_sSmDYX)oUUtaL(gGQF4WP>h(&ZJH`xF{VLY7&83nFp zQxLWseB5fZN#@bz%iF&<8P}74gvY)Hm9M)sm+yzs%YI+g1lQF+x7gJz?&EjxVD+iH~3;!%Z#Nt}D3-ruOPx zEZPQ#uSXm1FaiJ8rRZkk6vVJ5Lp9Pf<4Ojud1R_7Hj3tPoe;V=w#|_vv9D|39MzY< zeo)h0N(ncWmU^3TqL%@U-jvz2zw?NXTH0a>C>kU>Ok-~8(}sdcf97*7$zLCTC~pNb~FI3qne95 zA6MW+MnrC^#5BBQ6Pq6d^Q(9{m?60Tpr2;+*LQ3z0@r^Knwbp3_4Mo}{!#QW*2(hPj zJ|6AK*1V{%5YwO=PQh$*a-cR0=D{E^yVDtH<^?D}gcLcI0U2=){6c zHeYiA&-lo}`>)>H?NK5FEVGcCX-!6(`{#|0lYuvl(?LzNGwVZiWHVUIeVb!vCrg^f zz)7GG5P?sm^p-euc+jD{o_XF;GcFa#%-UfZCz-3jo?$rW1_HaNzd~LS_gZN+Ft^h% zrJ=5xG;3DT>;-o7(>}^NeA?(rPr7V|T=b^arXGZfN^Wci3n*d*Q(QQi;x=M;I7Bl1 zB3*+_&H(Xv}`P`#}tsG7GCc?r3oLRC&_TXb5PUI;jbR4c?3SwBL#W=-3X} ziPO7ZeR+YdC4;L}_L1Rk2M7zj?t(DX}s2G!*6)=VZ@oj;i}Z>6|M&@MWnObdtib=@r6rfHoEjNYbj8+-^D^-YIQ zAEKsb9%o$ub!wbc8b#3ilSI?bpFBd1jmJbnt3U$V{p+g$+^kxt-SDe>@$>?4E{$x< z$x0-kd1$_<2VL&m+Gm<}1~^B@#W4Xux0p!+Vz+GES$$77v}>v}Z;eGhmmVEFe+n{D z=nY$&_ScNsaPv6UqU}QRX(tCtw?ppgM~*E8>J!xofwx~YhTdK(E}b8ZeqUJa$&fp0 z6K;_?d5-}Nnp<(zgcUF0l2Os8IEG3F9VCj>C`6{DrmZ1}iOe-B1=49=SJRiB{Fr#Z zcWq!DJG%NI|5H#|(W5Z73^mI{&#!%=q23}r6u(&kjLc-qgo)>|a*7Sb7_}sZn*&>R z6P-g_OqFwl5gthe#=IHN9;vWyH`e!cc)3j<`TTu0af8$Ivm1abr~TrLOU}0ZrLB^; z`qbJd9fFEuy>3hiZ4EzfC_eDF3kX3Y`a+s@VZ{#ym>^I{DL)}(keUP@IShtwYN@l;SONczpSgr%>bWNjR3JkfR00lzR&eo4}dQ!yybPJ><^O)!?R;{YRe6fU-Jd`hGP)Th_f*%=LVGC zFF>)kL(DIc9gQXci-NBoHQb?ZohxHNc2?jKK1UMrNsaq3sW?2_VW*L=O7>GZS}Dx> zDjAp#iy=c`=PY0BoHC^7FLxYxXP3@y+RBo6-=@s!*p3o>h_sq%YQ*=R84673i!}Pc z^R2ioX(lZY3llT?VPha!Q~{E=^GJQ9)cqqyx~K>7)VqH8BtIEgGZznzm_7U9V*C%@ zW{?SEvLE2*7PqR__d3#7eQ-h`G4{S{`nRLlyK`0pN!s>7>?gDl#2#yx&<1JHIg@ zW%S{(*Yi2>jf%K-JlYVW#-L{MVNO~Cg^(fpYTag9AZt)&sC#cnqw0(UK~nUo)XE~ zt8xmsb^-mj-*~`3Cn4lmjV3;s5vWeOU!wV^p3+*4H3LZYy&NNH0FCu4*B?uhT;GK^vS4o=t`N=tM-f$<9X>EfZG%S zjRJ*H!R!dHpbyYmL7j*>_3S`Xi(ZP1imnsm9m`X#94+VLtmJ*y3FMwWSAfhFo%!g| za5FDek2C`_=S#T<{64(q&Ns2^FLIDSxk|8}0F%t$FiR@IfomGRKOSGQuCpKq>DO+q zFht*M8rNQ^iR8}wc-iUe(DezT!XqE?0hGTI+af)au4I_Bv`_h21Ar2LV9l$g{M3B5 z)4s=#6`XFSaE))rjb~XN?;a?nhWi$db>PCD#p&aCIJr`z_%&=L0;a3ast`t$%x|Wu zq`)J_I^5%*Lq^K?H;r^FWTYr%G}%ax{&$U(fv_}i%%q+n|CA9i^;K|cue!iG&Ujk0 zfr0JcAGx0k;76Ppgq?$6v{=<8@s3=|Z~WKSc;pnGDnps)W&#;!@kHU&+d%Ss{BPo{ z{nu33ra4!@)fWp=K|d^LmegD@3?6-Rj(RBhV*uLN-AivjoTlQ@>xJ z|ELL;jHL^BKE`4@*mIJQxt1LSJAvLKuc1S^>u(-PH|S7G(6&H_QuM!kD9`0vyHqU< zGaDo;nh06?-1xtAD7QJLx#i+#1P$^_cbF4yM*QEwGkRt@25<`7{-6t_+RmUm9V*Q& zoun$=`+tD@j?d~oJX*`=vgu+|?6r8E1mgr$^DEUjDYb;=aH@o~ummMB8__o5eGl$! z-EfN4W$V53f9yTYy7lh;^=tP%zTcPA*O+NQ=y70WTJGMbE4+1GtKuMI1I8W^1@q zj>i4}^G%xmkUI033-B{NwP*1LhoL8qW7DaPH(a~ zGDZI3Vo1gZtbImJ^cB}5c2pR@HVehY<$R0kr>4_{!UQfjo-ve#7~3;FBm~^kmu>aV zIF_|78+Ng_-t2LHQKflMtg40DNT;zKHh6=82mQ)Ml+)$%uWjR>zvp-EZ4kRYJpg&q zY|mw*Ym|nk)7l5ZtQR~r)uz^7LE-v1u3RgBpM9^b;E*8(gGdb631^nb^eq{4Yhj|v zkT6#nO)HV^4Ot8w;Z}O?8f+T{z$^0_c}alKcT8OCBmdwlZ1Sph4jv*Oxk~}hm=8bw$$ z>ktmRcsO=Y$U)1nR%L8)vF7;IchvyEr)1V!*r4!nuC>uvC@K8cR!VkO^qm;YKO`nq zc4~nNR%sk-SZ$nOpD`3-L5t>xY7k)Y*|okn0h7RB1E`qdapy#cu-2>E7I=_j+mMKz zaXIDr`8=Pn^Op~@jchR_y@>hR`DDm1-ww;fO)}_|$x?e!GYZzO+BfmiN|WN!w3Qw` zI`*7UcS^~A)q3P)PK4*dxN(=UsBs1sA%flNHIri|&dRfWV#(EgVm&&}HFK-h37=7_ za+M0RW4$TYCM1q(HSRRu5c@trf6KQfOSa!v)6W(haLx1AE?$sX56ZAz`WpgpCUPs)7;Rs3S)f7o6G^1trp-Cz&dC*<3{FvG+JnzWI{j-wq|+0CCyY*FuOZ=Rc3Q zgwUaO3zIgrkymplku#Dbe|txqAzPP}hy%7h{-3w?ep7qxu_+sp{0STnKc4dZnS%Qt zs2$%2VE6xW94Uh0$cr#2jv)T?al|}REPWxI(ABSIMYj;Gqf|=Z^~v2pc@_9ys5tp+ z{`bGVCu++d@+P}E({Vib5}jvd#mPaol(bPGnTMJoU!@j5k<3#;$-Em%5hU~I|3Wg~ zoo?BrF2`8Cqea|Zwfu+9~6dj zBgHW}R^q-_uGL!*@;`*8eud)tO(U=q;EsmfVe+*a-+Dmba^pJWWjjw#Cp?qpv-WFE zf$geu@J10VSEd2f*aZnY89mlTk&8v0{6dYHD}@SStNbfrNgXFhZyFK!wkLFtr|dZ- zykA^A*S!0~vgGBjid2kngs8csLw9xru$I2A5uKb@i>udK+NY#@q$MQsbLyO_vW2bv ztsk%2Z4r=gIJGprjRSQq$jO<3(1}L9=rl+ z@TOG9^T$?gbV<}) zN)SXYGvrX_A#r>z>Xd=XTeXhNuXE9tFrL&2j9=D1nAzEQns(J13{N)J&8&0`2a=bCj%997^sIc| zYE8s)CdO+^0}u`|Iduj(sDqv#$3s@FQw~A2aP*FDU>W1F9Olt-?agrXTDA5<%IngZ zjL2C|%&EiS@E--uoT*nYxNHt#@tmeZW#`m!Y7$-v8q_$iT6Ch*G3>5$ zl%Kf(Ungq+o@nvkuFcGb71&9sTjP{;8d|G+AEj0Hl!!R6YNj<}SMP2$bDOx?&N+%j zd0>PU<24z}Oi1H`R(_7F0JJr$UrSKS;9&;07%FF58pwnQAHP`>ytlW^3&ZN<%c)d) zhFWZwQFHvGy?i%|Zw49Df@$Wq=i?a^D=qYoub-_qoj&<4fe}u^4hWPfP&@EN$+wC> zlSn%R0vD56TOz54TiG8lH6H$tObt9^YDSnZEEqZQ@)QYW#(h6Xif6;8QexzL6^ZF# z^fq{C<=5rNFXaf(o=T6+!o8O|G3G<&2t-?16h#*q7rBQDt@-sHRT`~AMu)YUI=Gd! zHVX%4plPL;ZFSw5#TJAd1@Q0cCFwMFxzTdlHDhE$MTO*q`k%If`|}Q>R@ff8if%=w z)7Qz%vKS@dZp6G)+iKq9nQYl~Ptd$w;!z83_V~|&Etlumt_=tJ8-)fjuq|==HSem~ z{O)}!;9u#B53{uz-zZS4_jS4D3)=!TQq`K;5PcDW%NNLWmPV0NCxH zA6n6{%ea7%+0r`L{%yom42g(gSw8;Kd-)ZaP$D&awcWyW+67uIt;K$$o(1O`mjw1P zT554KBgX9Npx$bGha$DtM*+2D>;FhC85AOHI53t9Ef#$OMyBYO7poP~#}I zg`BXp0@Z7No%|D@5TjavLOS#^U|hoKTs_4X2KOwKMAU?Z(>+EJidd*fWi7b_$CKv= zf)J$fXKL_Am9PQ_f@FkJZqM$H0<}Clt6=2p$K=}|Q(A#+e(!x6xjno^WLlJC@wqh7 zO#;-1&=uXYO{_-Bt7`E>nn7OWYZt^nMp1rust zykOeMc;}ZJ^~G(ju{F}?8lz<08s$XBgyup7Of-RVhXfV4n!FX<4wdal>cF7{n34E; z!Qq$)ZE#tu<1_gDRR1K9^l&7Eil3bCaE?%KW>J6!P?V99_%lOxwOIpK6^7uE8^W zNi`i^16f;t9EQcD^yAtVJRSI_#a@wH=i>VI5}VwcZSq^x#%<~^HNF}O2aXK=&I za4oKdF$pCND+M$V-!OZ-hGHwJr7p~w1tnM`*z4X+nwK@Py9yNP*=y^!5zQOwDrKb@ z&CZSjU3<13Wilzk>;231XH2J`lYNyXakJS-id*l7Mk>EG$jJpsqkmozykpEnWDjMR(Y|xi(iA;S_{D_H~`?3t11(7?NN(A~IE9HTROt zA)F5$BOb^!pnChud^K%}-3lYk2@J~zBf_PHW4>_zt7qIM~7!JTc>AMipMSFgvgO`o4%=5BR9WNkvXxJpY=(o zF-kG1e23;`a$F;V4%)B9wc+S|HkKjluxn&4j0U*Up(~2_*SRpos3WltQS-M3=^nGo z1@B3+?-Say`Hc%HND z2lw0yqSy`ZH(f-hIhSa7Y3|OEbG*D{IA4<7KEP3&Gq=d{vz~{L2E#MXPpK^WY$Pt0 z%uvIbvvxt`OxS{o?|yw^Rh$K|CmtY?@P**{g;i8r|1mZU7}d*m#s9{7b9b`aruiqXbVRoC3Ef4Ohh=zp~I?W8>uDKeta)vG4kgqX}Mh7c(Mm=9S;s= zJP3hp*=x7&UI{hN-cH?-gqyokE;AXut)AWt7Dj{^>Z3F1BLMDK_j237341ig!Ax(` zy1ez@tc$vBP#%%Xq_9E(qDxI0r49)lp+=U@SRftsa<4p-Dy%LF{-0vLQsW5e2WmnX01RkN6;ua;{ANIOrWg#=?|_h!{5eFYt-iX$WC<@okAnSA zubwORrh9zu{wv%=^WEdbja2Z^h{Ksk;y7K|8Tk%I5m{R^^dx~)oF2ru$0QK>43r6C zcja!$(SBmpHE`p*F7ih-fzIN@5^SK(VoA6N&)BJNyIsKnXP;OEFvMRrY*Vu8EpBH5 zB6%w{;P;lAUrSqd(@h)COAc}VX*@IlsJ&GJZ8S!(Sn#UJge1~Jl5(1%LRA1Chvrfb z9fAZ~XZ5@j%!`{1Mfy>Zh>tizTYY9^1v+*qY1--mBjYg}O)m3%@AYScA}HjP_4sC# zqWCnKT3|wKpyhMjVeq-p&n8B_E%|j8eUMcxK<6HyHQ~r; z({-0^>IIn@#^QZp^TV!zQxDXH(Bjtpa>=?)A!c2Q(IsirD30`?6nTff#|;0ml?enZ zquVIH624Uh1RR9XC#nVmX#Pe7H@ch##H|Q8(lQQYTtgFXl29ztd3S%a7)}CzuK|%i z9nxJOGWMoXyX}oZZJ-)JkxONcOH%RbS>}WmuZO4&1_vC;=@-e{=Bf5ZII}{gZ_yar zw6%+#d?$_bZDJ|mV-Ja;U8a*w+42+1Jb-=_K_wMrVXi<= z%LE|6er}UTlOT2dK@cZ4^|u$hHo5gqs5mkzb&_WMdCj5;#oZY{+qRclFGc}lJseg8 zQq#-IVqkROSEE%a2;%jk@?8)M0)I?`^88!TUtmP>g%4Tqe&QvQ@L zuhsB}ZJqW&>EEpT0UcE>69CFZ1?K#A_(2;WnFOL+tw*@lwLlRBoYA`V27_oE-wG|( zt2O2sMfboO$kLXlQn+>c1D$(gj4{l9n7O3nd3KTFXiw$AUrFMz|2AEnsU+p==-8g^ z6rK8%%6}Old7YkLB(3>zWrl=7WZU0PCA5gcN|QceOS(>T!Qx1}V4!f)krhtoH&7i! zCjewzCL|aH;Og#7A}16RRF5x(>4TyNN0@`TjQ`OaPWp(AEB3X6p=pX0E&AM))4BaK z(Uvi%Bd4dqo+NZ401C~%&%Gy@bFJ4(2s;HE1h!5we9;% zW&77a%5`H9v2s&ZCQ<~f>ARwY{`eb3jok{<*jg5p_pLLIKw677I>froq7jBLr(#&>I;J1^ zAA?sCoFn{xwyQ@08InO*H87<5Tg036zide9z>umPJ{eN&$4>csKOMfm9yFpdynGyA zDJ3sKw3G=rCV8`Y#|oV!-E7+f)9F8;gvb#!8PlyN7dYKww){>W;>4BGdD#~KEbbo^ zvRQLs@ix`MoZGn(fkxBm_mN#I1k%`DLL>T`#Hj*Yt1`2Gm@2Y$V5^TUCvqJ(MKK(Hv5&8+jCd`V_~P_dtvTK~@)`S&wbLZ4te zG*bm+4}LgPb-fx{wlFi&3odJUbWr+PF{lh_gOU-i?G(5wZyG3QdVz8y+!O_YSDjM# zarEPx=NBCu9}YNMvdv$GG9UW`p)Z5)2A!k(b%<}o6Wdpr&b2bZq?T?`TvljY920tc z6DSUBBf1GiNO^epU>yW&@)nyI;?b z6C`~d>esJK*-6}uWE0*AXM2Ya-j@l~1_x! zKUoI&)AZn02$WM36QSwBZ;B*eO%J{<&DR-J@~RP?u2N3DSv>(`t_GMIlBUW8LR`+I zk9DwpA?6i_d96oVvD=2nGBC^tkfh;)Rq`Edx8@Dv+hMF4mi3a!*9-5pf-mHvb7QZC4KN^!E*G|GQ z5WU&?b4*yVt}kOU&8-O0=?%~Q3YPkLQA>pG5iYfKt{UNy_-?<);2zDGR^(hq-t%Qr zY`B(kHUyo<(OG7#H=M0%>FwqX%AXuG15#IIbugaeM6#9TywZ}LF>T!RH%^rYI926m zKbAH+uRjq)t0@}c8Nw$&3!tpEE(G6suOc>mKPg{Rfp^P>R};&f`C;-D*W z##VdEmdd!%RijMQZRYfKs{dwvjqGwdO07Gfi*AD<^9cB%_T%cZpCEQy(EE zT^kP#=W+-5T;BtyzxKB}4NqYHmsY?$$D3JOF90o>A)CvcY9>HMg{Nj}rM&HVd_0=? zNE`DpSHdD2T?u}3yR9_sOF;17`*la{r>6BcLR~p$loBBLGXhc1uZDfUOzSJFVJ3T7 zNP^>;y`F+o@7Z*`#AXNg7K0kvAt-H;VnJGtrnke*l|^7j$3S7g3?wPy(vG;ixl%6_ zJ_2JqK(5mwhop5tk&+DsCs+A)F!%KLdpP0{vz}|cv4w@E%B!j*hqWChOZ8Rbx z45J7!eYY9h-JC~4JO+BVZu8UFvNaTpN0+oJ!u0d6fi|_Vj8klzfGS@me z{l&%n>!(*V6T<4+uwnqS+d@zwv@Fq0UJH5swlFFP>T7yPA!i?*p%Qu-ZB1O5Nwywq+amx+r!Fs#=iodkc`~mP!T`yl zq0a66{{z7JR~~HK4j)T^O6S1-O1e{*1$lCCag(jX&OH&%OUG`?eymhWVFgaU3J6tw zWmn`MzO;3JG(>+48lo4+=RiaBkZ9A7hUg1HA4(dQ#}69X>4HlWMLJ1&b|f4tEO+7^ zi>ZA6U^N%Yw0uHX&E$B* z%QRQa26&+4zpsXIYJv8CBzH3hG@m;%oO|cmDON+y*o&uC?Rixfml-%IL4s72uoVu; zJUD=+i}tjvwM$XDt+cussimhrn%Sj5oRIA=X65+1Eiy50wv8}f>&R?@t??+L5{cK} z?l|GZQko^`%5d z-ej#ih0+!~zm0zexx$U6|C()3%C}i#VCTMpI+A$l`&Ht}5nLWxpwV`d)!gn3pN{fJkP6D!-^_g;Gc|!dlo>eMC(+bpjppE(k`oIy@(nlRP)8m*B~B}dO`Du7W8u&E-T|e!%+|j z$~)_a;XnnmMhjHTWdLs?N+w_`I2DMnE@Tb_8fjxg5T3oBB5>VWO-s^*x-n`0$LEfn z=XBv-z;X5c`jE(9IxgeoB5auwTu|ty4Eiut=fccnBZZt7R6WH>bWODyq_XAxW+0&q z`uh+!V2>v0rH`EJ$5ed@PIo0Oq!rqFjc8`a~r7^vD~H?Kd~;?0vY zn$jH?V$<`87u59NmrOt?*t1~uBFh3>3a%U{#{U6I#~o&c8|b!@QU&rSJ&Fnv@j1&} zTKS^+BqENQG=o|kqXP&|UnY?MFqD4!10n(%P%w%d=dxS!c%tM&gkMl!TtOoNPfRz# z>DB)R8c7CdB;fof(3WE5RQAr;$;FQ9E%1LW5|-y2#{7~VC2))}Q{0}RFq`QyDS4uR zD9xD_lbCJoIrzI1%B^{$7M-@(5adX>+NCtAFOovl!MucpJIL8*~bF@8|oXfQGc0=~s8 zPsj~^wiE32tZ4q%|2}T~NXA83=kh_VW8Nzw0`j^e8@(R1Z`?7%cn9PNiO30&$(bNc zy40xA-HX*WR_cpgj-^iWXj)t=wm@h6S+vb>#l1!tUVKVDxP4_B3 zwJyY)`4ztvlAs1fn1QtZ9=@AZ6R>?^n6PlI3-lt^@pPS-aC*BP!=Que0`6_Gc2u~4 zJV{=Lrm%EuchrstzfLj&4eUPYj02zQfGL;7H^Psl+*pGK3Zl5>q_PaSt=eq~y@FQz z(#l>eHIbEBSx92pCJ9%3S1qskcdo*3R5#j~Q8`XDT*4-G?hug?J38AorDs<3gs(Th z%)~uobiP_pcSOMMcUr`6)NSjshLW{8xIH5GdfUF_GFpxj59wM@NiPi+6Etzej1Zr( zdS9(xOv{B2PO5A*Yb?^9tCn}y;t}H*w;jzU6m={g2dQf9Pa(V?iM{*`!26A2FQy`n z-O;`AA`*-+H2!_7@ibit#Lj!bndm9e+Fxmgp2bc5&dl*QD%BN^p>xD{V7UlEt+ori z$(1+DO1Ud}+&6eF^K0f!(?PY*=~eq`V3NmUdVE25^cXR-)iyPvw^@&_B*d%64TBlt zGwY#p?Ejt6?>DOQIkg8MmJ~q66|0>w#8FHsAhI8>hPr@Wey=xaFM`^yxp2>G)jE<{ zr*;e-9cDVRRmaV*m@4p6pXEZg$#Ut44`9}wE~HFb4GxAP0P{zs$!dJz59 zVGse0`a|O1Ux}UkCr16Z!ZE}qs1IMT(;jYSUKL<%ik^JGdor${u1tEs;gIJ1J9+!n z8q{XT)JR;3nK&a}MCDcO*$?Zq3nL^v)ShYV;iy7s<=SCkzZJp$&Uigr9fYBmKz89< z^-DRma}F<-zT2%-208!UbVsG7LLRNzRqGw`^Cm8FbdDmkLG!Wx$8F*0=~k=B%1CVS z<@RNjrEWNBc-4Bx0t~(_bG#5&vdpJN1BhjOkp2le6F(~G(5%+$k>l90YQeE%&ZGhv z55G;&WKffB;~uwPD(xmYyl*DMW7*$YYy5rctb5VR{dCdAveLC4PU*`<{z7J0o9q2c zg!wZPdrGjvY@m6w1utIqXnkesw)s+3B? zYQ&0G?P-J&mk620^9RiaPndXep9r9#7Bf>*p9TetPPJvtrFk$qvTCE+ypfl?2ulc^ zbFH0`OxSBAmx`6XdLBUyq;0TAh%x*8ReK=A@&+C&XZ8#WYB#rQ1BtHE1_eY(Ev+M; zbqLBKSD)neTg%D6Gf`Xo(6m^R=hd-Y%6L(q*LbNpd9>WVCz?8#S;W{{HCwIz6q`J;_bfC33 zwt5fb2xq#RRA@F#&Yzg?fAppy)Ja#j!zpRUUC1fLFk8p{)PcOJp!xhW7vKjPZU6Pe zjV0G1u3Jk?_{OYO>3v=wNCTkviKLb%H^=xMM+70{w>CF^pQtpraSO-MsMFLY)l%O!ntMqWwOELA)srg4 zy?T>24L=!|v=PO!a*Jgpcjn{l&GBlx={kv7{-W?{!csl;>V;caIxl+7K0O#AsGB5? zKi04T0VJv219p;ZMs-%Hjd|1>cPyk$*06ZFforGBq_GZ`HsMy2mcc+~2qM}})|QD4 z{mmr1y%Y;^^N((V=vv>1OzgJ(Lf86j2^;wO^o1dgo(?}bPu_^qk_#5%XpKQoOBP>} zaD=p;|0W@!od9t^sW+a2xSxB!rLg^LyyW*)R>9XRCLsAc=X|QQM`JcmJ`rLW=CK^t z2y=0nnS_-kdDKUg+PKla05rrM-%{lMXPx2nNifi9!@Tt##CZB2Z3y^!vHY6` z4&W*QUR2dfo5@jXOFChb?r3f3jP~~`LSq%H_}vyh5GTVq(>(wm*#q#AwGiQevn>;^ zF?Y>j$X`mwC%G|KlJYWO+iv={{7bF{|68{0fB#HA6SGA)=ynGC3tBe{q88^Y>9T?9 z8g%_Y&$JZGqr5kLf|mO%U@o%#Ds$1e*8&vAMfa?S3gh31vbg5{2MXih>(x?*JqfM8 zB4vGML1oG9d2u;)l5-CGAnABOlcp|yGpT03dM)nt)Bph_ZlzBr`Fi|~G4&dQWp2y7 zkdG0!D((Q|im7?4_Ee4|m*^&6g^e*>Ei>6IWwJOse%g;~!CW-i+SZ|GLPWc?n9gq1 z?p#M+PavV{I7L}huYQSl`|<@uco=#S2HnCkDd60>Q%%0JTJ6ntKz()pW$LR(EhI8> zefu>qDC756gEIe5pg*Lc5sF$Eg2b}i83cGvfLT)PYh^Hk6t9`LfH($-E4QH;3AUS` zs!`mxBp7p;~ zy)x@B0%rZ&`XKx=K}trjUq|@%H=&NLx%>F>j!gl7Y<8-;ckJ-x?WcBakWNlZ(@sc8 zOKWOVG%_|aQd5g-YED-qxo%NCq8PV7rfU24Gh11wcWu(WcmMwSCnrz8b40R;Q4ArT zI2eTx^A~e5`B{ln?@~L7xpS)eS}g@A>&Ep8zCuQ8lbV^j2eP((T}=L>L?X)!_IR*I!FTtm-u@IRLV#E7z$b0hDidy{PX5zTm zo~&KsnsAI>0_6ZHCpq0zUT}MXCsG(+D{(TNzVj{t1)odEXBW@AE+^A!aFa0yE7C?; ztuggLIn_+XfzUs#Qc;%eFUgqo~_Zgyyw zf>BGN2SgiV2J#8ZizZ|1UV?de*a_pdU67hmK8f=!X)Z|v(Q({UY_|0j9~V*b^1`yy ziP)Y~nYJgp6(urq6g6l`meYrM4e;WVu41UPyt)}_5?iRvO|zx$%L2vXy&FkXc=%IA z5D@eKCzMu3xpFeg$1sY5b=Y^lAd%##u>a+QPq?vH3CtS6km^cnHrl zzbV@G%Bw7HD;z%$)$+B>ZJ`R7pPzh{Q=3{tzDn?!<~0o<;5G>qlX3?;L&Q%GFHXeZ z*1gOx=$!OK6jOn*E(B#np@7H?$R2T2 z0fD57ipq!!P!JFi!j1|gDo9jh$ciLD*bpFt%;&lj2Xul@>F>|G_Jw}Tec#u4o#Qya z2j@|Fdbq$R@Dlzg_72$Tn>ki!|EJbh0hK!-D?>f80bnW)+BDiMyPyAuP*oG#cn$Jd zdZ@IfsDI!>on^{iFUziG?*f^La1`QmT4#vu2iFwc$#1=2e6!#5$7`Fsk3n))0BmVs znErSOh>xwnswAZ0)L}Pz+3$*z7n z`To8zDSDRH37P(tKYq=drygFExJnbB*k_IBO^65JWDFO3fR*0ZzhBKdf8*L>4iy9Y zM$M*BhYLT@#oN|-FRSu`uJ^)=!ka$?i+1eXIPYZa^faoBQ=#eWcd5>@1JwJCE?a%_hdf^_vC#HD-gWmj0Tn-}v+4))zCr)Xw!b zd?Y&*@}~t%r|xRVc(706su=?9#Y&m%X7Glsez!;E?&&Oc)%5iEfvIe>s@q%=C>l@` zf<`=C4ig(VQg^RP$ze`^-Q-JA2AWdWiffvySq<(4iyW7O`hwxAOrS>{7Ikh1Yay`} z>BI7doxJk1X5XKPm0IY=^eS)~sihhF7OJt9dTmpJkDQUwpd$i~=;sR){K!Wr;agPW zTh!{8L6#B!I81!$RdEHbiPQ;w6n#x7fjp+~c>fs8u4b(mIM%elEump_l=&n?0cRs; z>5gC{`0Hx;-8YSw^L?}XI+MXd@AzHFsxAjfT*$WEy;EN!wG99fu(ReYcDY2p5vsD3 zq~sM@nj!xE#tvpWbG2nwG5ncu|l2LY>rH=^YE^ji)4=NId8QFdz% zJ^TSef(i-fH+ziAz{A<_Twh--~}c46zcyEatnq*4kTgqeYdGZvf%DEvD^kHaG!|?} zIqz1oR6n;_n*HwOppp5odp4;rI?$t_*?P8Hg0@F0uA#6R8M*oZ->^rM`?M~QuG@R2 z58d^^LRjI-;5H$aghuh~|K`Yewx!)gKZt;YXZpA!0rUFtjX#^Evuk(T&Cw>m`loy% zZ*VJF1HLss+7qltH|Y4|*bdb^7V zS#g8z2Zvy1?s?&>nt=l{c+7vDOEiF>l0yNxgwhUxj(N^CO9Zep=nkcg{|*I_66fz~ zs$zVttr;w%qJ}$7^%zRFcs1Wzq%P`P3dVF*TV$wtQ#=?bm)WI$4%jQ;!OL!2j5oGO1_OKb?U=% ziTL3Ih?JXWT{xgl<;jGsalqnadA&Zifj6M!drocRe8*n)Gr!(QnScmZ7}%cL`j7e4 zf?=h7Lub6c(!bmJ9!dJYjF`u3t$oYD=2)2+wc{Y<4s{hQz`wxr-f-muZix&5YyF5bT14xyWhy3Y9>e$nVxRg9KR zuH@byZ{P%R({2;&o0WvhBm#2L0R&>s|M-H1%CHz~pMz^`3Ugl^1^*T9-Ce^J(ZRAA z#AXGXpAIkQ8l(4IEEZjlO7WZTrm{P?n%ry27VWXh>4-+X`?Zz`r`d3#-}MDkyK>!` znvAo-@Wsjf0>|c?2IK0R1K<+u8z;gG@I*EqQiqVp|M9sQm4*X02?RtaYkd|?s{k8M zk8Hs`tAQ5sq4i@CF6a%rw&T?;JBSYmGLP*r7}H7oa0p7Qa}v^ch?{&9kB4eohKq{X zrLXA_6>J!IgNMsq+jlV7K2EE98H!j8V~@9t2e{~I+j*{90>RB!0Y@Mf)jwS>zbjUm z$|Kv%dAG%tT6KOh?n~{cCF5o^eXLZqvhUR2Ke7dc*Mq{24*K*M=!l?od*o)nYd`s` zrJ!+bA-xFof{Km;i3QvNV~}6;a)zlD%r~Q0f7jI!BUHPwu<}phDC_L@dmpp_$$u78 z75KOwK3aK=fn#Dnu3w%>RRv*H20yOaEQzITbE@i&xSx}ZLJcH8aUHnFT`_LJz{e(r z*vxIQxC$Fx8zBpLO&U;+`Et8^WM_fOTbqu@+1kW-tZ3b?YYZXhi~!y{-m-&Jd@&*G zHSinm-Zfhr3j;|#)GT{BQ;zV5EI^8upprmDHYzzLf_(s_sZE>8=HR z!cP=Bc_yJGFy7-`L5Xl=fveCdxxeE>>GhrArO10~KZu(y#a>M-TiO|?!3!<+r0Y?M z_Q>#(6$IU+DBXKSFK=dRm-S+i3srXox)*wj$o}KK35wMxURjG5&dgFI&A85Zuf>fU zk4?N8w{6ezWzKVUK;etfZ{@oq*Ps6mG?dhv7&*C6(KztTvCPJ9o_~uqtJRd2b4i{w zJFrNv+2;`VGtHymZx6y=uhIz zpT?Gf;FVBV>DQ}`U+AWS0N0wNLAomB4+HjY6E_pc_5G08^*w#BnK(t;F;Um|4;>$| z>$~M{asPKzzexb~^q>=F)GsX8u%`>^=crlw8i{a`!w;I!8qMAV=&5_=$j$uv+`#HK zsDZ1wBC0vL=;ffdFUb_f%g}KdjHTh{33A4pMYZtuPP}Oe$xy8lQ^akVOA|GR|Jas+ z%;9sci#ss9O7CQ`IXu&gH+)JLMd@;;))`P1$ogCZS3#yUyUe7Vpdw|u$)Gu~u57&7 zP-wsL#G7#9g~3abeymvlJ#LnE)Y6IH@(_u!UeazJbtrnHhp^Z)&Te5eR*+*P#VH{0 zhMb~Gn18u?*bLRUh5dTe(5d^|WVMx*BWfzKvPr_NkqxM0fj3CFkRL!3`O+1GkX?nM zr>RpnRw6~M0~Y)@X^fPjkkvj-N7$^NQgQy@yIF7(>wFs-jK{ay$6d_*pS!}bO@6!A zAbri_bb5<49Nye!{p75*HY(4!SYZQ6MH#j!AYtkTlPpD6gq&g@R<|ld+h>X9jiQ(J zQRTG!ga|L@%bFB|V>wqLbJ4Mrlul#L>t)E^4pnxU$fiIn#FG^@jXdWxoQq?E~s zR|2nUNk%*)G_xcuzG055A1gd}@I0AV8t+g>!lGYJ*~BaO-L)p$k}PMccNTonve4c- zn~tk5Oo?qW=uJKis0>bn?Bc0g53sGXyeFS`oozE2| zTu__c)cq)n%rWQG$OeiTIOZz_Ef>GQ8zzKjK*7Kh&lwI+ow|`SFkPXBP}&(N z8i~04mfx7fdAtQJtB0vu4&Oju`8TtP-%A^Z<1URZe&2VbIbb9{M&!_%rk$tRB%eq> zsw>`)*=EF7k3CE;`}SePKCrHqEFsgi_C_VexE`HK>7-P>`l;1&>bVo z8r4fUEX%{t69U%)+rDrBrUmpt%~b%(w-7+oB9ywSQ_V?Wj)6~6)b;#jXPgeIfPNX0 zD>bKo8!q)OY5Li51DHM(=A|nZo2|c{_LaC}gf@ex&>xvBXYutLyV_W-L=qL7-eBOP zlxZBNPdh#1@(6SyV{r|OaPe7deH1dY@Gdft=;n*DuW1~jn;0-CBN0|YorkK?(gHdE zPn`#?w0-~{H-S8hGToZ;<hWQfx$*Q9LAQJr4edb_pb$M^N|qVa15NqwCN>jOQ=N zcdAPAe$$iRoeo(Xxv}qvo8k?c-!rB)ZhSQH=3?FLn>)^CDN90JMm_m)f)xJog#d;U z_*!y2OHMOhDYC*}E%S}2-6<-XUJi{*GEwDRPU~t|gofTu*5%&mK+3ms9BR@X(?#OkhQG%!KxwJIbY2(Cu=9$|KFU@t- zlXMf1*|^gNGH$1rGpV}J$McHGCL;NMqB{FGrB^oe`hK~_tE>cvN!CUz!RZ{?4hr#< z$vsMm{T6sP>!4m|WH*8J))A)+TzSxY!ur9tk=vKwZQGcOLRIS0U9{h&nrC1jCiK>* zrE(w=_4&~8n!Cl_ztvf*=9ie9{^~Q16}TGLoqm6;Hd|c$Wu}|T0q|U0-{$L4)!p^M z3fna$)m^+^@X?Gsbrff&8CdiWD|$9oP41z34Q9n8Wt4zfOS-*1nhNx1OXt5!#)WJu z=2mC0L;`$ao0h(RqwJzE~*!qjh*-wQnuOU8<_HH{lnKI0%=yt(7c4PQwP z66{yQ?OP#BHOrz#6@Q?nkM%bq)+w{X%=?(JGcM%d5q13)IlbMMel=zj>)6-OsfVz2_0Q_P#~9{?;!_52og@aa|_d@@UB0E zU62_xGN{9Rvkwrgmo&^B`7`C(aB%5EAY3bbb9bK|z)C6(V{b!;ihVt5`^K-drPoZn zL#LH^=fdN;KS?^rQb+b&Sdi;)(Q-f?A6ioxK`7{y%WS{|mNE8GG!I{OzRY*l&qf*Y z-)i`lCKM>Osx{1jcpB42OQ8Q8rS!X5)Oa!wlTN+#!olZ|`4!{^8+LkL7hmM)57CE# z87R#xBfw0_|=MobHPiW*E4QiFcmp;@8^)F|g0D^`U|0rnqtORBs7gK|CI}UkR z08@f0jYqXebTD+t7!P8K?uiIF%vx#f#`$Q75(=dYC5(?`R z@q*E>_fl}V4~qzg@|v2hG6X|y*z^vh6Shf}U4P7=NTzXP;NNF^=EV*>aVctAKPSZ( z->Rw}nRfTYj~f&3>^NfBS$4FOmppKMo#PYNbr-*^1dtgwc6#wDA?mTSEp=BG^@;)7 z_0f8-m>`WB7ptY9uVz!B6!>tmqjN5Y8e!M@IuZ4HyJ}f6udhMl5rn$d>o45!LCTb) zIH+cs^D_k3L5yMoQuyzHuS=*+Vlrh(${j5FmT(v1;A=>W^Gn1T4 zE3^;%5h&DU|8`|dSf&&J{AtFH-HIRurqE;$(Ba1Yl@9m*%3xBpIZ~P39Ow>7eozCC zrF`cOKwbrqznX1joGxSmq24M=-2_nAb|q(}QNYHIWE0q%{US>|XZ5vrnPr>nG=J<< zf|BUwjk+I^;NHc1aT!foqK8$!A1CCQE5U8=Fkf=pBfg5b5c%ju$=A?x$r+?_YAq=W z1^xPZK%pH2u6jtVN;5?)>PHNwfG#`c{l^r1Fv#PB7GRPx=*0dj2z1CAi~HZq({24t zhgD~%_a!Hm!gsiLD0`KSh+9i~=u}nsn<%5}y>RaEZuB*Yk~KXt?Z>&=(%=1yvB~m4 zke*QB=vdaL2b*uy8&U~!=m&hhMc$Dkh5cc$vXinl-IE=&xx(RF#fVu>z}1SenlQLp z!=>&%s4O5^6maQdiHh*W%rwZ-2;BH>&o5>A549_R1r{ikoZ+Aj1nbbEQ5>kwGC|;X zAG#+_shb;8H_0__y!j8gn&@`EBZKB=5~W(Ga zvw%1km_dZ2Xhhec!uOSj_UBd}f0Zz`s}a7bETEa&WoU#FTcXKI_bZ?Qt3`2NA17@K zK{?bUWRi>2yZsyn7Oe!*9ZRTK-vt2NSJvC_05zEY3 zQm;QU7PvW!&m+hO8qlKjg1&Rz=>_Q`1P-#TfzauoydM^9-w|UI-~?#XNurWl#WKI; zu+7CCs@{?FTwICCvd^h+SEc--)388N-=+wZdi*^U*W8sSKL)oT!p6rYh*{}N1StaP zNHk^R;j7TTMR`rr5(4U}HudRB$G}O=9HO}x#{~Z*5$!t2A@7N}w~VkDP}XY!#oikc zPG(cbbsZsxW>;w#D9!io=8C*1B4Ltt z(Mpi9W;MZ#B~NeZ1;1%-OAk+6q2aQ3&+?MD7|AT$yqA8Me7fQA_9DM|ZcNYEg4Q{V z>;m)#haT<&onKxng0NqH4nX3Q-6DL8hn-QwDukZNjcwg}T)0wx%UMNRU^&_=6G6l% zD@rMO{HO%>24Fz1jUf*^`l$_U^bag$ z-yo%REv?hb8-<+ZnMZp~7&QWfJdo05OlmF-Efr6WTqz*Wn){AKE0}{=%Ijr;L{3-@ zs&lVu8QNn_ZQ|Q3k%r9%0lR2CIq$hupO^AZqUxo*mwE=RLO~Cx+p*ldYzYk2c^2*I zW-(8!0H@-y+k9pcG;I}hF;d= zN|mvqZ=g^~?Rkr1OxcK%(KzCa0+l@xq{>QFL?x}mR}G!r&o#gZ-|vcJHGtbrR5oR= zaUqR`JU4>1Q83yWV!Tt?Yv6=EKs;`4%oz+s@!$BCWhikBr*61>;!2pWjbKq2kjR)- zH}YtD`I?Zf8X&V4m1+bE4?)|ZQ#Yib3z(6dx6k{_UKNP;f`I|+g#G38f+Eq3#A39t z@-(4u%H9OHg0_dbGzP4+ob6}1Q$=tAyf;f7@ zbMOTg8?5Mi$OcEw8f{vE9)1GJ#i>9p4x741?u{u@j*UQB1ISCB#*ySDGcF&@Y!P0; z^PQm@u&iGxBz(%gIe~z0C$0fd`_Kl&ejPAASgpM#61N6{06Y#)e)EEuNgcUN;{HiY z1Eo@Ll}gB9GU|yO9XLZDA?r(RuSp?Fvomk0YTykFN3W%JHjy z$SzI4l>}xO;f{+*5Nn6E#McF4?M!MfVsd|+oBq1X83lSE8);V9aP0L7`x^bMjqPg% zwqT&OKd7T4c3ktB|81>0FY)Fv&~VQ5Y7H7WyNt(a>;S zC|asv`|BStDW1FzX&&*p^c-4s6-8bTtAsdwHCquD)qOb#4!|i#`JJoXnB&bqJAgGQ z?wWesmUrT1_r*`Z(yrY5fx21Sy_JQB*uTcobw&%JKB>WmmD1AA?xmc^9?v$FY%it- za-BS?u1tJ;5dy~mYLFu6e>y^rt(8CmgjoZ6c`#sZs4zgb0iKv;6<0Sb4-v1DA=jrq zIg;zY4jP#w@=tq%+P^Wl`GLW807jiXR%F9wtj*dJgC0eQg#_2IAB=U=Vd zAo^jeG|b@eRcUg1_-fe5PQY*5%4aen#v4&EUj<<9jy%zwnE-u1&fiY-0i_HBazxW{ z$zh7GeD*kgF8(o!Dl)i%IwfDI|HZX)?Dta0*M5xV&={j1_c023)ND-HC7pVkbe~FX zJCyExb?sjQx$=eFZeV=e7Y3|pwRdgmye*&E{J`EA(oaQzF7Y<>*L%e}-;6e?5>eY? zMLqwamu6+X0&{E>r0D{H1dm9CoRSmv32*uPt%L)~wvCuTqUtV-E|7eur1&u(nLS9K zrY)mAI$jtyOZ2TE;)3Th5B}rc=3f9<Tx4lPAqGrx-3XN@_Ht`uQ6n7yx0;5dcmp`p@4wCZ|B6gptfu=*n z6^#>Bh5kd-%a(582eTZ?z-(*%4;TrIX!nZc3a4VF8Tns@-W=BS*8p%RiyV1w&V5@r6yG0tewmc8 zoNau0O?W?A#1o*;y*}s|ulXlWgx9;;sML$>8eR)n5gKdGg2w+_HFBwpeDHTZ-ihyA zKWG7#>S_rYrJCanHl!gj-_NmA!uON;{ijl$uiB_j8ZG!5MREC;0an>Ezd_1n4pF;! z!L6-P=Ri=wFS})ydZ0|3F!I8+l8-zhJ~uHXHs`0gsceI^kp|}aqF1kg?BAbcn4`~j zvEsf&lJ2zJqTy_c#y#Qwzx9di?e50{7AX)^#$h6BGLSHNE04`01doXnF%>jyOMMRJ z*eq&L?s;_*5;jp>AYoI-*`mC~jrz!U2Vi(dT;K}0KLxH4R2Qb>_N3q2>UO`WQGQ6Z zqpe?L7$QM%|8I(=yg@BH?tb^jPt11gF(fkz-wrFC35CeBQe60TTT<%JzXDN44hf_wJki^NW@ftZ zf_osEG5s~`E9n>Lgj5gMvEg^^x`$@r!BS6Iavx54+1cLtq+Oi&w6*Km3{$o!ONMMi zg~IGA5N0(WWPmWM`@1k3t0=OqWQl9D9da)SovG&xL|)PwZ`I-~aa- z{r0WoOaa*Uf493!uW)}&#wsTA`_YTgrvHIRQlITidooA8$C2OX zODI^@eQC8h5z?P17z7;WcV!5>uJa|Fiqq>?KAzvGf5#&g+mLUPND{@bX5eeMH zM^hufi6PmQd&SalNWsoXrQ*|gj~5X8?;nMa`u%eZjEaLU3vUAyjg{zK`}x#UkTAb^ zd&(-$n(uAW3IH=zd9>pCUuLEvrhjDLL7@XsVmYs4ir9n4>A;2(WODN9l_B_;2&k^^N>znWDR(0_jUkNQtC? zHz(8mLdv-~&2aPXbdMpcP{l_5FA~lb{!W0La4WkSoRh)x>8$M%GKRM)LfUQVhKcJg zKH$#oAKqMnLl8u!I-7v2y)Dozx*q7R&A`rCn|ob^ATXlbBMksNb+^)cdehDw>t<@p ztZM9{f#rlJ98e6h(EEqGI{O>Cz5~-T83wey#LfuX2v)_{L*XZ3;D`#2gFBa zPRoCOWIkYq<;)tm(>m#*wpan1g1{hz97r`JB3$$WBK6V~vs7C?hk*iGf0=8NI~VqF zkDSbt7c;&FK~4?n>l@TVoMBgSXFH1eknQGueznR7$&dRso1v|$zmVn|*FN5_WLRlK z($Mq^gWXWIbA&mR1)-P!;eweo5VaT;*$xD>5vl3M8bhP zdTW)+udz~#pkp)m#+AXqDJ?C)Tw9oNjg^qL))OLHNt59V(B6$tu51i&cW=372G)C~ zjgE(ZhH$!0e>dZI@Iy9>X+Dh`c3t82frrARlFRZkjr=< zN*H)5ra$fti62$bta^XhrhMmULaokU-KbwX`DtqGq5YsMuoBA33i|S$L4sq|UZX0x zW-mL*g}rOv{HtYfql%T69UnAy?f94~YVKV^akXK(^`JWgT8g`sk*k)3(XF%0bpZQJ zbN_Ll2{6rMe|t!A0ATW^Y4S-Eju|GsdV}C?NzmlY#mk&j-z725OnBGt&mlayO`=k7 zU~*8r3T)df!!!*wg16js0gcU8j3MC)gEsG^Fuxk_TmHjl8%dIALYr-4K#-$1+a^zs z6x;|g=z<&`ZwDmxW&q-8hF&9*E22W%d@z_G8d9M(KhaDDON`UTCW+%%V#G>vC1{Cp z3?F&)6656Qk+``{42}%d3m>;Q+6cg}i%AVR`A@Mi@$#t&Av(f$_O)fkK6;PG`;i7A zf46i8_4Deqw?j*JW3c((xqn=`n?z{@43A6W+wdFG97`|8JCeXG^YsDwJk(orDkB+o zjt%p-uTT*ko3h^}#AT+P{K)TXL4=)NQCvA?Umc_z z5TSVLWp6a3NDHDV52_8@5nLRjgBwW0%kXTJ)^|!z*;6O@Wn_fWrq`?z7^S;$9xkZ; zfc#Za2fFN5cRz-rKWy0$H{^D~2<*L7jxH4B{QuY{{sZ|64(;>vR@?>q{9_Fn{u@>S z%}4NB6gHu04+BavxqAH2(SCqD4@EzN)h9Z|~W=}y`AW?j%a#K8FyQ~|AX z)w~2hE{G@gWq7-1`w$Uc$bb-l(?c>Arym4wZpPnkEdAL;Eckty2o{za|7u}r64jfe zULcUuEk^b8Y-{RbNXDuOIn{=4){J<7!%}0gP8TmC_4%idx5oJco0BG~`XC~M*4SI} zzaTQe-5_lv2NF5*BK5T9#d$mjug`P(h6TQMZ{C}_piizT8%3*&`noDYBw#E$1eTCpc!RwG_>?P#>8Os z((fc{Q&BwOY4j3#b^cJDJ3m|_5U&eq4` z`$fCOy`$-}yD-5dWkR)KpLMWVBfB&kMTDc}l6wWoQ}#9p9x9e8m6H+KDQ#qUXR_<; za`LxPNC2<#ZBa-+mZ-=cF`lx?rLa4J5|t{CUJDuGKot%+b3)a2qCsj#SnUh$?m~YG zfjMPwx^7?50V{kfh4$Na_pl`e#V)B4YpjN7xz5#CYU>j8d=OP&Q#V|8fr%naT~B>p zEI;XrR{H?xWWTKUN0De?cRN|+20R+jgCAcVUPNw={jurbWpk0a!%r&~elvUKh57B< zzxnd#_HVy9B`23wbA#n|)HS>MSoWc`1C|Y&_NN_ibzOZd@ldu|-0qpbB-mfrPMmgf z<`=Vnt)QWc+(q;sn2&S=5%glR7mshz&EuM71S4t%4Lp74;J^`1z)b!3dF=1I-;goL z$Fw0eNlb}7{nu$j*9Si-aRn)mfSmf0{~e@vwb;wa)uXYpuuT)ie4RmjtXHh#U=mbQ zwbqmJ+?m!+3Ykx;2-wH3gyYzYRql_g8U8Umr-+H+4e$PXQWWsPDoUL3AtYpI-oM23 z))c#zDJtR7gb_JZZ;425D4DR)=h}Ty)!M;F(X}KKY=}0dafHd}3KqSv^m{a}Nznhf zcPDI1iYb*YFIJx8P^j!u@Fl+44#)mu#NBR*&Ws7$G#srwS)!GdR~hCwgd{i_)mWm3QJVZ<8i zU`u|_dH2$9tB?x`=y&MAIWiU#E4eltPf9L>FOM{@%uU1|BwzmZ zw4!nR>mLXccA@bTHoW5J)6#X0z=K|X2%I2WQSAeecm$*%AbsQ>O zEmOBLkL_+d{1nBwN~`_sH?|HMzx0{x1GRwC7(v=o%m1PlINLx}bEcVwHX>3YB zu#2o?IFE~9N(m$UaLaN!UXhp5VSJ$GDb{#lf_-r-)0gLQITnik>UA+C{2@=R(+@}+;&vxs0c2lDu@2UF*|6QCXx| zTiJVJcst;$en0U&kIR5k6w{j}p%k&-RwiIiTaxc2tp5uC*dx$ZaKVqAs7K1(BWu^v z<9pniY7`+{tL5G_AH*Shmkr1EPVQ5x_XSS2vJ62#8gUjrlUt4UY4WZGzLYHkQrnA! zS%3+y1N5E{Hq-QcBn$!H1s`c`k%<-dBg~P(-i;n5(qv8;MbJcva?R-!A}cJ!7~@*2 z+t*IVZe2Waz`wCtN^8W5_ZZ`ums!WZZwz=c?7YQ8aW1~CyDx%mqoqy6CM;C#;pU_p z#|2W1>}Z#>84Np>sM&To{hN^Z>7MPnUyN4TkE@T`0>-Z>_iNDjbf?nx z%nd@oFwjlwf%QlozC0G%5`^TjyuJc=4pNbOxMP;O-{wdagM8=Rp>R02nO!Wu`oO)g z8!{Lc*#1)B*7g;#n_IHZ3Uz@2Jw*96)$J}Es*C`5QPm_M6pU6i?c>DJu!!PhnHv&* zrnDh-dal!n&){d4-rQ0A%Xbn2vgt3*wRSBva(hVAbEVHVKwSo&I%UI($g7JUS@=`Sr|>K?3wIGi4<_?XVim^09~XHXA`uf0G0*=IVCr4Vd0xt0DYXk z832+kX|IjdqgL)qDvdz$sjP#s+U^*@o?GKa5U{RjyEhLY&A>-{7JlLoIOO`G5i<4$ zA%A}xP7FgdE9?qg?6%Z!;(F*cnRhOzU)?5QBFnz5XIkWX8@@qJb35IVbDZhQc)Xe& z5pL%bX6NhgRlB^BAd1d(8+y)ZSk{ld+pvFiO96b%<7v7>*Po2Bwf;K;gZBmMc;!d$ z71)v(rfU5K=bYF5_)k#VF%psY{mSv=C>Dn(sB$&@T#@}vWuLllZ3ZvI@DI(eO|z7T z7S7I!m>Vi}mgP`Fc#dyN`gA8oywvh+)L=_=g zCfIM|@buR&5nEs@0A#t6x0x@Jv_mgdbe&dkTl({7e1B=+`@6FH{r7i>7ik0>jAg)u zQQ+Q|&0yCmE!{`#RWj=36Vr{Y9&)lWkI`;1PL{YwT$N>YPU^{h&BXxO_bRtS2Jt=j z_PX7C0Xx}yPNK{xsf3Y64TY=;`@4zC2enB)viUOQ%s2=cY0J$3& ztG5l1b^&1LQlU6K??-aA?Ef z+@_&YIYy>4HmsM}yAZS^x!|D{a)yA=*oYcT&RgkVqJO_TsOih6SLt7k)!zJ_LiK$s z@+{PfEOLSrs0On^X0*%?a*M-G z!A9K~ifX`P0&pU0HNqg~XrpJj8l%S%5y%nU5kc5j0HB7Iy$s#DFL_rKIIpyo=vQ}` zG3U=#D%T(B$XFvSD7zJ^67U0bOSF)BAC#|!JWWV<_T0*c7hh^fKdq@~!5w(e66H`? zm+25&9jKh^Bz!c-X6ba-zp^<_4|>t;?dY0G`3*8UKJE?wan(2T6Xndje>xPPafmBC z{rrpfPp}~dCol374B3VPa^e>haRMxtJas@LfuCXzmRn@PK@zfo&v*sQ$wg|60?}Y1i-2 zrBUY2OWl@gOF|y~xjgI}lPItkGEWq9B2r<2hHZ!F98ySjOJ_iTlO~64ygKFBiF-vq ziJ|c_tLA{smJ-)>jc)!uahznuT~T19wIK9GkXh~WbPG=h;LeCHq`j3VsWd1zc^A9Q z0JYJ~v0swM&{uw+wr|@ISGJHpnfgue%oYwj$pt&=)Uaikuo?4oK&1O{qe3+F%vzhk z?MI4O_0BZl@u64~7sBn-up`dhj@Zbr!U;F_fy^#J^u<1iiR=FMC43IB51RN&LFr!} zRmGTiWl>O7ge@^AkaTKEMn`_>CFA0S*t7!e=76XEndFDEll`IHVxD|?Qc6XE9Ng!n z_a(!U!acACSzJgb{P<>5YkMrn)zk?=9JDnsy03`UCV$O!#WyXEvGUyB1D*{7a0IS* zFA=921)q%!Uh|h%W#4)CGJ=qApIP;*z*aaM<84jtN^~rPa$n1Na8(vXcrks*Tk#vm zgk@s`_ut8g-#3gEpoTF!36c?yWpK2neQX%7N$XeOb{j#52keP4y37fi01=mQab3Dq z-uhx8Gebt?oZ(lt+IFz@nZX%mUqL@+h>Sq{u_X7wTe_3?7P3Wwk1Ig3e7j;-9LL!U zGJ3G`dZC#Kt_>oC1fwuVChhS#bfSs!?*3*K*ZdAE71E6J*8(X75*u2}|4uk?J&Sfw zuW-_DO{hLca$m=stwpq5+-J+`d22eG2JL5RH+pO#ql1rbEA(SfIW011ouEqKY@tF9 zsL4vucvoxfYdu%6Jn8PfWa1LXxCP6MFfL?waB)-u!wje&pcL4XnF(wSdmew)4*&GNOJNQ^p#8<<&MdYXD&842aR z2K*?C{PrAm-y%q6#c;z>i?nRnsh3j8|!_B!U6RG0gdY)71Tf9ME8!hBpfHl!tj|_{2Lls-~6v?Pc2) zln6%_xC)`G_9O5*-0)J+v!5k)5V)r`>7*xVt8ZdvKuJrv3K!4ma&?b{CU_@-E&$vX zKJGKV6@G@3+efMMog3WY1!x4NFG*Xrh@e&pV5%=t)OJ%6QrHdd1jy;f zt~6{x@AU-#_N%>Uk+i$t7GB0;0SV1Fx@TRG<9uCyt(5`*F*%d7g|GK^Bd_TDdx}>G z`(=U^G(pEIojy-m@_|0P`0Eyrs&~J;di|Vc7CLz*p-zj}){al~Ax11luPqivXp`ce zg%YPX;Of1@6=Q-`7iZ*a*c4D=Xan&f_{sf5d-cx3wetCc^&+8s@xYmcCww&G$E6EFzLy9Q|5bvAU$K^KL3?+em@zL5 z7_{Xjdxf4A*A;A+oi{hZ}{!kxwGBtXVrn-}$H4`ew-kpR<AM;w_XuJy-}uzmJ} zfcVIhBN{lID*)^L#J9c#ZB|`hM_pjoZ0nd@W+tqxXm!RpN^>`i#<3RNp477eEpYz- zi&;!orJNPsW(~HL$TAJK1#G{@!vX3if zG!aZI^^N~&g$a|)h3F2+iEuI90W_ssQy`y3Py(B2I-1a`^VJ*m>3_YCU46TF8BVr7 zS{%Tf`-ah=vf4NCW)d*f@NRI$mo1O6S_nJ|vA|>I_%GhT%84}GSrtgN5bvZ1e!!oA z>r|B2ZOw@0!58y(1=>`^dj4Fyyw8vSB-g9Vka5Z%7Fp#Jh#v2CO1mpYCpq1fpp!rg zG%w}-B+=}}!79J(zB$@t|Is6$Pd$WA-9wg|cl)2xe`VbkH*~M*32+YaGB z$PF&@N4<{oEsJ1twvG2~f7Yl@>u&$R-dG#4Qcthw7MVXY*JtIdnql6T167!Wq=WGWVT0@(uoPv21-}RnE^W=2gpMT zBIp4(P#i`2_pg#BW}Pp@QA6`*#0Mryn7T#8AoR+&73Qni$o&74!x; zybp0&Ddf{0LnojcuGp_Um3l2vv_z_(bK#06<59YCqo|ckrDH=7m}^WPBPCdvINnFV zAp8*zH=!7p2x8nRp(MuTZxNV1GNH}>j1#{yB_U|=8K=IsSgXPj7&${-f_Wn5E&KAz zW$Gb}2&k6;Dw7b-vfJUZs;tsX=FJYL+_PJZVK!QY)fG$hYCH_6RtR{po>SC#_09U%W15yKWNSaw#J!D$om&Dhrf?IHZdtyN6KwgX+w z{#L=<zE7r;Vf9&QMcbabOw*Q!fPSmP>&Xg5{B%uX=XYHd z6LjK@Y!W5+hSeFK`%)c1TRqUmqR14%`z)BZ>U>|%vEyY1f`tD(6JMsBS{XiL1#SUB zbEpcs9(G?cZ|aM7hUNO-9(}(9g@U^qU&a1X zwHn3i7QLg{>!Fg%Axg_~?X;9PqHhk~4NUgV;&pm-S9X}I{=Hr22ZzOtuy5KN;rCVd z?iZ+YZxBu$e`P2S!E9;JEY>tcVq2E*f$Ic17g^eIivh{MMCUkhwH?@`@Ugai)@4b} zH!7ARComcqXJ-gg$9qsVlV80NO^fA40FKctx3$wv%{AR6eYBMJdrpAwdnT5yKY9W) zmhao4H#jo%o=9qNl+-e@dyzluHoy6q>FqmQ$PTw2S->M3{eh&eYYDn{; z0WhOiK#w8=bqLrk2C)k$Q4AW1ZS-d#TdOSZo1XhaLP1r3*+bWM=)2GM zC2AUrHq5JQdFVH^nKEwm1wTW5SZQSNAUFD&Fa#w4?bh^F?c0^heAE$30?_jwn_a^uUT>|%D&5qL&W+iE*%X}IYT@3u?kL=)|% zML?9{s08#w2B12#%z5gY|v>)IlBFHtsQ*uvR_*6Ew0$AjVz`fdI;ULicA9AQ@Y|#7XW?-#dh_bDi`*qs_6>u==u^ zCFIY2F59`57^mw+1zBMqR!ks_lY0$z~rGi-<>W9&ajnI>C;W-Xs#iM_yZsR5b+x>ZY06SSz#l zjrVZ{3~*VrdTmCF-B#V3ZU|QasMD{Xm1adORuhv}UmSh%>+H+`W*19TeE9JxXar84 zD~92r$y=HJ^W9W-Lw9Fr#wH!8afZ3dOadDeTWgmexQG5`ExIEjlXr0$jl9^Ze!N|w zF{rbcDv10Bd1nK$Qp&N)Ys6Giwg(%*RUb;gRyB>C;Qrm1G;u*k-NT#5 z-afELRhyZYZILl}XyCR7D+?e{c4TWf=2x?sDzZU$~4!1 z&|aw%Qj5U28ku(Imp+#^rd^N{E%%8(zKvgYq}F=^m&TlJ_3l}n{qj*Y>d6q-?72kQ zX;vMl8D-vG>@gHKMvl9euErc`P8+&=5%3|+_VF-5>Bl7}puZ1uJN`s0QGR^Ml3uV; zvf9WrF+Fr;$}hjTN{VH6{D&2<7FKh4J8{sPT?W=o)PO4QwRgCgVoVuSOX``_A)3*g z7n52lZ==S|M);n{`)^>{hcd*~l_#R*t-4sUL!8{cc@SXkw9aL~N93~9iYpSnLz zPyMP&s@9qa`U`)@NaZ}&+T}HF0s3qG-oflb83oX~iRpOb^k5CxXlN|P~`)zL}2wg4f^jL{kIpHWXg zYd|zo8%M(HaiVIgm^47L1&7U2DI-k_Hy!QZ2kc?}mn zlIat?8|a~%Hr8h)tvwCi-4_#mcY~mwAGo5u2hzfg!GC|}{!t4j_AUxZk<2fv^yq7H zo!*SE%70kpd%XUFq|b5w=8mm3i^YXKnvy5!QeMV2)C0n7gZj0lc3a(KRbPw@CCGDH zZW1s+0aog0TBoqgD6;RMdFW=(_Pl>&od2F|F#^@K6@d2+2=D*>QcXG8wfd|*qtZBu zRCm6CIMiO4MV|#e%9gqZ-ur^M98C>}R!)Mqx5D?133Eozo&KI5_~F4poz22DMARu2G%f~ z4vPUIS{wI4i>YLN--Iu$O>oZ_UbY3O zEFe{(yd3&M-hh*5k$vP~p=iL;HhDIWc`vo(8{HwReD)e@f{a{~otbxIQ zvM<_3_hHjw%1CIR{X3QM&Ptg>-Qc67N{Mt68V5WI*}B@LYh`7+rs@sXi;#JKUF)`0>dQ}bO09-~da?epW?;Q?3@m>1 zdgbI5a3gt5Is8V>FjJL;q4{D<9E$Vlv(_R9%PcbcPWsVLmD@I7TozDMedM<||Fu&k zul$%x7L2@tl{&fuC<|C=GO^Lf|fg97k*AFP~kde=&LxV%Yr8 zt0--B&==HjzX>fdZW{ZCKQ1v&9t=(mfrsRR!jU9-QpIduX;w0!kUlH@5EsVis1Ky3 zh4Q~=UCp^aWq%wb*X7`2kt$GYtKAgsM4kgMRA}Nd=e|g782_}+Vcx#LDf?LlbRI;t zt7Tx~Rh1M%ccQn0AIBT0rL|}h!n6&#^-wP{$?Pe6696g`Z8g4ltj zxO}fzv)S*RHnbPuA0e|1;L!%ATrIFRcwi2yrWZXwOVvPcUSrEF5KKxQh{C1J1^PC4 z(Lq#4g*j`=zO`3WGO-rTxO`>9$V>6zvUx|er-YZKx<%IZu@fOA+|>PXLIEz)y=jD1 z=Q`MuNnxq73m*Zfq`HdVV7^~992s`Yp(u08hDxt~-q9dlIs)5-*IUoJntz`@3z#v4 zq5v3_Di?^>5|;>5HB{<3z6zxk_!87VXo10@E4M?OGXz@Tm|o^xap5{u4;@Po2%nG0 zWpBx>^&yod?8El@pKQ1+`W_l}`#n>EML`3DDO<`pQUvm1&JS;=o`w(3b3b_w-?nTP zgkUV~EI{k*y2_KEvRSi$9gkiN1_3faeIE^SWIE`c#AA_*eDCG1+Xed0K)H*qp0XVV z?LI$eF%2!G0k^QgBxDzP&RhZW77#FP9InNJY3$zZBEXVS8{4+}XO_(Wyyu1FmBGr& zA`mdC9*;v6S07%d&w>t{Sasy@)x1RgE$!Bn{U(E%IohT6GJ-&T=TLcKdi1VlL{fFLfZ^1}u2=8&BO+CnQ$Ul8gw7fb0Do;ClO#=ji8l(NR!ou*I=> zJyaS@*&ipUl1?V7VdG^XD1f;6DsSxT&)`V0(&oSL%Kf) zK|9fF8U=MxrtGVO2lRT;npM*ym-&PQgO;-~ICS}}gxq7D=u&vqVxpzY$o46lIHP@; zr*cKlaAkY4LJ&!jO?T|r&|mr)_HYhGFT(>Q??XmX`3rAl1a~BiAexjO?{uO z{&*gskotACZ7|3M4T8UgLKGAd`qOxbw|3oy%~5>wr=5VLHjQq~smfo2MCjEyWdT4NdLt3>F=mFC<^2DMMLq6#Jg#;4cWQ#Ui3>5VU^Z0!@M z9xGd3+XRD{hvNDEoO|{6*Q^Z~@Pf!DR6!`^^_2Z>IOKzU_ZshSTwEDq1i06k^jQbo ztyJXK3U@+xJLlyB->Dl|9Oe7xr)t9&tG@6zk6fZ#OrHfrmfr!9t9 zNwU02IE1c!=GClx%Lvo$f6^P$SoVv4-nj(t#TV?6nY!;y6`>4M#NUgclY`v>Y#59m zA;l#kPh_Wos+h;fw7WcY-&^~ft)$Cov9yOx&9DW_0&EUf)i4<}Lo|$LWEyU&#PgfF zIf|c96mtA{y&LQ|m16tuBpuMFwX1l_V06-Ix7BZ!iQYh-KE=92Hg2&w_W(PwQ%ht0 z*0LerK-};Eq|cL)7kEPyY{wGu{0Tm=-&Z*|{5qyq&~p zu{s`t%{Hu!TLi*KR5ZQND1-y4D(|-ssk&XtKE3F-4OsZtA@(>X;9xW6vDCI5R8H`! zhatLiM(-T|CqVD=a#tp?jo~Qo4zt^e!A7?i8i#OnBZQEySqY~bA{a2*naJN#sh>Py zRfalHWx#*jyO1r)^i@85V9`PLlkZokDjZhutkiYf{PT~CXLPM{FxM6qxY=muy_L@I zOILiON!L95=>HM-o>5J%UAyR_ND=7@QiGr(A|TR23m_;+i-?L+g^2Vfy#|n`G!f~& zNbk~nksu&7^cIjBAcPVKBqW^pu6Mor+uzuGjI+-~0t3HD zsK%%=P-qWJ>_a!D2?b`!)0K9nSYM}&DePH)+IB?+$Xysy?7E|QQ5*b{P#2uGTo4vG zXJX+LoW@CR>-n)QRM2s#&7^Ff+lTHlBIn&;SF7+dl=QP5o?rF)LR!w>!%~-TdA(Nc zoSU>T3r>=vEHe=~`Lm#mvaOb|Yos;(d(ol6f7YbEuECvXd#%04K%|$f|E&J|`Hu~a z=O)c=A1~9<2`MRMSy))y5f+YQVPzG8up=oRe8Xt=o)&x@TqiUG#2Ef zUaj}h&9V?}6mZ(--BH-AC54&!`s`C=4G3fy@aD54le|8~GiTO?38tqlTDv;V`lP!N zt(GBu3RzvtZoN#)pnd?6x0i2_$M01<d0Hx}Q>_DEVhdFOd%>x5b`dFjQ__Hrl=P4hBR z($inV741~wakKHYs_s5ZYuSxABw2`c4RVrCRj}dzEM$As&7?>zQ2u+de!hKI6frk1 z2d%q|SSd~X9k}K<|2n|JRiNb4r%%>nxsRT|e7Oq;t6>2L8d!E&t`1kYxEPMIxa6^e3Qr!{U~rTvOohJor5XpoHtk@Wf~K z1xgty%85M|-~T3~7Szz*;pEa>Q%f1si*8qI6u&~a>j?)EY`eD_X^SU4{?Fpyw-v&H ze6Op4FXX=;MiqFKFBeRe{CB;Xb#U@Xsyvw*UbGC|9JQNVIE{Hz7q+Duk?IT8ue;SX z#Q8orY1xvV%+4UvpVoAWsfr|#e=XFN_70b=-1hqS;^K*==h@WK)LH3^QwFoTtJF6) z=Z6nj(^&OFi`41ZMe|crIb*ygzG<F5&Z9e_lUbIvLTzFX*8yA?_2?9WjQaPbtDr?zw6lT8bR^p|4@NGk`zcQ0;Hx| z(}b0I;mfj6c0=$VN&GFIf8_PF#c=l*r{h0DoOdwuNOD3sWONvYqW52DxhTJHN8MAZ zmSujSm3S{lHJm~3@nfo?4EZDr2!x}OB)C!1Hob$o8mxl4`R)FAst`y%$fJ%y!(ecvbQ5|ulo%h z_9XG(xn4}LjXS}3a;FYVME?J?JL5lg7rdpq9cRBs(3vctl(GByk4ygBPyfepPgJnU ze-BIhM~EKtNsH@7zDApsFIVLKCZBPCPIr*XmqS zR+i6h>J@YmKscV(fA_9HDDiK@)8YDAKu6N1H~-Qm!>o>i`>UGyrCm`oRCz|r;AOpA3gJ_t-L62Z ztT z#if6T$p4kRM{=f1n)Z3RY%h(4PYBE|;L}QUXdS0Mv$j%-+0ncrxg)Lpny^5U`)>cU zP-G(F@s3`m>)(s0da;(lhLieXv+{1w(~@sMK3RlEV%CgtLObSv6P0F4 zSwNB3H6aWvBQdLi<`>Xss0VMsID@CO*#y*0i2g3jA@#^M&deB8tOw z1oW&m?j^5ZoX@SH{4vGKlL3VPioTp_O?22>6D^0|EiLQQCM5+TR_xE*O*l3M)e2kI z*$uKbu#YpS8&Wo3oD|oX7&q`1vldz5-d3J}cvNaV68i1jw5Y>sE@02U`Kfov(aKi~ z?S#7CTGWF4M9m|~RW`1K<-}P0{%$>OTQRf%>kAN`?LMP094V*}%4^Gv_Hj_EkMg-? zqNCc}(tzyMstb`;onLN?w=is3WE8x<{N;Lle`8&CqT`v>0QP;r^u(CGL?+Vtz;Moc zPk?h_!*DxU;fFA^?~D;?e-;3{m6y=6YW~86ql10y7VO�-pvrG&og4ZmKR*u2@1 zHMPvTv#4t{+^$1-VD+?N!o~Cqe>oAJlPh&@ieg#lOV@Jyh}hXmAxsFL*>2BUex4^p z=u$2iKDu>8&=av(IFv~bNXVS^rn}YmZY-a{OoC@bLF{yQ22tEvAJ{JbmYM!%Ix5k` zwfc)oaoelj#$NTp=5_WL8Efa5mpnF4cbZ5)!t3S_N4{3t-}Z`^{J9Cf(5}mz>Fy$y zc;|q*#0$}DFEf_0y3y|FRs5j`yuAioWU}L74;B|OYEr!LTQ`SY(|tjBPsmOIe1L5E5#zk+V7&~_p<2+c|_G;+l>1(6z#+$IWjq6FzvvNev=!9<7i){K9 zz%5%ilJ;y?i>*>)L8gtLPOjc-TIgFuky);18mVpGWsnd>y2$SNw^oE8N-ZPr497Yk zm-<{8%M1N20s2|HaUlHZ!Fai!5)L{&A#Uo9Fsh1*x$3msZ0W7`tJ$kK20?cc;)ezW z#2ks=<_EY-7JOgF0|BTpdBSBh$h0=mBl98xAuQP65-Wh#o;4jFv7Veo5w|1PNtz^Z zIF=PvoV^X)Y>2@w_Q~+R8fc8(Q;3}(l0be zlsPN})Gl(t(|s`(%aRLUz@V7}-isV;p%ObWrCdqNtZx?Cd)GKiYS4u`1;Eg{RKvcb~hwHS|Z{3 zrYlI23ih^uy^BZ;6NoJG9G{ddYr*p-&jysu5@+}5B9Uq~qSK}BeliU{HmM&&%M3%)cfu@1sM%atJ>Ox9NwELsa7I@Q-6<`$`_v$PGpWu>eU_+DXEl1z3Cd~XoWXHc z*6$Z09>C|5kphA1E4l7b?6nTC=dTTZc|9};^|Pjmwpk6btnJu^aL#&HfHQKHOj1%9 zer7qYvY4#-nBP-v%a*ubaFpPk&RG8B;#Z2P7Y+_iMK1orJRxFk`W||W631hURbR66 z3M=%Ps@15sQP(xW3UBvhRlv2wsR{IwJe`B_U`cpWdif04Xt;IA^-Wfk%@V|^>zSNk zE3#&<-+xyMo|cNF5I@;ds!Q1HCz>oC%Rjn})w*M;Pb5{y2y5S*pE*xUsDx}9BaSoewPlke&N%6Zo7KeZ(H&P9?AEAq_> zyXck*-}$=*6=HO3bokUs!O=DE3crZ44hegq3mE^=fx~y2{OHVz?Q?j za8!m$>^*J6Mg6*_sqzjjKQ0`$=R#WvZEu$E^40|NEeG7Ukh=ImeSnZQ>;DZ^)Ips> z-5`}62O|lBMAgc@V$Y{RrxzyyBV$`0bij+=MeOKy{7B=T&L;;|1c2DI^8wYcLnXeF zCkO}+c!Koy)5v@+O1nitwpH1M2o^tB_-gwouS)S zQiTFd2^vs4T1QK$beOJ!hh~ode!s;Ic`rn)c|}aJ^Qm@?%apstn3okb_d^MsxR>AI znECLV)TZ$ntNa4E0dvN9Vd{D)>*F$_NLfQ){3w#GHhV;0QWVciB+M;2G38PsX@_qk zIO?M^$UYMr%_V~Z$5_)}1Sq~N)p}tf)RnofS0U(kFTnMu`Z+5Ab}=WNR0)TdRVWqO zH4{>yqM$=TL$77^3Wd*FSO%|*OUD}E_2I%HD}>v6PmuY;6aTC132Qhb)r-K4GPyHJ z`2nPjHhvx%6EJc#qGM%RXyqZw$E4xYT#Qw+CKZHdn@0E!uvQG{_rQnMZkh0a-S^tQ zZt%C=>Q$K!R$EB*4{tV`h~fK`j#rEE`^@En5g5Sr6ON0J?^CNrmA8R>TgZW7rR*J_ z^N-MOn{6n*9W_AV?TigfvUxS-N1XpI@0533X!d@+hj}YpV7ghO08z%(>5(Id1qB52 zF5Um4+>EqQn@`)yB&$3C`|&BYt-kXZ7>AQIP}{%*2fFaXE`v$BgJ?M%y=?|KZyy}n z0vJ_V^ie1VeLh>CSrk>zF)Q0s;ro6}DVPn2dDWw&l1_9ObR*Zx7p$e8yM#Pq1&<5+ z?s=}~#3H7!91mOg+gdk4xZgkYEBt^o{!XWwNj+C^_cd-S*6D0LVl>%X_1ZvBF%|?5 ztdjmA!{1@Q<(w=32W!)`p1VntFx0UDF*<1ig>@*&og4X}M@LM&oda5-eCa2WeQ{7H zJWChHBQUc3{Z?UKeN%c1srXJC{)%>8@9E#~(la`hp@~WDhJxml@r zOy1Urck}>_!^{0MvuSzuRVqSob}6YmzSZea(nXCO3K z<6<(k-O-;rCIZ2ENW0n7wP!Y8X>KK@Xui;M8jeB6b&Sqa2P_YK_)c%HBj{sp$2HQr zHxRzM9jor>%{g?cEqQ4@mMT2|Wdd2HrlQ((Wg zqIr8~YY^rn2ryo#PTU=!$ce4iLY$uMY!p*&YAOc(ARIRmwB^hd2xqChZtcITgaJ4A zJ;N)P5q!G5hzIe?={q()h3K(k#fxsGFi5~V z8M-=5LkmMw5 zdR`TkN;lO!B(2hUXEolnT~`K66x^(oJ23O{M*F)xF`78?@-fOPw6Q1D6aPJuZTw(q>P}c-yrwWd%v?G9940YGyw4(eONk>?v6(x#lgC$&3A{ra-t72-aM!b?c&TlQcbL&y`RO*}j@8HL8r#kPGLVU;{M3@Ga$NLUMHH{G{& zeq7%cioJ*f$sXQsb6pk`EraC!_BI168Bb=#^lE#)sR!>mnK=#4Hk@X^+DgMnc5Ip< zKj|V?vcMarBjLBUX~V@qKwAlbg>6BlI9&B~zC(K6$#1hW78x%9b(^F!UXr1PZoRkg zvDN_u!y_}Df3A(F+sWOKSR`#r7B<`7JPX=_q!ltVXie(B^JDk1{$&bUU^UF?uuoOK zHECsX2AM}ZX~6m>Ler3O=ScNmC-|WgD@7^OMfmM120ELb6a(a0MuUEaO8f_Z^Ib-P zGx!sgv~}>bMS<#R4{n8WlUb3Y&lEU*?l5=-WNZjFa64xhLLVCt&tUD;*0a@p#@?e2 z{=Qol(_I}zjL|zEE@&&+_R&rq#p{MbL2f>JMFti(lTlBkP{||7ovg?8Euj}{u^lq- zgcM}pIa1oW^Ne-A@)qzi(nhzzY;3opV>wG~w>feu-Dfy~8r6dhhjvlNq#^}}Fpfmb zlXpHWTbcVyKEV>xgbz#adECy^+$m^>Ye@^&G0__Dnsv?O6t;TZ)CHh^xhcczO7oSL zn?S`bZ-%+twHfK>&s-A&8XWI*dA|k&B~RLeoDRSeZN*Cd*(sTW+R&pxsW#eh=^a|? z@e6y5$27X&Jl5H`BTQl`IH_)`n(Kdy1CWB~;M|DUsOu#>zrUBOzL!@_;S`CFOo?mohE`_*sBHo15t>lX0v) z-cn94agfde80z+fLkGC{_PD=LmW6_H8TaJQ>KtOIFt~G!5-5^YrTrQhbI=WlW1JvT?wlA=d{2R=#rh{S2BQ9g?+Mxw|VZxkFX2-%6c3rK~|-Sa7ZH z;>p37kbOtX2y`G9>eu-@gp)AA0etVK!=q&fwi#B0%llu{`1|G0DsNxcjIrqfatLsA zv6;t5Jf^@0!g-fC&2;(hjWA{iS`KKjr0 z-)OcJ4weA0IIEedy^Y^ua|vM$XHtCR`EE==aAhqtxCEkoMc~V8G{$E4`TlHmhxjZ- zIQ8cT)`cstWon|cGp(sH2boA#8&om-tPpMfrF3p40yQANip=kdZQSDrHiwp*g3C1N zi}=&O_Jo->#6Yf|_^yx&5#DUweC5S4w5=X8OCj z6^!sgLmh~B$Xx}|*#aY>DqexrWDv^n0oDtPZYEueTQ96;#>gRbu1bO7Mh3KCeNdyC%kXgHwNuMz{&bj9Vl z9%>kR8oFAfjGd_~Btl5PG9URX3vIde+}OT)PuVj+m)}piZFnh+Mha?D$%6?iwaiRC z&X`wzDQiEDV!qmE!!3P*C2YFK${jsNqo6H1FDFdfN1pZpN>o>_SR-QNCSy+hfuaq3 zR_2saYEkIQup3aX)D!pIc8vd1hJv~8mW&2p-|}u4Hmv7LL_M!fJn2c)ox{44$$ZJh zW9{xkJ86&Jz7~zGyDqW6ckF-e>&Lhe*!tUjH#z*LdMDElSUv-%O(SkXLLu>YTgkR2 zO(CGGiJ2jNi#54&85k;lNe}yGN6VKk@vxfD62=oCI79! zh)R**E**i28C$V^2m#U3Ldf}pg3cf1-`iVtkrgeRAk{lVYscAB(@&r1faD9!6?5y% zIYeYjWcA4UdLG%$xadZ{0!BEGGr+DcFUTBedSJ?mL^h7;aJ(Cq>9|R8@9QJS)&ga| zRYaBGBgv^tTMgHD?l%Pe{NTWEPC92i$m3__%m_oMYs*Dq#ojaU6HwnKp^ZzZ zk<=^|v6ONAPY1AwB{Q$xBxKWh__4p@6EB88Eivi-+m(;J@z0CoyU@9X z4!RfBe=zFrT>oj*cDruX*^2t9R~f2cZX9cbL7?zUh&fXm4)mg@Hs?Sp}@3!VRRJ*pI=6i22y&fprv(uEnovd0NF6CakGpfKX z$vOWZh|#|{^Rr$OnP7~bgVVReRPrg1*Iu3glO)M$zBzr{ZMZMfq&oZMgYI981mYP$H}+RNpXi_y*4i_GM<1(4kuSJB+?7GjQoWnTPs+ zwNZ?ZLt<+(yNX^1x6_{fPVth)Fj7cZeWzFHqi7@Fz3l#YF}fMBn`cqUipH5QRi0M8 z%hRRs`O8{3@Y?;Jb~#Cn=APbP!;CBp?!8W19#Q!0nUT4Tl1 z`{~`-CN#h&LNu-gMBdEI{pFK57sPWu1T=BW{bsrRH=CEE!`4nwXH|3gqc#L^li^mIqWxw z%_U16vL&)+z|7U!D{@wW9*=!hrztWn)iPSkM2Vcrz|_Emn>Y!al$+$J8OO0>a$0tD z=Zz)+V2lAw%6%B*Ue%`7Q2_%vnkBZRvX8{KpDf>0i0oTpD+~QFOwL*RDV4k(&`eV+ zj}aIhd&3Y^{{UMP#>A;SBQI&NRruIM(Cq@7Z!YR0O8Qy@6P8t1!$| z&FV+a$Y^n6Y@6zJ2{pYB`gMgMCJ2k$^R13ir^cP8abwQbTYbDa#Q1yXKlQBGFWI*BJZTG%l(2D zT*r^!?jx)$7&|5@NW&PeWVFoLP;LW>`qkecad0z(o6m)}A}ri(63?9+xuT_p~h{N7a~EAK_R z++7kPH5MKY)j@Od%OcsACh#t)UykT2Sv4_!Y8}gWu4grP%Fj}t@x>73zD3ZAs_7qU z^NI3auaDvZWFp)J*Kaa>o8^%rA2IX6{=_2PdPQ*qofp-w7LW3&2up|<^>X^396W8UDO(LOo~RdzhZimWXOgbFroe z6XlwcKk}ystfXLms+^wwpnZ{PquJ*)rqf2;yG9bx-Y`+@e#*Kxc|vBa^Vfi|#?R_y@$^4)#pTWwl#B<5#6-R>_8{&+8E&V?tU(TScAvRsC#x$!05lrSE0ZR|C={y4gMkI;;Wl2;b0MtQeCc>M8Uz`N36%>04(?q8U#4Ixv@owyIn3nwQ;oQ5tg z)Mt%P?P~WE$xK=ZJFF_Ja_{lxm9a0*CUmx4N5FIsX#Jdg?l;mGa4CS-ZDVR-l)3ng zrC8rbB*pGZj;`h+z3cu+2z*)js$!MGq=+U@1w~w#ECr=JOm`$dtG4$1R0(<9W;g+a zG#AWQTECn&+fOc+FXuSwkX=)~ovI-4V0-%9`x%I}Dp^8-HR3ocdI`o*ez7E-BzKb` z=VGTYBX@E_zp>m?;F1%m0rhPcR^F%aO}+=o9ol2^q$6mjngYJ0Z5kkp5onTt-_=PqnCmumnQ78NB< z)L3fSj*&C(8SNvEFSv{IM2Wp6vVvVJ66au+kmTyprE$pYQ&m}b1>23LV@5e7y+f#V^wUrKg zn4OonR$V&~uFxsgDsM$%C&Qb}xJk^;D4X+|@0&*@>{IXLgrLoA5+4MEJcbw|Xnp#&TWQ z+4@0kNM^rw;TG87WhI57Ds&DwTxu_|2m?QMc)MARuCyPbUg2a-ZwpX(PXTy}dt2dg zr&K%zDM0xj&c9x@%N8lBhtWP-jCrxl+=3S(#IQ%IK7SAK`bT z)9k!LK9njI`TqTT?RiyCM{_~0d;2$*qGL7lm~G~$@%6dW zMU5vnvlyQ08w~Rse~mm8d&X1Vv=59da|tHr=UWN+>i99fShaNJ`E%FwdUgR@RYuV4 zrS5m>f8D=x{8%%3IA`@*+LrU#Wl$UiAg+ijV#NiCu-Hscyajj~aBK=9+!nnX1m4$( zaRjSAlcJ8Gzcli6z4u|v^&nQpWwNYATN-z8YjBBZ;wUb-kjDHCGxCz2B9mUe!ML_9 z*L3Xg3sm0Xx5!rujJf1=mgzM26;KSC5d-->>sj!FPxR?Y%!rh!biYIkquXO!82ssM zQ?Jug^C59i7di81rv6(J_43DBM3&9U_I+U1k6>vP%9|kC+veQvp8%@2>I$vx#!CGx zD0Blmg=qLZscxF7Bdble-mbrtdsQE$)W}Rmn`@UZjx>X~5ZcGVTiOY1O#-0X(E`dh zA2;Nf7dITZr(Mn}JZwJNod{(VQKPqEm-*~-+vJH9`=E_O7xYxl4-3$DP24h9NSMsX8wwS3cFU}u z^>m@U>F0Hd6xkCWS62wJ&-tFJm9da9ZaJU z!F>&opdv87w`S!ej+|-^_{{!_3l5l+%03&nCCf%(%O{`^uCzF`*O5+?-!?X$dk{ ziAg-j)$1 zLinsy;adRCP3XJm(Nz$D?-jh%vvDi3m(3_z_*H1sxiQ*j^yu68&p~uu`KkNe3fV6I z+JcHNU=JIf`FPxIvmXC6JaAGR>0Dw@owYC~<-)&S%h``z2}lnlE4)%GqdU&=RW9pU zp8TQffnWL@{DyZ`C%?WwS3dpoQHbYac zH}=~wEo651jT3N|`t7ZBl=Iwh;MbiyiUoA@Lc1?^Rs~KaS@%{s%<_`iwpJr&msTW$ zXf&K-w4-cwdd4NgIWVjk_VQS><->UxeYWWniK2~Xm&)6+nUgv%F@JVGq`6Pwv6Zz| z2=u;0>Jd_}ZjRPo`g%2?m%v5f9=3H@^*t!ou9~gpFnq2M#duxN`S3D7Ur_B65-Ea0 zU-I{3^eS+SdMx_BpnDYHkqOJ~{l<_3+QMSEilAp+`MQ*T@gg*``!4@A;|+(yh& zG}6Gk1mUaG51QIzt$r=jXcYPSJ(r8tfam^p5b{aUv>T~X71e#*Z6ovA#h=8*xW^kS zE;@}pDA%s{)JlKIV@RKuI|r$4(~vize=EGfm98lTT)(aP5vklKEHk=NGjfLEOZN)_ zEq%#tjP0Q^x2uv(zkZc<@)J*pGhlBTcM2yZ-#>KafL&Dn+#|h5!aJ93R97Sv+Q9>7 zcTr-m`iJw1WVU0ynT~GgdaAT^7GEixTWLEWCaa5Q<;Jc)zn5-3dG~JU%DDlg1^vs5A6I@~7%+dWg|J@mO;SGC|xvQkIsraq<2IgeNfmOVtyy@cZeuA5I>( zKnQ{El-%9-v-q#dv+Q2-_;5@;bpzN>y>oSMRqwUElOX^ab9YxC$hDmrAv(xa*k2F;LhqdI z+5|U=h$U9@{XR|*Cp11646Q!8!5zd*W@FZMIra0|Upl|e+mY#f>@?)T%3l1V#Sjm# zm%la)KT>>=>Fjo$v3FCsWBOl^rvE@rE3&~=WncLzgKkF$?sNYRe47+R=VZZN(!wiLv z91%-hIymPdhiO^8lq|vhcvF1jhi6W?KZ>MlJKV%GN|!e40U;d%fbh<8F~4AeW@Tgl z+_&=T$|_BF0L|g5mRSd6c@gjO08BuBg5xKfIOP`2r4@hCJW&et2W&U*d}3}=>&ck! zZIfQ#*cm#IY4wsn;=3hxv^Jb_!YI;o>LiyQ|NNA#i^y}*<(YVIO;yt6FQF466Ma5( z!2K&r#tWxXDf*E-#eGIL7jmO`E~ss0^>89mnLUnG=}X<+8P?+k1R&Le%g)Oq z>0a)`q>bEL=)Q+$a4}0>I}zz?pq)A>RkZd?W2O37f%Q@#=Zo+kWZX@cd{YGA=+!oz zU3|iH23(T0?$PeMHBC5ieCP%8VzA-|kKk`Bp~N)cjVq z^l9UZOiESUn(rntB$e-vPe*BYB;^{_^6%0<%!5p*zWw1=xYTcO1X`cUHE2Dl%(>AY zfznkMo*Mu7DcTVqEiS@p>{BB0NUZrJ(8c+-q!#KomEQD^C!`c1$|Iq5kl8#t{1tTL z8VJLIFMBeE@IY$NDA^^iASG-%Q8cEhhR>70# zA!ui{Z>#`dP)ia;;b+8((U*>)s7qBL9A+660 zx8tNgGA936avNk5FB|O2Nt*v;nseAp=jfAP??Nax`u!Zn;pMxnj=MDi@xO9X2R7I^ zG%vvgKuZ&CD%w`*FM+G6dK#4?6?f84_3QyvtU9Yw3GKjxt1qS!Mn6v&d5>@#kB4rn z`u)6{&dan&jXx&DSFT&XB?W(Tt_R!s&4Rk$${LCG(^XDj6S^gi=EQ~H7kW0R*D^d0 zcN$I0bX1@ZJAx$yYX2IwT4A!X-X6DTc802TgdFMl7^^Q0hM(Aol^s?sDwJ2OwSC7h;LLey#m3VWBO3+1PAyK%xwl36z@nu(jBNEb3=GcT$9Rq2 zc(c%ZYB!OfB7gsZ372oqx1gz!A`07STfUvV`%91o?1aOcd!5OFXXHm=(kJiU-z*C$ zy26?6LkA#__H6em4$CXN@r<*UF@pv6H2kH&oeoqpN5I# zm@bmdFaX}U13~j9{Nv)2@sZVq>dz;Jh z*6p^`)^Cd`PVW!S@kN{7@N%_@o(5%?A&73b{ zTg7eP7kQM9fPSva8~AOrIwSA(a%mx%jVp4B*U)-;AvhE>pc1`54*!*I zHn!$LVh{j$@f`jEFvW+xZEc9cz5cmke(+w#qj0U4O?$oM=Y1bMYd-S;5FPVV9|r8i z8V_Ar!pCHAwsBlB2@cs%bo;o7=1{UUb~H&&Y2d7M!b+ld zQv&Wg3*UN7f-T9|L*ys*TTTNoD5BlzX8)lvZhBAX-pgtD{uJF-nCM*ik1*E}_`LU? zo^|^KQjatKo9w|og+m9!tc&y=Q$K6}Jj8?T&-cGxoM25@x1M`f2m{_Oj!*&C5YD`3 zu6ukQ6Jz?ZU;Ev_mDtlw;_q*mUm&c8e*C9GwX0fJ?^M5k=&u*T@=# z`mS^)*?5{0Y&7{|+U4IUcD);7nL9+w_vxd)*-n2`eXt4FF{z6cpCPyJPJZWkuBc;O zD(l_~#i-Zf$~LYS2x9awFY=-2rY|vx6`t!PCOI736x;Xy;;g5B>A9ZO?kZ%92+G<& z_Wo9i{HSQqlAzd*nzqsHQ`$#>ln9Kt{YH`~)0!0@sXmb0EHYqRd^9iCifRU^O*G)k z3#Q6zHJ(6+c^lV@0rPm)i*^%x{`PClF=VM1LX2!091j&TPT5s{tuwjfCzHAKiY*sZa|W1V z67gykOYNAGpL~xvkFGz-9-qU3GABzI74N^{+03Yzd2%r$^-+cbBYE$LEfw*?)ppKn z?~#x2h~nj;1zl)P^=r=8wfjFkt^Gk7PKtHeP8btS*^fPEjIrocZNY&*xBA#>d?YM8 zw&BhDlh}Fc#^VFWepaM#TisARMeiUI>7N>3n0dPnFKv>M7pir!J0Vbe8gk;KxHyjT z=1k6!jc#*uCPUrxLL{)mbFcY(E>menqJBW}t0w`^U-@?@WHC=C^gYf$dO?k>&VVfD z?$Zx6##3p2)aDsi+X@hGTl5gd)gN{Y&3gC~V-uKJh9PQkpt*=>DP+>0xKS^6hbAoFK` zvRe`R<5;4RunO?#=&!Uha3!EUsXi0hlfbjcpGd5{xN8g7jPyE9TF7y0-~KGDbgO`8 zn!dOScU`d=a+TH4XFEwc&2cB^IGX1YdTfxo4wP5O!4sgXKX2zxqWUq8ebV2HV@B^C zOCM{ez|O$vG%e~+b)d))5b;CMyf^D#$cFi5(jb+rK>$7^2m>XwFCzp88b*~oO}Z%C zGD*4>Ux6x%7TP(?%JGb8RDaxBF^I5vYv-WtBZ20sMW#!?ywO#RAz_629>Lfr&M<5| zl#Y~EpYk&mGkbAG76JLZ1@0)QL&^tI@S&SUeXsu{)=_P`f9KbHZ2JEq&%4-P{nOL6 zdRcUMRfVsWi78XSSw+`%%$;)ZVWi&@lnIMoAooGz~T`oyBH_vmu_a3+Id9g#$Z3uBK%Fb4TVhc3VHlA>t=(Z=<( zP>ClpWv|mdYX;H2R8QwLZWq457?v@4AR}2_UZCi`(m7PyvM*qe0m)-Qwh&~V+1l3^ zx5KmhA7mzy%tjmtNZ4epBHY?<8ovWl3(=}0K3 z1_I0|ov^2(r4G4pizv7u33tbhujH61Q`i)wJ%BeUbX+{1)6cgV`F#JepVRWY;CG}G zes3x^yHdWGp0wk_7ntZYU`K1eyz|kA;*=#6lTwHq*m<8CQPQ)v`+0U!$(*l;^YPJy zi2ak^JR+qxX7e7CWlc;kCMPE`3$Cf(JO4GTC#aKOT6nxO4WBAE5|Wos+xRsG(zq2$ zMW%LZ)?<%nJ3~4FoOqz!w7FF1e@S>&zr#1x_jG(<&H{ASQMG+@bM-16M9wU(@2pyn zHa&~G^yAENh_(1nbv61m)d(kTU=G-6d!;LRndZZJ zNu=eUskVnRPLPMS*S==3%*SL!fBpswi3fj<)u&=g>E=pev^MLi8Emw^8JJn60c+d5 zTN?qIeUb_Z%5;{aJv?atsb0$p`7_@(PbnzD2Z-T<)mA#ocFcE9eJ^$j!&3`_$e&8* zO0Srv8(U~c*oT}Srat8S;w}=tCUsja^ZM)&=-Z`8UX|O}KL+kL)FjgCw0GU3E zJ)4baT#3=T)L{^C7QngijyJ2`TpKuh$%0 zzc{#adL>rgM)&mE&G0g*z>=4(!+j%5N8Zmmuu77(WipLXp3w-$_$@=UJGsWn!kV^7zwr5X@X1y6z+_){d+4F?UF>U(uXayw^lp9`9FgW z_o+9FqeNc8&|#o3Yg-tlmD1Xcae8}tL0Jxc8+VXHznR9Q`!{2c0xN*n{NPC#tFzy+ zOL|q%;lVI)2qv+z#-x_k)fVy8QX9x|1#4O~fdlf-U)Lv1JPfPn17=hW(|y+{(~T(> zYFK;@T7vG$6!>2nY}zA8RBZe-hK1<2KRp@y5{5es9rQmZpDx!4-q`W6dPegR{_+UsJ<`6(Ifpx@YF9S&9vr`GA&PyT+SfvG;@AZ)W+amsEg=oTk>y>K#LTEdfc7TX68{IY9`|w zr8hZ0k=Tqd5kR3#SEBq)`gR4gCag=kX6T(aUedV`(s${6jTXOh1~lnUW)g|Pdzsvt zr^uz^fTtWPre|@^2OYWae->ZK@NU=4Q2Q`vyc$ZU+Z?2`Vyeai{gPwx1@L81Hi6>>Hzh$8;2Q{pctArq)9Q-?b^eL$j-mDQnu{%2b ztKmFYvplxJe(cK;GwpbCW9()}PvQK^qD9{Cwz)?{KAJyJQlkJLgT|7`O$GHvBL{!N zzsA9=%m47K&1g$T(3SPJlPl;p4~f6yoO{D;!06bQq1KD!c*%$zRIyN( z>1a-FUHY`tBi5yz{(tDzN7_vnr06CAsieVcM7*)kUYEMmIuhck4mycnnEpmQ<|m$D zhfW{_R8}>WAoNDYouT8V!eYDI+2vhCgJ)$e@488B>RsQ3e}ysAC&#ZVWKOV>i^}XW z3OVbeCmrD?OBaqdKe3hngF~%gQh*{;)yhUHEHLiDK(|l4!{3<<#(jrtX%%g+zS)=!VE5(MZ_;~|HgJG9!AikDjfnr^Onau|15elj zVD)r7$>P@x%%;|iG3EUS|AeO#_OfN{c9Lv--qCe^(l|>jl)WUzbm|+%bx`R=y%yZy zhx>1FrZHp`DfA6$J3$I!mD>(Ar(D~ZJ`N`vbACunlA@~KLVqrFhafcSBU%!b>#RX7+^87H_V^wEJzRYpSJ~gn!L- z{?zay$>+q_uxY1RD@j z1a<`vYY{JJouL8FMy$MO|8qFCD>TQb%#vtkc2-M8VciV za+~QAH|qy_Ss7ANZ0vLY_~$eIIjA8^E{KFixwRKRQM;|Ht4ry--K*rfTR@d`1336L zwzj!hSug$3OGDAE(M;;_Y~q)7v6=t*($8i16+dHk=daUuRpqzm119;;J7C7U{Tmi& znR4uwL=JW*uu=Fbm&Ck&`fp=98?Xzu4ru-H0TkMZ4ze_+SCi>F2^rOU2{MSew$H#` zzj`I-d$9eUMgC=Ao#g*CsAtSSqt2vu1&9sze-c|bMr`4;tw3x$|My~(#)8U!F14Jy zj>TOlO0N6i!v_jV%9hv|*8kz;P?-8b5GaL|hefTIo9D*==h=P7@&I&9xoO)CsvVaV zw^_c(X?-L6_i2MfQ%9x&S~DOyh?U76n8@iU$XvZciSy6-#mF$g5-0@FnJ7y;j?KmY zFdq=~VKYNlHdES*!h2$noBp4N*As!c=$C8IMQ{K2qW={yP@TW8@Bf`51({v_kBy*I zxr|Ir)xg$Owj*gt$yBgAM834NGz(3`my?_O9yGGqt7qroiJYFE_A%Ag(^IrUz^}c2 zF^3uj8xIZg)o7=kgP3Q?KgxOt1&E$plR>rj=7eW)(d$}k%Iot)()9NTZ?5P_ZOuX-{RC|tjc`rHA>f&05DHl%?6%XG5?8}=h2-+`%06A_fcX%LSNmz-c;Q_=xwdO6greb5H7K2oXpod5GBHwV+?G z(+}?M1kRPbOjxJ4K_#uzN1D07-axRhM%i$6Z-tciTAtqvVUI~ximAywdrCE*I~-1g zE&Oz2jq;jv%Ckyx0SW6@7Jalb7o}6m%d)-(V}}`A>`v*Tg`2JYC{E<VnC4ulWQUO`$y!pq^I}!1eMQ!>+&0lJ}h0I)mV=xdUi>g&mM{(`|V;HcLIN`?(_m z+k7ETUFsprhnvVz&_G2if!749sK3;rZ9XGfYSa5Tf`-5D+t()Vj#t+L4#+CuP*zLmsd{1NZKi8kXO>t zqJ|1y44h8<($u+7vjz$}-|(5O>K=n$Bt3!nWiK%Cv5G{9vPdrM%fmGH1U?H2k zbAz58=w6q(joCtb>{W>dudIj7FMC7Ct}X|*TaBopW(`9@v!xzfCZEs#4nsu@pc&JU zm1J|*Y|7Wd>zx_!NLoBUrxepFCl+yLGvA#bfo}KS-Kj_mT9Q~4@N>%XS*u46S3hl! zVG*zy;NY8YwobLQq;?;r6LQciHtkxvjSz62zP&hB>3BQBy7lg8C^g(={im!EZ~>@! z4Xh9;qH)tG)K&8n*BUb~DTIjWLy*b6%~~Mdd63_~uLt$9N^xK~MQ9t+5g?FJ*32m1 z8$*hm_AhC1%ZR^}n`dvxPsnd{K6p6mIuSI-tcAQ9G^f!Fy2va+t26uRL+A#>pm4SJqDFInduGEpT+dD5(w5{M?9Y*stm6yyslx_UYP z$rV6fhT?!77Fl^{dtFXvgrN9CQ)IZP$m(b3oV>g+=FT7|3M@~Nt=mdUwcivn1JG0c zX#@lWdyZAOXhvzj6q#qts>wo;H6Ck>8Yb>*ld5U{C!*o_W1sAowirWfP7fnxVCCbBX2@L^7QteneU*wIg+nJ~_uxINmOQaCDSUOf^hI$;M+cJQ4!b)1 z5t8>3eSMAF5|xIo?&w7vAjxyO0?)$F*5Pjy=S(hz)yUt745GYrK$9Nvu6XHF_z4NF ztc6xZ?=u;VDh`UO_x{bLm5qpy} zwXM$ZyVX5uza!YT^^|uR#Ge}r~C1naMe27`~69M>wG8FJ-IK2U~xyTAl~P=ux?#_ z{~739#oD3rtb*J_E7brJd~D%fZy18s9W|)4M^fv2X)?oeixKq0D&9$-7o)8WD{3?Y zP1bf?0c4pb59_@m)%_%ETm1lUf<@wm{KfRUUt4XETQ{oe4_9lsmv@NN|!R#<+;0^#RjK^_p4tG^?OWuvR6FmZPJ}_qUn#gEEYg5XV|#j zL|C_aS=^nQh+d>eH>j^q%WEcHe@{5QaCdoxpLfm(iK=-}9H}$PJ?w_}5+@j|QA2|NvO&E#L#5shCnhA)g)Q`b z@VRva88Nd)zjO6NOT~@dy>BE^Gn~p|bpo_WQr<5sGx_bYq}hezT?^59{^Yj?`WU@J zBL#7f)n6eRAr~L3v<5jdYsTn|alduLqk8iPV{&D`dV9Tke>S<^RH2gV_Al8-jI6r9 zYgc*~ON!s_h*dS`XQDlt{*&Xwg))ScMO*WjLv2_52PKv#?JSy1Tx8eJlko$U`rNhU z8^PqBp%k6vwlwI>dQs#%tu{cf9H;OBPn{2qavISjjexzm&j-0Mo>0wS_+%qZ*ycH4 zeNt*l-8rdw?WfyTVvr%YpvgG8&$^+kUw<4=PXQ*){hJra zF88YYwv)Og{80-4uEOu|<+GH*V*_aaJ|5L#B$tw#Jt*OR>CKFyDk7X6Rj%lIZW!EZ zXmUL9hsYphLvS*I4R8>a<)8qlth^nqg;4;;(gPud!H zsna<*ZV1(o`t}9>Bx_Pa1Zs?m1ko=XEEQXo7H@1jrwkS;soa{(_x^<%c$#8blnv*lAXg|7+cUoBQW5q_pNJxDRDiP&8a zPTMfLExA4OY@kOXZxqqw%jiZRjdBrkoK!Iw^Ncb?R;lqXt+|hkZJ^pbB?+wDP^0?A zh-Alx4z?2C;jhMyIr+ah*2Z2?>NsSMIyGK?3Jk8Jk!ou%+=av?1yxiN*) z1n8Hh<4rv$e!9}2x%Dm-tuw%|bw7gfz`1pInM-gKE00lm``kIFNMtDB`K=ILBjPLD z*M<>qK`;DVAK{LG?%$(sXcp^6`UGQ4=PJ+Q0J;I-7{A#xg+pw2oJf$iHc~02>AT&1 zYSXViCe$5uA#v`5ulGo6cNHMA?<@VK!*?(1-B!tWK=(-}&-?cB9^NWq4_v!pY+{Ij z)JswU)R9}P?J>ydh!R&LaIYkN1>F*#43|9QzPlCg`mlIa!a~CO0}C$e#PxH%v831V z@tI0a52sG|rWnNCe<|a5$z_s;{QBwhVqRg7gjkr=T+WV>oE)VmXcD+~FQmu}PnMfX z%{py{$J(TT=jNjX=COqHTA4pB zm5dFp_hW)`l#f{9+y7m>eD=NmZ393`|64y<4X zBM501kpWX!{v-HVGxAp%O|wz{>=P`H-Sm#vY&>$&sTK zh=ZTFBE_Fi5x?iwoT0l9BS%xYEP9)LC~Vq4oVq@KC6yf?M-6VF#kz47`7B{x8q0V{ z;TGR?W~$&dsjo%8n(+Xj;7qA~9Rh->!6v&ij;Xu{#EuMQ(sfr7(N4gDT*EujFNNGj zs_ADGN1yP$LgjRD7_>fM0ivpiOHBU`pPX&|&UC{osbSS5fl$yhxfv8uj@ojcyl^2) ziHOK8DvCo;#^EA|6I zxSf2~)n(fT*@Ms=2 z1>9d+R~Z8RWEX5g(= z8njYFQn%CdzO8nKPwPa%hAOulC$t&^C$fE1lHSB^OJgkQ!-I14gqzW?0eA`!;Qpq#UQ$&|HZ&3oe0l~iiyZ{10>Oy)xk zIp0n!MG(<&ixQJ6nzVk3JrZ`OOOsdE*E|^Vvzokz?ai7zhPMO@pw^|KBFrQGQnEa{ zA$jkba__(8O&3t)+u*hX4RHh4yPJba=1yZsiglZGB2h?)6pftwj1eEOC=m}+4$c7$6!;urgH=WgV+wM0F$e!DKZ=Rt#(j8%ubppRkQdB)lt6xrd#Gsa>E`2Ou zW*!lU4DEslp=S1MXQKSb$VimToa^a;JR5ptEP+ierG0H40lY%{?(5@8-y{~TJ0p+Z z$$P@La%`l-13kasA4#P3lHR0@S`sMx(nsvQg;rq@zkgmS_SdgRLo-ORES!%oH+|+_ z(tq;VQ8$AvB#(MArc`99r7q6;WR4bh*)>J^h_4jX)FhQCey$`ZHv7zSQ5oQ+!X*dy z@}T%zg-}Ow1KGg_TirHIq-fpP*W8_gyU7Yo2c6fCuo5$H00j9&*68giBMx_NYM<7w z(@##NDRu%pnrQ^hn8SB-h2gVLvzC}obW*9bK!1vuz*d(sucMXt1!TleR9qgSQA_erNHM$z8^9{-FjCl?n!dRhlJ zGbM#y>LJ}^qM)GQ>$h*)W21~J9aM)*JWOQVzW$`8qg!(4N$0@0pqU^*aT)o`A(O}W zQ_o8xIa@!o87te&9~R#HXP&WF4CvtPeJr_S#D{rmT; zq#906IK(yQv!p?IphA@0Sw30m0H|5zm%Vpe+}ags3QcuCvHjqPCn0YM+T4;xs-6Vb z3vPEFAENuM(tKM-_$@o%@tV}!?v%*WAGlukQ{qK6`4l#Y$<4Gi<68qZTK9<m^MX6>V4nPoNOL=510uqT5FN#+fhB*}WoZ$B#D1NB*%8}QQm&~@b@#Iai6 zfI#PqA6xQ<9!SxUPM~J)RB#mKOIA`qu6hdE2u=&fz)s9bIbWnGm1eS#{a#7U%U6vr zZgkFaBSpu9u35qs_Cbg&?6tdc2w?gniQr`{{s$MJ_g*7S9tH}cb;bJo7ux9X0fH5& z`C=kuTi4W(R0|Ry%-VM|{I(xP)%xmSWZ5ePx$7+M%k259jxV>4=70HpJSoWf>_7a_ zjHqxr2#t4in3cQE=sudT&JZvb_k#;kGz2LwYkqt1PcN1{x!-D{m3Yk>Qi3*6t&th$ z&R^IocVY%gS|U81sX4a8I2TWcnfek6M>Fh255$n$dZ7U1M7=I}4B z79RmF)&oKk)!jL@6S?n0ai8B2xyU@>G36_j@4PxL>UFqMS${=wzsBH0*K-qG@e)^p zMj1TzFZoES)=;{&x-DXHob*!@&zbmvbOpjnIvu+K;^a+TOOEBvGDatPRS}N;yTEj@p3)FU*6fWs9HlgM&CjeYTweMEn>t6OwE$a3mn^+d`+!jz zFn4nTw^f2rVqFDk!;c-|h#zgYj(j`c-V}J!!(5yfwDgv$o%Y+-W7?}no7{x9q#_Q; zv8y22P}F$hmC)btJG)x>$S-0ARKeD_C+7U6qDYGIJW#5+12rv?i5#yFjk zD$mq83@Z=BVt+uDdjyQ!tn-*r{~e0v%Ayt zJ*ShSeW~weXMWiP&r_`oPV=WO^5p9F_B@hXo%}xNmCC8^*mMc)* zw+>n3g$UglmOu9bjAu!~=9}WVs6`VSEpxv~kIax;Ol)+?{7>ZB(j`gxwlQezNY*MG z5qp^{mYK2DykGzJ#a|Y6zQ`czy;1PcgE96K2*(_pXoI#m=<^{1w9EO{3KVv=p-wXI z#0_r{xra~`2?3c}+B06?%9-;X-jU7jLtJ@i>IAuav{$m4oKr0a)t5gCqg)~%VbPyD z|Msky;&*U@HM_D|;XKE*6z6b(xe_*EK<6!Ig-Dm}dPM{$5ANsT@=?93m2$QuC7RcVvu^>ekolBei zlScsjtm5H==)ICfgM82&9`~)tD9~4DaD7wo6ZkkXY@Ob+>;Y;EAkIO5;Mx<3Riw^y z;Ne*vCyP5y|C@2UlE{RQW7^Q_id0Av;=9D_PG#*AVgh1Rsko(t!WMk?1V_Q-BKT{) zKAt4v%aA>548z#7OTeCu<@KtQrswsNUik3aap1w;9?YoZL4ZChIST)}S9#>U1m0ed z!r9v=^*?+nv$uzeUYPIAaBZQ~*NA46JQ}3L*45M`Yx(+BLs9YNP=(iJm4OYwp-?_% zJGUl7#2Plgae-%|wDv|v#3nz-N{N;`QkAGd`^vlZsu$z48pYjBeqZyY;042FG2q(- z#{Ha`XcDQIIYv*hr|1#j#y~9n*$;iK3Qh6lZ)Gak%NOZ_*MB)axi4Q2DlzVO?=C|H z1wA>M8C7|f76D|&z7lqKtGxCe?|j-R}Z10 zVOi$OX`!V=k2q$v3(#!p@a2lt!D5o3n>;;&Iu-|34Kf&VomdoM>~0+r#c3w(xk?n&n>?B+%EGcRlE0yXC$WlL)`ev`bS+zLwrz6 z7(4Z=R@d^tk)R`b4Y})A)J6=oQS!^f)IryT+!(*|jz?^1YyXs9ZoLDG zp6&7mMykm}z&+m1uMu+Mbev^wwTb=G$J3H0tj|LPY-1~r4rH_fq?JX|EaRVL%CQzX3x>9X= z7AP>r1Pb^EM8=1JGiPO258~wpk|P~80DTw@Z;?uA!HB#13OB2M&&>#8V&+u{$dz+= zS%EqPfhF500gz`Q?y@OZuLK_#t>Hec1UYIx^}Q&Wn8*}corW(#!p@Fn*$rm8qns)G zm$IG0UEyEvq$FWUPg9sSh3EKA2~(PWy)JHR13+l%!x;#nj)o~*8QrH@52E@Vg1;Ob z_F3oE1v5aY<>RSNOoJYcp=8q?MFZ6z+I;yU&=3WGfAr#)n?AjK}8PXH* zh@u@;xk?e}Z|3$x_jO!cGnO~rICD+#=S$PDkYADbGY?rrK+>xL7a#FFh7|3(I-Z!C zMEVeiskYXA<;nmFzIm4eXssOvh-^knIQ7=rojA4)>rGM@xs=l{xJ>K#Tjz0!Gl8pq zfr!f=XFnMhk=zfGE3@ce3#yY7WH8gEluzs3TXP5xNi0vmxGj8uUAhYriA56eLfW}6 zu6{Q03yIrXSfgCF5>lv>;ovi=c?~@zBSa2FA0>p1?dDT;?FR6Vo=?mY?Py1s@zt$k zMaz?FT1Wuv^GpA$NVP>9v6$1(-%cBrifUm;KjQodF5Ye`v+Ocw&jgVxsGv$oMQ+no z?IWFdw$m1xvBtt0+}kjIH-At@muQf&cA}ExSUHGToy=;+`%$fK<$&=ZHkDL@#z2TY zrTqJ(Q&6-A2l9#Y-E4Q5R=rC0qdKq>tpMimU*y0c%{2D z0YYpf7dvkhTzzi$oS2!E;r?f4f^*b58aKk;sbR~OkwzxX`2Ij2D}~;>6d9@*sX6_U zj?-2{rl%yAoAci1koAxF=g(igak12p?{jiq3vZsP^>Jm(b|`txT%*q2MIXv`D0o#MF7S{n%=%Lo zZcYgw9yhX=Z+Q>xp$A+~;DUH*Tl0e_ue{qOrwmu~!x zsxPn>5=0w`cI%aN@NS&RefXg&Q%R?~Vpwt8bjIG7gCp8gmLGc+z@S=6=ZZImN!_46 zl{<<{J7VS1;-r=5&h(n$GNZ9Xz$eI;bNx`&JA=l_eq#H3qKb`s{feNc!G^~ zPKT-U&X>YCTa6Eew`Ai}GQylZ;JKT=I^CrkMk+hL`O9gMzv#PKQ@24|+O+%*QF!P5 z@3XN_qlgUM424CN1cgQ0T5(vOMlDb>tIo2|J@Ies5Dk+K;U779<)U)`*+BQ<#~rk$ zXxsKFu?gE;yLX(2%2fT7QB1Omqr$IiKaT#ULzL*(_cKSQ)^J&<7iOgBG9?~yR{A*Z z)hTV&W+pqlc2I%F-*VWqg^go0-+XV)WQLtVE+Jj_e?nZR+yycgl~ydv_1 zMP|PqHh2-)Y13=}c}c%2M-U_+24;xcj!W<8WSY7W4-_4^pmz4oeX)|-N<`xD!DQWO zd-u5X7TeN4?6FkB%r))2k0|{w8C;x339lc8Nl!@l^_&_MA ze2*yrb?458dCh@COR-9f)<@WT zgVUKXvv|R9L_Cc=&dYDn+oOEM<^8^TaGxMtamn4#U1J~rHo3;!qALGr@ztuVF`!Mk z2T9#a^-sUIT_)s1p(_s88XGt21^vvzvLAeH`gWv~IVjq)W>xyz1_-oS*HI8sp!jP+ z`p^}RQ*z97OQFX#z=qnkf5&pg|Lk! z?PDpU9pAy?#^~KqzTE_B=9R|NlaaLJup+;GmrVHGM$yopG7yl3wm{>IYA8cpr;$9sBj8%HdYDPQUNnyFVvrFzwmIVhl@ zP zCsW^afAqV;Vq*BVR~pe>#=a-;g~~>d}`^?p;2lR(R|-%G02Z(w+6z zIXQL$PaKrw$w`Uw&7R1M`tS|ilIQC-U9DF01Bvc+?;6{0&;#?nnp7b^=vPR)UJ)|)LW5z(jL9WRyvipwv^jCPEuTn(sN6Bv8?xlRZ1V4 zJ{6^!TEv^}TL!sMU2( zY-O-JtYXYc+f?%p=OdXjf*mDBs}vTEhthUH&Ualv+bjtv`0%Pw)c zr{hzrMsCxG>cwME+6pIb5E~l zQ>k~Hg85p>^z%Gyst!_oQf8TFzn#Ov#)IC-MB;qI)_od9>qw!^{+G|e0r+^YJ481Z z+Qly!7|65!{X0Rb9AG7#uglzhK#rex$$<6W58xoz=@7N4(^N_Q*TpbzSeZ5A`{hFZ zs09E(oPBjo`N2b?*uNh)VDJv;?$-~$T@O%Y&AIy^_Ts-EprUbYE@wmWrrYm#^ZOZM zp2;MpTuqCryBZKAc>C|)X;=gRiI62=Wnv4(zT*r~xb^P`V60CoUCY2fWQBzVO{v&s z6gJi1zsoW27lXomf|yIgxBq`5=>H1$|DYECSGfNx;o5^5tjM7E@81ipxzqg)L(D`0 z(3-m%DJXasvs`O6jgVKYZ*UAUBf^TIbpl_GV$5ken5%?Ek0ss z@iF{m@qNa|0_C2BmE%wERRJ2^3}W*1gGDBE@ZIw4AO`ngmgSnIqK6>ho;Khx^DTa) zj6`bhfx*W|cVI^wZO!gu_SEj<&TS< zp{X_AYy7-l^wtHrnwOwY0uul|jLf{M0U5{4 zvLeO17-P^%*e-g(N*a3M=?a97sR4(~wJR~N&379;iO2lP)mUb-*B&`p!M8S_S^^5pm1f#Q+?0N}}MT`#` zop*wVs~b6oN5(?-YJ+ ze&-`;JlQFxGn;r6r`p7yw%>UJL@}M(7(4<&!Mb4mC-4~Q8@7W5%eEF47D(@@LsJ+K zEgiZuRa{v7y7iMM9OEGEr<%=a->^T61YDD_ltkYH8(Vk6`3EO7lNY0865rkJzA3Wg zzy@7ag9%cJ!ip4&lEHpENO84q-Pr=Z z4sa?gbActSpw_uoqWltb!zSbgrREBdx@H{jZ_NesRF2=`HmMOfw3?`KLt3kQ8w~>$ zW@nJ+UJPCNnhyVwuODpxX@t$L@p$(kpkH*7m43$uP9Oy;*uZ!gek`@!BhLa?5s;9e z2fwSdqgT+ENIx8#I&ts6r^MvzI%rm>sH9ZZAKOZOxqkZtACdQRsnYI2s>dXa-(EA5 z5Ij0a!GABckX+L-($zD{R}BxFnNVTXg}`(J{zbWV~Ft zV`EZQSUD-S#J)>CB)J;T^J(~s@r%$wo=-Gwv}^wBUvTNzoKse?b)6+qjGDwZRNvz$QylDbD zLPN^=4QrFwQ|U+|1mTu>#4F?u9hLI}QnPl2b6Qxn3L5dBuh3k9e(kFI)Bj}7zX{a8 z^gcOl;q!CWqrY|H`hL$`0%tztY80Nj=QnL3+I!ptp*WJIH*$7HZSo77xJ);~ND1{e zxu{kG#NqeOJ2{#!fOb1S$iY&*9Q*h^(0%FX|(|aTTX*PYx?_V|^>GW9B?L zXd>jh2vUh2s0!-3pEwUskI{~cOQ7zMWaz$&D#{jefM6iJAi5y-^-5~m$#ynN5|v5s zm4nvjMT1Lu`9%bvYT5$n5@&eSc!~yLiCo!I(wv>JAW`Qo^Y>~?f+H>~1tTtLhvNm$ z=KJpPP2{XpIXHI~4goKVw5Z`=F|vU%yx9SiY&(HV3!8d>H=gX{Fb$VA8qYwFyQsfM zbc?U0RCgx}JNE5tV1z`fZ1@hMamt<_A~8%ciwjJIY+?>}rS;NkU zC@8nlyQpZ(-m3#6LfDJ(&8UQ<>U>be%SiED4>gu62Qv+Z+e6}+N^gc>GPTz7S(vOECN_|MM>Ao$^cTnJfgU3~6WEEri2VH>^3tIIfg z4F~aC;T;A-LsN9k&|@>>dM`H-kfD^9SQT$H|6B?L^CDB#k@d#9^Q?68}j9#5Sz0CA@YN>+mC z?MqO!Ch#>qbz^Al^kgk~>ac$5djo~KhuB<-OOk1Hi(YBt)X8ooT?MteT-ea7Yxh1r zhi~X}vxP0ust3`U`3N=SSbY?<#8Mla**lbs9vD(8Is(=P#g<3{ku~T(%ny)m*^yQo{R}=M_+d zPl2Ob3~S+Pa;RN-vqKZE#ap-Dly$NtmjZS$NZxHPL^+DrLBOd>vlFCkh5|wH zQp3gp)6o~EKm$@8oz9Qnd20jbB-cDgI%G;qu2XTVy87;aH**lfkHbH2Dw8SXf_ohAIZMMrwS zL%j*KMjMCOgFP7+`8+%B-8vjrxAUm$z-Ld1*_k*Phb8ab=T@UN8;?(Wq*HDQ2*$;Y zv|%f5im)Zg6S0NNxTf}Y<-IOPKXTss?Y=C}ul-@5Qj6UD{Sbg;GQZ;`GhxYOYGxDn zk;g1lv@`mkaMgP)^>`EL?DzXtT}hNeV|HaFTixPZGD+(uKXD+eS2j6=E8mJp%%o*q zWd`w`UoM~N-wlz?c~%lx7m&T$wjGSVA$UEFg+& zl8S@jX*)|0j&d9&x?Jr9LK;QJQYUN3e1sX9-_+ptqVaFhel>kvx-fg=>+}ck05Qq~ zKNQ{66S0YfNJk%wVPJm<)_BCuSp!x^1X2^;!$6w|)YZa*^vn)NhiF$?(hSJM%UjJh zTrdH1gj4xoA(fs>hS~F0Ty~+1=KU!LL;q!Tt&eq<8@m?h+hEG#|hl=8*5A1wc zG`Vkx{d{(wV2GQ~CXA%mxRTdr;hvcd?cqin6BF29n2@?oq3-pq7^I!0f&Jopa#YjK zn+6`9r|Dcjjjt@eQm*}J$b2I<9J5>oWHD2b(;Rg}2@>gBWtnakFd2I%7!Lvazznh( z2*t_X()vb+?Wd^&4$`7T&!e{ubujEp@oO4!F%H$u^i=SH9^^USyb|IkL;vbSvr8 zm^DvGSP)0C?}}|1x!)!iJdb?tjTxU;Z@3&c9_VPGx(7}*Ixr+Yxe?XWU`&`gx%;V7 z)nNUS`erCQm#XU}ZSMPFEy}&Z(h3V8go-b{_l0B>?ooHMo4*^)Www78RXyy^9hI~g zCcW=*6FF8nDhB_q`%(i=MJnammvFe&OMm4SPX79)HpfBlgCw)y!d z2DN?yN4pKdWyNci585Wx6{9g{eTNItskZf!x(r-LK@;cMY_{{ib4ZjTisn>hsYA4M%HZ9l;<9crF5sG!J0F6~EhBs* z!b-r+6ZqX$Ew}f7IK-+SS$m@=Jj`Z4KI(Xt73aVC$(*bY0(nZ#RPWX5NGbDJ9q#4C zWk7*}17nFS?^m-Oe?yHQ>CbzZ>yJ{S2+NjlnaX~szor-xE%NYN0mUy!%3_#; zv8|BixjqGI6AF-mC{j%JU&r+)1uZyx_S||qR8WL5(~%o+$owbTb1R48SQhG=J{qhL z4u6S}_UDTP7{{K!N~4Aik}C~0hD*Jj7!H0KMdN>u76V13926XJF29J{#qHQ2D9R~& z24IFv+A+>-GfK=~_=X4c>AV%jS@xk|-r3@mzA5ylN7^G8kgg3=liL3k!!$)tXxMP@ zqgaTttZvnUY#E@lO0EH_;aD+>LV>{souF)qj1Ig>f z{>MvB`!fl`4%fvZvv&rvzy7>g@R#) zhGlHyuKlX2E3L)AC^{m1e#fPrvuJ^=vF{cOG(ori;8nNQXwYZoIFS^Z98{b~=hwRn zanOVvD9B8*tgTl^`FRS{;+_#SOuTs@2?So;6aNgn%qPicYEY^Ri>-e?UnW%yI<{uX zz1gdXQxm%$5fSl-y)S}~K9tGH6AETbhf0)&%mFR4<KqilV3p zemU;$j$$Y|Dsec1=vKq60a}_w@OoOZ*l#DlSxtQ9^~9u?nAVX|iVOFxFnw+fTC+Ox z#z8MFjio(^!mKAx9c69I%t_3N5;YsV-3CTGBR9krZ2V8`2L&n&=COKykx2hx_7nK*o}N- z>#O^1VY^@5G09&dl?&bn*4^^~(Ycg<7%x?0%M}r7jD#=WKBK^-9?wKEfu340RYY1( ziA9xa!Cal;*8l6d5;U|b?U{qDv_mL+-+k9!1tgS)^kRiaQ4rp3rT+MpZZj@!^txrD zO_PEG54j|{x^h^MCQ7~4T5`ea;|ct5d`>7Vj;)4|>i9k|7pi;+DB?qA1DYhLQUTlQ zqPI<6oZjz0?Xr=XF)wgJ>)+S^EuO1PJI4GRLT3mN19D=iy`RgUZXsH*-ovf{V{T*B z#l|TUhGS3~lULFHwaic+fICKKOTp4?9EnFfO}J48mUr zfun&}Ku&D~wO<*ak7VA}Vsa6zn^CJpp@R@qy=%nz#h_gr4RGh?4zKf>QqLD*0${fZ zVrpvD7_31#1DRqZ#+0T*KC#4#<;HYNP+4dY{|0uFLCh<&4S{q6SfA0wzEK%&qp+5H z8#dW*KQMH|#Iz+ITYt3u@*D>lBTsBi>ry8jb=W3-;v5pB5@)h8kVRcTuP_p-u5BWH zyrA9;Ia~|&rBxho9g6TLoB65cd9bElO(ll-RGrsmrF-)j*PA7$Vhd)Z!F?qxn>pT- zx5$m&N@~r0&@LS-bJ&r7DbWgEt*L3`!vn{z0ESf{6+51qx#h|yuqXO(#9ArN#CZxr zr7pG4PtSBmmI4#gx!{cZmK@T!au7<0aiLhDgcOYVcLkfoq_xO8#J$RdyfBDyLh(B{ z-=7rVgm9YqhAEVLV$A^&H{WZ2=ALTUAWA6r9$Hb~`5Nmqhd+WsiMFo>xd!=?PKa|lRN*GVdvZ%oLNaH<*3OQ5-0yJ3P;)?@L~>x; zfLme|L|~A zf42z%jp0MBy6Ka!!|hf&$MGkr)A-uJLR-OruPuobtE}}~y$V419M&;6CIqp)b(a0V^eQ)b>0R$|$eQ~q>FF8i?inUN zyiw9r^x*&QvzHD-QPIS`zDJ=-agoygyfrOW=I?bhzi3gu2!)6Gwvfk~o2^9gJKF9n z{$N@C4r_69n0u6`7G+|LS*;JU&Wu!|(Y0et@I)FS&u?bhMSsyBulosHIMcdVDA?#I zKlxA^1COa-L2pLwd6K3rUwvzM!mgpP*Rzza;I z0m&(o^hLq0(pFZtRtqz^0kRaNIz-cXNtiVT4t#=vtG0KA4f_~qp#g-HhUd)of^%6a zLT*^J#^gNwWawddsK7|9TZCP>ck*)_J`rfZAW)1>jV)lZ`nAhD&dr;W2o|I&`YfKf&bvD@_8fav!>G z5%b#R@#6=U7|~TctFy4V>hZ_zSsFobB4CN5%wPY?ew#1H=6nYabl}mE{xW3D1tck;DJN3DeN)8#k6M6pS|rqkHu}%=@}9!a zVC2t>d9j?`g1N%B?BAt>r$Y(Bh%bN<8}F#U2@a@Q5XJz4yu4SbQU9{MhM=lU^uN}~ z?}IX-#OPH`4F&B#Y9O$)Kqz&ty%vPz$R|*Ljs|n5GWr;BIxvw>X71#@xm#II?aq(8sM4CU>o zv(%Wq1JPgPfsud-#*u1{@o;sP6~F{y{&IB{V`w1_ud?Gj z%kok_la%}W7kJw$5Xh0-o$M`}=_UK?Z-BftWHG~z#L6VttM|LD@x#{n7{gfpa@^xH z3vuh?>REpK&%5&CfmE=KZEb#sa{-g9`pY`wz^I9h**Ptm9hw?_4MF+!ntz^P^vn{B zUUB;!vHx{fH{>xaGGsG~#)x|Y<1GDUNcNbSqy;lch3=eW%}Fx!um9)Li6g|Imis@? z+=IZJnQ=49&s5XmpNkpF(%3*Y{obE8{ZE1Ze^QeKMEu`6Bxrg3pD6hHuW|2?|VTGrj-Rp==Wdz(vRVRtM=Io5kcUhaw$(#nas{Ljw0=}IDGG(IUodf>hitSHfWH^&Uk;Q*<<-oJueqmBgLnBf5D#!$bF)psUZd4J281nJ_eX_Uv zWvglORh8eMYga^@!!We=bRpBI){j!1U zXO4PNaYPg$azzv^qa3lEUns`RH%{E}pxfGmI`79jAvL~@54T(mF3KpyFPWF$+ z(;&)`4oA^W$NsA#KK{m~+V)7&_T!T$AM}9k5lV73XW4HNkLN+SGfe=_COR9vvXp4XWv+Xad1|*+B9i|v_b3ozo@VsM77X>mJ>U*h^aGov9D;E}V}69{u$~|H^njd9lzynUYQvI64+QiCRX1$MRad{Y z%8h8)btb31X5uOpz=5y^wLik-0~{dVhmmTLZ!4Sr8Rd;DIkAAHuSv^XUqbqzm& zCqiw@`n=9)1-TS}n*r~I5|+BcD{YFonT?ww_W8+n(^rT3%Wb=~U?o;295WWiZ7X|#Kmm12@VD2TJTAYa zJ8rg((GUF~v%Lj#nAKM+8nvW1*r4SvxmSKr0c%!ihUh*J&~sRY@a<)d4{Jxse!Db3 zNp@mge7N46cNdhsY^-i&Iq||br?_$y=p{Dpqk8y$QXi1Vgmp!9R3RFxh;!~q zFF>Cm-VRe#Wc12z`24{eF4*?ucE?K4eL2tRX7-)IMM-q_laYJ~MKKmL{WXl-FxF}HEXUTIaTgkF4ZK zTeUTBpDM+MshNiG8RkGR~W0JC*Ds zKt~n7c#=6zIU;mcr;M(_gQ5DkOW%moyT{ppP7$4qM?4Z1m4z&> zuCqqy&rT)uRdU5(e<1@iN`$Q=PA_VtDPBhAp@Ej)DjJ;?~0uitI7=#9es;2L)HzSRlN@x~!W&4y~W({53_ zeQxHq1pm?ScsFEkC!=^S_XMym!oiV}#WSHfJ}pA>rNVN-bBt^vt3mZ-d#}4Xtn$z= zyOmAJ6QlB^Vio&jmr4170Gu~q4Ja$nTh$uw!Z{qegSnc66*)S(ASr8DQtW-!rl2&P zx(~#|O`L3OV5=BVf@(^K#?iBfQtCZ;TzLS`eGd&9!w($pgIeCRPt18BdmS$rnqP7+g=`wrasfZ_WTS`-i%@wtVf8a18UFD+9+|HGzIOBx zWL(|pr13dedhdb_Z@uknO=|!vXxq*4Bdz{%CMUQOe<9ZMcfq*5B+puHw)uS5Qh_y5*K^wFo=~62^Q#|) zSp7}|hFQ8XeNdRAJVi2H$y5?~Rz$LJo`Mb8>9oax1Er%4DfT@3#OSGA6+)6`mrJQJ z?4wEjWFX@(r~?(a0G%C}Xr>Syf8 z&h0(tNf)zD{3uzUWq)e-!CkxctB#-;(-_OCTndc8c^fL z3$h#xl^BiAr7K)aPt&qr3QhgJcfzBD+Fq@c1(uyXTsk-r38-|0@?*h|;GsdB z0d_>Xc~Z)`$FFz(L!}XB|Z07yfU%9P}c7KWR;ld9btQYde zE7AO8Y#C&B8Pb=jgp}Nzc$eZ3l39duP}whZL)t5Y2``KH>Zs^!9uh8*9WS#$3`WKP z`%;x-dl#>ovuF(uw||3m^up(C9@ z>7INQ7H!mS3US8qG_2-HmD4+Q+8C=b?CJofGD_d;n4WOQ+Jn?;gyOzxB@fA7#AG!b z+<-vVw^#f4ZDl5p0V*|zibG2p7p31akdKoADpd<4YBud>nRfh95)l-q?un&ivSmF^?0YMDocW|DQsVe zpPT2tqK$A;h|@w8p=Z_65t*#5<)ILqasR8ol9?xa>SuO$8@ET6PTKdHpgD!-c#<46b0s(n`saAvLaS><0lgT6~mALi7u+E#3! zC$^Hsiz`qMW5-21wf<2{EGYM+z8YZh+hr175e1YMBaY?#ZlcMfDO aC(TwE}*?| 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

  • fcKQ??62wuwS11~Z*$kQS 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ßykzP0P(;`PdE13?*zl}cZ9yRW){h?$lc8~Dp z+8b$$G0}!)uyTy?>9Bo4${luAKhxnzS3I5U2|BROdc=G$*uIuz5jDHimzG^TDI-6~YL;5*Ec(E-rImZKLu}`MM#w!6XwpfBLA<%k<5k){gT_!q! zO3SJ);iTfilqMU=Ztz%s$r?N;dxsv->kdfn4eMWt>B}n8^elIRU04y^z;BS`A%QV` z%h&{Yh3bg=q~PN46#F8l*vhwG3>updRoyBvpA>p!6)n3%mLCrC+QbS{DF7Q7ABk4) z%!K9<@Z=d z=yho-L8(~AJXu_OxEL;*o0zL+N0P2*U!YRzr@?pVQq+su@wUGFLw6-VqD44cyrz_M zP>nQ`Rj%>GwNkBI#kGY-mmWw2r9G-embI#U0)J)XMC)O>^QS^5x0vWMWm8oO1(x(` z$y3qHb#vp1t^{RSxYLT0<)PmEM5@B-D2w^Y7iFmvgOQR=dzBYX;Rp7o1;2EaaMcoiCU`lE$Nk1QB5l0NO`*YHP#j5I ztQ>?ltj9v;$Rj^5;^}o9l04mayYc;sdoo=Fg;Ii=!eGateChY9a)BUlQ{FW1vS~ljEZ z?}(*c$xDjxI00$A6ndrhVBq)Ub6$P0}69}mhTvNFj# zk%D%z0+hWP$D_HUaAHjAuYfjj+t`nXh({$bbsu{O)WlXSsmhSu}FvW`I7zMkzBSz#H6UK7m*DcrNY7XzV?qRtQED1{ba5!*}yI; zjaJLdbOgWRUHs_Vat!CQ_BTYTv-wueT#>`mjzBmT(bt;Jh|)D2=*HPsygMYL=#;7y zbuL+L=oZ`42>gC`Szf7gbEy|%(%P2sZW^Ct*fSx(y5~M`vh2BhuF#Owl4@mSJV