summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/tests/AVStreams/server_discovery/README
blob: ef0a7af2ceaa2b85c21b5d5a85007eeddeae4fd8 (plain)
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
Greetings, person designated to complete the AVDemo!,

This document details my design for the AVDemo, just how far I got in
implementing those designs, and what remains to be done. First, let me
explain that I had originally intended to use the JavaIDL ORB for this
demo, but their implementation of demarshalling Anys tossed
CORBA::Unknown and NullPointer exceptions like a sailor tossing
cookies in a typhoon. So then, I figured I could use the VisiBroker
for Java ORB, while continuing to use the nifty jdk1.2 GUI extensions
--- the "swing" components --- which I had already begun to
incorporate into the demo. However, in this latest version of the JDK,
the system classes are located automatically, and their path is not
required in the CLASSPATH environment variable. Since the Java CORBA
package names are standardized, I couldn't arrange the package search
order so that the VisiBroker packages were searched before the JavaIDL
ones. Conflicts occurred.

At this point, frustrated and dejected, I renounced Java ORBS
entirely, and decided to implement the client interaction using C++
TAO while keeping the GUI using Java1.2, and have the GUI invoke
native methods when it needed to fetch information from the Trading
Service. If you're unfamiliar with the Java Native Interface (JNI),
now's the time to get familiar, since this demo relies heavily on it,
but I'll give you a brief synopsis. In the Java code you declare
methods as native by prefixing the declaration with the 'native'
keyword. Once you've compiled the Java source into byte code, you run
the 'javah' program to generate C/C++ function declarations. The names 
of this functions are the product of name mangling the Java methods,
so the Java Runtime can call "dlsym" to retrieve a pointer to the
function's implementation when the native method is invoked in Java
code. At some point prior to invoking the native method, your Java
code must explicitly load the shared library in which your native
method implementations reside by calling System.loadLibrary (). Of
course, when I attempted to load the shared library contating my
TAO Trading Service client code, Java threw an
UnsatisfiedLinkException, not because it couldn't locate the library
as the misleading error message reported, but for some mysterious
reason which Carlos suspects has something to do with the native TAO
threads clashing with the Java VM's user-level threads. (In retropsect 
I could have enabled native threads which seem to be supported in
Java1.2 for Solaris, but what I came up with is a more elgant design
anyway). After trying various hacks, I settled on the following
design. Brace yourself....

DEMO VISION

My goals for this first demo were modest. And became increasingly more 
modest as I began meeting failure at every door. My full intentions
are described in my thesis (doc/papers/ugthesis_seth), but since I can 
already sense your guffawing at the notion of reading my thesis, I'll
summarize for you -- right now. Essentially, I wanted  the initial query
to the Trading Service to be as productive as possible, eliminating
the possibility that attempting to connect to a server in the returned 
offers will fail. Thus, that initial query will should include things
like: can accept another connection, supports the media formats
understood by the client, can transmit at a rate suitable to the
client's limiting bandwidth. Moreover, the client might want to limit
the pool of possible servers based on content --- must have movies of
a certain category --- or server performance --- must have a load less 
than 2.4. This kind of configuration information can be obtained
through dialogue boxes in the GUI, and then formatted as a constraint
string in the OMG Standard Constraint language. The results ---
performance properties and movie offerings for each server --- would
be displayed in the GUI, and the user would nominate a server who
offers the best performance for the content desired by the user.

DEMO REALITY --- the Server Side

orbsvcs/tests/AVStreams/mpeg/source/server contains the code for the
augmented server --- augmented from the original server because it
uses the TAO_Property_Exporter to form a service offer that it exports 
to a Trading Service instance. Properties exported by the
augmented_server include: maxmimum number of connections allowed,
current number of connections, list of movies offered and their
attributes, performance statistics (CPU usage, disk usage, load,
etc...). The TAO_Property_Exporter presents a kind of uniform
interface for exporting static and dynamic properties --- every
property mentioned above is dynamic except perhaps the maximum number
of connections allowed. There are actually three types of properties
exportable by Property_Exporter: static, where the value of the
property is stored twice: once in the offer and once in the MMDevice's 
CosProperty::PropertySet; semi-dynamic, where the value of the
property is stored in the property set, and a dynamic property in the
service offer retrieves the value from the property set (this is
useful for MMDevice dynamic properties); and dynamic, where the value
of the property isn't stored anywhere, but lazily-evaluated by a
dynamic property in the offer (this is useful for non-MMDevice
properties). 

Classes that export properties via the TAO_Property_Exporter inherit
from the TAO_Exportable interface. The define_properties and
export_properties methods allow an exporting class to encapsulate the
exporting of its own properties. The augmented server has three
TAO_Exportable classes representing three categories of properties: 1)
The AV_Audio_MMDevice exports those properties that are also
properties of the MMDevice --- properties that are used in the
lower-level AVStream stream establishment negotiation. The properties
are static and semi-dynamic. Hence when its define_properties method
is invoked, the AV_Audio_MMDevice adds to the Service Type Description
PropStructSeq, the names, types, and modes of each of the properties
its exporting. When its define_properties method is invoked, the
AV_Audio_MMDevice uses the TAO_Property_Exporter reference it's passed
to export its properties. 2) TAO_Video_Repository in addition to being
a TAO_Exportable is also a TAO_Dynamic_Property. In define_properties
is exports itself as a dynamic property with the TAO_Property_Exporter
its passed, and when called back, parses a manifest of available
movies, obtains information about them by parsing the headers of each
of the media files, and returns this information of a sequence of
structs, each struct containing the attributes of an individual
movie. The IDL code for this structure --- TAO_VR::Movie --- can be
found in VideoRepository.idl. 3) TAO_Machine_Properties is also a
dynamic property --- serveral actually. For each of the ten or so
performance properties, it exports a dynamic property with itself as
the evaluation interface reference. When its evalDP method is called,
it obtains the value for the statistic whose name is in the prop_name
parameter. The statistics are gathered by SunRPC from the rstatd
daemon and cached. The cache expires every so often and is then
refreshed by another rpc call, obviating the need for an rpc call for
every call to evalDP.

DEMO REALITY --- the Client Side

The Server Selection portion of the demo is actually a Java VM
embedded in a TAO Trading Service client. The main program bootstraps
the vm, initializes the ORB and bootstraps to the Trading Service,
performs the initial query of the Trading Service, and invokes the
'main' method on the Java Server_Discovery class. Embedding the VM in
this way is possible because of the JNI Invocation interface. On the
C++ side of things, the Trader_Client class queries the Trading
Service and caches the results in a two-tier hashtable: the first tier
maps the server name to who the offer belongs to a second-tier
hashtable, which maps each property name in the offer to its
value. The Server_Discovery.cpp file implements each of the native
methods used in the java portion of the demo, and each method
implementation follows the same pattern: convert the java string
paraemters into C++ strings, obtain the Trader_Client singleton
instance, delegate to that instance, and convert the return results to
Java objects.

The Server_Discovery class creates a JFrame with a JDesktopPane as its
ContentPane. The first window onto the Desktop is a
Server_Discovery_Selection pane which it split (JSplitPane) into two
halves: the upper portion containing a hierarcical menu (JTree) of
available movies, organized by category, title, and server; and the
bottom portion containing a table (JTable) of attributes for a selected
movie. The Server_Discovery class uses the native methods in
Server_Discovery_Util, get_server_names and get_movie_info, to supply
Server_Discovery_Selection with the information necessary to create
its displays. When a user clicks on a leaf node of the hierarchical
menuthe bottom half displays the table for that
server's movie offering. The table displays the contents of
TAO_VR::Movie structure for the selected movies. Also in the tables
are clickable labels to display the performance information for the
server, and to call up a web page describing the movie.

For viewing the performance a Server_Discovery_Perf JInternalFrame is
created in a callback to the Server_Discovery (a Mediator object). The 
Server_Discovery_Perf is supplied with the names of each of the
performance properties, instantiates a Strip_Chart for each one, and
spawns a thread to periodically update each chart by calling
Server_Discovery_Util.evaluate_performance_property for the chart's
property_name. For viewing a web page describing the movie, the
Server_Discovery_Browser, when given the description field of the
TAO_VR::Movie structure, will load a JEditorPane to fetch the page and 
display the parsed html! Pretty damn slick. The "browser" will also
respond to clicks on hyperlinks and fetch the selected pages! No joke!

Finally, if the user clicks on the button at the bottom of the
selection frame, Server_Discovery_Selection calls the native method
load_movie, which uses a UNIX socket to connect to the controller
process of the AV client, and passes it the name of the movie and the
IOR of the MMDevice interface. The AV client then transmutes the IOR
to an MMDevice object reference, and establishes the AV
stream. Hoorah! 

WHAT'S WRONG WITH THE DEMO?

Well, the first native method invocation --- get_server_names ---
works as verified by ACE_DEBUG messages, but hangs on returning from
it. Once this problem is solved, all that remains is to ensure the GUI 
looks and works as I've envisioned, and to code the interaction between
the Server Discovery and A/V client.

That, my friend, is the demo in an anxiously written nutshell. Enjoy!
Don't forget to set the JAVA_ROOT enivronment variable to the location 
of the lastest JDK version (when I was here, that was
/project/doc/pkg/jdk1.2beta4)!

-- Seth Widoff, sbw1@cs.wustl.edu