Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 47 additions & 66 deletions app/bootstrap/AppConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,11 @@ import play.api.Configuration

case class S3Config(credentials: AWSCredentials, bucket: String, endpoint: Option[String])

private[bootstrap] case class AppConfig(
s3Config: S3Config,
allowAllSessions: Boolean,
allowExpiredTokens: Boolean,
appVersionOverride: String,
demoOrgId: ObjectId,
dynamoDbActivate: Boolean,
dynamoDbLocalInit: Boolean,
dynamoDbLocalPort: Int,
dynamoDbUseLocal: Boolean,
elasticSearchUrl: URL,
envName: String,
rootOrgId: ObjectId,
v2playerOrgIds: Seq[ObjectId],
archiveContentCollectionId: ObjectId,
archiveOrgId: ObjectId,
publicSite: String,
mongoUri: String,
componentFilteringEnabled: Boolean,
sessionService: String,
sessionServiceUrl: String,
sessionServiceAuthToken: String,
sessionServiceArchiveEnabled: Boolean)
private[bootstrap] class AppConfig(val config: Configuration) {

object AppConfig {

private object Key extends Enumeration {
object Key extends Enumeration {
type Key = Value
val ALLOW_ALL_SESSIONS, ALLOW_EXPIRED_TOKENS, AMAZON_ACCESS_KEY, AMAZON_ACCESS_SECRET, AMAZON_ASSETS_BUCKET, AMAZON_ENDPOINT, APP_VERSION_OVERRIDE, DEMO_ORG_ID, DYNAMO_DB_ACTIVATE, DYNAMO_DB_LOCAL_INIT, DYNAMO_DB_LOCAL_PORT, DYNAMO_DB_USE_LOCAL, ELASTIC_SEARCH_URL, ENV_NAME, ROOT_ORG_ID, V2_PLAYER_ORG_IDS, COMPONENT_FILTERING_ENABLED, SESSION_SERVICE, SESSION_SERVICE_URL, SESSION_SERVICE_AUTHTOKEN, SESSION_SERVICE_ARCHIVE_ENABLED = Value
val ALLOW_ALL_SESSIONS, ALLOW_EXPIRED_TOKENS, AMAZON_ACCESS_KEY, AMAZON_ACCESS_SECRET, AMAZON_ASSETS_BUCKET, AMAZON_ENDPOINT, APP_VERSION_OVERRIDE, DEMO_ORG_ID, DYNAMO_DB_ACTIVATE, DYNAMO_DB_LOCAL_INIT, DYNAMO_DB_LOCAL_PORT, DYNAMO_DB_USE_LOCAL, ELASTIC_SEARCH_URL, ENV_NAME, ROOT_ORG_ID, V2_PLAYER_ORG_IDS, COMPONENT_FILTERING_ENABLED, SESSION_SERVICE, SESSION_SERVICE_URL, SESSION_SERVICE_AUTHTOKEN, SESSION_SERVICE_ARCHIVE_ENABLED, LOAD_EXPIRED_ITEM_DRAFTS = Value
}

import Key._
Expand All @@ -45,45 +21,50 @@ object AppConfig {

private implicit def keyToString(k: Key.Key): String = k.toString

def apply(config: Configuration): AppConfig = {

def notFound(n: String) = throw new RuntimeException(s"Not found: $n")

def getString(key: String): String = config.getString(key).getOrElse(throw new RuntimeException(s"Key not found: $key"))

val credentials = new AWSCredentials {
override def getAWSAccessKeyId: String = config.getString(AMAZON_ACCESS_KEY).getOrElse("?")
override def getAWSSecretKey: String = config.getString(AMAZON_ACCESS_SECRET).getOrElse("?")
}

val s3Config = S3Config(
credentials,
bucket = config.getString(AMAZON_ASSETS_BUCKET).getOrElse("?"),
endpoint = config.getString(AMAZON_ENDPOINT))

AppConfig(
s3Config,
allowAllSessions = config.getBoolean(ALLOW_ALL_SESSIONS).getOrElse(false),
allowExpiredTokens = config.getBoolean(ALLOW_EXPIRED_TOKENS).getOrElse(false),
appVersionOverride = config.getString(APP_VERSION_OVERRIDE).getOrElse(""),
demoOrgId = config.getString(DEMO_ORG_ID).map(new ObjectId(_)).getOrElse(throw new RuntimeException("demoOrgId - Not found")),
dynamoDbActivate = config.getBoolean(DYNAMO_DB_ACTIVATE).getOrElse(false),
dynamoDbLocalInit = config.getBoolean(DYNAMO_DB_LOCAL_INIT).getOrElse(false),
dynamoDbLocalPort = config.getInt(DYNAMO_DB_LOCAL_PORT).getOrElse(8000),
dynamoDbUseLocal = config.getBoolean(DYNAMO_DB_USE_LOCAL).getOrElse(false),
elasticSearchUrl = new URL(config.getString(ELASTIC_SEARCH_URL).getOrElse("?")),
envName = config.getString(ENV_NAME).getOrElse("dev"),
rootOrgId = config.getString(ROOT_ORG_ID).map(new ObjectId(_)).getOrElse(throw new RuntimeException("rootOrgId - Not found")),
v2playerOrgIds = config.getString(V2_PLAYER_ORG_IDS).map(_.split(",").map(new ObjectId(_)).toSeq).getOrElse(Seq.empty[ObjectId]),
archiveContentCollectionId = new ObjectId(getString("archive.contentCollectionId")),
archiveOrgId = new ObjectId(getString("archive.orgId")),
publicSite = config.getString("publicSiteUrl").getOrElse("//www.corespring.org"),
mongoUri = getString("mongodb.default.uri"),
componentFilteringEnabled = config.getBoolean(COMPONENT_FILTERING_ENABLED).getOrElse(notFound(COMPONENT_FILTERING_ENABLED)),
sessionService = config.getString(SESSION_SERVICE).getOrElse("?"),
sessionServiceUrl = config.getString(SESSION_SERVICE_URL).getOrElse("?"),
sessionServiceAuthToken = config.getString(SESSION_SERVICE_AUTHTOKEN).getOrElse("?"),
sessionServiceArchiveEnabled = config.getBoolean(SESSION_SERVICE_ARCHIVE_ENABLED).getOrElse(false))
private def notFound(n: String) = throw new RuntimeException(s"Not found: $n")

private def getString(key: String): String = config.getString(key).getOrElse(throw new RuntimeException(s"Key not found: $key"))

lazy val credentials = new AWSCredentials {
override def getAWSAccessKeyId: String = config.getString(AMAZON_ACCESS_KEY).getOrElse("?")

override def getAWSSecretKey: String = config.getString(AMAZON_ACCESS_SECRET).getOrElse("?")
}

lazy val s3Config = S3Config(
credentials,
bucket = config.getString(AMAZON_ASSETS_BUCKET).getOrElse("?"),
endpoint = config.getString(AMAZON_ENDPOINT))

lazy val loadExpiredItemDrafts = config.getBoolean(LOAD_EXPIRED_ITEM_DRAFTS).getOrElse(false)

lazy val allowAllSessions = config.getBoolean(ALLOW_ALL_SESSIONS).getOrElse(false)

lazy val allowExpiredTokens = config.getBoolean(ALLOW_EXPIRED_TOKENS).getOrElse(false)

lazy val appVersionOverride = config.getString(APP_VERSION_OVERRIDE).getOrElse("")

lazy val demoOrgId = config.getString(DEMO_ORG_ID).map(new ObjectId(_)).getOrElse(throw new RuntimeException("demoOrgId - Not found"))
lazy val dynamoDbActivate = config.getBoolean(DYNAMO_DB_ACTIVATE).getOrElse(false)
lazy val dynamoDbLocalInit = config.getBoolean(DYNAMO_DB_LOCAL_INIT).getOrElse(false)
lazy val dynamoDbLocalPort = config.getInt(DYNAMO_DB_LOCAL_PORT).getOrElse(8000)
lazy val dynamoDbUseLocal = config.getBoolean(DYNAMO_DB_USE_LOCAL).getOrElse(false)
lazy val elasticSearchUrl = new URL(config.getString(ELASTIC_SEARCH_URL).getOrElse("?"))
lazy val envName = config.getString(ENV_NAME).getOrElse("dev")
lazy val rootOrgId = config.getString(ROOT_ORG_ID).map(new ObjectId(_)).getOrElse(throw new RuntimeException("rootOrgId - Not found"))
lazy val v2playerOrgIds = config.getString(V2_PLAYER_ORG_IDS).map(_.split(",").map(new ObjectId(_)).toSeq).getOrElse(Seq.empty[ObjectId])
lazy val archiveContentCollectionId = new ObjectId(getString("archive.contentCollectionId"))
lazy val archiveOrgId = new ObjectId(getString("archive.orgId"))
lazy val publicSite = config.getString("publicSiteUrl").getOrElse("//www.corespring.org")
lazy val mongoUri = getString("mongodb.default.uri")
lazy val componentFilteringEnabled = config.getBoolean(COMPONENT_FILTERING_ENABLED).getOrElse(notFound(COMPONENT_FILTERING_ENABLED))
lazy val sessionService = config.getString(SESSION_SERVICE).getOrElse("?")
lazy val sessionServiceUrl = config.getString(SESSION_SERVICE_URL).getOrElse("?")
lazy val sessionServiceAuthToken = config.getString(SESSION_SERVICE_AUTHTOKEN).getOrElse("?")
lazy val sessionServiceArchiveEnabled = config.getBoolean(SESSION_SERVICE_ARCHIVE_ENABLED).getOrElse(false)
}

object AppConfig {
def apply(config: Configuration): AppConfig = new AppConfig(config)
}

63 changes: 33 additions & 30 deletions app/bootstrap/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,71 @@ import bootstrap.Actors.UpdateItem
import com.amazonaws.auth.AWSCredentials
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
import com.amazonaws.services.s3.transfer.TransferManager
import com.amazonaws.services.s3.{AmazonS3, S3ClientOptions}
import com.amazonaws.services.s3.{ AmazonS3, S3ClientOptions }
import com.mongodb.casbah.MongoDB
import com.novus.salat.Context
import developer.{DeveloperConfig, DeveloperModule}
import filters.{BlockingFutureQueuer, CacheFilter, FutureQueuer}
import developer.{ DeveloperConfig, DeveloperModule }
import filters.{ BlockingFutureQueuer, CacheFilter, FutureQueuer }
import org.bson.types.ObjectId
import org.corespring.amazon.s3.{ConcreteS3Service, S3Service}
import org.corespring.api.tracking.{ApiTracking, ApiTrackingLogger, NullTracking}
import org.corespring.api.v1.{V1ApiExecutionContext, V1ApiModule}
import org.corespring.assets.{EncodedKeyS3Client, ItemAssetKeys}
import org.corespring.common.config.{CdnConfig, ItemAssetResolverConfig}
import org.corespring.container.client.component.{ComponentSetExecutionContext, ComponentsConfig}
import org.corespring.amazon.s3.{ ConcreteS3Service, S3Service }
import org.corespring.api.tracking.{ ApiTracking, ApiTrackingLogger, NullTracking }
import org.corespring.api.v1.{ V1ApiExecutionContext, V1ApiModule }
import org.corespring.assets.{ EncodedKeyS3Client, ItemAssetKeys }
import org.corespring.common.config.{ CdnConfig, ItemAssetResolverConfig }
import org.corespring.container.client.component.{ ComponentSetExecutionContext, ComponentsConfig }
import org.corespring.container.client.controllers.resources.SessionExecutionContext
import org.corespring.container.client.integration.{ContainerConfig, ContainerExecutionContext}
import org.corespring.container.client.{NewRelicRumConfig, V2PlayerConfig, VersionInfo}
import org.corespring.container.components.loader.{ComponentLoader, FileComponentLoader}
import org.corespring.container.client.integration.{ ContainerConfig, ContainerExecutionContext }
import org.corespring.container.client.{ NewRelicRumConfig, V2PlayerConfig, VersionInfo }
import org.corespring.container.components.loader.{ ComponentLoader, FileComponentLoader }
import org.corespring.container.components.model.Component
import org.corespring.conversion.qti.transformers.{ItemTransformer, ItemTransformerConfig, PlayerJsonToItem}
import org.corespring.conversion.qti.transformers.{ ItemTransformer, ItemTransformerConfig, PlayerJsonToItem }
import org.corespring.csApi.buildInfo.BuildInfo
import org.corespring.drafts.item.DraftAssetKeys
import org.corespring.drafts.item.models.{DraftId, OrgAndUser, SimpleOrg, SimpleUser}
import org.corespring.drafts.item.models.{ DraftId, OrgAndUser, SimpleOrg, SimpleUser }
import org.corespring.drafts.item.services.ItemDraftConfig
import org.corespring.encryption.EncryptionModule
import org.corespring.importing.validation.ItemSchema
import org.corespring.importing.{ImportingExecutionContext, ItemImportModule}
import org.corespring.itemSearch.{ElasticSearchConfig, ElasticSearchExecutionContext, ItemSearchModule}
import org.corespring.importing.{ ImportingExecutionContext, ItemImportModule }
import org.corespring.itemSearch.{ ElasticSearchConfig, ElasticSearchExecutionContext, ItemSearchModule }
import org.corespring.legacy.ServiceLookup
import org.corespring.models.appConfig._
import org.corespring.models.auth.ApiClient
import org.corespring.models.item.{ComponentType, FieldValue, Item}
import org.corespring.models.item.{ ComponentType, FieldValue, Item }
import org.corespring.models.json.JsonFormatting
import org.corespring.models.{Standard, Subject}
import org.corespring.models.{ Standard, Subject }
import org.corespring.platform.core.LegacyModule
import org.corespring.platform.core.services.item.SupportingMaterialsAssets
import org.corespring.platform.data.VersioningDao
import org.corespring.platform.data.mongo.models.VersionedId
import org.corespring.services.salat.ServicesContext
import org.corespring.services.salat.bootstrap._
import org.corespring.v2.actions.{DefaultV2Actions, V2ActionExecutionContext}
import org.corespring.v2.actions.{ DefaultV2Actions, V2ActionExecutionContext }
import org.corespring.v2.api._
import org.corespring.v2.api.services.{BasicScoreService, OrgScoringExecutionContext, ScoreService, ScoreServiceExecutionContext}
import org.corespring.v2.auth.identifiers.{PlayerTokenConfig, UserSessionOrgIdentity}
import org.corespring.v2.api.drafts.item.ItemDraftsConfig
import org.corespring.v2.api.services.{ BasicScoreService, OrgScoringExecutionContext, ScoreService, ScoreServiceExecutionContext }
import org.corespring.v2.auth.identifiers.{ PlayerTokenConfig, UserSessionOrgIdentity }
import org.corespring.v2.auth.models.OrgAndOpts
import org.corespring.v2.auth.{AccessSettingsCheckConfig, V2AuthModule}
import org.corespring.v2.auth.{ AccessSettingsCheckConfig, V2AuthModule }
import org.corespring.v2.errors.V2Error
import org.corespring.v2.player._
import org.corespring.v2.player.cdn._
import org.corespring.v2.player.hooks.StandardsTree
import org.corespring.v2.player.services.item.{DraftSupportingMaterialsService, ItemSupportingMaterialsService, MongoDraftSupportingMaterialsService, MongoItemSupportingMaterialsService}
import org.corespring.v2.player.services.item.{ DraftSupportingMaterialsService, ItemSupportingMaterialsService, MongoDraftSupportingMaterialsService, MongoItemSupportingMaterialsService }
import org.corespring.v2.sessiondb._
import org.corespring.web.common.controllers.deployment.{AssetsLoader, BranchAndHash}
import org.corespring.web.common.controllers.deployment.{ AssetsLoader, BranchAndHash }
import org.corespring.web.user.SecureSocial
import org.joda.time.DateTime
import play.api.Mode.{Mode => PlayMode}
import play.api.libs.json.{JsArray, Json}
import play.api.Mode.{ Mode => PlayMode }
import play.api.libs.json.{ JsArray, Json }
import play.api.mvc._
import play.api.{Configuration, Logger, Mode}
import play.api.{ Configuration, Logger, Mode }
import play.libs.Akka
import se.radley.plugin.salat.SalatPlugin
import v2Player.{Routes => V2PlayerRoutes}
import v2Player.{ Routes => V2PlayerRoutes }
import web.models.WebExecutionContext
import web.{PublicSiteConfig, WebModule, WebModuleConfig, WebV2Actions}
import web.{ PublicSiteConfig, WebModule, WebModuleConfig, WebV2Actions }

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.{ ExecutionContext, Future }
import scalaz.Validation

object Main {
Expand Down Expand Up @@ -262,6 +263,8 @@ class Main(
}
}

override lazy val itemDraftsConfig = ItemDraftsConfig(appConfig.loadExpiredItemDrafts)

override lazy val elasticSearchConfig = ElasticSearchConfig(
appConfig.elasticSearchUrl,
appConfig.mongoUri,
Expand Down
3 changes: 3 additions & 0 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ ALLOW_EXPIRED_TOKENS=${?ALLOW_EXPIRED_TOKENS}
COMPONENT_FILTERING_ENABLED=true
COMPONENT_FILTERING_ENABLED=${?COMPONENT_FILTERING_ENABLED}

LOAD_EXPIRED_ITEM_DRAFTS=false
LOAD_EXPIRED_ITEM_DRAFTS=${?LOAD_EXPIRED_ITEM_DRAFTS}

# Logger - @see logger.xml + logging/*.xml

# Salat/Mongo Settings
Expand Down
3 changes: 3 additions & 0 deletions it-resources/application-logger.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
</appender>

<logger name="ch.qos.logback" level="WARN"/>
<logger name="org.apache.http" level="WARN"/>
<logger name="com.amazonaws" level="WARN"/>
<logger name="org.corespring.it.helpers" level="DEBUG"/>
<logger name="org.corespring.it.IntegrationSpecification" level="DEBUG"/>
<logger name="org.corespring.it.ItemIndexCleaner" level="DEBUG"/>
<logger name="org.corespring" level="WARN"/>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
Expand Down
11 changes: 6 additions & 5 deletions it/org/corespring/drafts/ItemDraftsIntegrationTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@ import org.specs2.mutable.BeforeAfter

import scalaz.{ Failure, Success }

class ItemDraftsIntegrationTest extends IntegrationSpecification {

class ItemDraftsIntegrationSpecification extends IntegrationSpecification {
lazy val itemService = main.itemService
lazy val draftService = main.draftService

def bump(vid: VersionedId[ObjectId], count: Int = 1) = vid.copy(version = vid.version.map(_ + count))

trait orgAndUserAndItem extends userAndItem with BeforeAfter {
lazy val orgAndUser: OrgAndUser = OrgAndUser(SimpleOrg(user.org.orgId, "?"), Some(SimpleUser.fromUser(user)))

Expand All @@ -48,6 +45,11 @@ class ItemDraftsIntegrationTest extends IntegrationSpecification {
def draftIdFromItemIdAndUser(itemId: VersionedId[ObjectId], o: OrgAndUser): DraftId = {
DraftId(itemId.id, o.user.map(_.userName).getOrElse("test"), o.org.id)
}
}

class ItemDraftsIntegrationTest extends ItemDraftsIntegrationSpecification {

def bump(vid: VersionedId[ObjectId], count: Int = 1) = vid.copy(version = vid.version.map(_ + count))

"ItemDrafts" should {

Expand Down Expand Up @@ -250,7 +252,6 @@ class ItemDraftsIntegrationTest extends IntegrationSpecification {
}
}


"listForOrg" should {

"list drafts" in new orgAndUserAndItem {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.corespring.drafts

import org.corespring.drafts.item.services.ItemDraftDbUtils
import com.mongodb.casbah.Imports._
import org.joda.time.DateTime

import scalaz.{ Failure, Success }

class LoadOrCreateExpiredDraftIntegrationTest extends ItemDraftsIntegrationSpecification with ItemDraftDbUtils {

override val context = main.context

"loadOrCreate with expired draft" should {
"overwrite the expired draft when loadingOrCreating" in new orgAndUserAndItem {

val draftId = draftIdFromItemIdAndUser(itemId, orgAndUser)
drafts.loadOrCreate(orgAndUser)(draftId)

val loadedDraft = drafts.load(orgAndUser)(draftId)

logger.trace(s">> loadedDraft: $loadedDraft")
logger.trace(s">> expires: ${loadedDraft.toOption.get.expires}")
val collection = main.db.getCollection("drafts.items")
val update: DBObject = $set("expires" -> DateTime.now.minusHours(1))

//set the expires so that the item will no longer load
collection.findAndModify(
idToDbo(draftId),
MongoDBObject.empty,
MongoDBObject.empty,
false,
update,
true,
false)

val secondLoadedDraft = drafts.load(orgAndUser)(draftId)

//the draft has expired so we can't load it any more
secondLoadedDraft.isFailure must_== true

logger.trace(s">> secondLoadedDraft: $secondLoadedDraft")

drafts.loadOrCreate(orgAndUser)(draftId) match {
case Failure(e) => ko("shouldnt be getting an error.")
case Success(draft) => {
logger.trace(s"overwritten draft expires: ${draft.expires}")
draft.expires.isAfter(DateTime.now) must_== true
}
}
}
}
}
Loading