Skip to content

Commit

Permalink
Fix tests - WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
patelh committed Apr 9, 2019
1 parent 79231d6 commit b7afe64
Show file tree
Hide file tree
Showing 63 changed files with 1,264 additions and 1,217 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,21 @@ You should increase the above for large # of consumers with consumer polling ena

Kafka managed consumer offset is now consumed by KafkaManagedOffsetCache from the "__consumer_offsets" topic. Note, this has not been tested with large number of offsets being tracked. There is a single thread per cluster consuming this topic so it may not be able to keep up on large # of offsets being pushed to the topic.

Authenticating a User with LDAP:
Warning, you need to have SSL configured with Kafka Manager to ensure your credentials aren't passed unencrypted.
Authenticating a User with LDAP is possible by passing the user credentials with the Authorization header.
LDAP authentication is done on first visit, if successful, a cookie is set.
On next request, the cookie value is compared with credentials from Authorization header.
LDAP support is through the basic authentication filter.

1. Configure basic authentication
- basicAuthentication.enabled=true
- basicAuthentication.realm=< basic authentication realm>

Encryption parameters :
- basicAuthentication.salt="<hex-string>"
- basicAuthentication.iv="<hex-string>"
- basicAuthentication.secret="my-secret-string"

2. Configure LDAP/LDAPS authentication

- basicAuthentication.ldap.enabled=< Boolean flag to enable/disable ldap authentication >
Expand Down
337 changes: 231 additions & 106 deletions app/controllers/BasicAuthenticationFilter.scala

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions app/kafka/manager/actor/KafkaManagerActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,13 @@ class KafkaManagerActor(kafkaManagerConfig: KafkaManagerActorConfig)
Future {
try {
log.debug(s"Acquiring kafka manager mutex...")
mutex.acquire(kafkaManagerConfig.mutexTimeoutMillis,TimeUnit.MILLISECONDS)
KMCommandResult(Try {
fn
})
if(mutex.acquire(kafkaManagerConfig.mutexTimeoutMillis,TimeUnit.MILLISECONDS)) {
KMCommandResult(Try {
fn
})
} else {
throw new RuntimeException("Failed to acquire lock for kafka manager command")
}
} finally {
if(mutex.isAcquiredInThisProcess) {
log.debug(s"Releasing kafka manger mutex...")
Expand Down
7 changes: 5 additions & 2 deletions app/kafka/manager/actor/cluster/ClusterManagerActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,11 @@ class ClusterManagerActor(cmConfig: ClusterManagerActorConfig)

private[this] def modify[T](fn: => T): T = {
try {
mutex.acquire(cmConfig.mutexTimeoutMillis,TimeUnit.MILLISECONDS)
fn
if(mutex.acquire(cmConfig.mutexTimeoutMillis,TimeUnit.MILLISECONDS)) {
fn
} else {
throw new RuntimeException("Failed to acquire mutex for cluster manager command")
}
} finally {
if(mutex.isAcquiredInThisProcess) {
mutex.release()
Expand Down
14 changes: 9 additions & 5 deletions app/views/broker/brokerList.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,25 @@
menu = theMenu,
breadcrumbs=views.html.navigation.breadCrumbs(models.navigation.BreadCrumbs.withViewAndCluster("Brokers",cluster))) {
<div class="col-md-7 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading">
<div class="card">
<div class="card-header">
<h3>
<button type="button" class="btn btn-link" onclick="goBack()">
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
<span class="octicon octicon-arrow-left" aria-hidden="true"></span>
</button>Brokers
</h3>
</div>
<div class="card-body">
@errorOrBrokers.fold( views.html.errors.onApiError(_), views.html.broker.brokerListContent(cluster,_) )
</div>
</div>
</div>
<div class="col-md-5 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading"><h3>Combined Metrics</h3></div>
<div class="card">
<div class="card-header"><h3>Combined Metrics</h3></div>
<div class="card-body">
@errorOrBrokers.fold( views.html.errors.onApiError(_), bl => renderBrokerMetrics(bl))
</div>
</div>
</div>

Expand Down
10 changes: 6 additions & 4 deletions app/views/broker/brokerView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
breadcrumbs=views.html.navigation.breadCrumbs(models.navigation.BreadCrumbs.withNamedViewAndCluster("Broker View",cluster,brokerId.toString)),
scripts=brokerScripts) {
<div class="col-md-12 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading">
<h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span></button>Broker Id @brokerId</h3>
</div>
<div class="card">
<div class="card-header">
<h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="octicon octicon-arrow-left" aria-hidden="true"></span></button>Broker Id @brokerId</h3>
</div>
<div class="card-body">
@errorOrBrokerView.fold[Html](views.html.errors.onApiError(_), views.html.broker.brokerViewContent(cluster, brokerId, _))
</div>
</div>
</div>
}
24 changes: 16 additions & 8 deletions app/views/broker/brokerViewContent.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

<div class="row">
<div class="col-md-7">
<div class="panel panel-default">
<div class="panel-heading"><h4>Summary</h4></div>
<div class="card">
<div class="card-header"><h4>Summary</h4></div>
<div class="card-body">
<table class="table">
<tbody>
<tr><td># of Topics</td><td>@brokerView.numTopics</td></tr>
Expand All @@ -30,19 +31,23 @@
}
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-5">
<div class="panel panel-default">
<div class="panel-heading"><h4>Metrics</h4></div>
<div class="card">
<div class="card-header"><h4>Metrics</h4></div>
<div class="card-body">
@renderBrokerMetrics
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading"><h4>Messages count</h4></div>
<div class="card">
<div class="card-header"><h4>Messages count</h4></div>
<div class="card-body">
<div class="ct-chart"></div>
<script>
var options = {
Expand All @@ -61,11 +66,13 @@
};
new Chartist.Line('.ct-chart', data, options);
</script>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><h4>Per Topic Detail</h4></div>
<div class="card">
<div class="card-header"><h4>Per Topic Detail</h4></div>
<div class="card-body">
<table class="table" id="broker-table" style="table-layout: fixed; width: 100%">
<thead>
<tr>
Expand All @@ -92,5 +99,6 @@
}
</tbody>
</table>
</div>
</div>

15 changes: 7 additions & 8 deletions app/views/cluster/addCluster.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
*@
@(addClusterForm: Form[kafka.manager.model.ClusterConfig])(implicit messages: play.api.i18n.Messages, menus: models.navigation.Menus, request:RequestHeader)

@import b4.vertical.fieldConstructor
@import controllers.routes

@theMenu = {
@views.html.navigation.defaultMenu(views.html.navigation.menuNav("Cluster","Add Cluster",menus.indexMenu))
}

@checkboxWithLink(field: play.api.data.Field) = {
@b4.inputFormGroup(field, withFeedback = false, withLabelFor = false, views.html.bs.Args.withDefault(Seq(), 'disabled -> false)) { fieldInfo =>
@checkboxWithLink(field: play.api.data.Field)(implicit fc: b4.B4FieldConstructor, msgsProv: MessagesProvider) = {
@b4.inputFormGroup(field, withLabelFor = false, views.html.bs.Args.withDefault(Seq(), 'disabled -> false)) { fieldInfo =>
<div class="checkbox">
<label for="@fieldInfo.id">
<input type="checkbox" id="@fieldInfo.id" name="@fieldInfo.name" value="true" @if(fieldInfo.value == Some("true")){checked} @toHtmlArgs(fieldInfo.innerArgsMap)>
Expand All @@ -23,7 +22,7 @@
}

@drawForm(form : Form[kafka.manager.model.ClusterConfig]) = {
@b4.form(routes.Cluster.handleAddCluster.copy(url = routes.Cluster.handleAddCluster.relative)) {
@b4.vertical.form(routes.Cluster.handleAddCluster.copy(url = routes.Cluster.handleAddCluster.relative)) { implicit fc =>
<fieldset>
@b4.text(form("name"), '_label -> "Cluster Name", 'placeholder -> "", 'autofocus -> true )
@b4.text(form("zkHosts"), '_label -> "Cluster Zookeeper Hosts", 'placeholder -> "zk1:2181,zk2:2181,zk3:2181/NAMESPACE")
Expand Down Expand Up @@ -59,16 +58,16 @@
@b4.select(form("saslMechanism"), options = kafka.manager.model.SASLmechanism.formSelectList, '_label -> "SASL Mechanism (only applies to SASL based security)" )
@b4.text(form("jaasConfig"), '_label -> "SASL JAAS Config (only applies to SASL based security)")
@b4.submit('class -> "submit-button btn btn-primary"){ Save }
<a href="@routes.Application.index().relative" class="cancel-button btn btn-default" role="button">Cancel</a>
<a href="@routes.Application.index()" class="cancel-button btn btn-secondary" role="button">Cancel</a>
</fieldset>
}
}

@main("Add Cluster", menu = theMenu, breadcrumbs = views.html.navigation.breadCrumbs(models.navigation.BreadCrumbs.withView("Add Cluster"))) {
<div class="col-md-6 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading"><h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span></button>Add Cluster</h3></div>
<div class="panel-body">
<div class="card">
<div class="card-header"><h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="octicon octicon-arrow-left" aria-hidden="true"></span></button>Add Cluster</h3></div>
<div class="card-body">
@drawForm(addClusterForm)
</div>
</div>
Expand Down
18 changes: 8 additions & 10 deletions app/views/cluster/clusterList.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
*@
@(clusters: IndexedSeq[kafka.manager.model.ClusterConfig])(implicit af: features.ApplicationFeatures, messages: play.api.i18n.Messages, request:RequestHeader)

@import b4.vertical.fieldConstructor

<table class="table">
<thead>
<tr><th>Active</th><th>Operations</th><th>Version</th></tr>
Expand All @@ -21,34 +19,34 @@
}
</td>
<td>
<div class="btn-group-horizontal" role="group" aria-label="...">
<div class="form-group" role="group" aria-label="Cluster Operations">
@features.app(features.KMClusterManagerFeature) {
@if(cluster.enabled) {
<a href="@routes.Cluster.updateCluster(cluster.name).relative" class="btn btn-default ops-button" role="button">Modify</a>
@b4.form(routes.Cluster.handleUpdateCluster(cluster.name).copy(url=routes.Cluster.handleUpdateCluster(cluster.name).relative)) {
<a href="@routes.Cluster.updateCluster(cluster.name).relative" class="btn btn-outline-primary" role="button">Modify</a>
@b4.vertical.form(routes.Cluster.handleUpdateCluster(cluster.name).copy(url=routes.Cluster.handleUpdateCluster(cluster.name).relative)) { implicit fc =>
<input type="hidden" name="name" value="@cluster.name">
<input type="hidden" name="kafkaVersion" value="@cluster.version.toString">
<input type="hidden" name="zkHosts" value="@cluster.curatorConfig.zkConnect">
<input type="hidden" name="securityProtocol" value="@cluster.securityProtocol.stringId">
<input type="hidden" name="operation" value="Disable">
@b4.submit('class -> "btn btn-warning ops-button"){ Disable }
@b4.submit('class -> "btn btn-outline-warning"){ Disable }
}
} else {
@b4.form(routes.Cluster.handleUpdateCluster(cluster.name)) {
@b4.vertical.form(routes.Cluster.handleUpdateCluster(cluster.name)) { implicit fc =>
<input type="hidden" name="name" value="@cluster.name">
<input type="hidden" name="kafkaVersion" value="@cluster.version.toString">
<input type="hidden" name="zkHosts" value="@cluster.curatorConfig.zkConnect">
<input type="hidden" name="securityProtocol" value="@cluster.securityProtocol.stringId">
<input type="hidden" name="operation" value="Enable">
@b4.submit('class -> "btn btn-success ops-button"){ Enable }
@b4.submit('class -> "btn btn-outline-success"){ Enable }
}
@b4.form(routes.Cluster.handleUpdateCluster(cluster.name)) {
@b4.vertical.form(routes.Cluster.handleUpdateCluster(cluster.name)) { implicit fc =>
<input type="hidden" name="name" value="@cluster.name">
<input type="hidden" name="kafkaVersion" value="@cluster.version.toString">
<input type="hidden" name="zkHosts" value="@cluster.curatorConfig.zkConnect">
<input type="hidden" name="securityProtocol" value="@cluster.securityProtocol.stringId">
<input type="hidden" name="operation" value="Delete">
@b4.submit('class -> "btn btn-danger ops-button"){ Delete }
@b4.submit('class -> "btn btn-outline-danger"){ Delete }
}
}
}
Expand Down
12 changes: 8 additions & 4 deletions app/views/cluster/clusterViewContent.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
@(cluster: String, clusterView: kafka.manager.model.ActorModel.CMView
)(implicit af: features.ApplicationFeatures, messages: play.api.i18n.Messages, request:RequestHeader)

<div class="panel panel-default">
<div class="panel-heading"><h3>Cluster Information</h3></div>
<div class="card">
<div class="card-header"><h3>Cluster Information</h3></div>
<div class="card-body">
<table class="table">
<tbody>
@features.app(features.KMClusterManagerFeature) {
Expand All @@ -19,9 +20,11 @@
</tr>
</tbody>
</table>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><h3>Cluster Summary</h3></div>
<div class="card">
<div class="card-header"><h3>Cluster Summary</h3></div>
<div class="card-body">
<table class="table">
<tbody>
<tr>
Expand All @@ -30,4 +33,5 @@
</tr>
</tbody>
</table>
</div>
</div>
6 changes: 4 additions & 2 deletions app/views/cluster/configReferences.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
* See accompanying LICENSE file.
*@

<div class="panel panel-info">
<div class="panel-heading">References</div>
<div class="card">
<div class="card-header"><h5>References</h5></div>
<div class="card-body">
<ol>
<li><a href="https://kafka.apache.org/08/quickstart.html">Kafka Quickstart</a></li>
<li><a href="https://github.com/Qihoo360/logkafka">LogKafka</a></li>
</ol>
</div>
</div>

4 changes: 2 additions & 2 deletions app/views/cluster/pendingClusterList.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*@
@(clusters: IndexedSeq[kafka.manager.model.ClusterConfig])(implicit messages: play.api.i18n.Messages, request:RequestHeader)

@import b4.vertical.fieldConstructor
@implicitFieldConstructor = @{ b4.vertical.fieldConstructor() }

@if(clusters.nonEmpty) {
<div class="panel-body"><br></div>
<br>
<table class="table">
<thead>
<tr><th>Pending</th><th>Status</th><th>Version</th></tr>
Expand Down
15 changes: 7 additions & 8 deletions app/views/cluster/updateCluster.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
@(clusterName: String, errorOrForm: kafka.manager.ApiError \/ Form[models.form.ClusterOperation]
)(implicit request: RequestHeader, messages: play.api.i18n.Messages, menus: models.navigation.Menus)

@import b4.vertical.fieldConstructor
@import controllers.routes

@theMenu = {
@views.html.navigation.defaultMenu(views.html.navigation.menuNav("Cluster","Update Cluster",menus.indexMenu))
}

@checkboxWithLink(field: play.api.data.Field) = {
@b4.inputFormGroup(field, withFeedback = false, withLabelFor = false, views.html.bs.Args.withDefault(Seq(), 'disabled -> false)) { fieldInfo =>
@checkboxWithLink(field: play.api.data.Field)(implicit fc: b4.B4FieldConstructor, msgsProv: MessagesProvider) = {
@b4.inputFormGroup(field, withLabelFor = false, views.html.bs.Args.withDefault(Seq(), 'disabled -> false)) { fieldInfo =>
<div class="checkbox">
<label for="@fieldInfo.id">
<input type="checkbox" id="@fieldInfo.id" name="@fieldInfo.name" value="true" @if(fieldInfo.value == Some("true")){checked} @toHtmlArgs(fieldInfo.innerArgsMap)>
Expand All @@ -25,7 +24,7 @@
}

@drawForm(form : Form[models.form.ClusterOperation]) = {
@b4.form(routes.Cluster.handleUpdateCluster(clusterName)) {
@b4.vertical.form(routes.Cluster.handleUpdateCluster(clusterName)) { implicit fc =>
<fieldset>
<input type="hidden" name="operation" value="Update">
<input type="hidden" name="name" value="@clusterName">
Expand Down Expand Up @@ -62,7 +61,7 @@
@b4.select(form("saslMechanism"), options = kafka.manager.model.SASLmechanism.formSelectList, '_label -> "SASL Mechanism (only applies to SASL based security)" )
@b4.text(form("jaasConfig"), '_label -> "SASL JAAS Config (only applies to SASL based security)")
@b4.submit('class -> "submit-button btn btn-primary btn"){ Save }
<a href="@routes.Application.index()" class="cancel-button btn btn-default" role="button">Cancel</a>
<a href="@routes.Application.index()" class="cancel-button btn btn-secondary" role="button">Cancel</a>
</fieldset>
}
}
Expand All @@ -73,9 +72,9 @@
breadcrumbs=views.html.navigation.breadCrumbs(models.navigation.BreadCrumbs.withViewAndCluster("Update Cluster",clusterName))) {

<div class="col-md-6 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading"><h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span></button>Update Cluster</h3></div>
<div class="panel-body">
<div class="card">
<div class="card-header"><h3><button type="button" class="btn btn-link" onclick="goBack()"><span class="octicon octicon-arrow-left" aria-hidden="true"></span></button>Update Cluster</h3></div>
<div class="card-body">
@errorOrForm.fold(views.html.errors.onApiError(_), drawForm(_))
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions app/views/common/resultOfCommand.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
@main(actionTitle, menu = theMenu, breadcrumbs = views.html.navigation.breadCrumbs(crumbs)) {

<div class="col-md-6 un-pad-me">
<div class="panel panel-default">
<div class="panel-heading"><h3>@actionTitle</h3></div>
<div class="card">
<div class="card-header"><h3>@actionTitle</h3></div>
<div class="card-body">
@errorOrSuccess.fold( a => views.html.errors.onApiError(a, Some(errorLink)) , b => link(successLink))
</div>
</div>
</div>

Expand Down
Loading

0 comments on commit b7afe64

Please sign in to comment.