mirror of
https://github.com/VinylDNS/vinyldns
synced 2025-08-29 13:27:43 +00:00
Merge pull request #1374 from Jay07GIT/latency_fix_batch_change
Fix for latency issue in batch change upload
This commit is contained in:
commit
7d9937d4af
@ -351,6 +351,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -348,6 +348,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -367,6 +367,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -352,6 +352,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,10 @@ dotted-hosts = {
|
|||||||
# The time period within which the TCP binding process must be completed.
|
# The time period within which the TCP binding process must be completed.
|
||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
package vinyldns.mysql.repository
|
package vinyldns.mysql.repository
|
||||||
|
|
||||||
import java.sql.Timestamp
|
import java.sql.Timestamp
|
||||||
|
|
||||||
import cats.data._
|
import cats.data._
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import scalikejdbc._
|
import scalikejdbc._
|
||||||
@ -166,8 +166,8 @@ class MySqlBatchChangeRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getBatchFromSingleChangeId(
|
def getBatchFromSingleChangeId(
|
||||||
singleChangeId: String
|
singleChangeId: String
|
||||||
)(implicit s: DBSession): Option[BatchChange] =
|
)(implicit s: DBSession): Option[BatchChange] =
|
||||||
GET_BATCH_CHANGE_METADATA_FROM_SINGLE_CHANGE
|
GET_BATCH_CHANGE_METADATA_FROM_SINGLE_CHANGE
|
||||||
.bind(singleChangeId)
|
.bind(singleChangeId)
|
||||||
.map(extractBatchChange(None))
|
.map(extractBatchChange(None))
|
||||||
@ -181,12 +181,9 @@ class MySqlBatchChangeRepository
|
|||||||
.apply()
|
.apply()
|
||||||
batchMeta.copy(changes = changes)
|
batchMeta.copy(changes = changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor("repo.BatchChangeJDBC.updateSingleChanges") {
|
monitor("repo.BatchChangeJDBC.updateSingleChanges") {
|
||||||
IO {
|
IO {
|
||||||
logger.info(
|
logger.info(s"Updating single change status: ${singleChanges.map(ch => (ch.id, ch.status))}")
|
||||||
s"Updating single change statuses: ${singleChanges.map(ch => (ch.id, ch.status))}"
|
|
||||||
)
|
|
||||||
DB.localTx { implicit s =>
|
DB.localTx { implicit s =>
|
||||||
for {
|
for {
|
||||||
headChange <- singleChanges.headOption
|
headChange <- singleChanges.headOption
|
||||||
@ -194,8 +191,7 @@ class MySqlBatchChangeRepository
|
|||||||
_ = UPDATE_SINGLE_CHANGE.batchByName(batchParams: _*).apply()
|
_ = UPDATE_SINGLE_CHANGE.batchByName(batchParams: _*).apply()
|
||||||
batchChange <- getBatchFromSingleChangeId(headChange.id)
|
batchChange <- getBatchFromSingleChangeId(headChange.id)
|
||||||
} yield batchChange
|
} yield batchChange
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ object Meta {
|
|||||||
Meta(
|
Meta(
|
||||||
config.getOptional[String]("vinyldns.version").getOrElse("unknown"),
|
config.getOptional[String]("vinyldns.version").getOrElse("unknown"),
|
||||||
config.getOptional[Boolean]("shared-display-enabled").getOrElse(false),
|
config.getOptional[Boolean]("shared-display-enabled").getOrElse(false),
|
||||||
config.getOptional[Int]("batch-change-limit").getOrElse(1000),
|
config.getOptional[Int]("api.limits.batchchange-routing-max-items-limit").getOrElse(1000),
|
||||||
config.getOptional[Long]("default-ttl").getOrElse(7200L),
|
config.getOptional[Long]("default-ttl").getOrElse(7200L),
|
||||||
config.getOptional[Boolean]("manual-batch-review-enabled").getOrElse(false),
|
config.getOptional[Boolean]("manual-batch-review-enabled").getOrElse(false),
|
||||||
config.getOptional[Boolean]("scheduled-changes-enabled").getOrElse(false),
|
config.getOptional[Boolean]("scheduled-changes-enabled").getOrElse(false),
|
||||||
|
@ -326,7 +326,7 @@
|
|||||||
<label class="batch-change-csv-label btn btn-default" for="batchChangeCsv" id="batchChangeCsvImportLabel">
|
<label class="batch-change-csv-label btn btn-default" for="batchChangeCsv" id="batchChangeCsvImportLabel">
|
||||||
<span><span class="glyphicon glyphicon-import"></span> Import CSV</span>
|
<span><span class="glyphicon glyphicon-import"></span> Import CSV</span>
|
||||||
</label>
|
</label>
|
||||||
<input type="file" id="batchChangeCsv" ng-model="csvInput" name="batchChangeCsv" class="batchChangeCsv" ng-change="uploadCSV(createBatchChangeForm.batchChangeCsv.$viewValue)" batch-change-file>
|
<input type="file" id="batchChangeCsv" ng-model="csvInput" name="batchChangeCsv" class="batchChangeCsv" ng-change="uploadCSV(createBatchChangeForm.batchChangeCsv.$viewValue, batchChangeLimit )" batch-change-file>
|
||||||
<p><a href="https://www.vinyldns.io/portal/dns-changes#dns-change-csv-import" target="_blank" rel="noopener noreferrer">See documentation for sample CSV</a></p>
|
<p><a href="https://www.vinyldns.io/portal/dns-changes#dns-change-csv-import" target="_blank" rel="noopener noreferrer">See documentation for sample CSV</a></p>
|
||||||
</div>
|
</div>
|
||||||
<p ng-if="newBatch.changes.length >= batchChangeLimit">Limit reached. Cannot add more than {{batchChangeLimit}} records per DNS change.</p>
|
<p ng-if="newBatch.changes.length >= batchChangeLimit">Limit reached. Cannot add more than {{batchChangeLimit}} records per DNS change.</p>
|
||||||
@ -336,6 +336,9 @@
|
|||||||
<button type="button" id="create-batch-changes-button" class="btn btn-primary" ng-click="submitChange(manualReviewEnabled)">Submit</button>
|
<button type="button" id="create-batch-changes-button" class="btn btn-primary" ng-click="submitChange(manualReviewEnabled)">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="formStatus=='pendingConfirm'" class="pull-right">
|
<div ng-if="formStatus=='pendingConfirm'" class="pull-right">
|
||||||
|
<div class="modal fade" id="loader" tabindex="-1" role="dialog" >
|
||||||
|
<div class="spinner" ></div>
|
||||||
|
</div>
|
||||||
<span ng-if="!batchChangeErrors">{{ confirmationPrompt }}</span>
|
<span ng-if="!batchChangeErrors">{{ confirmationPrompt }}</span>
|
||||||
<span ng-if="batchChangeErrors" class="batch-change-error-help">There were errors, please review the highlighted rows and then proceed.</span>
|
<span ng-if="batchChangeErrors" class="batch-change-error-help">There were errors, please review the highlighted rows and then proceed.</span>
|
||||||
<button class="btn btn-default" ng-click="cancelSubmit()">Cancel</button>
|
<button class="btn btn-default" ng-click="cancelSubmit()">Cancel</button>
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
$scope.manualReviewEnabled;
|
$scope.manualReviewEnabled;
|
||||||
$scope.naptrFlags = ["U", "S", "A", "P"];
|
$scope.naptrFlags = ["U", "S", "A", "P"];
|
||||||
|
|
||||||
|
|
||||||
$scope.addSingleChange = function() {
|
$scope.addSingleChange = function() {
|
||||||
$scope.newBatch.changes.push({changeType: "Add", type: "A+PTR"});
|
$scope.newBatch.changes.push({changeType: "Add", type: "A+PTR"});
|
||||||
var changesLength = $scope.newBatch.changes.length;
|
var changesLength = $scope.newBatch.changes.length;
|
||||||
@ -161,14 +162,14 @@
|
|||||||
$scope.alerts.push(alert);
|
$scope.alerts.push(alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.uploadCSV = function(file) {
|
$scope.uploadCSV = function(file, batchChangeLimit) {
|
||||||
parseFile(file).then(function(dataLength){
|
parseFile(file, batchChangeLimit).then(function(dataLength){
|
||||||
$scope.alerts.push({type: 'success', content: 'Successfully imported ' + dataLength + ' changes.' });
|
$scope.alerts.push({type: 'success', content: 'Successfully imported ' + dataLength + ' DNS changes.' });
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
$scope.alerts.push({type: 'danger', content: error});
|
$scope.alerts.push({type: 'danger', content: error});
|
||||||
});
|
});
|
||||||
|
|
||||||
function parseFile(file) {
|
function parseFile(file, batchChangeLimit) {
|
||||||
return $q(function(resolve, reject) {
|
return $q(function(resolve, reject) {
|
||||||
if (!file.name.endsWith('.csv')) {
|
if (!file.name.endsWith('.csv')) {
|
||||||
reject("Import failed. File should be of ‘.csv’ type.");
|
reject("Import failed. File should be of ‘.csv’ type.");
|
||||||
@ -177,6 +178,9 @@
|
|||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
var rows = e.target.result.split("\n");
|
var rows = e.target.result.split("\n");
|
||||||
|
if(rows.length - 1 > batchChangeLimit)
|
||||||
|
{reject("Import failed. Cannot add more than " + batchChangeLimit + " records per DNS change.");
|
||||||
|
} else {
|
||||||
if (rows[0].trim() == "Change Type,Record Type,Input Name,TTL,Record Data") {
|
if (rows[0].trim() == "Change Type,Record Type,Input Name,TTL,Record Data") {
|
||||||
$scope.newBatch.changes = [];
|
$scope.newBatch.changes = [];
|
||||||
for(var i = 1; i < rows.length; i++) {
|
for(var i = 1; i < rows.length; i++) {
|
||||||
@ -186,10 +190,10 @@
|
|||||||
}
|
}
|
||||||
$scope.$apply()
|
$scope.$apply()
|
||||||
resolve($scope.newBatch.changes.length);
|
resolve($scope.newBatch.changes.length);
|
||||||
} else {
|
} else {
|
||||||
reject("Import failed. CSV header must be: Change Type,Record Type,Input Name,TTL,Record Data");
|
reject("Import failed. CSV header must be: Change Type,Record Type,Input Name,TTL,Record Data");
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,17 @@
|
|||||||
"allowManualReview": allowManualReview
|
"allowManualReview": allowManualReview
|
||||||
}
|
}
|
||||||
var url = utilityService.urlBuilder('/api/dnschanges', params);
|
var url = utilityService.urlBuilder('/api/dnschanges', params);
|
||||||
return $http.post(url, data, {headers: utilityService.getCsrfHeader()});
|
let loader = $("#loader");
|
||||||
|
loader.modal({
|
||||||
|
backdrop: "static",
|
||||||
|
keyboard: false, //remove option to close with keyboard
|
||||||
|
show: true //Display loader!
|
||||||
|
})
|
||||||
|
let promis = $http.post(url, data, {headers: utilityService.getCsrfHeader()});
|
||||||
|
// Hide loader when api gets response
|
||||||
|
promis.then(()=>loader.modal("hide"))
|
||||||
|
.catch(()=>loader.modal("hide"))
|
||||||
|
return promis
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getBatchChanges = function (maxItems, startFrom, ignoreAccess, approvalStatus, userName, dateTimeRangeStart, dateTimeRangeEnd) {
|
this.getBatchChanges = function (maxItems, startFrom, ignoreAccess, approvalStatus, userName, dateTimeRangeStart, dateTimeRangeEnd) {
|
||||||
|
@ -34,7 +34,7 @@ class MetaSpec extends Specification with Mockito {
|
|||||||
Meta(Configuration.from(config)).sharedDisplayEnabled must beTrue
|
Meta(Configuration.from(config)).sharedDisplayEnabled must beTrue
|
||||||
}
|
}
|
||||||
"get the batch-change-limit value in config" in {
|
"get the batch-change-limit value in config" in {
|
||||||
val config = Map("batch-change-limit" -> 21)
|
val config = Map("api.limits.batchchange-routing-max-items-limit" -> 21)
|
||||||
Meta(Configuration.from(config)).batchChangeLimit must beEqualTo(21)
|
Meta(Configuration.from(config)).batchChangeLimit must beEqualTo(21)
|
||||||
}
|
}
|
||||||
"default to 1000 if batch-change-limit is not found" in {
|
"default to 1000 if batch-change-limit is not found" in {
|
||||||
|
@ -302,6 +302,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
@ -360,6 +360,10 @@ akka.http {
|
|||||||
# Set to `infinite` to disable.
|
# Set to `infinite` to disable.
|
||||||
bind-timeout = 5s
|
bind-timeout = 5s
|
||||||
|
|
||||||
|
# A default request timeout is applied globally to all routes and can be configured using the
|
||||||
|
# akka.http.server.request-timeout setting (which defaults to 20 seconds).
|
||||||
|
# request-timeout = 60s
|
||||||
|
|
||||||
# Show verbose error messages back to the client
|
# Show verbose error messages back to the client
|
||||||
verbose-error-messages = on
|
verbose-error-messages = on
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user