diff --git a/app/uk/gov/hmrc/cataloguefrontend/BobbyExplorerController.scala b/app/uk/gov/hmrc/cataloguefrontend/BobbyExplorerController.scala
new file mode 100644
index 000000000..1f07a7150
--- /dev/null
+++ b/app/uk/gov/hmrc/cataloguefrontend/BobbyExplorerController.scala
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 HM Revenue & Customs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package uk.gov.hmrc.cataloguefrontend
+
+import javax.inject.Inject
+import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
+import uk.gov.hmrc.cataloguefrontend.service.BobbyService
+import uk.gov.hmrc.play.bootstrap.controller.FrontendController
+import views.html.BobbyExplorerPage
+
+import scala.concurrent.ExecutionContext
+
+class BobbyExplorerController @Inject() (mcc : MessagesControllerComponents,
+ page : BobbyExplorerPage,
+ bobbyService: BobbyService
+ )( implicit val ec: ExecutionContext) extends FrontendController(mcc) {
+ def list(): Action[AnyContent] = Action.async { implicit request =>
+ bobbyService.getRules().map(r => Ok(page(r)))
+ }
+}
diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueFrontendModule.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueFrontendModule.scala
index 9406e1f07..8eb72031d 100644
--- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueFrontendModule.scala
+++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueFrontendModule.scala
@@ -16,12 +16,15 @@
package uk.gov.hmrc.cataloguefrontend
+import java.time.Clock
+
import com.google.inject.AbstractModule
import uk.gov.hmrc.cataloguefrontend.service.EventsReloadScheduler
class CatalogueFrontendModule extends AbstractModule {
- override def configure(): Unit =
+ override def configure(): Unit = {
+ bind(classOf[Clock]).toInstance(Clock.systemDefaultZone)
bind(classOf[EventsReloadScheduler]).asEagerSingleton()
-
-}
+ }
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/ConfigConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/ConfigConnector.scala
index 3e38452f3..2ed0cafb4 100644
--- a/app/uk/gov/hmrc/cataloguefrontend/connector/ConfigConnector.scala
+++ b/app/uk/gov/hmrc/cataloguefrontend/connector/ConfigConnector.scala
@@ -18,12 +18,13 @@ package uk.gov.hmrc.cataloguefrontend.connector
import javax.inject.{Inject, Singleton}
import play.api.libs.json._
+import uk.gov.hmrc.cataloguefrontend.connector.model.BobbyRuleSet
import uk.gov.hmrc.cataloguefrontend.service.ConfigService._
import uk.gov.hmrc.http.{HeaderCarrier, HttpReads, HttpResponse}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.http.HttpClient
-import scala.concurrent.ExecutionContext
+import scala.concurrent.{ExecutionContext, Future}
@Singleton
class ConfigConnector @Inject()(
@@ -50,4 +51,6 @@ class ConfigConnector @Inject()(
def configByKey(service: String)(implicit hc: HeaderCarrier) =
http.GET[ConfigByKey](s"$serviceConfigsBaseUrl/config-by-key/$service")
+
+ def bobbyRules()(implicit hc: HeaderCarrier): Future[BobbyRuleSet] = http.GET[BobbyRuleSet](s"$serviceConfigsBaseUrl/bobby/rules")
}
diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/model/BobbyRule.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/model/BobbyRule.scala
new file mode 100644
index 000000000..05bd2bc5b
--- /dev/null
+++ b/app/uk/gov/hmrc/cataloguefrontend/connector/model/BobbyRule.scala
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2019 HM Revenue & Customs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package uk.gov.hmrc.cataloguefrontend.connector.model
+
+import java.time.LocalDate
+
+import play.api.libs.json.{Json, Reads}
+
+case class BobbyRule(organisation: String, name: String, range: String, reason: String, from: LocalDate) {
+ val groupArtifactName: String = {
+ val wildcard = "*"
+ if (organisation == wildcard && name == wildcard) "*" else s"$organisation:$name"
+ }
+}
+object BobbyRule {
+ implicit val reader: Reads[BobbyRule] = Json.reads[BobbyRule]
+}
+
+case class BobbyRuleSet(libraries: Seq[BobbyRule], plugins: Seq[BobbyRule])
+object BobbyRuleSet {
+ implicit val reader: Reads[BobbyRuleSet] = Json.reads[BobbyRuleSet]
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/BobbyService.scala b/app/uk/gov/hmrc/cataloguefrontend/service/BobbyService.scala
new file mode 100644
index 000000000..75ad8c7a6
--- /dev/null
+++ b/app/uk/gov/hmrc/cataloguefrontend/service/BobbyService.scala
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 HM Revenue & Customs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package uk.gov.hmrc.cataloguefrontend.service
+
+import java.time.{Clock, LocalDate}
+
+import javax.inject.Inject
+import uk.gov.hmrc.cataloguefrontend.connector.ConfigConnector
+import uk.gov.hmrc.cataloguefrontend.connector.model.{BobbyRule, BobbyRuleSet}
+import uk.gov.hmrc.cataloguefrontend.service.model.BobbyRulesView
+import uk.gov.hmrc.http.HeaderCarrier
+
+import scala.concurrent.{ExecutionContext, Future}
+
+class BobbyService @Inject()(configConnector: ConfigConnector, clock: Clock)(implicit val ec: ExecutionContext) {
+
+ def getRules()(implicit hc: HeaderCarrier) : Future[BobbyRulesView] = {
+ val today = LocalDate.now(clock)
+ def filterUpcoming(rule: BobbyRule) = rule.from.isAfter(today)
+ def filterActive(rule: BobbyRule) = rule.from.isBefore(today) || rule.from.isEqual(today)
+ def compareUpcoming(rule1: BobbyRule, rule2: BobbyRule) = compareRules(rule1, rule2)(_ isBefore _)
+ def compareActive(rule1: BobbyRule, rule2: BobbyRule) = compareRules(rule1, rule2)(_ isAfter _)
+ def compareRules(x: BobbyRule, y: BobbyRule)(sortDirection: (LocalDate, LocalDate) => Boolean) =
+ if (x.from == y.from) x.groupArtifactName < y.groupArtifactName else sortDirection(x.from, y.from)
+
+ configConnector.bobbyRules().map(r => BobbyRulesView(
+ upcoming = BobbyRuleSet(libraries = r.libraries.filter(filterUpcoming).sortWith(compareUpcoming), plugins = r.plugins.filter(filterUpcoming).sortWith(compareUpcoming)),
+ active = BobbyRuleSet(libraries = r.libraries.filter(filterActive).sortWith(compareActive), plugins = r.plugins.filter(filterActive).sortWith(compareActive)))
+ )
+ }
+
+}
\ No newline at end of file
diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/model/BobbyRulesView.scala b/app/uk/gov/hmrc/cataloguefrontend/service/model/BobbyRulesView.scala
new file mode 100644
index 000000000..14711e569
--- /dev/null
+++ b/app/uk/gov/hmrc/cataloguefrontend/service/model/BobbyRulesView.scala
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 HM Revenue & Customs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package uk.gov.hmrc.cataloguefrontend.service.model
+
+import uk.gov.hmrc.cataloguefrontend.connector.model.BobbyRuleSet
+
+case class BobbyRulesView (upcoming: BobbyRuleSet, active: BobbyRuleSet)
\ No newline at end of file
diff --git a/app/views/BobbyExplorerPage.scala.html b/app/views/BobbyExplorerPage.scala.html
new file mode 100644
index 000000000..a54459bd4
--- /dev/null
+++ b/app/views/BobbyExplorerPage.scala.html
@@ -0,0 +1,68 @@
+@*
+ * Copyright 2019 HM Revenue & Customs
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *@
+
+@import uk.gov.hmrc.cataloguefrontend.ViewMessages
+@import uk.gov.hmrc.cataloguefrontend.connector.model.{BobbyRule, BobbyRuleSet}
+@import uk.gov.hmrc.cataloguefrontend.service.model.BobbyRulesView
+
+@this(viewMessages: ViewMessages)
+
+@(rules: BobbyRulesView)(implicit request: Request[_])
+
+@standard_layout(s"Bobby rules") {
+ Bobby Rules
+
@artifactType | +Version | +Reason | +Active from | +
---|