Add link to ToDo document; restyle HTML
[WeStealzYourDataz.git] / index.md
1 # We Stealz Your Dataz (WSYD) social network
2
3 This document is created as `index.md` in Markdown text. It can be manually converted to HTML using pandoc with the command:
4
5     pandoc --standalone --from=markdown --to=html5 --output=index.html index.md
6
7 The [**To Do list**](todo.html).
8
9 ## Introduction
10
11 In this Java project I wanted to challenge myself to use some of the same concepts I've used in previous C++ projects in order to contrast and understand the different approaches taken in both languages.
12
13 The project criteria already suggested to me that the design would need to implement **multi-threading** and as there was no specific requirement to use a database I opted to use **object serialization** which would provide two useful functions: persisting the member data to file and passing pure java objects over the network.
14
15 I adopted the **Javadoc** standard for all my code annotations and as a result the **[entire code base is consistently documented](dist/javadoc/index.html)** in the same style as the Java API in HTML without requiring me to write separate documentation.
16
17 I used [**Remarkable**](Made with Remarkable!), a [**Markdown text**](http://daringfireball.net/projects/markdown/syntax) editor with live HTML preview, to create this report and allow the report and the Javadoc to link together as one HTML web.
18
19 After becoming familiar with the NetBeans IDE I explored its Test-Driven Development (TDD) support using **[Junit](http://junit.org)** and found it provided valuable feedback on bugs in my code that were not obvious before the tests were written.
20
21 I set out to implement the assessment criteria specified for a **First class** result.
22
23 ## Design
24
25 The criteria requires a minimum of three separate executable processes: GUI User client, Social Server and Chat Server. I opted to add a fourth: GUI Server Management client. This allowed me to implement the Social and Chat servers as true **background service daemons** and have them communicate with the GUI Server Management client over the network.
26
27 As well as displaying log messages received from the servers the GUI Server Management client allows the **independent restarting or stopping** of each server.
28
29 The GUI User client makes extensive use of Swing components. The NetBeans IDE is responsible for generating most of the GUI skeleton code for handling user actions via `ActionEvent` and `PropertyChange` event listeners and several function-specific child windows and dialogs for presentation during log-in, profile editing, chat and configuration. After the GUI skeleton code was complete I added support for the network services background threads and then implemented the links between them and the GUI components.
30
31 Since the criteria requires a range of network functionality shared across clients and servers I implemented a **[common network library](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/package-frame.html)**. This network library, and the server services it implements, needs to support **multi-threading** especially on the client since listening for incoming connections is an **operation that blocks** in the operating system kernel. If those blocking operations were performed on the GUI Event Dispatch thread it would cause **poor response** in the user interface.
32
33 Fortunately the [`javax.swing.SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) class was designed especially for this purpose. As it implements the [`java.lang.Runnable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html) interface too it made the **perfect base class** for my own [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html) class because I could use it for both service daemon (non-GUI) and client (Swing GUI) applications.
34
35 I considered adopting an existing network protocol (or designing my own) for the communications between servers and clients and clients with clients. I considered Hyper Text Transport Protocol (HTTP) for the server to client connections. For client chat I looked at Internet Relay Chat (IRC) and its related Client To Client Protocol (CTCP) and the Direct Client Connect (DCC) sub-protocol (that supports file transfer) which together implement a server-mediated peer-to-peer (P2P) approach as a chat solution that has been in use since the 1990s.
36
37 The problem I found was that each *type* of communication would require a different protocol to be implemented. As well as requiring a lot of work to implement this had the risk of introducing **subtle hard-to-find runtime bugs** in the live communications.
38
39 I investigated using some form of pre-existing [`Message Queue`](http://blog.codepath.com/2013/01/06/asynchronous-processing-in-web-applications-part-2-developers-need-to-understand-message-queues/)  implementation such as Java `Enterprise Edition (EE)` [`Java Message Service (JMS)`](http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html) but decided most of these would be too over-engineered and complex for my requirements and therefore I would **create a simple message queue** implementation myself.
40
41 I'd already decided I'd use serialization for persisting member data and after looking at some examples of how easy it is to **serialize Java objects** over any kind of stream, including **network streams**, I realised it could make network communications reliable and consistent with minimal additional code both at run-time and at coding time since Java provides serialization as part of the Virtual Machine. The only requirement to support serialization is that each class of object that would be passed over the network should implement [`java.io.Serializable`](http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html) - which usually only requires a single addition:
42
43     public MyClass extends SomeClass implements java.io.Serializable {
44
45 This design decision makes it as **easy to pass an image or other file-type over the network** as it does to send simple text and with 100% reliability. In my implementation I wrapped each object being sent over the network in a [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) wrapper class that contains additional information such as sender and target service and the *intent* of the message.
46
47 A further issue I considered was **how the clients would discover the servers**. Since in the lab setting there will be no facility for adding Domain Name System (DNS) records to the local DNS server zone file it would require either:
48
49  1. hard-coding an IP address into the source-code and rebuilding the code each time the project was demonstrated
50  2. providing for the user to enter the IP address manually when each application starts
51  3. Using some form of automatic network discovery
52
53 I decided to opt for (3) implemented using [`java.net.MulticastSocket`](http://docs.oracle.com/javase/7/docs/api/java/net/MulticastSocket.html) with a fall-back to (2) in case automatic discovery fails.
54
55 Clients will create long-running Transmission Control Protocol (TCP) connections to the server for passing serialized [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) objects back and forth, starting with log-in.
56
57 Clients can discover each other via the Organisation-scope Multicast group, or if it isn't available, by requests to the Chat server which will mediate chat authorisations.
58
59 I implemented the asynchronous update from server to client requirement with User Datagram Protocol (UDP). If the Multicast group isn't active the update service will fall-back to using Unicast to each known client.
60
61 To avoid using something other than object serialization for sending notifications via UDP packets (which do not have support for streams) I used the [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html)  [`serialize()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#serialize(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)) and [`deserialize()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#deserialize(byte[])) methods to convert the object to and from a `byte[]` that can be transported by [`java.net.DatagramPacket`](http://docs.oracle.com/javase/7/docs/api/java/net/DatagramPacket.html).
62
63
64 ## Functionality
65
66 ==TODO:== Describe each application's core functionality and stand-out features
67
68 ### Social Server
69
70 ### Chat Sever
71
72 ### GUI Server Management client
73
74 ### GUI User client
75
76 ## Code
77
78 I began by designing and creating the skeleton GUI client using the NetBeans IDE.
79
80 Questions that came up during GUI client design led to coding [`WSYD_Member`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html), the class that wraps the data structure representing each member of the WSYD social network. As well as data storage I implemented a static CSV parser [`createWYSD_Member()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#createWSYD_Member(java.lang.String)), the inverse method [`toString()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#toString()), and support for the [`java.lang.Comparable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html) interface in [`compareTo()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#compareTo(uk.ac.ntu.n0521366.wsyd.libs.WSYD_Member)). I inherited serialization for free because all the attribute classes already support the [`java.io.Serializable`](http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html) interface.
81
82 The networking library was the next task. I investigated Java's networking support and looked at several code snippets and examples at sites such as *StackOverflow* as well as the official Java API documentation. I realised there were two requirements: the network services themselves, and the object passing.
83
84 Objects being passed need to encode the destination. For example, a "*Friend Is Online*" notification needs to be handled by a client method that knows what to do with that information. The network services only deal with transport not context. Therefore [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) objects know their [`sender`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#getSender()), [`target`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#setTarget(java.lang.String)) and the **`intent`** - `java.lang.String`s that allow received messages to be dispatched by the server service to the correct handler and for acknowledgements to be sent in return.
85
86 The mechanism for passing received objects from the server service to the GUI (or server process) implements a custom event [`NetworkMessageEvent`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html) which extends [`java.util.EventObject`](http://docs.oracle.com/javase/7/docs/api/java/util.EventObject.html) and adds  interface [`NetworkMessageEventGenerator`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventGenerator.html) to [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html) which registers objects of classes that implement the [`NetworkMessageEventListener`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventListener.html) interface. These objects are notified when a new [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) is received. 
87
88 The network server classes all inherit their core functionality from [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html). Common functionality implemented here includes [`javax.swing.SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) multi-threading, [`NetworkMessageEvent`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html) dispatching, the socket listener main loop in [`doInBackground()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#doInBackground()), logging, and unsolicited outbound message queuing via [`queueMessage()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#queueMessage(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)) and [`dequeueMessage()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#dequeueMessage()).
89
90 The implementing classes `NetworkServerTCP`, `NetworkServerUDP` and `NetworkServerMulticast` add minimal code via method overrides to support protocol specific functionality.
91
92 ==TODO:== discuss other classes and notable features and coding/learning experiences
93
94 I used NetBeans **Action Items** to keep track of `TODO:` and `FIXME:` outstanding tasks, and `XXX:` to call attention to important notes.
95
96 ## Testing
97
98 I used the NetBeans-generated `JUnit version 4` test class templates as the basis for my **Unit Tests**, creating **close to 100% coverage** of the non-network library code. I didn't write tests for network connections functionality although they would have been very useful due to the amount of time, and the difficulty, I estimated it would require to develop them - much more than writing the network library itself.
99
100 ==TODO:== add examples of bugs the testing revealed and experiences in writing the more complicated test cases.
101
102
103 ## Bibliography
104
105 This is a list of many, but not all, of the very many resources I looked at in developing this project. Some were of more use than others but all of these contributed something to the development, design and coding.
106
107 ### References
108
109 [Administratively Scoped IPv4 Multicast Addresses](http://en.wikipedia.org/wiki/Multicast_address#Administratively_Scoped_IPv4_Multicast_addresses)
110
111
112 ### HTML formatted note taking
113
114 [Pandoc extended Markdown syntax](http://pandoc.org/demo/example9/pandocs-markdown.html)
115
116 [Markdown syntax](http://daringfireball.net/projects/markdown/syntax)
117
118
119 ### NetBeans IDE
120
121 [How to configure \@author tag](http://stackoverflow.com/questions/15922390/netbeans-how-to-change-author)
122
123 [Writing JUnit tests](https://netbeans.org/kb/docs/java/junit-intro.html#Exercise_20)
124
125
126 ### Java documentation
127
128 [Java Platform Standard Edition 7 Documentation](http://docs.oracle.com/javase/7/docs/index.html)
129
130 [Java SE 7 API](http://docs.oracle.com/javase/7/docs/api/)
131
132 [Controlling Access to Members of a Class](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
133
134
135 ### Java Generics
136
137 [Java Tutorials: Generics](https://docs.oracle.com/javase/tutorial/java/generics/)
138
139 [Java Tutorials: Generics (by Gilad Bracha)](https://docs.oracle.com/javase/tutorial/extra/generics/index.html)
140
141
142 ### Serialization
143
144 [Serialize Object over UDP](http://www.javaworld.com/article/2077539/learn-java/java-tip-40--object-transport-via-datagram-packets.html)
145
146 [Deep cloning techniques](http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/)
147
148 [Why should a Comparator implement Serializable](http://stackoverflow.com/questions/8642012/why-should-a-comparator-implement-serializable)
149
150
151
152 ### Multi-threading
153
154 [Using SwingWorker to implement a UDP Client/Server](http://wenda.soso.io/questions/2765593/using-swingworker-to-implement-a-udp-client-server)
155
156 [Multi-threaded Network Server](http://www.tutorialspoint.com/javaexamples/net_multisoc.htm)
157
158 [How do I use SwingWorker in Java](http://stackoverflow.com/questions/782265/how-do-i-use-swingworker-in-java)
159
160 [Concurrency in Swing (multi-threading for background tasks)](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/)
161
162 [Synchronized Methods](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)
163
164 [Synchronized Statements](https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html)
165
166
167 ### Network
168
169 [Getting Network Interface Parameters](https://docs.oracle.com/javase/tutorial/networking/nifs/parameters.html)
170
171 [Testing a socket is listening on all network interfaces/wildcard interface](http://www.markhneedham.com/blog/2013/07/14/java-testing-a-socket-is-listening-on-all-network-interfaceswildcard-interface/)
172
173 [Socket Logging (network logger)](https://blogs.oracle.com/CoreJavaTechTips/entry/socket_logging)
174
175
176 ### Tutorials
177
178 [How to Write Doc Comments for the Javadoc Tool](http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html)
179
180 [Write Image to File](http://examples.javacodegeeks.com/core-java/io/java-imageio-write-image-to-file/)
181
182 [Iterating over a TreeMap](http://stackoverflow.com/questions/1318980/how-to-iterate-over-a-treemap)
183
184 [How do I call one constructor from another in Java](http://stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java)
185
186 [James Gosling's explanation of why Java's byte is signed](http://stackoverflow.com/questions/3108297/james-goslings-explanation-of-why-javas-byte-is-signed)
187
188 [When to use flush() in Java](http://stackoverflow.com/questions/7300676/when-to-use-flush-in-java)
189
190 [How do I check if a file exists in Java](http://stackoverflow.com/questions/1816673/how-do-i-check-if-a-file-exists-in-java)
191
192 [Java String.equals() versus ==](http://stackoverflow.com/questions/767372/java-string-equals-versus)
193
194 [Calculating byte-size of Java object](http://stackoverflow.com/questions/3983360/calculating-byte-size-of-java-object)
195
196 [Mr. Happy Object teaches custom events](http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html)
197
198 [Multiple Swing Timers](https://www.daniweb.com/software-development/java/threads/350345/multipe-swing-timers)
199
200 [Launching a browser for a web page](http://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html#browse%28java.net.URI%29)
201
202 [Jbutton that does not show focus](http://www.java2s.com/Code/Java/Swing-JFC/CreateaJButtonthatdoesnotshowfocus.htm)
203
204 [Set JFrame iconImage in NetBeans](http://www.areaofthoughts.com/2011/08/netbeans-jframe-properties-iconimage.html)
205
206 [JTable scrolling to a specific row](http://stackoverflow.com/questions/853020/jtable-scrolling-to-a-specified-row-index)