changeset 1590:2fdd8e57542d

Added DELETE /imports/scheduler/{id:[0-9]+} to delete a schedule from the scheduler.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 14 Dec 2018 12:34:12 +0100
parents e0bd82f6ee14
children 2d53065c95af
files pkg/controllers/routes.go pkg/controllers/scheduler.go pkg/scheduler/scheduler.go
diffstat 3 files changed, 106 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/routes.go	Fri Dec 14 11:29:28 2018 +0100
+++ b/pkg/controllers/routes.go	Fri Dec 14 12:34:12 2018 +0100
@@ -176,6 +176,11 @@
 	})).Methods(http.MethodPost)
 
 	// Import scheduler configuration
+	api.Handle("/imports/scheduler/{id:[0-9]+}",
+		waterwayAdmin(&JSONHandler{
+			Handle: deleteSchedule,
+		})).Methods(http.MethodDelete)
+
 	api.Handle("/imports/scheduler",
 		waterwayAdmin(&JSONHandler{
 			Input:  func() interface{} { return new(models.ImportConfig) },
--- a/pkg/controllers/scheduler.go	Fri Dec 14 11:29:28 2018 +0100
+++ b/pkg/controllers/scheduler.go	Fri Dec 14 12:34:12 2018 +0100
@@ -15,11 +15,15 @@
 
 import (
 	"database/sql"
+	"errors"
+	"fmt"
 	"net/http"
+	"strconv"
 
 	"gemma.intevation.de/gemma/pkg/auth"
 	"gemma.intevation.de/gemma/pkg/models"
 	"gemma.intevation.de/gemma/pkg/scheduler"
+	"github.com/gorilla/mux"
 )
 
 const (
@@ -40,8 +44,69 @@
 (username, kind, cron, send_email, auto_accept, url)
 VALUES ($1, $2, $3, $4, $5, $6)
 RETURNING id`
+
+	hasImportConfigurationSQL = `
+SELECT true FROM waterway.import_configuration
+WHERE id = $1`
+
+	deleteImportConfiguationSQL = `
+DELETE FROM waterway.import_configuration
+WHERE id = $1`
 )
 
+func deleteSchedule(
+	_ interface{},
+	req *http.Request,
+	conn *sql.Conn,
+) (jr JSONResult, err error) {
+
+	ctx := req.Context()
+
+	id, _ := strconv.ParseInt(mux.Vars(req)["id"], 10, 64)
+
+	var tx *sql.Tx
+	if tx, err = conn.BeginTx(ctx, nil); err != nil {
+		return
+	}
+	defer tx.Rollback()
+
+	var found bool
+	err = tx.QueryRowContext(ctx, hasImportConfigurationSQL, id).Scan(&found)
+	switch {
+	case err == sql.ErrNoRows:
+		err = JSONError{
+			Code:    http.StatusNotFound,
+			Message: fmt.Sprintf("No schedule %d found", id),
+		}
+		return
+	case err != nil:
+		return
+	case !found:
+		err = errors.New("Unexpected result")
+		return
+	}
+
+	if _, err = tx.ExecContext(ctx, deleteImportConfiguationSQL, id); err != nil {
+		return
+	}
+
+	// Remove from running scheduler.
+	scheduler.UnbindByID(id)
+
+	if err = tx.Commit(); err != nil {
+		return
+	}
+
+	var result = struct {
+		ID int64 `json:"id"`
+	}{
+		ID: id,
+	}
+
+	jr = JSONResult{Result: &result}
+	return
+}
+
 func addSchedule(
 	input interface{},
 	req *http.Request,
@@ -97,12 +162,7 @@
 	}
 
 	if err = tx.Commit(); err != nil {
-		scheduler.UnbindAction(
-			string(importConfig.Kind),
-			session.User,
-			&id,
-		)
-		return
+		scheduler.UnbindByID(id)
 	}
 
 	var result = struct {
--- a/pkg/scheduler/scheduler.go	Fri Dec 14 11:29:28 2018 +0100
+++ b/pkg/scheduler/scheduler.go	Fri Dec 14 12:34:12 2018 +0100
@@ -128,6 +128,11 @@
 	global.unbindAction(name, user, cfgID)
 }
 
+// UnbindByID unbinds all schedules with a given id.
+func UnbindByID(cfgID int64) {
+	global.unbindByID(cfgID)
+}
+
 // UnbindUser unbinds all schedules for a given user.
 func UnbindUser(user string) {
 	global.unbindUser(user)
@@ -181,6 +186,36 @@
 	s.cr.Start()
 }
 
+func (s *scheduler) unbindByID(cfgID int64) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	entries := s.cr.Entries()
+
+	var found bool
+	for _, entry := range entries {
+		ua := entry.Job.(*userAction)
+		if ua.cfgID != nil && *ua.cfgID == cfgID {
+			found = true
+			break
+		}
+	}
+
+	if !found {
+		return
+	}
+
+	s.cr.Stop()
+	s.cr = cron.New()
+	for _, entry := range entries {
+		ua := entry.Job.(*userAction)
+		if ua.cfgID == nil || *ua.cfgID != cfgID {
+			s.cr.Schedule(entry.Schedule, entry.Job)
+		}
+	}
+	s.cr.Start()
+}
+
 func (s *scheduler) unbindAction(name, user string, cfgID *int64) {
 	s.mu.Lock()
 	defer s.mu.Unlock()