This section describes the recommended Developer Environment and how to set it up. You are welcome to use any other tools you prefer.
- JDK 8. This can also be either installed, or downloaded as a .zip. If you do not use the installer, be sure to set the
JAVA_HOME
environment variable to the location of the JDK. - Eclipse. Eclipse is a Java IDE. It can be downloaded as an installer or as a .zip file that does not require installation.
- When the installer asks which version you'd like to install, choose "Eclipse IDE for Java Developers".
- node.js 7.x.
- git. While this is not required, it is highly recommended if you will be doing active development on ANET.
- Checkout the source code from github.
git clone [email protected]:deptofdefense/anet.git
- You cannot access the source code repo. Solution: Get someone who does have admin access to add you as a collaborator. Ensure that you have the correct public key installed to github. See https://help.github.com/articles/connecting-to-github-with-ssh/ for more information on troubleshooting this step.
- The git clone command takes a long time, then fails. Solution: Some networks block ssh. Try using the
https
URL from github to download the source code.
The frontend is run with npm
. We recommend running the backend via eclipse
if you are doing any backend development, and gradle
if you are only doing frontend development.
- Set up Gradle
- Open a command line in the
anet
directory that was retrieved from github. - Create a new empty file at
localSettings.gradle
. (touch localSettings.gradle
on linux/mac). This will be a file for all of your local settings and passwords that should not be checked into GitHub. - Run
./gradlew eclipse
(linux/mac) or./gradlew.bat eclipse
(windows) to download all the java dependencies. This can take several minutes depending on your internet connection.
- Open a command line in the
- Set up npm
- Change Directories into the
client/
directory - Run
npm install
to download all the javascript dependencies. This can take several minutes depending on your internet connection. If the command hangs, it may be because your network blocks ssh. Try the command again on a different network.
- Change Directories into the
- Set up Eclipse
- Eclipse will ask you for a
workspace
directory. You can choose any empty directory. - Import the
anet/
directory into eclipse as an existing project. - Run the project as a Java Application. Open the Run Configuration and make sure:
- The main method is
mil.dds.anet.AnetApplication
- Arguments includes
server anet.yml
- Environment variables include anything set in build.gradle or localSettings.gradle. If you are using sqlite as your database, this will include:
ANET_DB_DRIVER=org.sqlite.JDBC
,ANET_DB_URL=jdbc:sqlite:development.db
,ANET_DB_DATE_STRING_FORMAT=yyyy-MM-dd hh:mm:ss.SSS Z"
,ANET_DB_DATE_CLASS=text
- The main method is
- Ensure there are no compile errors. If there are, you are probably missing dependencies or forgot to set environment variables in Eclipse. Try re-running
./gradlew eclipse
or checking the Eclipse run configuration vs gradle configs.
- Eclipse will ask you for a
- Update the settings in
anet.yml
for your environment. See the ANET Configuration documentation for more details on these configuration options. You are most likely to change:emailFromAddr
- use your own email address for testing.
- You can either use SQLite or Microsoft SQL Server for your database. The former allows you to run entirely on your local machine and develop offline. The latter allows you to test on the same database and feature set that production will use. We do our best to support both but cannot guarantee that the SQLite code will exactly match the SQL Server.
-
SQLite
- This is currently the default, so you don't need to do anything special
- To re-force gradle to use SQLite you can set the
DB_DRIVER
environment variable tosqlite
(e.g.export DB_DRIVER=sqlite
)
-
MSSQL
- Run the gradle commands in the rest of this document with the DB_DRIVER env variable (e.g.
DB_DRIVER=sqlserver ./gradlew run
) - Paste the following in your
localSettings.gradle
file (with the correct values):
run.environment("ANET_DB_USERNAME","username") run.environment("ANET_DB_PASSWORD", "password") run.environment("ANET_DB_SERVER", "db server hostname") run.environment("ANET_DB_NAME","database name")
- Run the gradle commands in the rest of this document with the DB_DRIVER env variable (e.g.
-
- Run
./gradlew dbMigrate
to build and migrate the database.- The database schema is stored in
src/main/resources/migrations.xml
.
- The database schema is stored in
- Seed the initial data:
- SQLite:
cat insertBaseData.sql | ./mssql2sqlite.sh | sqlite3 development.db
- MSSQL: You'll need to manually connect to your sqlserver instance and run
insertBaseData.sql
through the GUI or run 'sqlcmd -S -U -P -d testanet -i insertBaseData.sql'
- SQLite:
- Run
./gradlew build
to download all dependencies and build the project.- Some tests will fail if you are using SQLite, because it has a bad implementation of some timezone stuff. You'll need to use MSSQL to see all the tests passing.
Note: You can run the backend with either gradle
or with Eclipse. Eclipse does not use gradle's configurations, so you'll have to set them up yourself. You'll want to create a run configuration with:
- Main Class:
mil.dds.anet.AnetApplication
- Program Arguments:
server anet.yml
- Environment Variables: These values are used in anet.yml. We set them through environment variables rather than checking them into the git repository to allow each developer to use different settings.
- SQLite:
ANET_DB_DATE_CLASS
:text
ANET_DB_DATE_STRING_FORMAT
:yyyy-MM-dd hh:mm:ss
ANET_DB_URL
:jdbc:sqlite:development.db
ANET_DB_DRIVER
:org.sqlite.JDBC
- MSSQL:
ANET_DB_URL
:jdbc:sqlserver://[sqlserver hostname]:1433;databaseName=[dbName]
ANET_DB_USERNAME
: username to your dbANET_DB_PASSWORD
: password to your dbANET_DB_DRIVER
:com.microsoft.sqlserver.jdbc.SQLServerDriver
- SQLite:
Provided with the ANET source code is the file insertBaseData.sql
. This file contains a series of raw SQL commands that insert some sample data into the database that is both required in order to pass all the unit tests, and also helpful for quickly developing and testing new features. The Base Data Set includes a set of fake users, organizations, locations, and reports. Here are some of the accounts that you can use to log in and test with:
User | username | organization | position | role |
---|---|---|---|---|
Erin Erinson | erin | EF2.2 | EF2.2 Advisor D | Advisor who can also approve their own reports |
Rebecca Beccabon | rebecca | EF2.2 | EF2.2 Final Reviewer | Super User |
Arthur Dmin | arthur | ANET Admins | ANET Administrator | Administrator |
Jack Jackson | jack | EF2.1 | EF2.1 Advisor B | Advisor |
Henry Henderson | henry | EF2.1 | EF2.1 SuperUser | Super User |
Steve Steveson | MoD | Cost Adder | Principal |
To log in as one of the base data users, when prompted for a username and password, just enter their name as the username and leave the password blank.
-
Run
./gradlew dbMigrate
whenever you pull new changes to migrate the database.- You may need to occasionally destroy, re-migrate, and re-seed your database if it has fallen too far out of sync with master. TODO: How do you destroy the database?
-
Run
./gradlew run
to run the server via Gradle, or hit Run in Eclipse- You can ignore exceptions like the following, because the SMTP server is not necessary for local development:
ERROR [2017-02-10 16:39:38,044] mil.dds.anet.AnetEmailWorker: Sending email to [[email protected]] re: ANET Report Approved javax.mail.MessagingException: Unknown SMTP host: ${ANET_SMTP_SERVER};
- The following output indicates that the server is ready:
INFO [2017-02-10 16:44:59,902] org.eclipse.jetty.server.Server: Started @4098ms > Building 75% > :run
-
Go to http://localhost:8080/ in your browser.
- When prompted for credentials:
- Username:
erin
- Password: Leave it blank
- Username:
- You will get an error about a missing
index.ftl
file; this is expected and means the backend server is working. The error looks like:
ERROR [2017-02-10 16:49:33,967] javax.ws.rs.ext.MessageBodyWriter: Template Error ! freemarker.template.TemplateNotFoundException: Template not found for name "/views/index.ftl".
The web page will say Template Error
- When prompted for credentials:
-
If you want to see the app running, continue to the React Frontend instructions.
- Make sure you have node.js v7.x installed: ( http://nodejs.org )
cd client/
- All of the frontend code is in the
client/
directory.
- All of the frontend code is in the
- Install the development dependencies:
npm install
- Run the server:
npm start
- Go to http://localhost:3000/ in your browser.
- When prompted for credentials:
- Username:
erin
- Password: Leave it blank
- Username:
- When prompted for credentials:
NB: You only need node.js and the npm dependencies for developing. When we deploy for production, everything is compiled to static files. No javascript dependencies are necessary on the server.
In the anet.yml
file there is a flag for developmentMode
. This flag does several valuable things::
- On every graphql query, the entire graphql graph is reloaded and re-parsed. This helps in backend evelopment by allowing you to make quick changes without having to restart the server. (Note: this only helps if you're running ANET out of eclipse in debug mode).
- ANET will use AuthType Basic rather than windows authentication. This allows you to develop on non-windows computers and also quickly impersonate other accounts for testing. To log in with an account, enter the
domainUsername
value for that user in the 'Username' field when prompted by your browser. Leave the password field blank. - You can easily simulate a "new user" in development mode by entering a new username into both the username and password field. This will activate the same code path as if a user came to the production system with a valid Windows Authentication Principal but we don't find them in the
people
table. If you enter an unknown username and no password, ANET will reject you. If you enter an unknown username and the same unknown username into the password field, it will create that account and drop you into the new user workflow.