Iteration 9: Distribution using Broker I

Deadline

Always at 23.59 on the same day as your TA session (Except Monday classes).

Consult the deadline for your class on the delivery plan.

Learning Goals

The primary learning goal of this iteration is understanding and implementing Broker delegates to make HotCiv into a distributed system. A secondary learning goal is reinforced learning of how test doubles can be used to have automated testing of (much of) a distributed system.

The product goal is to get all methods that do not return object references developed for HotCiv.

Learning Context

HotCiv is architecturally well suited for a Broker based client-server system: The central Game interface is a Facade pattern which serves as the role to split between client and server. On a central server a GameServant keeps track of the game's state, while a number of clients run a HotCiv GUI (one for each player) which interacts with the game state via a GameClientProxy. However, it is also complex in the sense that the GameServant will create new objects (like new units and/or cities) that must be accessible on the client side. And, it uses the Observer pattern, which our Broker pattern cannot handle, and thus needs special treatment.

Therefore, the development will be broken into two iterations:

  1. Iteration 9 (this one): Here you will develop distribution for those methods in interface Game, City, Unit, and Tile that does not involve objects references, and you will develop the main programs for server and client.
  2. Iteration 10 (next one): Here you will extend your system to handle also methods returning object references (getCityAt() etc.), and you will make the MiniDraw GUI operate in the clients.

Preparation for the Exercise

By now, you should have a pretty complex compositional architecture to handle multiple HotCiv variants, encapsulated behind the Game Facade; and a MiniDraw based GUI that can operate it.

To extend the system to become distributed, you will need a few initial steps.

  1. Obviously, you need the Broker framework. It is available at the JCenter/BinTray repository (not Maven repository yet), so ensure your 'build.gradle' includes 'com.baerbak.maven:broker:1.7', similar to
    repositories {
        jcenter()
    }
        
    dependencies {
        compile 'com.baerbak.maven:minidraw:1.13'
        compile 'com.baerbak.maven:broker:1.7'
    
        testCompile 'junit:junit:4.12'
        testCompile 'org.hamcrest:hamcrest-library:1.3'
    }
                
    Issue a 'gradle test' to see the Broker library being downloaded.
  2. You probably need to kick IntelliJ to make it include the broker library. Hit the menu item 'View' -> 'Tools Window' -> 'Gradle'. This will show a new window, and you have to click the 'Refresh' button, as shown below:
    Now, the Broker library is available in your project, including the source code so you can actually 'Ctrl-B' on any Broker interface/class and browse the code.
  3. For the manual tests in exercise 1.3 you need to add gradle targets to the build.gradle file ala:
    task hotcivServer(type: JavaExec) {
      group 'SWEA Distribution'
      description 'Run HotCiv server (Socket)'
    
      classpath sourceSets.test.runtimeClasspath
      main = 'hotciv.broker.main.HotCivServer'
    }
            

Exercise

Solve and document exercises:

  1. Broker 1.1. TDD of Game methods that do not return references. Use TDD and test doubles to develop well tested Broker role implementations of the ClientProxy and the Invoker role under automated testing control. As a simplification you should let your server only handle a single game at the time (only one GameServant instance.) Be sure to consult the 'Notes and Hints' section below on how to get going.
  2. Broker 1.2. TDD of City, Unit, and Tile methods. Use TDD, test doubles, and "FakeSomeOfIt" to develop well tested Broker role implementations of the ClientProxies and Invoker(s) to handle all City, Unit, and Tile methods.
  3. Broker 1.3. Integration test. Develop a socket based HotCiv server application (target: 'hotcivServer'), and a MANUAL test client (target: 'hotcivStoryTest'). Test your developed code in exercise 1.1 by letting the manual test client execute a user story ala:
    1. Connect to the HotCivServer and establish the GameProxy.
    2. Executes a few of the developed methods (getAge(), moveUnit(), endOfTurn(), etc.) and outputs the returned value (if any) as shell output.
    (Example output is shown in the Notes and Hints section below.)

And release them using the tag/branch name "Release9".

Deliveries:

  1. Document your group's work by following the requirements defined in the iteration 9 report template (pdf) (LaTeX source)

Notes and Hints

Note 1

Actually, there is relatively little code to make in this exercise, and writing it becomes pretty 'repetitive' once you see the big picture - the main challenge is understanding Broker so you know what code to write, and how to use TDD and test doubles to develop them. Reading the code of the TeleMed system (the client proxy and invoker implementations) will provide much of the template and inspiration of what you are supposed to do.

Remember, that the implementations of the other Broker roles (Requestor, Client- and ServerRequestHandler) are general and provided in the frs.broker package and subpackages.

I strongly advice to take a close look at my Week 11 Mandatory Intro slides. There are myriads of ways to implement this exercise and many lead to misery, so pay close attention to the many hints and advice in the slides! It tries to keep you "taking small steps and keeping focus."

Note 2: 'hotcivStoryTest'

Example output from my own story test:

csdev@m31:~/proj/frsproject/hotciv-framework-start$ gradle hotcivStoryTest
[...]
:hotcivStoryTest
=== HotCiv Story Test Client (Socket) (host:localhost) ===
=== Testing simple methods ===
 -> Game age              : 42
 -> Game winner           : YELLOW
 -> Game PlayerInTurn     : RED
 -> Game move (2,2)-(3,3) : true
 -> Now PlayerInTurn after endOfTurn: BLUE
[...]
            
The test code looks like:
System.out.println("=== Testing simple methods ===");
System.out.println(" -> Game age              : " + game.getAge());
[...]
            

(Note that output reflects that a STUB is used in the server for this test.)

Evaluation criteria

Your submission is evaluated against the learning goals and adherence to the submission guidelines. The grading is explained in Grading Guidelines. The TAs will use the Iteration 9 Grade sheet to evaluate your submission. The score counts towards your final grade.

Learning Goal Assessment parameters
Submission Git repository can be pulled using "Release9". Git repository is not public! Code must compile; 'gradle test jacocoTestReport' must pass, and so must the integration test targets ('hotcivServer' and 'hotcivStoryTest'); required artefact (report following the template including having good quality screenshots that outline the story) is present.
Broker/Game Implementation The implementations of the Broker delegates for the Game role are functionally correct (allow distribution over several computers), respect role responsibilities (is a correct Broker pattern), and the code is clean. The report document process and resulting code correctly.
Broker/City, Unit, Tile Implementation The implementations of the Broker delegates for the City, Unit, and Tile roles are functionally correct (allow distribution over several computers), respect role responsibilities (is a correct Broker pattern), and the code is clean. The report document process and resulting code correctly.
Test Doubles Test doubles are used correctly to support automated testing of Broker delegates and are correctly discussed and presented in the report.
Integration Test The integration test correctly runs a distributed story test, and represent a good integration testing of the Game's methods.