SIENTIAPDE-1312

Update image tag in values.yaml and refactor OpcManager error handling

- Updated the image tag in values.yaml from "0.4.5" to "0.4.9" for the latest version.
- Refactored error handling in OpcManager to improve logging and maintain code clarity.
- Adjusted unit tests for better readability and consistency in assertions.
This commit is contained in:
vitor-aignosi
2025-10-21 17:03:58 -03:00
parent 3eacf27faf
commit 95c9ad85f9
3 changed files with 26 additions and 20 deletions

View File

@@ -1,7 +1,7 @@
import asyncio import asyncio
import json import json
from pathlib import Path
import traceback import traceback
from pathlib import Path
from asyncua import Client from asyncua import Client
from asyncua.crypto.security_policies import SecurityPolicyBasic256 from asyncua.crypto.security_policies import SecurityPolicyBasic256
@@ -86,7 +86,6 @@ class OpcManager(BaseActivity):
self.data_manager = data_manager self.data_manager = data_manager
self.metadata = metadata self.metadata = metadata
BaseActivity.__init__( BaseActivity.__init__(
self, logger=logger, notification_handler=notification_handler, set_error_counter=True self, logger=logger, notification_handler=notification_handler, set_error_counter=True
) )
@@ -209,7 +208,7 @@ class OpcManager(BaseActivity):
pod_id=self.pod_id, server_name=self.name, server_url=self.url pod_id=self.pod_id, server_name=self.name, server_url=self.url
).set(1) ).set(1)
self.logger.info(f'Connection to {self.name} successful.') self.logger.info(f'Connection to {self.name} successful.')
except Exception as e: except Exception:
await self.disconnect() await self.disconnect()
raise raise
@@ -239,7 +238,8 @@ class OpcManager(BaseActivity):
raise ValueError('Client not connected. Call connect first.') raise ValueError('Client not connected. Call connect first.')
try: try:
self.subscriptions[name] = await self.client.create_subscription( self.subscriptions[name] = await self.client.create_subscription(
self.subscription_period_ms, self) self.subscription_period_ms, self
)
self.logger.info(f'Subscription {name} created on {self.name}.') self.logger.info(f'Subscription {name} created on {self.name}.')
metrics.OPC_SUBSCRIPTIONS_CREATED.labels( metrics.OPC_SUBSCRIPTIONS_CREATED.labels(
pod_id=self.pod_id, server_name=self.name, slot_name=name pod_id=self.pod_id, server_name=self.name, slot_name=name
@@ -336,12 +336,16 @@ class OpcManager(BaseActivity):
await self.client.disconnect() await self.client.disconnect()
return [] return []
except Exception as e: except Exception as e:
self.logger.error(f'Failed to disconnect from OPC UA serve in attempt {i+1} of 5: {e}') self.logger.error(
error_stack.append({ f'Failed to disconnect from OPC UA serve in attempt {i + 1} of 5: {e}'
)
error_stack.append(
{
'attempt': i + 1, 'attempt': i + 1,
'error': str(e), 'error': str(e),
'traceback': traceback.format_exc(), 'traceback': traceback.format_exc(),
}) }
)
await asyncio.sleep(0.1 * i) await asyncio.sleep(0.1 * i)
return error_stack return error_stack
@@ -375,7 +379,6 @@ class OpcManager(BaseActivity):
except Exception as sub_error: except Exception as sub_error:
self.logger.error(f'Failed to clean up subscription: {sub_error}') self.logger.error(f'Failed to clean up subscription: {sub_error}')
errors = await self.disconnection_fallback() errors = await self.disconnection_fallback()
if errors: if errors:

View File

@@ -194,6 +194,7 @@ async def test_connect_exception_handling_and_metrics(
opc_manager_instance.disconnect.assert_called_once() opc_manager_instance.disconnect.assert_called_once()
@mark.asyncio @mark.asyncio
async def test_create_subscription_no_client(raw_opc_manager): async def test_create_subscription_no_client(raw_opc_manager):
try: try:
@@ -209,7 +210,8 @@ async def test_create_subscription_success_has_period(opc_manager):
await opc_manager.create_subscription('sub1') await opc_manager.create_subscription('sub1')
opc_manager.client.create_subscription.assert_called_once_with( opc_manager.client.create_subscription.assert_called_once_with(
opc_manager.subscription_period_ms, opc_manager) opc_manager.subscription_period_ms, opc_manager
)
assert opc_manager.subscriptions['sub1'] is not None assert opc_manager.subscriptions['sub1'] is not None
@@ -218,7 +220,8 @@ async def test_create_subscription_success_no_period(opc_manager):
await opc_manager.create_subscription('sub1') await opc_manager.create_subscription('sub1')
opc_manager.client.create_subscription.assert_called_once_with( opc_manager.client.create_subscription.assert_called_once_with(
opc_manager.subscription_period_ms, opc_manager) opc_manager.subscription_period_ms, opc_manager
)
assert opc_manager.subscriptions['sub1'] is not None assert opc_manager.subscriptions['sub1'] is not None
@@ -302,7 +305,6 @@ async def test_unsubscribe_success(opc_manager_subscribed):
assert opc_manager_subscribed.subscriptions.get('sub1') is None assert opc_manager_subscribed.subscriptions.get('sub1') is None
@mark.asyncio @mark.asyncio
async def test_disconnection_fallback_success(opc_manager): async def test_disconnection_fallback_success(opc_manager):
opc_manager.client = AsyncMock() opc_manager.client = AsyncMock()
@@ -310,6 +312,7 @@ async def test_disconnection_fallback_success(opc_manager):
result = await opc_manager.disconnection_fallback() result = await opc_manager.disconnection_fallback()
assert result == [] assert result == []
@mark.asyncio @mark.asyncio
async def test_disconnection_fallback_fail(opc_manager): async def test_disconnection_fallback_fail(opc_manager):
opc_manager.client = AsyncMock() opc_manager.client = AsyncMock()
@@ -320,7 +323,8 @@ async def test_disconnection_fallback_fail(opc_manager):
{'attempt': 2, 'error': 'Test error', 'traceback': ANY}, {'attempt': 2, 'error': 'Test error', 'traceback': ANY},
{'attempt': 3, 'error': 'Test error', 'traceback': ANY}, {'attempt': 3, 'error': 'Test error', 'traceback': ANY},
{'attempt': 4, 'error': 'Test error', 'traceback': ANY}, {'attempt': 4, 'error': 'Test error', 'traceback': ANY},
{'attempt': 5, 'error': 'Test error', 'traceback': ANY}, ] {'attempt': 5, 'error': 'Test error', 'traceback': ANY},
]
assert opc_manager.client.disconnect.call_count == 5 assert opc_manager.client.disconnect.call_count == 5
@@ -373,7 +377,6 @@ async def test_disconnect_error(opc_manager_subscribed):
opc_manager_subscribed.client = None opc_manager_subscribed.client = None
@patch('ingestor.managers.opc_manager.metrics') @patch('ingestor.managers.opc_manager.metrics')
@mark.asyncio @mark.asyncio
async def test_disconnect_metrics_on_successful_path(mock_metrics_module, raw_opc_manager): async def test_disconnect_metrics_on_successful_path(mock_metrics_module, raw_opc_manager):

View File

@@ -11,7 +11,7 @@ image:
# This sets the pull policy for images. # This sets the pull policy for images.
pullPolicy: Always pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion. # Overrides the image tag whose default is the chart appVersion.
tag: "0.4.5" tag: "0.4.9"
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: imagePullSecrets: