1+ import os
2+ import urllib .request
3+ from cfenv import AppEnv
4+ from oauth2 import OAuth2Client
5+ import py_eureka_client .eureka_client as eureka_client
6+ import py_eureka_client .http_client as http_client
7+ from urllib .error import URLError
8+ from typing import Union
9+
10+
11+ class _OAuth2HttpClient (http_client .HttpClient ):
12+ """
13+ A custom http client that uses OAuth2 to authenticate requests.
14+ """
15+
16+ def __init__ (self , credentials : dict ):
17+ self .oauth_client = OAuth2Client (
18+ client_id = credentials ['client_id' ],
19+ client_secret = credentials ['client_secret' ],
20+ access_token_uri = credentials ['access_token_uri' ]
21+ )
22+
23+ async def urlopen (self , request : Union [str , http_client .HttpRequest ] = None ,
24+ data : bytes = None , timeout : float = None ) -> http_client .HttpResponse :
25+ if isinstance (request , http_client .HttpRequest ):
26+ req = request
27+ elif isinstance (request , str ):
28+ req = http_client .HttpRequest (request , headers = {'Accept-Encoding' : 'gzip' })
29+ else :
30+ raise URLError ("Invalid URL" )
31+
32+ req = req ._to_urllib_request ()
33+ req .add_header ("Connection" , "close" )
34+ req .add_header ("Authorization" , f"Bearer { self .oauth_client .get_access_token ()} " )
35+ res = urllib .request .urlopen (req , data = data , timeout = timeout )
36+ return http_client .HttpResponse (res )
37+
38+ def _on_err (err_type : str , err : Exception ):
39+ if err_type in (eureka_client .ERROR_REGISTER , eureka_client .ERROR_DISCOVER ):
40+ eureka_client .stop ()
41+ else :
42+ print (f"{ err_type } ::{ err } " )
43+
44+ def init_client (port : int ):
45+ """
46+ Initializes the eureka client.
47+ """
48+
49+ env = AppEnv ()
50+
51+ service_registry = env .get_service (label = "p.service-registry" )
52+ if not service_registry :
53+ raise ValueError ("No 'p.service-registry' service instance found." )
54+
55+ credentials = service_registry .credentials
56+
57+ http_client .set_http_client (_OAuth2HttpClient (credentials ))
58+
59+ eureka_client .init (
60+ app_name = env .name ,
61+ instance_host = env .uris [0 ],
62+ instance_ip = os .getenv ('CF_INSTANCE_INTERNAL_IP' ),
63+ instance_id = f"{ env .uris [0 ]} :{ env .app .get ('instance_id' ) or '0' } " ,
64+ instance_unsecure_port_enabled = True ,
65+ instance_port = port ,
66+ instance_secure_port_enabled = True ,
67+ instance_secure_port = port ,
68+ eureka_server = credentials ['uri' ],
69+ on_error = _on_err
70+ )
0 commit comments