diff --git a/apps/dashboard-app/src/main/resources/reference.conf b/apps/dashboard-app/src/main/resources/reference.conf index e1891c4f0..af6432c2c 100644 --- a/apps/dashboard-app/src/main/resources/reference.conf +++ b/apps/dashboard-app/src/main/resources/reference.conf @@ -1,47 +1,47 @@ shrine { - admin { + dashboard { gruntWatch = false //false for production, true for mvn tomcat7:run . Allows the client javascript and html files to be loaded via gruntWatch . happyBaseUrl = "http://localhost:6060/shrine/rest/happy" } pmEndpoint { url = "http://changeme.com/i2b2/services/PMService/getServices" //"http://services.i2b2.org/i2b2/services/PMService/getServices" acceptAllCerts = true timeout { seconds = 1 } } authenticate { realm = "SHRINE Steward API" usersource { type = "PmUserSource" //Must be ConfigUserSource (for isolated testing) or PmUserSource (for everything else) - domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in admin.conf" //"i2b2demo" + domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in dashboard.conf" //"i2b2demo" } } // If the pmEndpoint acceptAllCerts = false then you need to supply a keystore // keystore { // file = "shrine.keystore" // password = "chiptesting" // privateKeyAlias = "test-cert" // keyStoreType = "JKS" // caCertAliases = [carra ca] // } } //todo typesafe config precedence seems to do the right thing, but I haven't found the rules that say this reference.conf should override others akka { loglevel = INFO // log-config-on-start = on loggers = ["akka.event.slf4j.Slf4jLogger"] // logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" } spray.servlet { boot-class = "net.shrine.dashboard.Boot" request-timeout = 30s } diff --git a/apps/dashboard-app/src/main/scala/net/shrine/dashboard/DashboardService.scala b/apps/dashboard-app/src/main/scala/net/shrine/dashboard/DashboardService.scala index a8c641574..8cd29e689 100644 --- a/apps/dashboard-app/src/main/scala/net/shrine/dashboard/DashboardService.scala +++ b/apps/dashboard-app/src/main/scala/net/shrine/dashboard/DashboardService.scala @@ -1,150 +1,150 @@ package net.shrine.dashboard import akka.actor.{ActorSystem, Actor} import akka.event.Logging import net.shrine.authentication.UserAuthenticator import net.shrine.authorization.steward.OutboundUser import net.shrine.i2b2.protocol.pm.User import net.shrine.dashboard.httpclient.HttpClientDirectives.httpRequestWithUnmatchedPath import shapeless.HNil import spray.http.{HttpResponse, HttpRequest, StatusCodes} import spray.httpx.Json4sSupport import spray.routing.directives.LogEntry import spray.routing.{AuthenticationFailedRejection, Rejected, RouteConcatenation, Directive0, Route, HttpService} import org.json4s.{DefaultFormats, Formats} import scala.concurrent.ExecutionContext.Implicits.global // we don't implement our route structure directly in the service actor because // we want to be able to test it independently, without having to spin up an actor class DashboardServiceActor extends Actor with DashboardService { // the HttpService trait defines only one abstract member, which // connects the services environment to the enclosing actor or test def actorRefFactory = context // this actor only runs our route, but you could add // other things here, like request stream processing // or timeout handling def receive = runRoute(route) } // this trait defines our service behavior independently from the service actor trait DashboardService extends HttpService with Json4sSupport { implicit def json4sFormats: Formats = DefaultFormats val userAuthenticator = UserAuthenticator(DashboardConfigSource.config) //don't need to do anything special for unauthorized users, but they do need access to a static form. lazy val route:Route = gruntWatchCorsSupport{ staticResources ~ makeTrouble ~ about ~ authenticatedInBrowser } // logs just the request method, uri and response at info level def logEntryForRequestResponse(req: HttpRequest): Any => Option[LogEntry] = { case res: HttpResponse => { Some(LogEntry(s"\n Request: $req \n Response: $res", Logging.InfoLevel)) } case _ => None // other kind of responses } // logs just the request method, uri and response status at info level def logEntryForRequest(req: HttpRequest): Any => Option[LogEntry] = { case res: HttpResponse => { Some(LogEntry(s"\n Request: $req \n Response status: ${res.status}", Logging.InfoLevel)) } case _ => None // other kind of responses } //pathPrefixTest shields the QEP code from the redirect. def authenticatedInBrowser: Route = pathPrefixTest("user"|"admin") { logRequestResponse(logEntryForRequestResponse _) { //logging is controlled by Akka's config, slf4j, and log4j config reportIfFailedToAuthenticate { authenticate(userAuthenticator.basicUserAuthenticator) { user => pathPrefix("user") { userRoute(user) } ~ pathPrefix("admin") { adminRoute(user) } } } } } val reportIfFailedToAuthenticate = routeRouteResponse { case Rejected(List(AuthenticationFailedRejection(_,_))) => complete("AuthenticationFailed") } def makeTrouble = pathPrefix("makeTrouble") { complete(throw new IllegalStateException("fake trouble")) } lazy val staticResources = pathPrefix("client"){ logRequestResponse(logEntryForRequest _){ getFromResourceDirectory("client") } ~ pathEnd { redirect("shrine-dashboard/client/index.html", StatusCodes.PermanentRedirect) //todo pick up the top of the url from context instead of hard-coded "shrine-dashboard" } ~ path( "index.html" ) { redirect("client/index.html", StatusCodes.PermanentRedirect) } ~ pathSingleSlash { redirect("client/index.html", StatusCodes.PermanentRedirect) } } lazy val about = pathPrefix("about") { complete("Nothing here yet") //todo } def userRoute(user:User):Route = get { pathPrefix("whoami") { complete(OutboundUser.createFromUser(user)) } } //todo is this an admin? Does it matter? def adminRoute(user:User):Route = get { pathPrefix("happy") { - val happyBaseUrl = DashboardConfigSource.config.getString("shrine.admin.happyBaseUrl") + val happyBaseUrl = DashboardConfigSource.config.getString("shrine.dashboard.happyBaseUrl") implicit val system = ActorSystem("sprayServer") httpRequestWithUnmatchedPath(happyBaseUrl) } } } //adapted from https://gist.github.com/joseraya/176821d856b43b1cfe19 object gruntWatchCorsSupport extends Directive0 with RouteConcatenation { import spray.http.HttpHeaders.{`Access-Control-Allow-Methods`, `Access-Control-Max-Age`, `Access-Control-Allow-Headers`,`Access-Control-Allow-Origin`} import spray.routing.directives.RespondWithDirectives.respondWithHeaders import spray.routing.directives.MethodDirectives.options import spray.routing.directives.RouteDirectives.complete import spray.http.HttpMethods.{OPTIONS,GET,POST} import spray.http.AllOrigins private val allowOriginHeader = `Access-Control-Allow-Origin`(AllOrigins) private val optionsCorsHeaders = List( `Access-Control-Allow-Headers`("Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, User-Agent, Authorization"), `Access-Control-Max-Age`(1728000)) //20 days - val gruntWatch:Boolean = DashboardConfigSource.config.getBoolean("shrine.admin.gruntWatch") + val gruntWatch:Boolean = DashboardConfigSource.config.getBoolean("shrine.dashboard.gruntWatch") override def happly(f: (HNil) => Route): Route = { if(gruntWatch) { options { respondWithHeaders(`Access-Control-Allow-Methods`(OPTIONS, GET, POST) :: allowOriginHeader :: optionsCorsHeaders){ complete(StatusCodes.OK) } } ~ f(HNil) } else f(HNil) } } diff --git a/apps/dashboard-app/src/test/resources/log4j.properties b/apps/dashboard-app/src/test/resources/log4j.properties index d4b45f8d4..05223de6b 100644 --- a/apps/dashboard-app/src/test/resources/log4j.properties +++ b/apps/dashboard-app/src/test/resources/log4j.properties @@ -1,19 +1,19 @@ # LOG Pattern Layouts are covered here: http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html # ROOT CONFIGURATION log4j.rootLogger=info, R log4j.appender.R=org.apache.log4j.DailyRollingFileAppender log4j.appender.R.DatePattern='.'yyyy-MM-dd -log4j.appender.R.File=logs/shrine-admin.log +log4j.appender.R.File=logs/shrine-dashboard.log log4j.appender.R.layout=net.shrine.log.CustomPatternLayout log4j.appender.R.layout.ConversionPattern=%d{yyyy-MMM-dd-HH:mm:ss.SSS} %p [ROOT][%c{1}][%t] %m %n %throwable # Shrine log4j.logger.net.shrine=debug, shrine log4j.additivity.net.shrine=false log4j.appender.shrine=org.apache.log4j.DailyRollingFileAppender log4j.appender.shrine.DatePattern='.'yyyy-MM-dd -log4j.appender.shrine.File=logs/shrine-admin.log +log4j.appender.shrine.File=logs/shrine-dashboard.log log4j.appender.shrine.layout=net.shrine.log.CustomPatternLayout -log4j.appender.shrine.layout.ConversionPattern=%d{yyyy-MMM-dd-HH:mm:ss.SSS} %p [SHRINE][%c{1}][%t] %m %n %throwable +log4j.appender.shrine.layout.ConversionPattern=%d{yyyy-MMM-dd-HH:mm:ss.SSS} %p [DASHBOARD][%c{1}][%t] %m %n %throwable diff --git a/apps/dashboard-war/src/main/resources/reference.conf b/apps/dashboard-war/src/main/resources/reference.conf index c033e30d0..4b089eb02 100644 --- a/apps/dashboard-war/src/main/resources/reference.conf +++ b/apps/dashboard-war/src/main/resources/reference.conf @@ -1,47 +1,47 @@ shrine { - admin { + dashboard { gruntWatch = false //false for production, true for mvn tomcat7:run . Allows the client javascript and html files to be loaded via gruntWatch . } pmEndpoint { url = "http://changeme.com/i2b2/services/PMService/getServices" //"http://services.i2b2.org/i2b2/services/PMService/getServices" acceptAllCerts = true timeout { seconds = 1 } } // If the pmEndpoint acceptAllCerts = false then you need to supply a keystore // keystore { // file = "shrine.keystore" // password = "chiptesting" // privateKeyAlias = "test-cert" // keyStoreType = "JKS" // caCertAliases = [carra ca] // } authenticate { realm = "SHRINE API" usersource { type = "PmUserSource" //Must be ConfigUserSource (for isolated testing) or PmUserSource (for everything else) - domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in admin.conf" //"i2b2demo" + domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in dashboard.conf" //"i2b2demo" } } } //todo typesafe config precedence seems to do the right thing, but I haven't found the rules that say this reference.conf should override others akka { loglevel = INFO // log-config-on-start = on loggers = ["akka.event.slf4j.Slf4jLogger"] // logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" } spray.servlet { boot-class = "net.shrine.dashboard.Boot" request-timeout = 30s } diff --git a/commons/auth/src/test/resources/admin.conf b/commons/auth/src/test/resources/dashboard.conf similarity index 100% rename from commons/auth/src/test/resources/admin.conf rename to commons/auth/src/test/resources/dashboard.conf diff --git a/commons/auth/src/test/scala/net/shrine/authentication/ConfigUserSourceTest.scala b/commons/auth/src/test/scala/net/shrine/authentication/ConfigUserSourceTest.scala index c9b90a5ea..97a5424a7 100644 --- a/commons/auth/src/test/scala/net/shrine/authentication/ConfigUserSourceTest.scala +++ b/commons/auth/src/test/scala/net/shrine/authentication/ConfigUserSourceTest.scala @@ -1,23 +1,23 @@ package net.shrine.authentication import com.typesafe.config.ConfigFactory import net.shrine.util.ShouldMatchersForJUnit import org.junit.Test /** * @author david * @since 8/12/15 */ class ConfigUserSourceTest extends ShouldMatchersForJUnit { @Test def testIsAuthenticated { - val config = ConfigFactory.load("admin") + val config = ConfigFactory.load("dashboard") val userSource = ConfigUserSource.apply(config) userSource.qepUserName should equal("qep") } } diff --git a/pom.xml b/pom.xml index 6f4b79b4e..dbbfa1102 100644 --- a/pom.xml +++ b/pom.xml @@ -1,361 +1,361 @@ 4.0.0 SHRINE net.shrine shrine-base pom 1.20.0-SNAPSHOT UTF-8 4.1.6.RELEASE 2.6.2 2.11.7 2.11 4.12 1.7.12 1.2.17 1.19 2.2.5 3.2.0 0.9.6-RC3 1.2.1 1.4.185 3.3.1 5.1.35 2.3 3.0.1 0.9.5 1.3.3 2.3.8 2.3.11 3.2.11 3.0.0 apps/dashboard-app apps/dashboard-war apps/steward-app apps/steward-war apps/proxy apps/shrine-app apps/war qep/service hub/broadcaster-aggregator hub/broadcaster-service adapter/adapter-api adapter/adapter-service hms-support tools commons/util commons/auth commons/protocol-query commons/data-commons commons/protocol commons/crypto commons/client commons/config commons/ont-support commons/test-commons install integration shrine-webclient net.alchim31.maven scala-maven-plugin ${scala-maven-plugin-version} compile testCompile incremental true -XX:+AggressiveOpts -XX:CompileThreshold=500 -XX:+UseFastAccessorMethods -XX:+UseStringCache -XX:+OptimizeStringConcat -XX:+TieredCompilation -XX:+UseConcMarkSweepGC -XX:+DoEscapeAnalysis -server -Xms64m -Xmx1024m -XX:MaxPermSize=384m ${scala-version} -Xcheckinit -unchecked -deprecation -Xlint:adapted-args,inaccessible,infer-any,missing-interpolator,private-shadow,type-parameter-shadow,unsound-match maven-compiler-plugin 1.6 1.6 org.codehaus.mojo buildnumber-maven-plugin 1.1 org.apache.maven.plugins maven-jar-plugin 2.4 org.apache.maven.plugins maven-war-plugin 2.1.1 org.codehaus.mojo buildnumber-maven-plugin validate create {0,date,yyyy-MM-dd HH:mm:ss} (not available) org.apache.maven.plugins maven-jar-plugin true ${buildNumber} ${scmBranch} ${timestamp} org.apache.maven.plugins maven-war-plugin true ${buildNumber} ${scmBranch} ${timestamp} org.apache.tomcat.maven tomcat7-maven-plugin 2.2 true true true - true - http://shrine-dev1.catalyst:6060/shrine/rest/happy + true + http://shrine-dev1.catalyst:6060/shrine/rest/happy scm:svn:https://open.med.harvard.edu/svn/shrine/trunk/code scm:svn:https://open.med.harvard.edu/svn/shrine/trunk/code https://open.med.harvard.edu/svn/shrine/trunk/code CBMI-Nexus https://repo.open.med.harvard.edu/nexus/content/groups/public/ com.typesafe config ${typesafe-config-version} log4j log4j ${log4j-version} org.springframework spring-jdbc ${spring.version} test com.h2database h2 ${h2-version} test org.easymock easymock ${easymock-version} test org.slf4j slf4j-log4j12 ${slf4j-version} test mysql mysql-connector-java ${mysql-version} net.sf.opencsv opencsv ${opencsv-version} net.liftweb lift-json_${scala-major-version} ${lift-version} com.sun.jersey jersey-server ${jersey-version} com.sun.jersey jersey-servlet ${jersey-version} com.sun.jersey jersey-client ${jersey-version} org.squeryl squeryl_${scala-major-version} ${squeryl-version} javax.servlet javax.servlet-api ${servlet-api-version} provided org.scala-lang scala-library ${scala-version} junit junit ${junit-version} test org.scalatest scalatest_${scala-major-version} ${scalatest-version} test org.scala-lang scala-actors org.scala-lang scala-reflect org.scala-lang scala-actors ${scala-version} test org.scala-lang scala-reflect ${scala-version} nexus Nexus Repo https://repo.open.med.harvard.edu/nexus/content/repositories/snapshots false nexus Nexus Repo https://repo.open.med.harvard.edu/nexus/content/repositories/releases