Skip to content

Commit f516820

Browse files
committed
WIP working example child class multitenant controller
1 parent 326ac0c commit f516820

File tree

7 files changed

+839
-197
lines changed

7 files changed

+839
-197
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.idea/
2+
.venv
23
.code
34
dist
45
*.egg-info
@@ -14,4 +15,4 @@ libs/om-aries-controller/demo/bob/image_received.png
1415
# exception to the rule
1516
!libs/om-aries-controller/demo/bob/received_files/.gitkeep
1617

17-
**/*.pt
18+
**/*.pt

libs/aries-basic-controller/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ dist
44
*.egg-info
55
build
66
.env
7-
.ipynb_checkpoints/
7+
.ipynb_checkpoints/
8+
.venv
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
from aiohttp import (
2+
web,
3+
ClientSession,
4+
ClientRequest,
5+
)
6+
from dataclasses import dataclass
7+
from pubsub import pub
8+
import sys
9+
10+
from .controllers.connections import ConnectionsController
11+
from .controllers.messaging import MessagingController
12+
from .controllers.mediation import MediationController
13+
from .controllers.schema import SchemaController
14+
from .controllers.wallet import WalletController
15+
from .controllers.definitions import DefinitionsController
16+
from .controllers.issuer import IssuerController
17+
from .controllers.proof import ProofController
18+
from .controllers.ledger import LedgerController
19+
from .controllers.credential import CredentialController
20+
from .controllers.multitenant import MultitenancyController
21+
from .controllers.server import ServerController
22+
from .controllers.oob import OOBController
23+
from .controllers.action_menu import ActionMenuController
24+
from .controllers.revocation import RevocationController
25+
26+
# from .aries_base_controller import AriesBaseController
27+
from .aries_webhook_listener import AriesWebhookListener
28+
29+
import logging
30+
31+
logger = logging.getLogger("aries_controller")
32+
33+
34+
@dataclass
35+
class AriesAgentController:
36+
"""The Aries Agent Controller class
37+
38+
This class allows you to interact with Aries by exposing the aca-py API.
39+
40+
Attributes
41+
----------
42+
webhook_host : str
43+
The url of the webhook host
44+
webhook_port : int
45+
The exposed port for webhooks on the host
46+
admin_url : str
47+
The URL for the Admin API
48+
webhook_base : str
49+
The base url for webhooks (default is "")
50+
connections : bool
51+
Specify whether to create connecitons (default is True)
52+
messaging : bool
53+
Initialise the messaging interface (default is True)
54+
is_multitenant : bool
55+
Initialise the multitenant interface (default is False)
56+
mediation : bool
57+
Initialise the mediation interface (default is False)
58+
issuer : bool
59+
Initialise the issuer interface (defautl is True)
60+
action_menu : bool
61+
Initialise the action menu interface (default is True)
62+
revocations : bool
63+
Initialise revocation interface for credentials (default is True)
64+
api_key : str
65+
The API key (default is None)
66+
tenant_jwt: str
67+
The tenant JW token (default is None)
68+
wallet_id : str
69+
The tenant wallet identifier
70+
"""
71+
72+
# TODO rethink how to initialise. Too many args?
73+
# is it important to let users config connections/issuer etc
74+
admin_url: str
75+
webhook_host: str = None
76+
webhook_port: int = None
77+
webhook_base: str = ""
78+
# connections: bool = True
79+
# messaging: bool = True
80+
is_multitenant: bool = False
81+
mediation: bool = False
82+
# issuer: bool = True
83+
# action_menu: bool = True
84+
# revocations: bool = True
85+
api_key: str = None
86+
tenant_jwt: str = None
87+
wallet_id: str = None
88+
89+
def __post_init__(self):
90+
"""Constructs additional attributes,
91+
and logic defined by attributes set during initial instantiation
92+
"""
93+
94+
self.webhook_site = None
95+
self.connections_controller = None
96+
97+
# Construct headers for Client Session and the session itself
98+
self.headers = {}
99+
100+
if self.api_key:
101+
self.headers.update({"X-API-Key": self.api_key})
102+
103+
if self.tenant_jwt:
104+
self.headers.update({'Authorization': 'Bearer ' + self.tenant_jwt, 'content-type': "application/json"})
105+
106+
self.client_session: ClientSession = ClientSession(headers=self.headers)
107+
108+
self.webhook_listener: AriesWebhookListener = AriesWebhookListener(webhook_host=self.webhook_host, webhook_port=self.webhook_port, webhook_base=self.webhook_base, is_multitenant=self.is_multitenant)
109+
110+
# Instantiate controllers based on the provided attributes
111+
# if self.connections:
112+
self.connections = ConnectionsController(self.admin_url, self.client_session)
113+
114+
# if self.messaging:
115+
self.messaging = MessagingController(self.admin_url, self.client_session)
116+
117+
self.proofs = ProofController(self.admin_url, self.client_session)
118+
self.ledger = LedgerController(self.admin_url, self.client_session)
119+
self.credentials = CredentialController(self.admin_url, self.client_session)
120+
self.server = ServerController(self.admin_url, self.client_session)
121+
self.oob = OOBController(self.admin_url, self.client_session)
122+
123+
if self.is_multitenant:
124+
self.multitenant = MultitenancyController(self.admin_url, self.client_session)
125+
126+
if self.mediation:
127+
self.mediation = MediationController(self.admin_url, self.client_session)
128+
129+
# if self.issuer:
130+
self.schema = SchemaController(self.admin_url, self.client_session)
131+
self.wallet = WalletController(self.admin_url, self.client_session)
132+
self.definitions = DefinitionsController(self.admin_url, self.client_session)
133+
self.issuer = IssuerController(self.admin_url, self.client_session, self.connections,
134+
self.wallet, self.definitions)
135+
136+
# if self.action_menu:
137+
self.action_menu = ActionMenuController(self.admin_url, self.client_session)
138+
139+
# if self.revocations:
140+
self.revocations = RevocationController(
141+
self.admin_url,
142+
self.client_session
143+
)
144+
145+
def update_wallet_id(self, wallet_id: str):
146+
"""This wallet_id is used to register for webhooks specific to this sub_wallet
147+
148+
Args:
149+
----
150+
wallet_id : str
151+
The tenant wallet identifier
152+
"""
153+
self.wallet_id = wallet_id
154+
155+
156+
def update_tenant_jwt(self, tenant_jwt: str, wallet_id: str):
157+
"""Update the tenant JW token attribute and the header
158+
159+
Args:
160+
----
161+
tenant_jwt : str
162+
The tenant's JW token
163+
wallet_id : str
164+
The tenant wallet identifier
165+
"""
166+
self.tenant_jwt = tenant_jwt
167+
self.update_wallet_id(wallet_id)
168+
self.headers.update({'Authorization': 'Bearer ' + tenant_jwt, 'content-type': "application/json"})
169+
self.client_session.headers.update(self.headers)
170+
171+
172+
def update_api_key(self, api_key: str):
173+
"""Update the API Key attribute and the header
174+
175+
Args:
176+
----
177+
api_key : str
178+
The API Key
179+
"""
180+
self.api_key = api_key
181+
self.headers.update({"X-API-Key": api_key})
182+
self.client_session.headers.update(self.headers)
183+
184+
185+
def remove_api_key(self):
186+
"""Removes the API key attribute and corresponding headers from the Client Session"""
187+
self.api_key = None
188+
if 'X-API-Key' in self.client_session.headers:
189+
del self.client_session.headers['X-API-Key']
190+
del self.headers['X-API-Key']
191+
192+
193+
def remove_tenant_jwt(self):
194+
"""Removes the tenant's JW Token attribute and corresponding headers from the Client Session"""
195+
self.tenant_jwt = None
196+
if 'Authorization' in self.client_session.headers:
197+
del self.client_session.headers['Authorization']
198+
del self.headers['Authorization']
199+
if 'content-type' in self.client_session.headers:
200+
del self.client_session.headers['content-type']
201+
del self.headers['content-type']
202+
203+
204+
def register_listeners(self, listeners, defaults=True):
205+
"""Registers the webhook listners
206+
207+
Args:
208+
----
209+
listeners : [dict]
210+
A collection of dictionaries comprised of a "handler": handler (fct) and a "topic":"topicname" key-value pairs
211+
defaults : bool
212+
Whether to connect to the default handlers for connections, basicmessage and present_proof
213+
(default is True)
214+
"""
215+
try:
216+
if defaults:
217+
if self.connections:
218+
pub.subscribe(self.connections.default_handler, "connections")
219+
if self.messaging:
220+
pub.subscribe(self.messaging.default_handler, "basicmessages")
221+
if self.proofs:
222+
pub.subscribe(self.proofs.default_handler, "present_proof")
223+
224+
for listener in listeners:
225+
self.add_listener(listener)
226+
except Exception as exc:
227+
print(f"Register webhooks listeners failed! {exc!r} occurred.")
228+
logger.warn(f"Register webhooks listeners failed! {exc!r} occurred.")
229+
230+
def add_listener(self, listener):
231+
"""Subscribe to a listeners for a topic
232+
233+
Args:
234+
----
235+
listener : dict
236+
A dictionary comprised of a "handler": handler (fct) and a "topic":"topicname" key-value pairs
237+
"""
238+
try:
239+
pub_topic_path = listener['topic']
240+
if self.wallet_id:
241+
pub_topic_path = f"{self.wallet_id}.{pub_topic_path}"
242+
print("Subscribing too: " + pub_topic_path)
243+
pub.subscribe(listener["handler"], pub_topic_path)
244+
245+
logger.debug("Lister added for topic : ", pub_topic_path)
246+
except Exception as exc:
247+
print(f"Adding webhooks listener failed! {exc!r} occurred.")
248+
logger.warn(f"Adding webhooks listener failed! {exc!r} occurred.")
249+
250+
251+
252+
def remove_listener(self, listener):
253+
"""Remove a listener for a topic
254+
255+
Args:
256+
----
257+
listener : dict
258+
A dictionary comprised of a "handler": handler (fct) and a "topic":"topicname" key-value pairs
259+
"""
260+
try:
261+
if pub.isSubscribed(listener["handler"], listener["topic"]):
262+
pub.unsubscribe(listener["handler"], listener["topic"])
263+
else:
264+
logger.debug("Listener not subscribed", listener)
265+
except Exception as exc:
266+
print(f"Removing webhooks listener failed! {exc!r} occurred.")
267+
logger.warn(f"Removing webhooks listener failed! {exc!r} occurred.")
268+
269+
270+
271+
def remove_all_listeners(self, topic: str = None):
272+
"""Remove all listeners for one or all topics
273+
274+
Args:
275+
----
276+
topic : str
277+
The topic to stop listening for (default is None). Default will cause unsubscribing from all topics.
278+
"""
279+
# Note advanced use of function can include both listenerFilter and topicFilter for this
280+
# Add when needed
281+
try:
282+
pub.unsubAll(topicName=topic)
283+
except Exception as exc:
284+
print(f"Removing all webhooks listeners failed! {exc!r} occurred.")
285+
logger.warning(f"Removing all webhooks listeners failed! {exc!r} occurred.")
286+
287+
288+
async def listen_webhooks(self):
289+
# self.webhook_listener: AriesWebhookListener = AriesWebhookListener(webhook_host=webhook_host, webhook_port=webhook_port, webhook_base=webhook_base, is_multitenant=is_multitenant)
290+
291+
if self.webhook_listener:
292+
await self.webhook_listener.listen_webhooks()
293+
294+
async def terminate(self):
295+
await self.client_session.close()
296+
await self.webhook_listener.terminate()

0 commit comments

Comments
 (0)