Skip to content

Commit b247840

Browse files
author
Matias Melograno
committed
added metadata into streaming client
1 parent 7850aa6 commit b247840

File tree

15 files changed

+128
-39
lines changed

15 files changed

+128
-39
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
- BREAKING CHANGE: Deprecated Python2 support.
55
- Removed six, future and futures libs for compatibility between Python2 and Python3.
66
- Updated strings encoding to utf-8 by default for Redis.
7+
- BREAKING CHANGE: Deprecated `redisCharset` config.
8+
- Added SDK Metadata headers to streaming client.
79

810
8.4.1 (Apr 16, 2021)
911
- Bumped mmh3cffi dependency which now requires c99 flag to build.

splitio/api/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,29 @@ def status_code(self):
1515
return self._status_code
1616

1717

18-
def headers_from_metadata(sdk_metadata):
18+
def headers_from_metadata(sdk_metadata, client_key=None):
1919
"""
2020
Generate a dict with headers required by data-recording API endpoints.
2121
2222
:param sdk_metadata: SDK Metadata object, generated at sdk initialization time.
2323
:type sdk_metadata: splitio.client.util.SdkMetadata
2424
25+
:param client_key: client key.
26+
:type client_key: str
27+
2528
:return: A dictionary with headers.
2629
:rtype: dict
2730
"""
28-
return {
31+
32+
metadata = {
2933
'SplitSDKVersion': sdk_metadata.sdk_version,
3034
'SplitSDKMachineIP': sdk_metadata.instance_ip,
3135
'SplitSDKMachineName': sdk_metadata.instance_name
3236
} if sdk_metadata.instance_ip != 'NA' and sdk_metadata.instance_ip != 'unknown' else {
3337
'SplitSDKVersion': sdk_metadata.sdk_version,
3438
}
39+
40+
if client_key is not None:
41+
metadata['SplitSDKClientKey'] = client_key
42+
43+
return metadata

splitio/client/config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
'redisUnixSocketPath': None,
4040
'redisEncoding': 'utf-8',
4141
'redisEncodingErrors': 'strict',
42-
'redisCharset': 'utf-8',
4342
'redisErrors': None,
4443
'redisDecodeResponses': True,
4544
'redisRetryOnTimeout': False,

splitio/client/factory.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
362362

363363
sdk_ready_flag = threading.Event() if not preforked_initialization else None
364364
manager = Manager(sdk_ready_flag, synchronizer, apis['auth'], cfg['streamingEnabled'],
365-
streaming_api_base_url)
365+
sdk_metadata, streaming_api_base_url, api_key[-4:])
366366

367367
storages['events'].set_queue_full_hook(tasks.events_task.flush)
368368
storages['impressions'].set_queue_full_hook(tasks.impressions_task.flush)
@@ -439,9 +439,10 @@ def _build_localhost_factory(cfg):
439439
), None, None, None, None, None,
440440
)
441441

442+
sdk_metadata = util.get_metadata(cfg)
442443
ready_event = threading.Event()
443444
synchronizer = LocalhostSynchronizer(synchronizers, tasks)
444-
manager = Manager(ready_event, synchronizer, None, False)
445+
manager = Manager(ready_event, synchronizer, None, False, sdk_metadata)
445446
manager.start()
446447
recorder = StandardRecorder(
447448
ImpressionsManager(cfg['impressionsMode'], True, None),

splitio/push/manager.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
class PushManager(object): # pylint:disable=too-many-instance-attributes
2121
"""Push notifications susbsytem manager."""
2222

23-
def __init__(self, auth_api, synchronizer, feedback_loop, sse_url=None):
23+
def __init__(self, auth_api, synchronizer, feedback_loop, sdk_metadata, sse_url=None, client_key=None):
2424
"""
2525
Class constructor.
2626
@@ -33,8 +33,14 @@ def __init__(self, auth_api, synchronizer, feedback_loop, sse_url=None):
3333
:param feedback_loop: queue where push status updates are published.
3434
:type feedback_loop: queue.Queue
3535
36+
:param sdk_metadata: SDK version & machine name & IP.
37+
:type sdk_metadata: splitio.client.util.SdkMetadata
38+
3639
:param sse_url: streaming base url.
3740
:type sse_url: str
41+
42+
:param client_key: client key.
43+
:type client_key: str
3844
"""
3945
self._auth_api = auth_api
4046
self._feedback_loop = feedback_loop
@@ -52,8 +58,8 @@ def __init__(self, auth_api, synchronizer, feedback_loop, sse_url=None):
5258
}
5359

5460
kwargs = {} if sse_url is None else {'base_url': sse_url}
55-
self._sse_client = SplitSSEClient(self._event_handler, self._handle_connection_ready,
56-
self._handle_connection_end, **kwargs)
61+
self._sse_client = SplitSSEClient(self._event_handler, sdk_metadata, self._handle_connection_ready,
62+
self._handle_connection_end, client_key, **kwargs)
5763
self._running = False
5864
self._next_refresh = Timer(0, lambda: 0)
5965

splitio/push/splitsse.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from enum import Enum
55
from splitio.push.sse import SSEClient, SSE_EVENT_ERROR
66
from splitio.util.threadutil import EventGroup
7+
from splitio.api import headers_from_metadata
78

89

910
_LOGGER = logging.getLogger(__name__)
@@ -20,14 +21,18 @@ class _Status(Enum):
2021
ERRORED = 2
2122
CONNECTED = 3
2223

23-
def __init__(self, event_callback, first_event_callback=None,
24-
connection_closed_callback=None, base_url='https://streaming.split.io'):
24+
def __init__(self, event_callback, sdk_metadata, first_event_callback=None,
25+
connection_closed_callback=None, client_key=None,
26+
base_url='https://streaming.split.io'):
2527
"""
2628
Construct a split sse client.
2729
2830
:param callback: fuction to call when an event is received.
2931
:type callback: callable
3032
33+
:param sdk_metadata: SDK version & machine name & IP.
34+
:type sdk_metadata: splitio.client.util.SdkMetadata
35+
3136
:param first_event_callback: function to call when the first event is received.
3237
:type first_event_callback: callable
3338
@@ -36,6 +41,9 @@ def __init__(self, event_callback, first_event_callback=None,
3641
3742
:param base_url: scheme + :// + host
3843
:type base_url: str
44+
45+
:param client_key: client key.
46+
:type client_key: str
3947
"""
4048
self._client = SSEClient(self._raw_event_handler)
4149
self._callback = event_callback
@@ -45,6 +53,7 @@ def __init__(self, event_callback, first_event_callback=None,
4553
self._status = SplitSSEClient._Status.IDLE
4654
self._sse_first_event = None
4755
self._sse_connection_closed = None
56+
self._metadata = headers_from_metadata(sdk_metadata, client_key)
4857

4958
def _raw_event_handler(self, event):
5059
"""
@@ -117,7 +126,8 @@ def start(self, token):
117126
def connect(url):
118127
"""Connect to sse in a blocking manner."""
119128
try:
120-
self._client.start(url, timeout=self.KEEPALIVE_TIMEOUT)
129+
self._client.start(url, timeout=self.KEEPALIVE_TIMEOUT,
130+
extra_headers=self._metadata)
121131
finally:
122132
self._status = SplitSSEClient._Status.IDLE
123133
self._sse_connection_closed.set()

splitio/storage/adapters/redis.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,6 @@ def _build_default_client(config): # pylint: disable=too-many-locals
353353
unix_socket_path = config.get('redisUnixSocketPath', None)
354354
encoding = config.get('redisEncoding', 'utf-8')
355355
encoding_errors = config.get('redisEncodingErrors', 'strict')
356-
charset = config.get('redisCharset', 'utf-8')
357356
errors = config.get('redisErrors', None)
358357
decode_responses = config.get('redisDecodeResponses', True)
359358
retry_on_timeout = config.get('redisRetryOnTimeout', False)
@@ -378,7 +377,6 @@ def _build_default_client(config): # pylint: disable=too-many-locals
378377
unix_socket_path=unix_socket_path,
379378
encoding=encoding,
380379
encoding_errors=encoding_errors,
381-
charset=charset,
382380
errors=errors,
383381
decode_responses=decode_responses,
384382
retry_on_timeout=retry_on_timeout,

splitio/sync/manager.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Manager(object): # pylint:disable=too-many-instance-attributes
1616

1717
_CENTINEL_EVENT = object()
1818

19-
def __init__(self, ready_flag, synchronizer, auth_api, streaming_enabled, sse_url=None): # pylint:disable=too-many-arguments
19+
def __init__(self, ready_flag, synchronizer, auth_api, streaming_enabled, sdk_metadata, sse_url=None, client_key=None): # pylint:disable=too-many-arguments
2020
"""
2121
Construct Manager.
2222
@@ -29,8 +29,17 @@ def __init__(self, ready_flag, synchronizer, auth_api, streaming_enabled, sse_ur
2929
:param auth_api: Authentication api client
3030
:type auth_api: splitio.api.auth.AuthAPI
3131
32+
:param sdk_metadata: SDK version & machine name & IP.
33+
:type sdk_metadata: splitio.client.util.SdkMetadata
34+
3235
:param streaming_enabled: whether to use streaming or not
3336
:type streaming_enabled: bool
37+
38+
:param sse_url: streaming base url.
39+
:type sse_url: str
40+
41+
:param client_key: client key.
42+
:type client_key: str
3443
"""
3544
self._streaming_enabled = streaming_enabled
3645
self._ready_flag = ready_flag
@@ -39,7 +48,7 @@ def __init__(self, ready_flag, synchronizer, auth_api, streaming_enabled, sse_ur
3948
self._push_status_handler_active = True
4049
self._backoff = Backoff()
4150
self._queue = Queue()
42-
self._push = PushManager(auth_api, synchronizer, self._queue, sse_url)
51+
self._push = PushManager(auth_api, synchronizer, self._queue, sdk_metadata, sse_url, client_key)
4352
self._push_status_handler = Thread(target=self._streaming_feedback_handler,
4453
name='PushStatusHandler')
4554
self._push_status_handler.setDaemon(True)

splitio/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '9.0.0-all'
1+
__version__ = '9.0.0-rc1'

tests/api/test_util.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Split API tests module."""
2+
3+
import pytest
4+
5+
from splitio.api import headers_from_metadata
6+
7+
from splitio.client.util import SdkMetadata
8+
9+
10+
class UtilTests(object):
11+
"""Util test cases."""
12+
13+
def test_headers_from_metadata(self, mocker):
14+
"""Test headers from metadata call."""
15+
metadata = headers_from_metadata(SdkMetadata('1.0', 'some', '1.2.3.4'))
16+
assert metadata['SplitSDKVersion'] == '1.0'
17+
assert metadata['SplitSDKMachineIP'] == '1.2.3.4'
18+
assert metadata['SplitSDKMachineName'] == 'some'
19+
assert 'SplitSDKClientKey' not in metadata
20+
21+
metadata = headers_from_metadata(SdkMetadata('1.0', 'some', '1.2.3.4'), 'abcd')
22+
assert metadata['SplitSDKVersion'] == '1.0'
23+
assert metadata['SplitSDKMachineIP'] == '1.2.3.4'
24+
assert metadata['SplitSDKMachineName'] == 'some'
25+
assert metadata['SplitSDKClientKey'] == 'abcd'
26+
27+
metadata = headers_from_metadata(SdkMetadata('1.0', 'some', 'NA'))
28+
assert metadata['SplitSDKVersion'] == '1.0'
29+
assert 'SplitSDKMachineIP' not in metadata
30+
assert 'SplitSDKMachineName' not in metadata
31+
assert 'SplitSDKClientKey' not in metadata
32+
33+
metadata = headers_from_metadata(SdkMetadata('1.0', 'some', 'unknown'))
34+
assert metadata['SplitSDKVersion'] == '1.0'
35+
assert 'SplitSDKMachineIP' not in metadata
36+
assert 'SplitSDKMachineName' not in metadata
37+
assert 'SplitSDKClientKey' not in metadata
38+
39+

0 commit comments

Comments
 (0)