Skip to content

Commit 569df34

Browse files
support S2S
1 parent 7f4a155 commit 569df34

3 files changed

Lines changed: 83 additions & 1 deletion

File tree

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def _configure_internal(
117117
exporter = Agent365Exporter(
118118
token_resolver=token_resolver,
119119
cluster_category=cluster_category,
120+
use_s2s_endpoint=kwargs.pop("use_s2s_endpoint", False),
120121
**kwargs,
121122
)
122123
else:

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def __init__(
4444
self,
4545
token_resolver: Callable[[str, str], str | None],
4646
cluster_category: str = "prod",
47+
use_s2s_endpoint: bool = False,
4748
**kwargs: Any,
4849
):
4950
if token_resolver is None:
@@ -53,6 +54,7 @@ def __init__(
5354
self._lock = threading.Lock()
5455
self._token_resolver = token_resolver
5556
self._cluster_category = cluster_category
57+
self.use_s2s_endpoint = use_s2s_endpoint
5658

5759
# ------------- SpanExporter API -----------------
5860

@@ -74,7 +76,12 @@ def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
7476
# Resolve endpoint + token
7577
discovery = PowerPlatformApiDiscovery(self._cluster_category)
7678
endpoint = discovery.get_tenant_island_cluster_endpoint(tenant_id)
77-
url = f"https://{endpoint}/maven/agent365/agents/{agent_id}/traces?api-version=1"
79+
endpoint_path = (
80+
f"/maven/agent365/service/agents/{agent_id}/traces"
81+
if self.use_s2s_endpoint
82+
else f"/maven/agent365/agents/{agent_id}/traces"
83+
)
84+
url = f"https://{endpoint}{endpoint_path}?api-version=1"
7885

7986
headers = {"content-type": "application/json"}
8087
try:

tests/test_agent365_exporter.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,80 @@ def test_partitioning_by_scope(self):
213213
expected_scopes = [("scope.a", 2), ("scope.b", 1), ("scope.c", 1)]
214214
self.assertEqual(scope_data, expected_scopes)
215215

216+
def test_s2s_endpoint_path_when_enabled(self):
217+
"""Test 4: Test that S2S endpoint path is used when use_s2s_endpoint is True."""
218+
# Arrange - Create exporter with S2S endpoint enabled
219+
s2s_exporter = Agent365Exporter(
220+
token_resolver=self.mock_token_resolver, cluster_category="test", use_s2s_endpoint=True
221+
)
222+
223+
spans = [self._create_mock_span("s2s_span")]
224+
225+
# Mock the PowerPlatformApiDiscovery class
226+
with patch(
227+
"microsoft_agents_a365.observability.core.exporters.agent365_exporter.PowerPlatformApiDiscovery"
228+
) as mock_discovery_class:
229+
mock_discovery = Mock()
230+
mock_discovery.get_tenant_island_cluster_endpoint.return_value = "test-endpoint.com"
231+
mock_discovery_class.return_value = mock_discovery
232+
233+
# Mock the _post_with_retries method
234+
with patch.object(s2s_exporter, "_post_with_retries", return_value=True) as mock_post:
235+
# Act
236+
result = s2s_exporter.export(spans)
237+
238+
# Assert
239+
self.assertEqual(result, SpanExportResult.SUCCESS)
240+
mock_post.assert_called_once()
241+
242+
# Verify the call arguments - should use S2S path
243+
args, kwargs = mock_post.call_args
244+
url, body, headers = args
245+
246+
self.assertIn("test-endpoint.com", url)
247+
self.assertIn("/maven/agent365/service/agents/test-agent-456/traces", url)
248+
self.assertNotIn("/maven/agent365/agents/test-agent-456/traces", url)
249+
self.assertEqual(headers["authorization"], "Bearer test_token_123")
250+
self.assertEqual(headers["content-type"], "application/json")
251+
252+
def test_default_endpoint_path_when_s2s_disabled(self):
253+
"""Test 5: Test that default endpoint path is used when use_s2s_endpoint is False."""
254+
# Arrange - Create exporter with S2S endpoint disabled (default behavior)
255+
default_exporter = Agent365Exporter(
256+
token_resolver=self.mock_token_resolver, cluster_category="test", use_s2s_endpoint=False
257+
)
258+
259+
spans = [self._create_mock_span("default_span")]
260+
261+
# Mock the PowerPlatformApiDiscovery class
262+
with patch(
263+
"microsoft_agents_a365.observability.core.exporters.agent365_exporter.PowerPlatformApiDiscovery"
264+
) as mock_discovery_class:
265+
mock_discovery = Mock()
266+
mock_discovery.get_tenant_island_cluster_endpoint.return_value = "test-endpoint.com"
267+
mock_discovery_class.return_value = mock_discovery
268+
269+
# Mock the _post_with_retries method
270+
with patch.object(
271+
default_exporter, "_post_with_retries", return_value=True
272+
) as mock_post:
273+
# Act
274+
result = default_exporter.export(spans)
275+
276+
# Assert
277+
self.assertEqual(result, SpanExportResult.SUCCESS)
278+
mock_post.assert_called_once()
279+
280+
# Verify the call arguments - should use default path
281+
args, kwargs = mock_post.call_args
282+
url, body, headers = args
283+
284+
self.assertIn("test-endpoint.com", url)
285+
self.assertIn("/maven/agent365/agents/test-agent-456/traces", url)
286+
self.assertNotIn("/maven/agent365/service/agents/test-agent-456/traces", url)
287+
self.assertEqual(headers["authorization"], "Bearer test_token_123")
288+
self.assertEqual(headers["content-type"], "application/json")
289+
216290

217291
if __name__ == "__main__":
218292
unittest.main()

0 commit comments

Comments
 (0)