Skip to content

Commit

Permalink
Merge branch 'release/2.3.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
seratch committed Feb 12, 2015
2 parents ead7639 + ec5e2f2 commit 59d12a9
Show file tree
Hide file tree
Showing 28 changed files with 479 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AggregatorServicesModule extends Module {
bind[PartRequestServiceBase] to new PartRequestService(
inject[ConfigsRepository],
inject[HttpHandlerFactory]
) with PartResponseCachingSupport {
) with PartResponseCachingSupport with PartResponseLocalContentSupport {
val cacheOps = inject[CacheOps]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.m3.octoparts.aggregator.service

import com.m3.octoparts.aggregator.PartRequestInfo
import com.m3.octoparts.model.PartResponse
import com.m3.octoparts.model.config.{ HttpPartConfig, ShortPartParam }

import scala.concurrent.Future

trait PartResponseLocalContentSupport extends PartRequestServiceBase {

override def processWithConfig(ci: HttpPartConfig,
partRequestInfo: PartRequestInfo,
params: Map[ShortPartParam, Seq[String]]): Future[PartResponse] = {
if (ci.localContentsEnabled) {
Future(createPartResponse(ci, partRequestInfo))
} else {
super.processWithConfig(ci, partRequestInfo, params)
}
}

private def createPartResponse(ci: HttpPartConfig,
partRequestInfo: PartRequestInfo) = PartResponse(
ci.partId,
id = partRequestInfo.partRequestId,
statusCode = Some(200),
contents = ci.localContents,
retrievedFromLocalContents = true
)
}
11 changes: 10 additions & 1 deletion app/com/m3/octoparts/model/config/HttpPartConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import scala.util.Try
/**
* Model for holding configuration data for a Http dependency that
* comes with a companion-object that can populate it from the database
*
* @param localContentsEnabled whether local contents is enabled
* @param localContents the static contents which is used instead of actual contents of this part
*/
case class HttpPartConfig(id: Option[Long] = None, // None means that the record is new
partId: String,
Expand All @@ -30,6 +33,8 @@ case class HttpPartConfig(id: Option[Long] = None, // None means that the record
alertPercentThreshold: Option[Double],
alertInterval: FiniteDuration,
alertMailRecipients: Option[String],
localContentsEnabled: Boolean,
localContents: Option[String],
createdAt: DateTime,
updatedAt: DateTime) extends ConfigModel[HttpPartConfig] {

Expand Down Expand Up @@ -79,7 +84,9 @@ object HttpPartConfig {
alertAbsoluteThreshold = config.alertAbsoluteThreshold,
alertPercentThreshold = config.alertPercentThreshold,
alertInterval = config.alertInterval,
alertMailRecipients = config.alertMailRecipients
alertMailRecipients = config.alertMailRecipients,
localContentsEnabled = config.localContentsEnabled,
localContents = config.localContents
)
}

Expand All @@ -101,6 +108,8 @@ object HttpPartConfig {
alertPercentThreshold = config.alertPercentThreshold,
alertInterval = config.alertInterval,
alertMailRecipients = config.alertMailRecipients,
localContentsEnabled = config.localContentsEnabled,
localContents = config.localContents,
createdAt = DateTime.now,
updatedAt = DateTime.now
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ object HttpPartConfigRepository extends ConfigMapper[HttpPartConfig] with Timest
"alertAbsoluteThreshold" -> SkinnyParamType.Int,
"alertPercentThreshold" -> SkinnyParamType.Double,
"alertInterval" -> DurationParamType,
"alertMailRecipients" -> SkinnyParamType.String
"alertMailRecipients" -> SkinnyParamType.String,
"localContentsEnabled" -> SkinnyParamType.Boolean,
"localContents" -> SkinnyParamType.String
)

case object DurationParamType extends AbstractParamType({
Expand Down Expand Up @@ -155,6 +157,8 @@ object HttpPartConfigRepository extends ConfigMapper[HttpPartConfig] with Timest
alertPercentThreshold = rs.get(n.alertPercentThreshold),
alertInterval = rs.long(n.alertInterval).seconds,
alertMailRecipients = rs.get(n.alertMailRecipients),
localContentsEnabled = rs.get(n.localContentsEnabled),
localContents = rs.get(n.localContents),
createdAt = rs.get(n.createdAt),
updatedAt = rs.get(n.updatedAt)
)
Expand Down
22 changes: 19 additions & 3 deletions app/controllers/AdminForms.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ object AdminForms {
alertInterval: Option[Long],
alertAbsoluteThreshold: Option[Int],
alertPercentThreshold: Option[BigDecimal],
alertMailRecipients: Option[String]) {
alertMailRecipients: Option[String],
localContentsConfig: LocalContentsConfig) {
data =>

/** Create a brand new HttpPartConfig using the data input into the form */
Expand All @@ -56,6 +57,8 @@ object AdminForms {
alertAbsoluteThreshold = data.alertAbsoluteThreshold,
alertPercentThreshold = data.alertPercentThreshold.map(_.toDouble),
alertMailRecipients = data.alertMailRecipients,
localContentsEnabled = data.localContentsConfig.enabled,
localContents = data.localContentsConfig.contents,
createdAt = DateTime.now,
updatedAt = DateTime.now
)
Expand Down Expand Up @@ -83,6 +86,8 @@ object AdminForms {
alertAbsoluteThreshold = data.alertAbsoluteThreshold,
alertPercentThreshold = data.alertPercentThreshold.map(_.toDouble),
alertMailRecipients = data.alertMailRecipients,
localContentsEnabled = data.localContentsConfig.enabled,
localContents = data.localContentsConfig.contents,
updatedAt = DateTime.now
)

Expand All @@ -107,7 +112,10 @@ object AdminForms {
alertInterval = Some(part.alertInterval.toSeconds),
alertAbsoluteThreshold = part.alertAbsoluteThreshold,
alertPercentThreshold = part.alertPercentThreshold.map(BigDecimal(_)),
alertMailRecipients = part.alertMailRecipients
alertMailRecipients = part.alertMailRecipients,
localContentsConfig = LocalContentsConfig(
enabled = part.localContentsEnabled,
contents = part.localContents)
)

private def trimPartId(original: String): String = {
Expand Down Expand Up @@ -138,10 +146,18 @@ object AdminForms {
"alertInterval" -> optional(longNumber),
"alertAbsoluteThreshold" -> optional(number),
"alertPercentThreshold" -> optional(bigDecimal),
"alertMailRecipients" -> optional(text)
"alertMailRecipients" -> optional(text),
"localContentsConfig" -> mapping(
"enabled" -> boolean,
"contents" -> optional(text)
)(LocalContentsConfig.apply)(LocalContentsConfig.unapply)
)(PartData.apply)(PartData.unapply)
)

case class LocalContentsConfig(
enabled: Boolean,
contents: Option[String])

case class ParamData(
outputName: String,
inputNameOverride: Option[String],
Expand Down
52 changes: 51 additions & 1 deletion app/views/part/edit.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,31 @@
form.validationEngine({
prettySelect : true
});

var localContentsConfigContents = $("#localContentsConfig_contents");
var localContents = $("#localContents");

$("#jsonValidateButton").click(function () {
var valid = isValidJsonString(localContentsConfigContents.val());
localContents.toggleClass("has-success", valid);
localContents.toggleClass("has-error", !valid);
localContentsConfigContents.popover("show");
});

localContentsConfigContents.popover({trigger: "manual", content: function() {
var valid = isValidJsonString($(this).val());
return valid ? '@Messages("parts.localContents.contents.valid")' : '@Messages("parts.localContents.contents.invalid")';
}});

function isValidJsonString(s) {
try {
JSON.parse(s);
return true;
} catch (e) {
return false;
}
}

form.on('submit', function(e) {
var partIdInput = $('#partId');
var origPartId = partIdInput.data('orig-value');
Expand Down Expand Up @@ -238,6 +263,32 @@ <h2>@title</h2>
</div>
</fieldset>

<fieldset>
<legend>@Messages("parts.section.localContents")</legend>

<div class="form-group">
<label for="localContentsEnabled" class="col-sm-2 control-label">@Messages("parts.localContents.enabled")</label>
<div class="row">
<div class="col-sm-5">
@helper.checkbox(form("localContentsConfig.enabled"))
</div>
</div>
</div>

<div class="form-group" id="localContents">
<label for="localContents" class="col-sm-2 control-label">@Messages("parts.localContents.contents")</label>
<div class="row">
<div class="col-sm-5">
@helper.textarea(form("localContentsConfig.contents"),
'class -> "form-control",
'rows -> 12,
Symbol("data-placement") -> "top")
</div>
<button id="jsonValidateButton" type="button" class="btn btn-default">@Messages("parts.localContents.validateJson")</button>
</div>
</div>
</fieldset>

<br/>
<div class="form-group">
<label class="col-sm-2 control-label">&nbsp;</label>
Expand All @@ -248,5 +299,4 @@ <h2>@title</h2>
</div>
</div>
</form>

}
8 changes: 8 additions & 0 deletions app/views/part/list.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<th>@Messages("parts.partId")</th>
<th>@Messages("parts.url")</th>
<th>@Messages("parts.owner")</th>
<th>@Messages("parts.section.localContents")</th>
<th>@Messages("action")</th>
</tr>
</thead>
Expand All @@ -35,6 +36,13 @@
</td>
<td>@partView.uriToInterpolate</td>
<td>@partView.config.owner</td>
<td>
@if(partView.config.localContentsEnabled) {
@Messages("parts.localContents.enabled")
} else {
@Messages("parts.localContents.disabled")
}
</td>
<td width="390px">
<a href="@partView.tryItLink" class="btn btn-default">@Messages("parts.tryIt")</a>
<a href="@partView.detailLink" class="btn btn-success">@Messages("detail")</a>
Expand Down
7 changes: 7 additions & 0 deletions app/views/part/show.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,11 @@ <h2>@Messages("parts.section.alertMail")</h2>
<p>@Messages("parts.alertMail.none")</p>
}

<hr/>
<h2>@Messages("parts.section.localContents")</h2>
@if(part.config.localContentsEnabled) {
<pre>@part.config.localContents.orNull</pre>
} else {
<p>@Messages("parts.localContents.disabled")</p>
}
}
2 changes: 2 additions & 0 deletions conf/db/migration/default/V3__Add_local_content.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE http_part_config ADD COLUMN local_contents_enabled boolean DEFAULT false NOT NULL;
ALTER TABLE http_part_config ADD COLUMN local_contents text;
7 changes: 7 additions & 0 deletions conf/messages.en
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ parts.alertMail.interval.label=Interval (seconds)
parts.alertMail.selectOne=At least one of these must be selected
parts.alertMail.none=Disabled
parts.alertMail.enabled=Enabled
parts.section.localContents=Local content settings
parts.localContents.enabled=Enabled
parts.localContents.disabled=Disabled
parts.localContents.contents=Content
parts.localContents.validateJson=Validate JSON
parts.localContents.contents.valid=Valid JSON
parts.localContents.contents.invalid=Invalid JSON

tryIt.title=Try {0} !
tryIt.disable=Disable
Expand Down
7 changes: 7 additions & 0 deletions conf/messages.ja
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ parts.alertMail.interval.label=間隔(秒)
parts.alertMail.selectOne=どちらか指定必須、両方指定も可能
parts.alertMail.none=送信しません
parts.alertMail.enabled=有効
parts.section.localContents=ローカルコンテンツ設定
parts.localContents.enabled=有効
parts.localContents.disabled=無効
parts.localContents.contents=コンテンツ
parts.localContents.validateJson=JSON確認
parts.localContents.contents.valid=有効なJSONです
parts.localContents.contents.invalid=無効なJSONです

tryIt.title={0}の送信テスト
tryIt.disable=無効にする
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.m3.octoparts.client

import java.nio.charset.StandardCharsets

import com.fasterxml.jackson.databind.ObjectReader
import com.m3.octoparts.model.config.ParamType
import com.m3.octoparts.model.{ HttpMethod, AggregateRequest }
import com.m3.octoparts.model.config.json.HttpPartConfig
Expand Down Expand Up @@ -60,7 +61,8 @@ class OctopartsApiBuilderTest extends FunSpec with BeforeAndAfterAll with Matche
| "alertPercentThreshold": 5,
| "alertInterval": 60000
| }""".stripMargin
val partConfig = OctopartsApiBuilder.Mapper.reader(classOf[HttpPartConfig]).readValue[HttpPartConfig](source)
val reader: ObjectReader = OctopartsApiBuilder.Mapper.reader(classOf[HttpPartConfig])
val partConfig = reader.readValue[HttpPartConfig](source)
partConfig.method should be(HttpMethod.Put)
partConfig.parameters.head.paramType should be(ParamType.Header)
}
Expand Down
2 changes: 1 addition & 1 deletion maintainers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
- Run `./scripts/publish_libs.sh`
- Use `sbt sonatypeRelease` from `sbt-sonatype` plugin or access sonatype console (https://oss.sonatype.org/)
- Set version as "{next-version}-SNAPSHOT" on develop branch

- Update documentation (https://github.com/m3dev/octoparts-site/blob/develop/data/versions.yml)
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ case class ResponseMeta(@(ApiModelProperty @field)(required = true)@BeanProperty
* @param errors
* @param warnings
* @param retrievedFromCache
* @param retrievedFromLocalContents
*
*/
case class PartResponse(@(ApiModelProperty @field)(required = true)@BeanProperty partId: String,
Expand All @@ -65,7 +66,8 @@ case class PartResponse(@(ApiModelProperty @field)(required = true)@BeanProperty
@(ApiModelProperty @field)(required = false, dataType = "string")@BeanProperty contents: Option[String] = None,
@BeanProperty warnings: Seq[String] = Nil,
@BeanProperty errors: Seq[String] = Nil,
@(ApiModelProperty @field)(required = true)@BooleanBeanProperty retrievedFromCache: Boolean = false)
@(ApiModelProperty @field)(required = true)@BooleanBeanProperty retrievedFromCache: Boolean = false,
@(ApiModelProperty @field)(required = true)@BooleanBeanProperty retrievedFromLocalContents: Boolean = false)

/**
* Immutable wrapper for cookies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ case class HttpPartConfig(
@(ApiModelProperty @field)(dataType = "integer", required = false, allowableValues = "range[0, Infinity]") alertAbsoluteThreshold: Option[Int] = None,
@(ApiModelProperty @field)(dataType = "float", required = false, allowableValues = "range[0, 100]") alertPercentThreshold: Option[Double] = None,
@(ApiModelProperty @field)(dataType = "integer", required = true, allowableValues = "range[0, Infinity]", value = "in ms") alertInterval: FiniteDuration,
@(ApiModelProperty @field)(dataType = "string", required = false) alertMailRecipients: Option[String] = None)
@(ApiModelProperty @field)(dataType = "string", required = false) alertMailRecipients: Option[String] = None,
@(ApiModelProperty @field)(required = true) localContentsEnabled: Boolean = false,
@(ApiModelProperty @field)(dataType = "string", required = false) localContents: Option[String] = None)
Loading

0 comments on commit 59d12a9

Please sign in to comment.