-
Notifications
You must be signed in to change notification settings - Fork 6
/
CHANGES
9082 lines (6666 loc) · 387 KB
/
CHANGES
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Ganymede Release 2.0
29 October 2013
CHANGES
---------------------------------------------
-------------------- Changes from 1.0.12 to 2.0.0 -------------------
RELEASE DATE: 29 October 2013
1. [EVERYTHING] Ganymede Rebooted.. Subversion, Ant
Went through everything in the old Ganymede tree and did lots of
surgery, completely restructuring the source tree, moving files into
new packages. Created sub packages arlut.csd.ganymede.server,
arlut.csd.ganymede.common, arlut.csd.ganymede.rmi,
arlut.csd.ganymede.admin, to make clear the different roles various
classes in the old arlut.csd.ganymede package play.
Deepak created a very nice Ant-based build system for Ganymede, and
restructured the source code into a package structure to make builds
with Ant convenient.
We imported the old Ganymede CVS repository into Subversion. I went
through all of the source files and replaced the old CVS keywords with
Subversion keywords.
Subversion is wonderful. Ganymede 2.0 would never have happened if we
were still stuck with CVS.
2. [SERVER] Localization
The Ganymede clients and server now incorporates a method for
localizing message strings. A new class,
arlut.csd.Util.TranslationService, has been added which handles string
lookup and templatization from string resource files held in the
src/resources tree.
A considerable portion of the Ganymede server has been modified to use
this localization mechanism, as has the admin console, and the
entirety of the Ganymede graphical client.
The default, American English version of these localization files held
in the src/resources tree are simply called <classname>.properties.
When the Ganymede server is run under a JVM that is configured to use
a different locale, the TranslationService class will automatically
read any translated resources from the appropriate file, if it is
present in the appropriate directory.
For instance, if an adopter wanted to translate the messages used by
the arlut.csd.ganymede.server.GanymedeSession class into French, he
would create the file
src/resources/arlut/csd/ganymede/server/GanymedeSession_fr.properties
Ganymede uses the standard Java Internationalization method for
handling message strings, with interpolated parameters injected into
the message strings with tokens like {0}, {1}, and etc.
The new Ant build system provides a task to cross check the default
localization resources against the Ganymede source code, to ensure
that the localization message strings match the usage in the Ganymede
source code. If you run 'ant validate' in the src directory, a Perl
script is run to do this analysis and verification.
3. [SERVER] Added support for SSHA password hashing in DBPasswordField
Here at ARL, we're working to move from NIS to LDAP for our Unix and
Mac OS X systems. Since the OpenLDAP server doesn't support md5Crypt
and since traditional Unix crypt is just too inadequate in the face of
John the Ripper and other brute force dictionary attacks, I've
implemented support for encoding passwords entered into Ganymede using
the Netscape Salted SHA-1 hash algorithm.
See http://www.openldap.org/faq/data/cache/347.html for more details
on the SSHA hash format.
Nota bene: From what I've read, SSHA is actually a relatively cheap
hash algorithm.. it doesn't contain the arbitrary delay features that
something like md5Crypt uses to slow down the hashing algorithm. As a
consequence of this, attempts to use brute force dictionary attacks
against SSHA hashes can be pretty successful. The primary benefit of
SSHA over Crypt in the LDAP context is that longer passwords can be
supported (vs. the 8 character limit of traditional Unix Crypt).
4. [SERVER] Integrated Jython interpreter support in the server
XXX - to be written. Discuss DBEditObject subclasses, tasks.
5. [SERVER, CLIENT] Java 5.0 fixes
Sun, long may their name be praised, decided in Java 5.0 to
arbitrarily make 'enum' a language keyword, despite never having put
it on the reserved keyword list. We had to go through the entire
source code and replace 'enum' with 'en'.
In a number of other places, we had to explicitly cast some parameters
when making reflection calls to avoid confusion between an older
method call that has null as the final parameter and the newer Java
5.0 varargs versions of those methods.
We've made the ant build files for everything specify a source code
and class file target level of Java 1.4, so nothing in Ganymede 2.0
should require a Java 5.0 system.
6. [CLIENT] Cleaned up some threading
We're now using FoxTrot (http://foxtrot.sourceforge.net/) to allow
some activity in the client to be synchronous in ordering but
asynchronous in that we allow the GUI thread to continue redraw and
processing further GUI events until certain server calls complete.
This fire-and-wait support makes the GUI client feel much snappier in
a few places.
7. [SERVER] The return of passive password capture
Thanks to Deepak, we have now re-enabled the passive password capture
logic in the PasswordDBField class that was removed in 1.0.10.
Previously, the big showstopper with passive password capture was that
it was possibly to capture erroneous plaintext that nonetheless
matched a stored hash format, particularly the 8-character-significant
traditional UNIX 'crypt' hash function..
Now, passive password capture is back, but it is smart enough not to
capture plaintext on login if the password is not known from a hash
with adequate specifity. The whole point of having passive password
capture is that it enables Ganymede to learn about plaintext from
interacting with a user, while still allowing us to forego saving
plaintext passwords persistently to our ganymede.db file.
8. [SERVER] Made transaction commit more resilient to exceptions in commitPhase1
The DBEditSet's transaction commit logic was vulnerable to getting
into a confused and broken state if an object's commitPhase1() method
threw an uncaught exception. It's fixed now so that the client gets
an exception report and the transaction unwinds itself back to a
consistent state, ready to try committing again (though it will
probably fail if the error condition in the plugin classes is not
fixed).
9. [SERVER, CLIENT] Added SSL support, 1.4 requirement, Firewall friendliness
Added the arlut.csd.ganymede.server.GanymedeRMIManager class to handle
all RMI exports, with support for SSL encryption of client/server
communications through the
arlut.csd.ganymede.common.RMISSLClientSocketFactory and
arlut.csd.ganymede.common.RMISSLServerSocketFactory classes.
The Ant build process now incorporates automatic generation and
distribution of key and certificate material into the appropriate jar
files when the jar files are built.
The SSL support now present in Ganymede requires a minimum of Java 1.4
to work. We are therefore intending to make JDK 1.4 a minimum
requirement of Ganymede 2.0.
It is now possible to specify the port number that the Ganymede server
should use for publishing its RMI object targets. This means that the
Ganymede server will now use only two ports, one for the rmiregistry
and one for client access, and that these can be specified for
compatibility with a fixed firewall configuration.
10. [SERVER, CLIENT] Changes to Query system (Deepak)
Deepak implemented support for a text based (ANTLR-based) querying
language that can be used by Jython code to do queries on the Ganymede
server. Deepak also added the new
arlut.csd.ganymede.common.QueryResultContainer class, which acts like
the old arlut.csd.ganymede.common.QueryResult class, but which
implements the java.util.List interface for convenient use from
Jython. At this writing, this new QueryResultContainer isn't actually
being used, yet.
In specifying the ANTLR grammar, Deepak defined a new dereference
operator, which allows for a query to express a constraint based on
the value pointed to be an invid field. By using this dereference
operation, I was able to drastically simplify and speed up the
GanymedeSession query logic by pulling some of it inside-out.
11. [SERVER, CLIENT] Removed the OwnerObjectsOwned field from OwnerBase
With this change, Owner Group objects no longer include an
InvidDBField tracking objects owned by that Owner Group. Instead, it
is the responsibility of the owned object to point to its owner.
By making this relationship non-symmetrical, we gain the ability to
add or remove objects from an owner group during a transaction without
having to check out the owner group for exclusive editing. As such,
this change will significantly improve concurrency in the Ganymede
system when many objects are owned by a single owner group.
This change was made possible by the (now quite old) change described
in 0.99.8, #17.
The 'Objects Owned' pane is still present in the client when viewing
or editing an Owner Group object, but this is now done using discrete
query logic rather than the old InvidDBField lookup, again for the
benefit of avoiding Owner Group locking.
12. [SERVER] Added a per-DBObjectBaseField lastChange variable
For the entire history of Ganymede, the GanymedeBuilderTask has
consulted a lastChange variable in each DBObjectBase to decide whether
any objects of a given type (user, group, system, etc.) has been
changed since that builder task last ran. Our custom builder tasks
use this to avoid doing builds when the builder task is not interested
in what has changed since it last ran.
One problem with this has always been that the object-level timestamp
didn't really have as much granularity as we would desire. Now, each
DBObjectBaseField has its own timestamp, so we can write builder tasks
that will, say, check to see if any user has had their username or
password changed since the builder task last ran. Previously, all the
builder task could do was check to see if any user had been edited in
any way since it last ran. This meant that editing the Notes field on
a user would trigger unnecessary activity in all builder tasks that
cared at all about user changes.
13. [CLIENT] Numerous fixes in the client's query table logic
Fixed a number of bugs in the client, including the bug that allowed
an object to be deleted in the client then viewed in an empty state
through the use of the query result table pop-up menu. Now, all
checks against an object being already marked as deleted are done at
the proper place, rather than being done in the tree response code.
Also, I fixed bugzilla bug #14, which caused the title of query
windows not to be properly updated when a transaction is committed and
the query windows are refreshed, possibly with a different number of
entries (see 1.0.12, item 14, below). While I was working on that, I
shuffled some code around in the client for better thread safety when
accessing some windowPanel data structures, as well as the use of a
common windowPanel.setWindowTitle() method for picking and maintaining
unique window names.
14. [ADMIN CONSOLE] Significant fixes to bugs in console login process
Improved the admin console login procedure. The server now returns
an explicit dialog refusing admin console login if the user provides
an unprivileged or incorrect username and password. The admin
console now responds properly to a failure to login or to the
Ganymede server being down. The admin console will now also
repeatedly test the server to see whether it has come up, and can be
told to attempt a new connection if the server is believed to come
back up.
Much of the connection establishment threading has been improved in
design. The use of the arlut.csd.Util.booleanSemaphore also helps
some, by allowing for proper exclusion of overlapping connection
threads. The connection thread now properly uses the SwingUtilities
to handle proper issuance of gui updates in response to the
connection thread.
Good stuff, and long overdue.
15. [NIS PASSWORD CLIENT] Removed the rpcpass program
I've taken out the old rpcpass program which was used in conjunction
with the -x option to Thorsten Kukuk's NIS yppasswdd daemon for Linux.
The vaguely named rpcpass was used to propagate password, shell, and
finger info changes from the Linux yppasswdd daemon into Ganymede.
Unfortunately, the passwords that the yppasswdd is capable of
transmitting to Ganymede are in the old Unix crypt() format, which
means that passwords submitted in this way are useless if Ganymede
needs to sync to anything but NIS.
Therefore, and given that we at ARL have not used this code in nearly
five years, I removed it. If you are reading this out there in
Internet land and decide that you've got to have it, let me know and
I'll see about resurrecting it from Subversion.
16. [XMLCLIENT] Massive speed-ups in the XML client, reversal of method calls
Previously, when the xmlclient was used to extract data from the
Ganymede server, the xmlclient would publish an RMI target and allow a
thread on the server to repeatedly call the client, pushing XML data
from the server.
This had the disadvantage that the xmlclient could not be run on a
system with a local firewall blocking incoming TCP connections. With
SSL support now added to the Ganymede server, this reverse flow of RMI
method calls also meant that the xmlclient needed its own SSL
certificates and key material, or else XML sent from the server to the
client would be unprotected on the wire.
Now that the xmlclient pulls data down from the server with iterative
method calls, the XML is naturally protected with the existing SSL
connection.
In addition to this change of direction for the method calls, the
arlut.csd.Util.BigPipedInputStream class has been fixed so that it
actually will properly increase the size of the buffer used for
internal pipes within the Ganymede server. In the case of the pipes
used to feed the xmlclient, this means that the server can now provide
64kbyte chunks from the XMLWriter, rather than the default 1k chunks
normally provided by PipedInputStream. This has the effect of
reducing the number of RMI calls required to transmit XML to the
client by a factor of 64, resulting in a massive speed-up.
In testing here, this change made the new code 5 times faster at
wall-clock time in doing a system-local xmlclient dump to /dev/null,
even with the overhead of SSL encryption included, relative to
previous releases.
17. [SERVER] Use of external rmiregistry eliminated
The Ganymede server now implements an rmiregistry in-process, rather
than depending on an external rmiregistry support process. This
simplifies the startup and shutdown of the Ganymede server, as well as
operational usage generally.
18. [XML] Improvements to namespace handling in <ganyschema>
In some testing we were doing, we got surprised at the case
sensitivity of namespaces that we were creating with the xmlclient.
The surprise was that by default, namespaces created are
case-insensitive. To be fair, our documentation said this, but it was
just too easy to forget this when crafting xml test data. To address
this, we have made the system warn if the case-sensitive attribute is
not present in <namespace>.
Also, the Ganymede server now properly handles switching a namespace
from case-sensitive to insensitive, or vice-vera, as needed, and
checks to make sure that this redefinition operation can be done
safely on the namespace-constrained data loaded in the server. The
admin console's schema editor still does not allow changing the case
sensitivity of a namespace, but the xmlclient may be used to do this.
19. [SERVER] Fixed a bug that made newly defined object types inaccessible
Oops! We weren't properly updating the baseTransport cache after
schema editing. This resulted in a failure whenever we tried to use
the Ganymede client to access an object of a type that did not exist
before the schema edit immediately after the schema edit took place.
The only reason this didn't bite us before was that we haven't added a
lot of object types through the schema editor without subsequently
shutting down and restarting the server.
Gotta love really exercising old code paths in relatively new ways.
20. [CLIENT,SERVER,userKit] Scalability work
Lots of work on increasing the scalability of the Ganymede server and
client. At the time of this writing, we've tested the userKit to a
loading of 250,000 users and 250,000 groups, a total of some 7.5
million data fields, with a nominal (fully garbage-collected rest
state) memory usage of around 600 megabytes on the server. In order
to get there, we had to fix some poor algorithmic choices in certain
points in the Ganymede server. This included a complete cut over from
using the old cheapo QuickSort implementation I slapped together in a
day from someone's online course notes to using the java.util.Arrays
sort algorithm that came in Java 1.2.
I also fixed a bug in the userKit userCustom.java class that made it
do about a bazillion times more work than it should have when doing
processing, thanks to a failure to set and retain the schemaConfStamp
time stamp variable properly.
The Ganymede transaction logging system is now very much more
efficient as well. Previously, all events that needed to be logged in
conjunction with a transaction would be assembled into a Vector of
DBLogEvent objects before any events were logged to disk. Now, the
transaction commit logic streams these log events to the logging
system as they are generated, so that garbage collection can occur
during the logging process. This should help reduce memory loading on
very large transactions.
Made some improvements in the XML import logic to intern commonly
occuring strings, again to reduce memory usage.
21. [CLIENT,SERVER] Invid redefined, private constructors, InvidPool
The Ganymede object id pointer class, arlut.csd.ganymede.common.Invid,
has been modified slightly to make its constructors private, in order
to force code wanting to create Invids to go through the Invid class'
static factory method, createInvid(). The purpose of this is to allow
for intelligent re-use of Invid objects on the server, so that the
server will only need to keep one copy of any given Invid. This has
an effect similar to the interning that the Ganymede server has always
done when loading strings from its database, and should help lower the
server's memory usage a bit on large datasets.
In addition, an InvidPool has been implemented on the server, which
uses a hashing SoftReference data structure to efficiently implement
Invid interning. This seems to cut memory loading on the server with
large datasets by 15% or more.
22. [CLIENT] Reworked the client layout/rendering algorithm
The layout/rendering algorithm for the client object windows and the
admin console schema editor has been rewritten to behave better in a
greater variety of circumstances. In particular, bugs that were seen
when using the multi-line label field have been addressed.
23. [SERVER,ADMIN CONSOLE,CLIENT] New data field type added for Sync Channel
Introducing the first new DBField type since the introduction of Float
back in 1999.. the FieldOptionDBField!
The purpose of the FieldOptionDBField is to allow the client and/or
xmlclient to configure the list of objects and fields that the new
Sync Channel synchronization channels (to be introduced hereafter)
will use when writing out an XML description of transactions to disk
as they happen.
The intention is that the Sync Channel will write out an XML
description in a known format for each transaction that is committed,
and a dedicated queue runner will be launched on an asynchronous basis
to sweep up the XML records for the queue, up to a fixed transaction
number, for integration into directory services oriented around change
requests rather than complete dump and reloads.
24. [SERVER] Made DBEditObject.deleting variable private
I've made the deleting boolean in DBEditObject private rather than
protected, so that use of it can be controlled better. If your custom
plugins consult deleting directly, they will need to be tweaked to use
"isDeleting()" rather than "deleting".
25. [SERVER, XML] Corrected xmlclient behavior for namespace swaps
The xmlclient is intended to allow just about any legal change to the
Ganymede server's data to be made by submitting a declarative xml
file. Unfortunately, it turned out that one thing the Ganymede server
could not do when handed an xml file was to swap two namespace values
around.
That is, suppose you wanted to rename two user accounts
simultaneously, giving account A the name previously associated with
account B, and account B the name previously associated with account
A. If you try to do this in the GUI client, you'll find that you need
to make up some transient name to act as a placeholder for account A,
then give A's name to B, then go back and give B's name to A, erasing
the placeholder in the A account.
This kind of fine grained control over the order of operations isn't
possible when using the xmlclient, so I have tweaked the server's
namespace management logic so that it will allow non-interactive
sessions to have an arbitrary number of namespace linkages 'in flight'
at a time. Giving name 'A' to account B will be allowed, even though
it means that for a brief window, both account A and the old account B
will be associated with the 'A' name. If the name 'A' is not unlinked
from the old account A by the time the xmlclient's transaction
commits, however, an exception will be reported and the transaction
will be canceled.
This logic is even capable of resolving object renaming cycles, such
as would occur in an XML file that required
System A to be renamed as System B
System B to be renamed as System C
System C to be renamed as System A
26. [SERVER, XML, EVERYTHING] Object labels no longer virtualizable, must be namespace constrained
The Ganymede server has never previously actually enforced a
requirement that all objects must have unique labels. I thought this
very clever in my initial design, allowing DBEditObject plugin classes
to completely fabricate labels for objects on demand.
In fact, this was a very stupid idea, as it makes all sorts of things
much more complicated, including the XML dump and load logic. Not
being able to know for sure that an object's name is unique in an xml
dump means that the xml file format is basically kind-of-close to
useful, but not actually trustworthy.
In Ganymede 2.0, all object types registed in the Ganymede server must
have honest to goodness label fields, guarded with a namespace
constraint to ensure unique labels within the object type. It is
still permissible to allow multiple kinds of objects to have their
label fields share a namespace if you so desire.
Object types in the base Ganymede system that did not meet this
criterion, such as the Object Event type, have been modified to
include a hidden label field that is automatically maintained by the
new preCommitHook() method added to the DBEditObject class.
This change may cause some difficulty for people trying to transition
a Ganymede 1.0 environment to 2.0, but I've put in some logic to try
and help you out. When you load an old 1.0 database that has any
object types without namespace constrained label fields, the Ganymede
server will print a warning on startup. When you go to edit the
schema, either with the GUI schema editor or the xmlclient, your
schema change will refuse to commit unless you make sure that all
objects meet this constraint.
As well, any built-in Ganymede types that are affected by this change
will automatically be tweaked for you by the system the first time you
start the server on top of an old ganymede.db file.
This change bumped the DBStore version number to 2.11.
27. [SERVER] Clarified that Vector fields may not hold duplicates
Previously, certain parts of Ganymede implicitly assumed that
duplicate values were not allowed in vector fields, but no code made
sure that duplicates were not introduced into vector fields. I have
now introduced code to test and enforce that constraint.
This change may slow down bulk loading, but it will assure that we
have a consistent semantic for vector fields, and other code in the
Ganymede server can safely rely on the uniqueness of vector field
elements.
28. [SERVER] Added GanyPermissionException to server
Several classes in the Ganymede server now throw
arlut.csd.ganymede.common.GanyPermissionException when permission
problems are encountered. This change was to help insure that
Ganymede server internal code was properly tracking permissions
failures.
As a result of this change, custom schema kit code written to the
Ganymede 1.0 series may need to be altered to catch the
GanyPermissionException, as it is a declared exception that derives
from RemoteException for compatibility with the client.
In some cases, methods that previously returned ReturnVal to indicate
permissions failures may now throw GanyPermissionException.
29. [SERVER] Added entirely new Sync Channel build systems
With Ganymede 2.0, the Ganymede server now has an entirely new family
of synchronization services.
Previously, all builds were done through the use of the
GanymedeBuilderTask and its subclasses, using a two phase process. In
phase one, portions of Ganymede's internal datastore were locked
against changes while the builder task scanned the database and wrote
data (usually text files) out to a specified directory. In phase two,
the database was unlocked, and the builder task ran an external
synchronization process that used the data files written out by phase
1. When the external build system finished, the task's execution was
complete, and a new build could be scheduled and issued for that same
task.
All of that is still there, and it all works the same way that it ever
did. Now, though, there is a second system, based on the SyncRunner
and syncChannelCustom classes and the use of an XML file format. I
call it the 'Sync Channel' system.
The Sync Channel system comes in three flavors.. "Automatic Full
State", "Automatic Incremental", and "Manual".
The Automatic Incremental Sync Channel system is the most different
from GanymedeBuilderTask.
It is based on tracking the changes made to the Ganymede data store.
When a change is made, the Ganymede transaction commit logic examines
all Incremental Sync Channels registered in the server, looking to see
if any of them are interested in the objects and fields that have
changed. If any Incremental Sync Channel is so interested, that Sync
Channel will write out an XML description of the transaction with
respect to the objects and fields that the Sync Channel cares about.
Each standardized transaction description is written out to a
directory devoted to the Incremental Sync Channel, in a file whose
name is the transaction's id number. The Ganymede server then
triggers the external service program specified for each Incremental
Sync Channel, passing it the number of the highest transaction known
to have been successfully written out at the time that the service
program is run.
The service program is intended to read all of the transactions up to
and including the number given it, and to integrate those changes into
whatever directory service the Sync Channel is intended to support.
There's much more to read about this major new feature, including
details about the "Automatic Full State" and "Manual" Sync Channels,
in doc/synchronization/index.html, or you can go on the web to
http://tools.arlut.utexas.edu/svn/ganymede/trunk/ganymede/doc/synchronization/index.html
for the details.
30. [SERVER] Forced java.rmi.server.randomIDs on by default
In conjunction with the adoption of SSL in Ganymede 2.0, the
definition of the property statement 'java.rmi.server.randomIDs=true'
is necessary to avoid direct JRMP wire-level access to RMI objects
intended to be published by Ganymede for the benefit of a single
client.
With this property defined in the runServer script, Ganymede RMI
objects will be given cryptographically secure 64 bit random object id
numbers. Anyone wishing to hijack an RMI-published object would have
to have some way of guessing a 64 bit random number in order to send a
JRMP message to the Ganymede server forcing an unauthenticated
operation.
In theory turning off java.rmi.server.randomIDs should make the
Ganymede server startup marginally faster, but any modern system that
provides high entropy random numbers through a /dev/random device
shouldn't see any delay to speak of anyway, and the Ganymede server is
much, much, much more secure with both SSL and randomIDs turned on
than it is with just one or the other of them turned on.
31. [XMLCLIENT] Added sync argument to allow for constrained dumps
Now that Ganymede 2.0 allows you to define object and field
constraints on sync channels, the xmlclient has been elaborated to be
able to apply a sync channel constraint to a dump. This makes it
possible to dump out a tailored XML report that only contains the
object and field types that a given synchronization target might be
interested in.
The ultimate purpose of this is to allow an administrator to pull the
full state of Ganymede with respect to certain objects and fields, for
the purpose of doing initial setup of an external directory service
target, before setting up a sync channel to transmits deltas as they
are committed to Ganymede.
Use is simple, just type
xmlclient -dumpdata sync=Systems > systems.xml
and Ganymede will dump out all data that fits the Systems Sync Channel
constraint.
32. [SERVER] Ripped out the old schema printing logic
The Ganymede server, from way back when, included logic for printing
its schema definitions in a readable form to HTML or plain text. All
of that code really became redundant when the xmlclient was
introduced, so I have gone through and removed it. The Ganymede
server will no longer support the ganymede.htmldump property, and will
no longer support dumping the schema to an HTML page on server
startup.
If anyone is interested in generating a schema web page from the
xmlclient -dumpschema output, that should just be an XLST script away.
Getting rid of that old code helps reduce the maintenance burden on
Ganymede, as I don't have to change schema printing logic in three
places anymore.
33. [SERVER, XML] Miscellaneous fixes to XML input processing
The Ganymede server's XML input processing is now far more robust in
terms of dealing with invid label resolution, regardless of the order
in which objects are presented in the XML input, and especially in the
case where objects are renamed as the XML file is processed.
The status report at the end of an xmlclient data batch submission has
been fixed.
Fixed the bug that led to sshatext being ignored on XML input.
Fixed the bug that caused leading or trailing white space to be
ignored in scalar string elements.
34. [SERVER, CLIENT] The client now catches and displays exceptions reliably
The Ganymede client now catches and displays exception conditions to
the user when they happen, rather than just dumping them out the back
door to STDERR. When an unhandled exception occurs, the Ganymede
client will display a dialog showing the exception. The dialog
includes a button to allow the user to report the exception to the
Ganymede server for logging.
35. [SERVER] Improved various error messages from Invid fields
Lots of clean ups to make the error messages that occur while linking
and unlinking objects more readable.
36. [SERVER, CLIENT] The server reports bad regular expression queries to the client
The server will now send a dialog to the client explaining about a
malformed regular expression query, rather than silently failing to
return any data.
37. [SERVER] Honor DBEditObject.canClone()
The canClone() method in DBEditObject wasn't being checked by
GanymedeSession, which meant that users could clone objects that the
schema kit author intended not to be cloneable.
This bug was reported by [email protected].
38. [SERVER] Fixed non-namespace constrained IPDBField fields.
IP fields that are not namespace constrained no longer throw a rod
when you try to change them.
This bug was reported by [email protected].
39. [SERVER] Properly handle regexp description in XML input
Made sure to read/set the regular expression description attribute
when processing xml input.
This bug was reported by [email protected].
40. [SERVER] Properly clear qr cache in InvidDBField
Made sure to clear the qr cache in a few more places so as to not
allow lingering choice lists to be retained.
This bug was reported by [email protected].
41. [SERVER] String field schema consistency checks now in GanymedeValidationTask
I've added support in the DBField class to allow a consistency check
to be made on values held in a field against the static constraints
specified in the Ganymede schema. This check is integrated into the
old verifyNewValue() call for StringDBField, and the
GanymedeValidationTask will run the field contents integrity test when
you do the database consistency test from the admin console.
Most constraints on fields are still implemented by dynamic method
hooks in the DBEditObject class, and those constraints can't really be
tested out except at commit time, when the editing context is
available.
This change came about because we found that a system record in the
laboratory's Ganymede server had a colon character in its Manufacturer
field, despite our having modified the schema to prevent that some
time ago.
Note that if you apply a new constraint to a string field, there is no
guarantee that previously existing data will match the new constraint
until you run the Database Consistency Test / GanymedeValidationTask
to be sure.
42. [ADMIN CONSOLE] Split sync tasks into separate task table
The admin console now includes a second task monitor table, devoted to
sync tasks (i.e., schedulable tasks derived from
arlut.csd.ganymede.server.GanymedeBuilderTask or
arlut.csd.ganymede.server.SyncRunner).
Adding a third tab for this in the admin console makes it easier to
track builds and what-not.
43. [SERVER, XMLCLIENT] Added logic for handling space characters on the command line
Previously, the Ganymede xmlclient and server, both of which require
the ability to process command line arguments, did not properly handle
command line arguments containing whitespace.
This was due to a major design flaw in how the Java runtime
environment handles command line arguments.. in Java, rather than
letting the shell break the command line into an argument list, the
runtime is responsible for doing this, and it always breaks on
whitespace, regardless of attempts at quoting or escaping arguments.
This made it impossible to use xmlclient to do sync channel dumps with
sync channels whose names contained whitespace.
Now, the Ganymede command line argument parser recognizes HTTP-style
space character encoding.. any "%20" sequence encountered on the
command line will be treated as a space character instead.
The xmlclient wrapper script is now written in Perl, and converts
space characters in arguments to %20 for passing into the xmlclient
Java executable.
44. [SERVER, XMLCLIENT] Added support for full-fidelity dumping and loading
The xmlclient now has support for an -includeHistory command line
argument, which causes the Ganymede server to include the historical
fields (creation time, creator info, modification time, modification
info) when dumping out Ganymede objects.
The xmlclient now has support for an -includeOid command line
argument, which causes the Ganymede server to include the precise
invid for dumped objects in the <object> element's oid attribute.
The Ganymede server now has support for a -magic_import command line
argument, which causes the Ganymede server to support loading the
historical fields from an xml file, as well as using the oid attribute
to create objects with a predetermined invid number.
Between -includeHistory, -includeOid, and -magic_import, it's now
possible to dump a server's complete state to an XML file, modify the
XML dump by hand to alter the schema (for instance) and then load it
into a new server, with all invids and historical fields matching the
original server's state.
45. [EVERYTHING] Added support for server-defined custom tabs in the client
This change introduces tabs to the Ganymede schema model. Adopters
can now place user-defined fields into user-defined tabs, and the
client will display the appropriate fields in separate fields,
accordingly.
The goal here is to make it possible to add more data fields to an
object type without overwhelming the user.
46. [CLIENT, ADMIN CONSOLE] No More Redundant Login Box When Running As Application
The Ganymede client and admin console are both designed to be able to
function either as an application or as an applet, depending on the
manner in which they are launched.
When they are run as applets within a web browser's window, the applet
must remain open in order to avoid terminating the applet.
Things are different when the client and console are started as
applications, however. In this case, the login box that is displayed
when the program is started is fully under control of the application.
With this change, the Ganymede client and admin console, when run as
applications, will now close their initial login windows after the
user has logged into the client or console.
This eliminates the redundant/vestigial login window that used to hang
around uselessly after logging in to the client and console.
When running as an applet (using the 'native' or 'plugin' mode from
the Ganymede web launcher), the applet window stays up still, of
course.
47. [CLIENT, ADMIN CONSOLE] Application Mode with Java Web Launch
In order to take advantage of the previous change, I've changed the
JNLP launch files for the Ganymede client and admin console so that
they are run as applications rather than as applets.
I had already moved in this direction by signing the client and
console jar files with the SSL key material. Going ahead and making
the client and console run as applications gives me control over
disposing the login window, allows me to manage threads a bit better,
and lets the client/console connect to whatever machine hosts the
Ganymede server, even if different from the web server from which the
client or console is downloaded.
This will help when it comes time to support fast failover of the
Ganymede server.
48. [XMLCLIENT, SERVER] Added support for running queries with xmlclient
The xmlclient now supports queries using the GanyQL query language
that Deepak developed.
See doc/xml/xmlclient.html and doc/querylanguage/index.html for full
details.
49. [SERVER] Fixed invid vector cloning
Previously, if you cloned an object that contained an Invid vector,
any failure in the vector cloning would cause no items at all to be
cloned, and the cloned object would have that field empty.
Now, the InvidDBField.addElements() method is cognizant of the
partialSuccess intention for object cloning, and will clone partial
objects.
50. [SERVER, CLIENT] Miscellaneous fixes to client operations
I fixed up the logic for the 'default owner' dialog in the client, so
that you can close it without making a selection to no ill effect. It
will also remember your previous owner group settings, so that you can
revisit the dialog and see what defaults you have in effect.
I tweaked the server and client so that the client is informed when an
object being edited has its label field changed. All objects that
point to the edited object through an invid link will be refreshed in
the client to reflect the object's new name.
This is even true for view-only object windows. The logic here is
that changing the label for a linked object doesn't truly change the
object being viewed, so having the link label reflect the new name is
actually no change at all. It is a bit at odds with the fact that an
object view window is a flash-frozen view of an object, though.
Newly created objects are now given default object labels on the
server until such time as their label field is set. The confusion
about these temporary labels is what led to making the client react
visibly to object renaming.
51. [CLIENT, JDATACOMPONENT] Fixed listHandle
One of the primary data structures used in the client, the
arlut.csd.JDataComponent.listHandle, turned out to be not fully
defined. It was lacking a hashCode() method, and certain revisions I
made in #50, above, needed it to be reliably hashable based on content
rather than object identity.
By fixing this, it ensures that the optimized VectorUtils class
methods can properly manipulate listHandle vectors.
52. [SERVER, CLIENT, JDATACOMPONENT] Added support for server-side reformatting of input
The Ganymede system now has the ability to respond to string input
from the client by approving a canonicalized version of the input.
Previously, the server could accept a given string, reject it
outright, or engage the user in a wizard sequence.
Now, the verifyNewValue() method in the DBEditObject subclass can use
the new setTranformedValueObject() method in the ReturnVal to signify
to the Ganymede server and client that the submitted value was
accepted but that it was transformed in some fashion and that the
client should refresh the GUI widget.
We use this with the GASHARL schema kit to auto-format MAC address
entry in the Embedded System Interface object's "Ethernet Info"
field.. if the user enters "AB-CD-EF-11-22-3", the server will
automatically reformat this string to "ab:cd:ef:11:22:03", in keeping
with our policy, and the user will get immediate visual feedback that
the data was massaged by the server.
Good stuff, although it doesn't make the code on the client and server
any simpler. ;-/
53. [CLIENT, ADMIN] Use of Java 1.4 Preferences API to remember window position, etc.
The Ganymede client and admin console now use the Java 1.4 Preferences
API to remember window positions and various default selections from
invocation to invocation on a given client system.
54. [CLIENT, ADMIN] Added support for the scroll wheel
The Ganymede client and admin console now properly support the scroll
wheel in the custom tree and table components.
55. [SERVER] Fixed a bug relating to limited privilege users in the incremental sync channel logic
Came across an interesting bug when dealing with a user who was set up
with extremely limited privileges in Ganymede. The emitXMLDelta()
method was assuming that all fields defined on an object would be
present (not null), and would fail if an administrator with limited
privileges edited an object (explicitly or implicitly) in which he did
not have permission to edit or see all fields.
The bug caused a NullPointerException to be thrown, and a transaction
involving this scenario could not successfully proceed to commit.
56. [SERVER] Liberalized anonymous linking behavior for non-privileged admins
The DBEditObject class is meant to allow normal permissions to be
overridden to allow linking to a symmetric field, even if the admin or
user in question did not have permission to edit the target object
and/or field.
Unfortunately, this logic had a loop hole that caused anonymous object
linking to break if the admin or user did not have permission to
create the target field and the object, as persisted in the object
base, did not contain an defined instance of the target field.
This has been fixed by a change to the InvidDBField.bind() method.
57. [SERVER] Various cleanups to avoid proliferation of switch statements on field type
I created a handful of static factory methods on the DBField class,
and modified a lot of classes to use these factory methods, rather
than to repetitively have their own switch statements on the set of
field types defined. Now, adding a new DBField subtype is (almost!)
as easy as editing a few static factory methods at the top of DBField,
rather than having to edit a scattered collection of internal Ganymede
code modules.
In fact, in doing this work, I fixed a bug that made the DBJournal
improperly fail to process FieldOptionDBField data in the journal if
the server was abnormally terminated without consolidating its
database. This is precisely the sort of bug that this change is
intended to help prevent in the future.
58. [CLIENT] Misc fixes.. case insensitive sort, window size, motd window
The client now uses a case insensitive sort throughout. The default
window size for object view windows is now big enough not to require
a horizontal scrollbar.
The 'Message of the day' window now appears with the top of the
message visible in the dialog, rather than the bottom.
59. [SERVER, CLIENT] Added support for user photos
By redefining the getImageURLForObject() method in a custom user
DBEditObject subclass, it is now possible to display user photographs
in the client.
The getImageURLForObject() method is designed to return a URL to a
photograph for the user located on a web server accessible by the
Ganymede client.
There is no support for user photographs in the Ganymede server,
itself.
60. [SERVER] Fixed nested monitor deadlock in GanymedeScheduler, scheduleHandle
The GanymedeScheduler and scheduleHandle classes had a big opportunity
for a nested monitor deadlock. We haven't previously hit the deadlock
in the many years we've been running Ganymede as far as I know, but
there it is regardless.
scheduleHandle now drops all synchronization before calling
notifyCompletion() on the GanymedeScheduler.
This fixes a bug that caused things to seize up a bit if a user sent a
disableTask command to a task while the task was running in the
scheduler.
61. [SERVER] Added Event Reporting When External Build Processes Fail
I've added an 'externalerror' event to the System Events predefined in