1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# *****************************************************************************
# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others.
# * All rights reserved. This program and the accompanying materials
# * are made available under the terms of the Eclipse Public License v1.0
# * which accompanies this distribution, and is available at
# * http://www.eclipse.org/legal/epl-v10.html
# *
# * Contributors:
# * Wind River Systems - initial API and implementation
# *****************************************************************************
import collections
import threading
from .. import protocol
_providers = []
_lock = threading.RLock()
class ServiceProvider(object):
"""
Clients can implement this abstract class if they want to provide
implementation of a local service or remote service proxy.
"""
def getLocalService(self, channel):
pass
def getServiceProxy(self, channel, service_name):
pass
def addServiceProvider(provider):
with _lock:
_providers.append(provider)
def removeServiceProvider(provider):
with _lock:
_providers.remove(provider)
def onChannelCreated(channel, services_by_name):
with _lock:
# TODO ZeroCopy support is incomplete
# zero_copy = ZeroCopy()
# services_by_name[zero_copy.getName()] = zero_copy
for provider in _providers:
try:
arr = provider.getLocalService(channel)
if not arr:
continue
for service in arr:
if service.getName() in services_by_name:
continue
services_by_name[service.getName()] = service
except Exception as x:
protocol.log("Error calling TCF service provider", x)
def onChannelOpened(channel, service_names, services_by_name):
with _lock:
for name in service_names:
for provider in _providers:
try:
service = provider.getServiceProxy(channel, name)
if not service:
continue
services_by_name[name] = service
break
except Exception as x:
protocol.log("Error calling TCF service provider", x)
if name in services_by_name:
continue
services_by_name[name] = GenericProxy(channel, name)
def getServiceManagerID():
# In current implementation ServiceManager is a singleton,
# so its ID is same as agent ID.
return protocol.getAgentID()
class GenericCallback(object):
def __init__(self, callback):
self.callback = callback
def __getattr__(self, attr):
if attr.startswith("done"):
return self.callback
class Service(object):
def getName(self):
raise NotImplementedError("Abstract method")
def __str__(self):
return self.getName()
def _makeCallback(self, done):
if isinstance(done, collections.Callable):
return GenericCallback(done)
return done
class ZeroCopy(Service):
def getName(self):
return "ZeroCopy"
class GenericProxy(Service):
"""
* Objects of GenericProxy class represent remote services, which don't
* have a proxy class defined for them.
* Clients still can use such services, but framework will not provide
* service specific utility methods for message formatting and parsing.
"""
def __init__(self, channel, name):
self.__channel = channel
self.name = name
def getName(self):
return self.name
def getChannel(self):
return self.__channel
class DefaultServiceProvider(ServiceProvider):
package_base = "tcf.services.remote"
def getLocalService(self, channel):
# TODO DiagnosticsService
# return [DiagnosticsService(channel)]
return []
def getServiceProxy(self, channel, service_name):
service = None
try:
clsName = service_name + "Proxy"
package = self.package_base + "." + clsName
clsModule = __import__(package, fromlist=[clsName],
globals=globals())
cls = clsModule.__dict__.get(clsName)
service = cls(channel)
assert service_name == service.getName()
except ImportError:
pass
except Exception as x:
protocol.log("Cannot instantiate service proxy for " +
service_name, x)
return service
addServiceProvider(DefaultServiceProvider())
|