This project aims to solve the Millenium Falcon Challenge.
To be able to compile/run/build the project, you must have:
- Java 8 or higher and make sure it is added to the path (JAVA_PATH variable defined with selected version).
- Yarn 1.22.18 or higher.
- Gradle 7.6 or higher
If you already have a packaged WAR (from releases page for example), you can skip steps 1-4 and go directly to step 5.
- Open your favourite terminal and navigate to the frontendapp folder.
- Execute
yarn build
to build the JS/React code which will create the static files underfrontend/build/static
(these will be packaged into the final WAR). - Navigate to the project's root folder and execute
gradle clean build
to clean up any temp files and generate the WAR "millenium-0.0.1-SNAPSHOT.war". - Navigate to the folder "build/libs".
- Copy the packaged WAR into the folder "scripts".
- Navigate to the folder "scripts" and type
./install-alias.sh
to generate the launch script calledgive-me-the-odds.sh
.
Important: The only condition is to keep the WAR, ./install-alias.sh
and give-me-the-odds.sh
in the same folder (can be scripts or any another external folder).
Once give-me-the-odds.sh have been generated, you can open the terminal and execute it with or without parameters to either deploy the App or execute the CLI.
Deploys the App locally and can be accessed at http://localhost:8080. If you don't specify any parameter, the default config file config/millenium-falcon.json will be used automatically.
Deploys the App locally and can be accessed at http://localhost:8080. The specified parameter will be used to initialize the Millenium Falcon configuration. The parameter can be either:
- Relative path to the folder resources/examples for example:
./give-me-the-odds.sh example1/millennium-falcon.json
- Absolute path to any millenium falcon config of your choice for example:
./give-me-the-odds.sh /ROOT_TO_EXTERNAL_CONFIG/millennium-falcon.json
This will enable the CLI mode of the App, use the first/second param to load the Millenium Falcon/Empire data and compute the success probability. For example:
./give-me-the-odds.sh example1/millennium-falcon.json example1/empire.json
./give-me-the-odds.sh /ROOT_TO_EXTERNAL_CONFIG/millennium-falcon.json /ROOT_TO_EXTERNAL_CONFIG/empire.json
./give-me-the-odds.sh example1/millennium-falcon.json /ROOT_TO_EXTERNAL_CONFIG/empire.json
./give-me-the-odds.sh /ROOT_TO_EXTERNAL_CONFIG/millennium-falcon.json example1/empire.json
This is the Millenium Falcon Dashboard:
-
Flow Stepper (on the left): These are the instructions for further details on how to use the App, please make sure to go through them.
-
Routes Graph (in the center of the screen): This is the graph that represents the Millenium Falcon routes from planet to planet with the travel times, the departure and the arrival of the mission => this data is computed from the millenium-falcon.json file.
You can click on the button Regenerate Graph
to refresh the Graph's UI if the nodes are not well positioned or if the graph is not well rendered.
You can also move around nodes by dragging them and you can click on the rectangle near the zoom controls to re-center the graph.
-
File Upload zone (on the upper-center of the screen): This is where you can upload or drag and drop a file containing the empire intercepted data. Once that's done, the result will be computed and further details will be provided on the right part.
-
Mission Success Probability (on right part of the screen, see next section for screenshot): This will contain the mission success probability and the detailed route if there is a solution (meaning that the result is greater than 0%).
Once the empire.json
file is uploaded, the app will compute the mission success probability from the Departure to Arrival given the autonomy, routes, countdown and bounty hunters positions as below:
Whenever the app is launched using 2 parameters (please refer to the section above) to load both config files, the CLI mode will be enabled and the mission success probability will be printed on the console as below:
Logs containing extra details on the configs, route success probability computation, etc.. are being generated on the root of the folder where the script is being launched. The kind of details you can find are as below:
01:50:23.038 [main] INFO c.d.millenium.cli.CommandLineRunner - Computing mission result from CLI..
01:50:23.118 [main] INFO c.d.millenium.business.PathOptimizer - Compute mission result started. Departure: [Tatooine], Arrival: [Endor], Countdown: [10], Autonomy: [6]
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - 2 Possible paths found that lead from Tatooine to Endor in 10 days.
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - [Planet{name='Tatooine', day='0'}, Planet{name='Dagobah', day='6'}, Planet{name='Dagobah', day='7', Refuel}, Planet{name='Hoth', day='8'}, Planet{name='Endor', day='9'}] is a possible path.
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - [Planet{name='Tatooine', day='0'}, Planet{name='Hoth', day='6'}, Planet{name='Hoth', day='7', Refuel}, Planet{name='Endor', day='8'}] is a possible path.
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - Computing the best success probability from all possible paths..
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - [[Planet{name='Tatooine', day='0'}, Planet{name='Dagobah', day='6'}, Planet{name='Dagobah', day='7', Refuel}, Planet{name='Hoth', day='8', Risky}, Planet{name='Endor', day='9'}]] is the best path so far as it has [1] risky positions and arrives on [Endor] on Day [9].
01:50:23.119 [main] INFO c.d.millenium.business.PathOptimizer - [[Planet{name='Tatooine', day='0'}, Planet{name='Dagobah', day='7', delay='1'}, Planet{name='Dagobah', day='8', Refuel}, Planet{name='Hoth', day='9'}, Planet{name='Endor', day='10'}]] is the best path so far as it has [0] risky positions and arrives on [Endor] on Day [10].
01:50:23.119 [main] INFO c.d.millenium.services.RouteService - Compute mission result ended with a success probability of [100.0%].
01:50:23.120 [main] INFO c.d.m.aspect.MethodDurationAspect - Method computeMissionResult in class com.dataiku.millenium.services.RouteService took 81 ms
01:50:23.120 [main] INFO c.d.millenium.cli.CommandLineRunner - ****************** Results ******************
01:50:23.120 [main] INFO c.d.millenium.cli.CommandLineRunner - Mission Success Probability: 100.0
01:50:23.120 [main] INFO c.d.millenium.cli.CommandLineRunner - *********************************************
So please refer to these if you need more details on the result computation.
You can use the command below to stream the application log:
tail -f /PATH_TO_THE_LOGS/application.log
If you are familiar with Postman, you can import the configuration file from here and you'll be able to query the below endpoints:
/healthcheck
(GET)
Check that app is deployed/running.
/missionResultSuccess
(POST)
Compute the mission's success probability given the empire data (passed as body).
/missionData
(GET)
Fetches the current mission's data (extracted from the millenium falcon config file).
- Plug the logs (backend/frontend) to a log aggregator such as Splunk/Datadog.
- Track the technical performance of the App especially the TP99, TP90, TP50 of the endpoint
/missionResultSuccess
and setup alerts to be aware if at some point the performance is degraded below a certain threshold. - Add user metrics to have a better understanding of the feature usage/success/failure with a platform like Amplitude.
- Add unit tests and Cypress tests for UI code.
- Enhance the logging to the UI level with a proper logger (using a dedicated Util).
- Add coverage on the Java code using JaCoCo.
- Audit the performance/complexity of the component GraphUtil.js as the part that ensures the min distance between nodes might not scale correctly. That would either lead to move the heavy computation code to the backend and solve the issue with multithreading or rework the algorithm with another approach such as Poisson-disc Sampling.
- Split the class PathOptimizer.java into multiple classes for different responsabilities such as one to compute the possible paths, another one to compute the best path and another one to compute the final success probability.