func (h *GetService) OnIncomingRequest(req *http.Request) util.JSONResponse {
	if req.Method != "POST" {
		return util.MessageResponse(405, "Unsupported Method")
	}
	var body struct {
		ID string
	}
	if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
		return util.MessageResponse(400, "Error parsing request JSON")
	}
	if body.ID == "" {
		return util.MessageResponse(400, `Must supply a "ID"`)
	}
	srv, err := h.DB.LoadService(body.ID)
	if err != nil {
		if err == sql.ErrNoRows {
			return util.MessageResponse(404, `Service not found`)
		}
		util.GetLogger(req.Context()).WithError(err).Error("Failed to LoadService")
		return util.MessageResponse(500, `Failed to load service`)
	}
	return util.JSONResponse{
		Code: 200,
		JSON: struct {
			ID     string
			Type   string
			Config types.Service
		}{srv.ServiceID(), srv.ServiceType(), srv},
	}
}
OnIncomingRequest handles POST requests to /admin/getService.

The request body MUST be a JSON body which has an "ID" key which represents
the service ID to get.

Request:
POST /admin/getService
{
"ID": "my_service_id"
}
Response:
HTTP/1.1 200 OK
{
"ID": "my_service_id",
"Type": "github",
"Config": {
// service-specific config information
}
}
package handlers
import (
	"database/sql"
	"encoding/json"
	"fmt"
	"net/http"
	"sync"
	"github.com/matrix-org/go-neb/api"
	"github.com/matrix-org/go-neb/clients"
	"github.com/matrix-org/go-neb/database"
	"github.com/matrix-org/go-neb/matrix"
	"github.com/matrix-org/go-neb/metrics"
	"github.com/matrix-org/go-neb/polling"
	"github.com/matrix-org/go-neb/types"
	"github.com/matrix-org/util"
	log "github.com/sirupsen/logrus"
)
type ConfigureService struct {
	db               *database.ServiceDB
	clients          *clients.Clients
	mapMutex         sync.Mutex
	mutexByServiceID map[string]*sync.Mutex
}
func NewConfigureService(db *database.ServiceDB, clients *clients.Clients) *ConfigureService {
	return &ConfigureService{
		db:               db,
		clients:          clients,
		mutexByServiceID: make(map[string]*sync.Mutex),
	}
}
func (s *ConfigureService) getMutexForServiceID(serviceID string) *sync.Mutex {
	s.mapMutex.Lock()
	defer s.mapMutex.Unlock()
	m := s.mutexByServiceID[serviceID]
	if m == nil {
		m = &sync.Mutex{}
		s.mutexByServiceID[serviceID] = m
	}
	return m
}
func (s *ConfigureService) OnIncomingRequest(req *http.Request) util.JSONResponse {
	if req.Method != "POST" {
		return util.MessageResponse(405, "Unsupported Method")
	}
	service, httpErr := s.createService(req)
	if httpErr != nil {
		return *httpErr
	}
	logger := util.GetLogger(req.Context())
	logger.WithFields(log.Fields{
		"service_id":      service.ServiceID(),
		"service_type":    service.ServiceType(),
		"service_user_id": service.ServiceUserID(),
	}).Print("Incoming configure service request")
	mut := s.getMutexForServiceID(service.ServiceID())
	mut.Lock()
	defer mut.Unlock()
	old, err := s.db.LoadService(service.ServiceID())
	if err != nil && err != sql.ErrNoRows {
		logger.WithError(err).Error("Failed to LoadService")
		return util.MessageResponse(500, "Error loading old service")
	}
	client, err := s.clients.Client(service.ServiceUserID())
	if err != nil {
		return util.MessageResponse(400, "Unknown matrix client")
	}
	if err := checkClientForService(service, client); err != nil {
		return util.MessageResponse(400, err.Error())
	}
	if err = service.Register(old, client); err != nil {
		return util.MessageResponse(500, "Failed to register service: "+err.Error())
	}
	oldService, err := s.db.StoreService(service)
	if err != nil {
		logger.WithError(err).Error("Failed to StoreService")
		return util.MessageResponse(500, "Error storing service")
	}
	if _, ok := service.(types.Poller); ok {
		if err := polling.StartPolling(service); err != nil {
			logger.WithFields(log.Fields{
				"service_id": service.ServiceID(),
				log.ErrorKey: err,
			}).Error("Failed to start poll loop.")
		}
	}
	service.PostRegister(old)
	metrics.IncrementConfigureService(service.ServiceType())
	return util.JSONResponse{
		Code: 200,
		JSON: struct {
			ID        string
			Type      string
			OldConfig types.Service
			NewConfig types.Service
		}{service.ServiceID(), service.ServiceType(), oldService, service},
	}
}
func (s *ConfigureService) createService(req *http.Request) (types.Service, *util.JSONResponse) {
	var body api.ConfigureServiceRequest
	if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
		res := util.MessageResponse(400, "Error parsing request JSON")
		return nil, &res
	}
	if err := body.Check(); err != nil {
		res := util.MessageResponse(400, err.Error())
		return nil, &res
	}
	service, err := types.CreateService(body.ID, body.Type, body.UserID, body.Config)
	if err != nil {
		res := util.MessageResponse(400, "Error parsing config JSON")
		return nil, &res
	}
	return service, nil
}
type GetService struct {
	DB *database.ServiceDB
}