-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #479 from softwareconstruction240/reduce-endpoint-…
…dependencies Remove Server's dependency on Controller classes
- Loading branch information
Showing
5 changed files
with
433 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import edu.byu.cs.autograder.GradingException; | ||
import edu.byu.cs.server.endpointprovider.EndpointProvider; | ||
import edu.byu.cs.server.endpointprovider.EndpointProviderImpl; | ||
import edu.byu.cs.dataAccess.DaoService; | ||
import edu.byu.cs.dataAccess.DataAccessException; | ||
import edu.byu.cs.properties.ApplicationProperties; | ||
import edu.byu.cs.server.Server; | ||
import edu.byu.cs.service.SubmissionService; | ||
import edu.byu.cs.util.ResourceUtils; | ||
import org.apache.commons.cli.*; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Properties; | ||
|
||
public class Main { | ||
private static Logger LOGGER = LoggerFactory.getLogger(Main.class); | ||
|
||
private static EndpointProvider endpointProvider = new EndpointProviderImpl(); | ||
|
||
public static void main(String[] args) { | ||
ResourceUtils.copyResourceFiles("phases", new File("")); | ||
setupProperties(args); | ||
|
||
try { | ||
DaoService.initializeSqlDAOs(); | ||
} catch (DataAccessException e) { | ||
LOGGER.error("Error setting up database", e); | ||
throw new RuntimeException(e); | ||
} | ||
|
||
new Server(endpointProvider).start(8080); | ||
|
||
try { | ||
SubmissionService.reRunSubmissionsInQueue(); | ||
} catch (IOException | DataAccessException | GradingException e) { | ||
LOGGER.error("Error rerunning submissions already in queue", e); | ||
} | ||
} | ||
|
||
private static void setupProperties(String[] args) { | ||
Options options = getOptions(); | ||
|
||
Properties properties = new Properties(); | ||
|
||
CommandLineParser parser = new DefaultParser(); | ||
try { | ||
CommandLine cmd = parser.parse(options, args); | ||
if (cmd.hasOption("db-host")) { | ||
properties.setProperty("db-host", cmd.getOptionValue("db-host")); | ||
} | ||
if (cmd.hasOption("db-port")) { | ||
properties.setProperty("db-port", cmd.getOptionValue("db-port")); | ||
} | ||
if (cmd.hasOption("db-name")) { | ||
properties.setProperty("db-name", cmd.getOptionValue("db-name")); | ||
} | ||
if (cmd.hasOption("db-user")) { | ||
properties.setProperty("db-user", cmd.getOptionValue("db-user")); | ||
} | ||
if (cmd.hasOption("db-pass")) { | ||
properties.setProperty("db-pass", cmd.getOptionValue("db-pass")); | ||
} | ||
if (cmd.hasOption("frontend-url")) { | ||
properties.setProperty("frontend-url", cmd.getOptionValue("frontend-url")); | ||
} | ||
if (cmd.hasOption("cas-callback-url")) { | ||
properties.setProperty("cas-callback-url", cmd.getOptionValue("cas-callback-url")); | ||
} | ||
if (cmd.hasOption("canvas-token")) { | ||
properties.setProperty("canvas-token", cmd.getOptionValue("canvas-token")); | ||
} | ||
if (cmd.hasOption("use-canvas")) { | ||
properties.setProperty("use-canvas", cmd.getOptionValue("use-canvas")); | ||
} | ||
if (cmd.hasOption("disable-compilation")) { | ||
properties.setProperty("run-compilation", "false"); | ||
} | ||
} catch (ParseException e) { | ||
throw new RuntimeException("Error parsing command line arguments", e); | ||
} | ||
|
||
ApplicationProperties.loadProperties(properties); | ||
} | ||
|
||
private static Options getOptions() { | ||
Options options = new Options(); | ||
options.addOption(null, "db-host", true, "Database Host"); | ||
options.addOption(null, "db-port", true, "Database Port"); | ||
options.addOption(null, "db-name", true, "Database Name"); | ||
options.addOption(null, "db-user", true, "Database User"); | ||
options.addOption(null, "db-pass", true, "Database Password"); | ||
options.addOption(null, "frontend-url", true, "Frontend URL"); | ||
options.addOption(null, "cas-callback-url", true, "CAS Callback URL"); | ||
options.addOption(null, "canvas-token", true, "Canvas Token"); | ||
options.addOption(null, "use-canvas", true, "Using Canvas"); | ||
options.addOption(null, "disable-compilation", false, "Turn off student code compilation"); | ||
return options; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,224 +1,123 @@ | ||
package edu.byu.cs.server; | ||
|
||
import edu.byu.cs.autograder.GradingException; | ||
import edu.byu.cs.controller.WebSocketController; | ||
import edu.byu.cs.dataAccess.DaoService; | ||
import edu.byu.cs.dataAccess.DataAccessException; | ||
import edu.byu.cs.properties.ApplicationProperties; | ||
import edu.byu.cs.service.SubmissionService; | ||
import edu.byu.cs.util.ResourceUtils; | ||
import org.apache.commons.cli.*; | ||
import edu.byu.cs.server.endpointprovider.EndpointProvider; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Properties; | ||
|
||
import static edu.byu.cs.controller.AdminController.*; | ||
import static edu.byu.cs.controller.AuthController.*; | ||
import static edu.byu.cs.controller.CasController.*; | ||
import static edu.byu.cs.controller.ConfigController.*; | ||
import static edu.byu.cs.controller.SubmissionController.*; | ||
import static edu.byu.cs.controller.UserController.*; | ||
import static spark.Spark.*; | ||
|
||
public class Server { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(Server.class); | ||
private final EndpointProvider provider; | ||
|
||
public Server(EndpointProvider endpointProvider) { | ||
this.provider = endpointProvider; | ||
} | ||
|
||
public static int setupEndpoints(int port) { | ||
public int start(int desiredPort) { | ||
int chosenPort = setupEndpoints(desiredPort); | ||
LOGGER.info("Server started on port {}", chosenPort); | ||
return chosenPort; | ||
} | ||
|
||
private int setupEndpoints(int port) { | ||
port(port); | ||
|
||
webSocket("/ws", WebSocketController.class); | ||
webSocketIdleTimeoutMillis(300000); | ||
|
||
staticFiles.location("/frontend/dist"); | ||
|
||
before((request, response) -> { | ||
response.header("Access-Control-Allow-Headers", "Authorization,Content-Type"); | ||
response.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS"); | ||
response.header("Access-Control-Allow-Credentials", "true"); | ||
response.header("Access-Control-Allow-Origin", ApplicationProperties.frontendUrl()); | ||
}); | ||
before(provider.beforeAll()); | ||
|
||
path("/auth", () -> { | ||
get("/callback", callbackGet); | ||
get("/login", loginGet); | ||
get("/callback", provider.callbackGet()); | ||
get("/login", provider.loginGet()); | ||
|
||
// all routes after this point require authentication | ||
post("/logout", logoutPost); | ||
post("/logout", provider.logoutPost()); | ||
}); | ||
|
||
path("/api", () -> { | ||
before("/*", (req, res) -> { | ||
if (!req.requestMethod().equals("OPTIONS")) | ||
verifyAuthenticatedMiddleware.handle(req, res); | ||
if (!req.requestMethod().equals("OPTIONS")) provider.verifyAuthenticatedMiddleware().handle(req, res); | ||
}); | ||
|
||
patch("/repo", repoPatch); | ||
patch("/repo", provider.repoPatch()); | ||
|
||
get("/submit", submitGet); | ||
post("/submit", submitPost); | ||
get("/submit", provider.submitGet()); | ||
post("/submit", provider.submitPost()); | ||
|
||
get("/latest", latestSubmissionForMeGet); | ||
get("/latest", provider.latestSubmissionForMeGet()); | ||
|
||
get("/submission", submissionXGet); | ||
get("/submission/:phase", submissionXGet); | ||
get("/submission", provider.submissionXGet()); | ||
get("/submission/:phase", provider.submissionXGet()); | ||
|
||
get("/me", meGet); | ||
get("/me", provider.meGet()); | ||
|
||
get("/config", getConfigStudent); | ||
get("/config", provider.getConfigStudent()); | ||
|
||
path("/admin", () -> { | ||
before("/*", (req, res) -> { | ||
if (!req.requestMethod().equals("OPTIONS")) | ||
verifyAdminMiddleware.handle(req, res); | ||
if (!req.requestMethod().equals("OPTIONS")) provider.verifyAdminMiddleware().handle(req, res); | ||
}); | ||
|
||
patch("/repo/:netId", repoPatchAdmin); | ||
patch("/repo/:netId", provider.repoPatchAdmin()); | ||
|
||
get("/repo/history", repoHistoryAdminGet); | ||
get("/repo/history", provider.repoHistoryAdminGet()); | ||
|
||
get("/users", usersGet); | ||
get("/users", provider.usersGet()); | ||
|
||
post("/submit", adminRepoSubmitPost); | ||
post("/submit", provider.adminRepoSubmitPost()); | ||
|
||
path("/submissions", () -> { | ||
post("/approve", approveSubmissionPost); | ||
post("/approve", provider.approveSubmissionPost()); | ||
|
||
get("/latest", latestSubmissionsGet); | ||
get("/latest", provider.latestSubmissionsGet()); | ||
|
||
get("/latest/:count", latestSubmissionsGet); | ||
get("/latest/:count", provider.latestSubmissionsGet()); | ||
|
||
get("/active", submissionsActiveGet); | ||
get("/active", provider.submissionsActiveGet()); | ||
|
||
get("/student/:netId", studentSubmissionsGet); | ||
get("/student/:netId", provider.studentSubmissionsGet()); | ||
|
||
post("/rerun", submissionsReRunPost); | ||
post("/rerun", provider.submissionsReRunPost()); | ||
}); | ||
|
||
get("/test_mode", testModeGet); | ||
get("/test_mode", provider.testModeGet()); | ||
|
||
get("/analytics/commit", commitAnalyticsGet); | ||
get("/analytics/commit", provider.commitAnalyticsGet()); | ||
|
||
get("/analytics/commit/:option", commitAnalyticsGet); | ||
get("/analytics/commit/:option", provider.commitAnalyticsGet()); | ||
|
||
get("/honorChecker/zip/:section", honorCheckerZipGet); | ||
get("/honorChecker/zip/:section", provider.honorCheckerZipGet()); | ||
|
||
get("/sections", sectionsGet); | ||
get("/sections", provider.sectionsGet()); | ||
|
||
path("/config", () -> { | ||
get("", getConfigAdmin); | ||
get("", provider.getConfigAdmin()); | ||
|
||
post("/phases", updateLivePhases); | ||
post("/phases/shutdown", scheduleShutdown); | ||
post("/banner", updateBannerMessage); | ||
post("/phases", provider.updateLivePhases()); | ||
post("/phases/shutdown", provider.scheduleShutdown()); | ||
post("/banner", provider.updateBannerMessage()); | ||
|
||
post("/courseIds", updateCourseIdsPost); | ||
get("/courseIds", updateCourseIdsUsingCanvasGet); | ||
post("/courseIds", provider.updateCourseIdsPost()); | ||
get("/courseIds", provider.updateCourseIdsUsingCanvasGet()); | ||
|
||
post("/penalties", updatePenalties); | ||
post("/penalties", provider.updatePenalties()); | ||
}); | ||
}); | ||
}); | ||
|
||
// spark's notFound method does not work | ||
get("/*", (req, res) -> { | ||
if (req.pathInfo().equals("/ws")) | ||
return null; | ||
|
||
String urlParams = req.queryString(); | ||
urlParams = urlParams == null ? "" : "?" + urlParams; | ||
res.redirect("/" + urlParams, 302); | ||
return null; | ||
}); | ||
init(); | ||
get("/*", provider.defaultGet()); | ||
|
||
return port(); | ||
} | ||
after(provider.afterAll()); | ||
|
||
private static void setupProperties(String[] args) { | ||
Options options = getOptions(); | ||
|
||
Properties properties = new Properties(); | ||
|
||
CommandLineParser parser = new DefaultParser(); | ||
try { | ||
CommandLine cmd = parser.parse(options, args); | ||
if (cmd.hasOption("db-host")) { | ||
properties.setProperty("db-host", cmd.getOptionValue("db-host")); | ||
} | ||
if (cmd.hasOption("db-port")) { | ||
properties.setProperty("db-port", cmd.getOptionValue("db-port")); | ||
} | ||
if (cmd.hasOption("db-name")) { | ||
properties.setProperty("db-name", cmd.getOptionValue("db-name")); | ||
} | ||
if (cmd.hasOption("db-user")) { | ||
properties.setProperty("db-user", cmd.getOptionValue("db-user")); | ||
} | ||
if (cmd.hasOption("db-pass")) { | ||
properties.setProperty("db-pass", cmd.getOptionValue("db-pass")); | ||
} | ||
if (cmd.hasOption("frontend-url")) { | ||
properties.setProperty("frontend-url", cmd.getOptionValue("frontend-url")); | ||
} | ||
if (cmd.hasOption("cas-callback-url")) { | ||
properties.setProperty("cas-callback-url", cmd.getOptionValue("cas-callback-url")); | ||
} | ||
if (cmd.hasOption("canvas-token")) { | ||
properties.setProperty("canvas-token", cmd.getOptionValue("canvas-token")); | ||
} | ||
if (cmd.hasOption("use-canvas")) { | ||
properties.setProperty("use-canvas", cmd.getOptionValue("use-canvas")); | ||
} | ||
if (cmd.hasOption("disable-compilation")) { | ||
properties.setProperty("run-compilation", "false"); | ||
} | ||
} catch (ParseException e) { | ||
throw new RuntimeException("Error parsing command line arguments", e); | ||
} | ||
|
||
ApplicationProperties.loadProperties(properties); | ||
} | ||
|
||
private static Options getOptions() { | ||
Options options = new Options(); | ||
options.addOption(null, "db-host", true, "Database Host"); | ||
options.addOption(null, "db-port", true, "Database Port"); | ||
options.addOption(null, "db-name", true, "Database Name"); | ||
options.addOption(null, "db-user", true, "Database User"); | ||
options.addOption(null, "db-pass", true, "Database Password"); | ||
options.addOption(null, "frontend-url", true, "Frontend URL"); | ||
options.addOption(null, "cas-callback-url", true, "CAS Callback URL"); | ||
options.addOption(null, "canvas-token", true, "Canvas Token"); | ||
options.addOption(null, "use-canvas", true, "Using Canvas"); | ||
options.addOption(null, "disable-compilation", false, "Turn off student code compilation"); | ||
return options; | ||
} | ||
|
||
|
||
public static void main(String[] args) { | ||
ResourceUtils.copyResourceFiles("phases", new File("")); | ||
setupProperties(args); | ||
|
||
try { | ||
DaoService.initializeSqlDAOs(); | ||
} catch (DataAccessException e) { | ||
LOGGER.error("Error setting up database", e); | ||
throw new RuntimeException(e); | ||
} | ||
|
||
int port = setupEndpoints(8080); | ||
|
||
LOGGER.info("Server started on port {}", port); | ||
init(); | ||
|
||
try { | ||
SubmissionService.reRunSubmissionsInQueue(); | ||
} catch (IOException | DataAccessException | GradingException e) { | ||
LOGGER.error("Error rerunning submissions already in queue", e); | ||
} | ||
return port(); | ||
} | ||
|
||
} |
Oops, something went wrong.