feat: remove deprecated stuff (#726)

This commit is contained in:
Julien Neuhart
2023-12-01 09:45:07 +01:00
committed by GitHub
parent 66142b1dd8
commit 21c47f60f2
18 changed files with 115 additions and 583 deletions

View File

@@ -29,8 +29,6 @@ func init() {
// middlewares or health checks. // middlewares or health checks.
type Api struct { type Api struct {
port int port int
readTimeout time.Duration
writeTimeout time.Duration
timeout time.Duration timeout time.Duration
rootPath string rootPath string
traceHeader string traceHeader string
@@ -157,23 +155,11 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor {
fs := flag.NewFlagSet("api", flag.ExitOnError) fs := flag.NewFlagSet("api", flag.ExitOnError)
fs.Int("api-port", 3000, "Set the port on which the API should listen") fs.Int("api-port", 3000, "Set the port on which the API should listen")
fs.String("api-port-from-env", "", "Set the environment variable with the port on which the API should listen - override the default port") fs.String("api-port-from-env", "", "Set the environment variable with the port on which the API should listen - override the default port")
fs.Duration("api-read-timeout", time.Duration(30)*time.Second, "Set the maximum duration allowed to read a complete request, including the body")
fs.Duration("api-process-timeout", time.Duration(30)*time.Second, "Set the maximum duration allowed to process a request")
fs.Duration("api-write-timeout", time.Duration(30)*time.Second, "Set the maximum duration before timing out writes of the response")
fs.Duration("api-timeout", time.Duration(30)*time.Second, "Set the time limit for requests") fs.Duration("api-timeout", time.Duration(30)*time.Second, "Set the time limit for requests")
fs.String("api-root-path", "/", "Set the root path of the API - for service discovery via URL paths") fs.String("api-root-path", "/", "Set the root path of the API - for service discovery via URL paths")
fs.String("api-trace-header", "Gotenberg-Trace", "Set the header name to use for identifying requests") fs.String("api-trace-header", "Gotenberg-Trace", "Set the header name to use for identifying requests")
fs.Bool("api-disable-health-check-logging", false, "Disable health check logging") fs.Bool("api-disable-health-check-logging", false, "Disable health check logging")
var err error
err = multierr.Append(err, fs.MarkDeprecated("api-read-timeout", "use api-timeout instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-process-timeout", "use api-timeout instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-write-timeout", "use api-timeout instead"))
if err != nil {
panic(fmt.Errorf("create deprecated flags for the api module: %v", err))
}
return fs return fs
}(), }(),
New: func() gotenberg.Module { return new(Api) }, New: func() gotenberg.Module { return new(Api) },
@@ -184,9 +170,7 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor {
func (a *Api) Provision(ctx *gotenberg.Context) error { func (a *Api) Provision(ctx *gotenberg.Context) error {
flags := ctx.ParsedFlags() flags := ctx.ParsedFlags()
a.port = flags.MustInt("api-port") a.port = flags.MustInt("api-port")
a.readTimeout = flags.MustDeprecatedDuration("api-read-timeout", "api-timeout") a.timeout = flags.MustDuration("api-timeout")
a.writeTimeout = flags.MustDeprecatedDuration("api-write-timeout", "api-timeout")
a.timeout = flags.MustDeprecatedDuration("api-process-timeout", "api-timeout")
a.rootPath = flags.MustString("api-root-path") a.rootPath = flags.MustString("api-root-path")
a.traceHeader = flags.MustString("api-trace-header") a.traceHeader = flags.MustString("api-trace-header")
a.disableHealthCheckLogging = flags.MustBool("api-disable-health-check-logging") a.disableHealthCheckLogging = flags.MustBool("api-disable-health-check-logging")
@@ -373,10 +357,10 @@ func (a *Api) Start() error {
a.srv = echo.New() a.srv = echo.New()
a.srv.HideBanner = true a.srv.HideBanner = true
a.srv.HidePort = true a.srv.HidePort = true
a.srv.Server.ReadTimeout = a.readTimeout a.srv.Server.ReadTimeout = a.timeout
a.srv.Server.IdleTimeout = a.timeout a.srv.Server.IdleTimeout = a.timeout
// See https://github.com/gotenberg/gotenberg/issues/396. // See https://github.com/gotenberg/gotenberg/issues/396.
a.srv.Server.WriteTimeout = a.writeTimeout + a.writeTimeout a.srv.Server.WriteTimeout = a.timeout + a.timeout
a.srv.HTTPErrorHandler = httpErrorHandler() a.srv.HTTPErrorHandler = httpErrorHandler()
// Let's prepare the modules' routes. // Let's prepare the modules' routes.

View File

@@ -9,7 +9,6 @@ import (
"github.com/alexliesenfeld/health" "github.com/alexliesenfeld/health"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"go.uber.org/multierr"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg" "github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
@@ -217,18 +216,6 @@ func (mod *Chromium) Descriptor() gotenberg.ModuleDescriptor {
ID: "chromium", ID: "chromium",
FlagSet: func() *flag.FlagSet { FlagSet: func() *flag.FlagSet {
fs := flag.NewFlagSet("chromium", flag.ExitOnError) fs := flag.NewFlagSet("chromium", flag.ExitOnError)
// Deprecated flags.
fs.String("chromium-user-agent", "", "Override the default User-Agent header")
fs.Int("chromium-failed-starts-threshold", 5, "Set the number of consecutive failed starts after which the module is considered unhealthy - 0 means ignore")
var err error
err = multierr.Append(err, fs.MarkDeprecated("chromium-user-agent", "use the extraHttpHeaders form field instead"))
err = multierr.Append(err, fs.MarkDeprecated("chromium-failed-starts-threshold", "use the chromium-restart-after property instead"))
if err != nil {
panic(fmt.Errorf("create deprecated flags for the Chromium module: %v", err))
}
fs.Int64("chromium-restart-after", 0, "Number of conversions after which Chromium will automatically restart. Set to 0 to disable this feature") fs.Int64("chromium-restart-after", 0, "Number of conversions after which Chromium will automatically restart. Set to 0 to disable this feature")
fs.Bool("chromium-auto-start", false, "Automatically launch Chromium upon initialization if set to true; otherwise, Chromium will start at the time of the first conversion") fs.Bool("chromium-auto-start", false, "Automatically launch Chromium upon initialization if set to true; otherwise, Chromium will start at the time of the first conversion")
fs.Duration("chromium-start-timeout", time.Duration(10)*time.Second, "Maximum duration to wait for Chromium to start or restart") fs.Duration("chromium-start-timeout", time.Duration(10)*time.Second, "Maximum duration to wait for Chromium to start or restart")
@@ -359,22 +346,6 @@ func (mod *Chromium) Stop(ctx context.Context) error {
// Metrics returns the metrics. // Metrics returns the metrics.
func (mod *Chromium) Metrics() ([]gotenberg.Metric, error) { func (mod *Chromium) Metrics() ([]gotenberg.Metric, error) {
return []gotenberg.Metric{ return []gotenberg.Metric{
{
// TODO: remove deprecated.
Name: "chromium_active_instances_count",
Description: "Current number of active Chromium instances - deprecated.",
Read: func() float64 {
return 1
},
},
{
// TODO: remove deprecated.
Name: "chromium_failed_starts_count",
Description: "Current number of Chromium consecutive starting failures - deprecated.",
Read: func() float64 {
return 0
},
},
{ {
Name: "chromium_requests_queue_size", Name: "chromium_requests_queue_size",
Description: "Current number of Chromium conversion requests waiting to be treated.", Description: "Current number of Chromium conversion requests waiting to be treated.",

View File

@@ -334,26 +334,16 @@ func TestChromium_Metrics(t *testing.T) {
t.Fatalf("expected no error but got: %v", err) t.Fatalf("expected no error but got: %v", err)
} }
if len(metrics) != 4 { if len(metrics) != 2 {
t.Fatalf("expected %d metrics, but got %d", 4, len(metrics)) t.Fatalf("expected %d metrics, but got %d", 2, len(metrics))
} }
actual := metrics[0].Read() actual := metrics[0].Read()
if actual != float64(1) {
t.Errorf("expected %f for chromium_active_instances_count, but got %f", float64(1), actual)
}
actual = metrics[1].Read()
if actual != float64(0) {
t.Errorf("expected %f for chromium_failed_starts_count, but got %f", float64(0), actual)
}
actual = metrics[2].Read()
if actual != float64(10) { if actual != float64(10) {
t.Errorf("expected %f for chromium_requests_queue_size, but got %f", float64(10), actual) t.Errorf("expected %f for chromium_requests_queue_size, but got %f", float64(10), actual)
} }
actual = metrics[3].Read() actual = metrics[1].Read()
if actual != float64(0) { if actual != float64(0) {
t.Errorf("expected %f for chromium_restarts_count, but got %f", float64(0), actual) t.Errorf("expected %f for chromium_restarts_count, but got %f", float64(0), actual)
} }

View File

@@ -31,7 +31,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
waitDelay time.Duration waitDelay time.Duration
waitWindowStatus string waitWindowStatus string
waitForExpression string waitForExpression string
userAgent string
extraHttpHeaders map[string]string extraHttpHeaders map[string]string
emulatedMediaType string emulatedMediaType string
landscape, printBackground, omitBackground bool landscape, printBackground, omitBackground bool
@@ -47,7 +46,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
Duration("waitDelay", &waitDelay, defaultOptions.WaitDelay). Duration("waitDelay", &waitDelay, defaultOptions.WaitDelay).
String("waitWindowStatus", &waitWindowStatus, defaultOptions.WaitWindowStatus). String("waitWindowStatus", &waitWindowStatus, defaultOptions.WaitWindowStatus).
String("waitForExpression", &waitForExpression, defaultOptions.WaitForExpression). String("waitForExpression", &waitForExpression, defaultOptions.WaitForExpression).
String("userAgent", &userAgent, ""). // FIXME: deprecated.
Custom("extraHttpHeaders", func(value string) error { Custom("extraHttpHeaders", func(value string) error {
if value == "" { if value == "" {
extraHttpHeaders = defaultOptions.ExtraHttpHeaders extraHttpHeaders = defaultOptions.ExtraHttpHeaders
@@ -92,17 +90,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
Content("footer.html", &footerTemplate, defaultOptions.FooterTemplate). Content("footer.html", &footerTemplate, defaultOptions.FooterTemplate).
Bool("preferCssPageSize", &preferCssPageSize, defaultOptions.PreferCssPageSize) Bool("preferCssPageSize", &preferCssPageSize, defaultOptions.PreferCssPageSize)
// FIXME: deprecated.
if userAgent != "" {
ctx.Log().Warn("'userAgent' is deprecated; prefer the 'extraHttpHeaders' form field instead")
if extraHttpHeaders == nil {
extraHttpHeaders = make(map[string]string)
}
extraHttpHeaders["User-Agent"] = userAgent
}
options := Options{ options := Options{
FailOnConsoleExceptions: failOnConsoleExceptions, FailOnConsoleExceptions: failOnConsoleExceptions,
WaitDelay: waitDelay, WaitDelay: waitDelay,
@@ -133,31 +120,16 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
// data. Fallback to default value if the considered key is not present. // data. Fallback to default value if the considered key is not present.
func FormDataChromiumPdfFormats(ctx *api.Context) gotenberg.PdfFormats { func FormDataChromiumPdfFormats(ctx *api.Context) gotenberg.PdfFormats {
var ( var (
pdfFormat string pdfa string
pdfa string pdfua bool
pdfua bool
) )
ctx.FormData(). ctx.FormData().
String("pdfFormat", &pdfFormat, "").
String("pdfa", &pdfa, ""). String("pdfa", &pdfa, "").
Bool("pdfua", &pdfua, false) Bool("pdfua", &pdfua, false)
// FIXME: deprecated.
// pdfa > pdfFormat.
var actualPdfArchive string
if pdfFormat != "" {
ctx.Log().Warn("'pdfFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = pdfFormat
}
if pdfa != "" {
actualPdfArchive = pdfa
}
return gotenberg.PdfFormats{ return gotenberg.PdfFormats{
PdfA: actualPdfArchive, PdfA: pdfa,
PdfUa: pdfua, PdfUa: pdfua,
} }
} }

View File

@@ -28,25 +28,6 @@ func TestFormDataChromiumPdfOptions(t *testing.T) {
ctx: &api.ContextMock{Context: new(api.Context)}, ctx: &api.ContextMock{Context: new(api.Context)},
expectedOptions: DefaultOptions(), expectedOptions: DefaultOptions(),
}, },
{
scenario: "deprecated userAgent form field",
ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetValues(map[string][]string{
"userAgent": {
"foo",
},
})
return ctx
}(),
expectedOptions: func() Options {
options := DefaultOptions()
options.ExtraHttpHeaders = map[string]string{
"User-Agent": "foo",
}
return options
}(),
},
{ {
scenario: "invalid extraHttpHeaders form field", scenario: "invalid extraHttpHeaders form field",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
@@ -132,19 +113,6 @@ func TestFormDataChromiumPdfFormats(t *testing.T) {
ctx: &api.ContextMock{Context: new(api.Context)}, ctx: &api.ContextMock{Context: new(api.Context)},
expectedPdfFormats: gotenberg.PdfFormats{}, expectedPdfFormats: gotenberg.PdfFormats{},
}, },
{
scenario: "deprecated pdfFormat form field",
ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetValues(map[string][]string{
"pdfFormat": {
"foo",
},
})
return ctx
}(),
expectedPdfFormats: gotenberg.PdfFormats{PdfA: "foo"},
},
{ {
scenario: "pdfa and pdfua form fields", scenario: "pdfa and pdfua form fields",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
@@ -726,7 +694,7 @@ func TestConvertUrl(t *testing.T) {
expectOutputPathsCount: 0, expectOutputPathsCount: 0,
}, },
{ {
scenario: "success with pdfFormat form field", scenario: "success with pdfa form field",
ctx: &api.ContextMock{Context: new(api.Context)}, ctx: &api.ContextMock{Context: new(api.Context)},
api: &ApiMock{func(ctx context.Context, logger *zap.Logger, url, outputPath string, options Options) error { api: &ApiMock{func(ctx context.Context, logger *zap.Logger, url, outputPath string, options Options) error {
return nil return nil

View File

@@ -47,7 +47,6 @@ type Options struct {
Landscape bool Landscape bool
// PageRanges allows to select the pages to convert. // PageRanges allows to select the pages to convert.
// TODO: should prefer a method form PdfEngine.
// Optional. // Optional.
PageRanges string PageRanges string
@@ -80,21 +79,6 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor {
ID: "libreoffice-api", ID: "libreoffice-api",
FlagSet: func() *flag.FlagSet { FlagSet: func() *flag.FlagSet {
fs := flag.NewFlagSet("api", flag.ExitOnError) fs := flag.NewFlagSet("api", flag.ExitOnError)
// Deprecated flags.
fs.Duration("uno-listener-start-timeout", time.Duration(10)*time.Second, "Time limit for restarting the LibreOffice")
fs.Int64("uno-listener-restart-threshold", 10, "Conversions limit after which the LibreOffice listener is restarted - 0 means no restart")
fs.Bool("unoconv-disable-listener", false, "Do not start a long-running listener - save resources in detriment of unitary performance")
var err error
err = multierr.Append(err, fs.MarkDeprecated("uno-listener-start-timeout", "use the libreOffice-start-timeout property instead"))
err = multierr.Append(err, fs.MarkDeprecated("uno-listener-restart-threshold", "use the libreOffice-restart-after property instead"))
err = multierr.Append(err, fs.MarkDeprecated("unoconv-disable-listener", "use the libreOffice-auto-start property instead"))
if err != nil {
panic(fmt.Errorf("create deprecated flags for the LibreOffice module: %v", err))
}
fs.Int64("libreoffice-restart-after", 10, "Number of conversions after which LibreOffice will automatically restart. Set to 0 to disable this feature") fs.Int64("libreoffice-restart-after", 10, "Number of conversions after which LibreOffice will automatically restart. Set to 0 to disable this feature")
fs.Bool("libreoffice-auto-start", false, "Automatically launch LibreOffice upon initialization if set to true; otherwise, LibreOffice will start at the time of the first conversion") fs.Bool("libreoffice-auto-start", false, "Automatically launch LibreOffice upon initialization if set to true; otherwise, LibreOffice will start at the time of the first conversion")
fs.Duration("libreoffice-start-timeout", time.Duration(10)*time.Second, "Maximum duration to wait for LibreOffice to start or restart") fs.Duration("libreoffice-start-timeout", time.Duration(10)*time.Second, "Maximum duration to wait for LibreOffice to start or restart")
@@ -123,7 +107,7 @@ func (a *Api) Provision(ctx *gotenberg.Context) error {
a.args = libreOfficeArguments{ a.args = libreOfficeArguments{
binPath: libreOfficeBinPath, binPath: libreOfficeBinPath,
unoBinPath: unoBinPath, unoBinPath: unoBinPath,
startTimeout: flags.MustDeprecatedDuration("uno-listener-start-timeout", "libreoffice-start-timeout"), startTimeout: flags.MustDuration("libreoffice-start-timeout"),
} }
// Logger. // Logger.
@@ -139,7 +123,7 @@ func (a *Api) Provision(ctx *gotenberg.Context) error {
// Process. // Process.
a.libreOffice = newLibreOfficeProcess(a.args) a.libreOffice = newLibreOfficeProcess(a.args)
a.supervisor = gotenberg.NewProcessSupervisor(a.logger, a.libreOffice, flags.MustDeprecatedInt64("uno-listener-restart-threshold", "libreoffice-restart-after")) a.supervisor = gotenberg.NewProcessSupervisor(a.logger, a.libreOffice, flags.MustInt64("libreoffice-restart-after"))
return nil return nil
} }
@@ -204,46 +188,6 @@ func (a *Api) Stop(ctx context.Context) error {
// Metrics returns the metrics. // Metrics returns the metrics.
func (a *Api) Metrics() ([]gotenberg.Metric, error) { func (a *Api) Metrics() ([]gotenberg.Metric, error) {
return []gotenberg.Metric{ return []gotenberg.Metric{
// TODO: remove deprecated.
{
Name: "unoconv_active_instances_count",
Description: "Current number of active unoconv instances - deprecated.",
Read: func() float64 {
return 1
},
},
// TODO: remove deprecated.
{
Name: "libreoffice_listener_active_instances_count",
Description: "Current number of active LibreOffice listener instances - deprecated.",
Read: func() float64 {
return 1
},
},
// TODO: remove deprecated.
{
Name: "unoconv_listener_active_instances_count",
Description: "Current number of active unoconv listener instances- deprecated.",
Read: func() float64 {
return 1
},
},
// TODO: remove deprecated.
{
Name: "libreoffice_listener_queue_length",
Description: "Current number of processes in the LibreOffice listener queue - deprecated, prefer libreoffice_requests_queue_size.",
Read: func() float64 {
return float64(a.supervisor.ReqQueueSize())
},
},
// TODO: remove deprecated.
{
Name: "unoconv_listener_queue_length",
Description: "Current number of processes in the queue - deprecated, prefer libreoffice_requests_queue_size.",
Read: func() float64 {
return float64(a.supervisor.ReqQueueSize())
},
},
{ {
Name: "libreoffice_requests_queue_size", Name: "libreoffice_requests_queue_size",
Description: "Current number of LibreOffice conversion requests waiting to be treated.", Description: "Current number of LibreOffice conversion requests waiting to be treated.",

View File

@@ -284,41 +284,16 @@ func TestApi_Metrics(t *testing.T) {
t.Fatalf("expected no error but got: %v", err) t.Fatalf("expected no error but got: %v", err)
} }
if len(metrics) != 7 { if len(metrics) != 2 {
t.Fatalf("expected %d metrics, but got %d", 7, len(metrics)) t.Fatalf("expected %d metrics, but got %d", 2, len(metrics))
} }
actual := metrics[0].Read() actual := metrics[0].Read()
if actual != float64(1) {
t.Errorf("expected %f for unoconv_active_instances_count, but got %f", float64(1), actual)
}
actual = metrics[1].Read()
if actual != float64(1) {
t.Errorf("expected %f for libreoffice_listener_active_instances_count, but got %f", float64(1), actual)
}
actual = metrics[2].Read()
if actual != float64(1) {
t.Errorf("expected %f for unoconv_listener_active_instances_count, but got %f", float64(1), actual)
}
actual = metrics[3].Read()
if actual != float64(10) {
t.Errorf("expected %f for libreoffice_listener_queue_length, but got %f", float64(10), actual)
}
actual = metrics[4].Read()
if actual != float64(10) {
t.Errorf("expected %f for unoconv_listener_queue_length, but got %f", float64(10), actual)
}
actual = metrics[5].Read()
if actual != float64(10) { if actual != float64(10) {
t.Errorf("expected %f for libreoffice_requests_queue_size, but got %f", float64(10), actual) t.Errorf("expected %f for libreoffice_requests_queue_size, but got %f", float64(10), actual)
} }
actual = metrics[6].Read() actual = metrics[1].Read()
if actual != float64(0) { if actual != float64(0) {
t.Errorf("expected %f for libreoffice_restarts_count, but got %f", float64(0), actual) t.Errorf("expected %f for libreoffice_restarts_count, but got %f", float64(0), actual)
} }

View File

@@ -24,25 +24,19 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
// Let's get the data from the form and validate them. // Let's get the data from the form and validate them.
var ( var (
inputPaths []string inputPaths []string
landscape bool landscape bool
nativePageRanges string nativePageRanges string
nativePdfA1aFormat bool pdfa string
nativePdfFormat string pdfua bool
pdfFormat string nativePdfFormats bool
pdfa string merge bool
pdfua bool
nativePdfFormats bool
merge bool
) )
err := ctx.FormData(). err := ctx.FormData().
MandatoryPaths(libreOffice.Extensions(), &inputPaths). MandatoryPaths(libreOffice.Extensions(), &inputPaths).
Bool("landscape", &landscape, false). Bool("landscape", &landscape, false).
String("nativePageRanges", &nativePageRanges, ""). String("nativePageRanges", &nativePageRanges, "").
Bool("nativePdfA1aFormat", &nativePdfA1aFormat, false).
String("nativePdfFormat", &nativePdfFormat, "").
String("pdfFormat", &pdfFormat, "").
String("pdfa", &pdfa, ""). String("pdfa", &pdfa, "").
Bool("pdfua", &pdfua, false). Bool("pdfua", &pdfua, false).
Bool("nativePdfFormats", &nativePdfFormats, true). Bool("nativePdfFormats", &nativePdfFormats, true).
@@ -52,42 +46,8 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
} }
// FIXME: deprecated.
// pdfa > nativePdfFormat > pdfFormat > nativePdfA1aFormat.
var (
actualPdfArchive string
nativeFormats bool
)
if nativePdfA1aFormat {
ctx.Log().Warn("'nativePdfA1aFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = gotenberg.PdfA1a
nativeFormats = true
}
if pdfFormat != "" {
ctx.Log().Warn("'pdfFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = pdfFormat
nativeFormats = false
}
if nativePdfFormat != "" {
ctx.Log().Warn("'nativePdfFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = nativePdfFormat
nativeFormats = true
}
if pdfa != "" {
actualPdfArchive = pdfa
nativeFormats = nativePdfFormats
}
if pdfua {
nativeFormats = nativePdfFormats
}
pdfFormats := gotenberg.PdfFormats{ pdfFormats := gotenberg.PdfFormats{
PdfA: actualPdfArchive, PdfA: pdfa,
PdfUa: pdfua, PdfUa: pdfua,
} }
@@ -101,7 +61,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
PageRanges: nativePageRanges, PageRanges: nativePageRanges,
} }
if nativeFormats { if nativePdfFormats {
options.PdfFormats = pdfFormats options.PdfFormats = pdfFormats
} }
@@ -132,7 +92,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
// Now, let's check if the client want to convert this result // Now, let's check if the client want to convert this result
// PDF to specific PDF formats. // PDF to specific PDF formats.
zeroValued := gotenberg.PdfFormats{} zeroValued := gotenberg.PdfFormats{}
if !nativeFormats && pdfFormats != zeroValued { if !nativePdfFormats && pdfFormats != zeroValued {
convertInputPath := outputPath convertInputPath := outputPath
convertOutputPath := ctx.GeneratePath(".pdf") convertOutputPath := ctx.GeneratePath(".pdf")
@@ -169,7 +129,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
// Ok, we don't have to merge the PDFs. Let's check if the client // Ok, we don't have to merge the PDFs. Let's check if the client
// want to convert each PDF to a specific PDF format. // want to convert each PDF to a specific PDF format.
zeroValued := gotenberg.PdfFormats{} zeroValued := gotenberg.PdfFormats{}
if !nativeFormats && pdfFormats != zeroValued { if !nativePdfFormats && pdfFormats != zeroValued {
convertOutputPaths := make([]string, len(outputPaths)) convertOutputPaths := make([]string, len(outputPaths))
for i, outputPath := range outputPaths { for i, outputPath := range outputPaths {

View File

@@ -88,9 +88,12 @@ func TestConvertRoute(t *testing.T) {
"document.docx": "/document.docx", "document.docx": "/document.docx",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"pdfFormat": { "pdfa": {
"foo", "foo",
}, },
"nativePdfFormats": {
"false",
},
}) })
return ctx return ctx
}(), }(),
@@ -120,9 +123,12 @@ func TestConvertRoute(t *testing.T) {
"document.docx": "/document.docx", "document.docx": "/document.docx",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"pdfFormat": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
"nativePdfFormats": {
"false",
},
}) })
return ctx return ctx
}(), }(),
@@ -209,7 +215,7 @@ func TestConvertRoute(t *testing.T) {
expectOutputPathsCount: 2, expectOutputPathsCount: 2,
}, },
{ {
scenario: "success with non-native PDF/A (single file)", scenario: "success with non-native PDF/A & PDF/UA (single file)",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
@@ -219,6 +225,9 @@ func TestConvertRoute(t *testing.T) {
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
"pdfua": {
"true",
},
"nativePdfFormats": { "nativePdfFormats": {
"false", "false",
}, },
@@ -243,31 +252,19 @@ func TestConvertRoute(t *testing.T) {
expectOutputPathsCount: 1, expectOutputPathsCount: 1,
}, },
{ {
scenario: "success with every non-native PDF/A & PDF/UA form fields (single file)", scenario: "success with native PDF/A & PDF/UA (single file)",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
"document.docx": "/document.docx", "document.docx": "/document.docx",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"nativePdfA1aFormat": {
"true",
},
"pdfFormat": {
gotenberg.PdfA1a,
},
"nativePdfFormat": {
gotenberg.PdfA1a,
},
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
"pdfua": { "pdfua": {
"true", "true",
}, },
"nativePdfFormats": {
"false",
},
}) })
return ctx return ctx
}(), }(),
@@ -469,7 +466,7 @@ func TestConvertRoute(t *testing.T) {
expectOutputPathsCount: 1, expectOutputPathsCount: 1,
}, },
{ {
scenario: "success with non-native PDF/A (merge)", scenario: "success with non-native PDF/A & PDF/UA (merge)",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
@@ -483,6 +480,53 @@ func TestConvertRoute(t *testing.T) {
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
"pdfua": {
"true",
},
"nativePdfFormats": {
"false",
},
})
return ctx
}(),
libreOffice: &libreofficeapi.ApiMock{
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
return nil
},
ExtensionsMock: func() []string {
return []string{".docx"}
},
},
engine: &gotenberg.PdfEngineMock{
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
return nil
},
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
return nil
},
},
expectError: false,
expectHttpError: false,
expectOutputPathsCount: 1,
},
{
scenario: "success with non-native PDF/A & PDF/UA (merge)",
ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{
"document.docx": "/document.docx",
"document2.docx": "/document2.docx",
})
ctx.SetValues(map[string][]string{
"merge": {
"true",
},
"pdfa": {
gotenberg.PdfA1a,
},
"pdfua": {
"true",
},
"nativePdfFormats": { "nativePdfFormats": {
"false", "false",
}, },

View File

@@ -54,18 +54,6 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
names := flags.MustStringSlice("pdfengines-engines") names := flags.MustStringSlice("pdfengines-engines")
mod.disableRoutes = flags.MustBool("pdfengines-disable-routes") mod.disableRoutes = flags.MustBool("pdfengines-disable-routes")
loggerProvider, err := ctx.Module(new(gotenberg.LoggerProvider))
if err != nil {
return fmt.Errorf("get logger provider: %w", err)
}
logger, err := loggerProvider.(gotenberg.LoggerProvider).Logger(mod)
if err != nil {
return fmt.Errorf("get logger: %w", err)
}
logger = logger.Named("pdfengines")
engines, err := ctx.Modules(new(gotenberg.PdfEngine)) engines, err := ctx.Modules(new(gotenberg.PdfEngine))
if err != nil { if err != nil {
return fmt.Errorf("get PDF engines: %w", err) return fmt.Errorf("get PDF engines: %w", err)
@@ -81,13 +69,13 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
// Selection from user. // Selection from user.
mod.names = names mod.names = names
for i, name := range names { // Example in case of deprecated module name.
// FIXME: deprecated. //for i, name := range names {
if name == "unoconv-pdfengine" || name == "uno-pdfengine" { // if name == "unoconv-pdfengine" || name == "uno-pdfengine" {
logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name)) // logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name))
mod.names[i] = "libreoffice-pdfengine" // mod.names[i] = "libreoffice-pdfengine"
} // }
} //}
return nil return nil
} }

View File

@@ -6,8 +6,6 @@ import (
"strings" "strings"
"testing" "testing"
"go.uber.org/zap"
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg" "github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
) )
@@ -34,16 +32,12 @@ func TestPdfEngines_Provision(t *testing.T) {
ctx: func() *gotenberg.Context { ctx: func() *gotenberg.Context {
provider := &struct { provider := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
gotenberg.LoggerProviderMock
}{} }{}
provider.DescriptorMock = func() gotenberg.ModuleDescriptor { provider.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module {
return provider return provider
}} }}
} }
provider.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) {
return zap.NewNop(), nil
}
engine := &struct { engine := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
@@ -75,17 +69,12 @@ func TestPdfEngines_Provision(t *testing.T) {
ctx: func() *gotenberg.Context { ctx: func() *gotenberg.Context {
provider := &struct { provider := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
gotenberg.LoggerProviderMock
}{} }{}
provider.DescriptorMock = func() gotenberg.ModuleDescriptor { provider.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module {
return provider return provider
}} }}
} }
provider.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) {
return zap.NewNop(), nil
}
engine1 := &struct { engine1 := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
gotenberg.ValidatorMock gotenberg.ValidatorMock
@@ -130,108 +119,17 @@ func TestPdfEngines_Provision(t *testing.T) {
expectedPdfEngines: []string{"b", "a"}, expectedPdfEngines: []string{"b", "a"},
expectError: false, expectError: false,
}, },
{
scenario: "user select deprecated unoconv-pdfengine",
ctx: func() *gotenberg.Context {
provider := &struct {
gotenberg.ModuleMock
gotenberg.LoggerProviderMock
}{}
provider.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module {
return provider
}}
}
provider.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) {
return zap.NewNop(), nil
}
engine := &struct {
gotenberg.ModuleMock
gotenberg.ValidatorMock
gotenberg.PdfEngineMock
}{}
engine.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "libreoffice-pdfengine", New: func() gotenberg.Module { return engine }}
}
engine.ValidateMock = func() error {
return nil
}
fs := new(PdfEngines).Descriptor().FlagSet
err := fs.Parse([]string{"--pdfengines-engines=unoconv-pdfengine"})
if err != nil {
t.Fatalf("expected no error but got: %v", err)
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: fs,
},
[]gotenberg.ModuleDescriptor{
provider.Descriptor(),
engine.Descriptor(),
},
)
}(),
expectedPdfEngines: []string{"libreoffice-pdfengine"},
expectError: false,
},
{
scenario: "no logger provider",
ctx: func() *gotenberg.Context {
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: new(PdfEngines).Descriptor().FlagSet,
},
[]gotenberg.ModuleDescriptor{},
)
}(),
expectError: true,
},
{
scenario: "no logger from logger provider",
ctx: func() *gotenberg.Context {
provider := &struct {
gotenberg.ModuleMock
gotenberg.LoggerProviderMock
}{}
provider.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module {
return provider
}}
}
provider.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) {
return nil, errors.New("foo")
}
return gotenberg.NewContext(
gotenberg.ParsedFlags{
FlagSet: new(PdfEngines).Descriptor().FlagSet,
},
[]gotenberg.ModuleDescriptor{
provider.Descriptor(),
},
)
}(),
expectError: true,
},
{ {
scenario: "no valid PDF engine", scenario: "no valid PDF engine",
ctx: func() *gotenberg.Context { ctx: func() *gotenberg.Context {
provider := &struct { provider := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
gotenberg.LoggerProviderMock
}{} }{}
provider.DescriptorMock = func() gotenberg.ModuleDescriptor { provider.DescriptorMock = func() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module {
return provider return provider
}} }}
} }
provider.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) {
return zap.NewNop(), nil
}
engine := &struct { engine := &struct {
gotenberg.ModuleMock gotenberg.ModuleMock
gotenberg.ValidatorMock gotenberg.ValidatorMock

View File

@@ -23,14 +23,12 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route {
// Let's get the data from the form and validate them. // Let's get the data from the form and validate them.
var ( var (
inputPaths []string inputPaths []string
pdfFormat string
pdfa string pdfa string
pdfua bool pdfua bool
) )
err := ctx.FormData(). err := ctx.FormData().
MandatoryPaths([]string{".pdf"}, &inputPaths). MandatoryPaths([]string{".pdf"}, &inputPaths).
String("pdfFormat", &pdfFormat, "").
String("pdfa", &pdfa, ""). String("pdfa", &pdfa, "").
Bool("pdfua", &pdfua, false). Bool("pdfua", &pdfua, false).
Validate() Validate()
@@ -38,20 +36,8 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route {
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
} }
var actualPdfArchive string
if pdfFormat != "" {
// FIXME: deprecated
ctx.Log().Warn("'pdfFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = pdfFormat
}
if pdfa != "" {
actualPdfArchive = pdfa
}
pdfFormats := gotenberg.PdfFormats{ pdfFormats := gotenberg.PdfFormats{
PdfA: actualPdfArchive, PdfA: pdfa,
PdfUa: pdfua, PdfUa: pdfua,
} }
@@ -118,14 +104,12 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route {
// Let's get the data from the form and validate them. // Let's get the data from the form and validate them.
var ( var (
inputPaths []string inputPaths []string
pdfFormat string
pdfa string pdfa string
pdfua bool pdfua bool
) )
err := ctx.FormData(). err := ctx.FormData().
MandatoryPaths([]string{".pdf"}, &inputPaths). MandatoryPaths([]string{".pdf"}, &inputPaths).
String("pdfFormat", &pdfFormat, "").
String("pdfa", &pdfa, ""). String("pdfa", &pdfa, "").
Bool("pdfua", &pdfua, false). Bool("pdfua", &pdfua, false).
Validate() Validate()
@@ -133,20 +117,8 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route {
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
} }
var actualPdfArchive string
if pdfFormat != "" {
// FIXME: deprecated.
ctx.Log().Warn("'pdfFormat' is deprecated; prefer the 'pdfa' form field instead")
actualPdfArchive = pdfFormat
}
if pdfa != "" {
actualPdfArchive = pdfa
}
pdfFormats := gotenberg.PdfFormats{ pdfFormats := gotenberg.PdfFormats{
PdfA: actualPdfArchive, PdfA: pdfa,
PdfUa: pdfua, PdfUa: pdfua,
} }

View File

@@ -145,7 +145,7 @@ func TestMergeHandler(t *testing.T) {
expectOutputPathsCount: 0, expectOutputPathsCount: 0,
}, },
{ {
scenario: "success with every PDF/A & PDF/UA form fields", scenario: "success with PDF/A & PDF/UA form fields",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
@@ -153,9 +153,6 @@ func TestMergeHandler(t *testing.T) {
"file2.pdf": "/file2.pdf", "file2.pdf": "/file2.pdf",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"pdfFormat": {
gotenberg.PdfA1a,
},
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
@@ -322,16 +319,13 @@ func TestConvertHandler(t *testing.T) {
expectOutputPathsCount: 0, expectOutputPathsCount: 0,
}, },
{ {
scenario: "success with every PDF/A & PDF/UA form fields (single file)", scenario: "success with PDF/A & PDF/UA form fields (single file)",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
"file.pdf": "/file.pdf", "file.pdf": "/file.pdf",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"pdfFormat": {
gotenberg.PdfA1a,
},
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },
@@ -351,7 +345,7 @@ func TestConvertHandler(t *testing.T) {
expectOutputPathsCount: 1, expectOutputPathsCount: 1,
}, },
{ {
scenario: "success with every PDF/A & PDF/UA form fields (many files)", scenario: "success with PDF/A & PDF/UA form fields (many files)",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
ctx := &api.ContextMock{Context: new(api.Context)} ctx := &api.ContextMock{Context: new(api.Context)}
ctx.SetFiles(map[string]string{ ctx.SetFiles(map[string]string{
@@ -359,9 +353,6 @@ func TestConvertHandler(t *testing.T) {
"file2.pdf": "/file2.pdf", "file2.pdf": "/file2.pdf",
}) })
ctx.SetValues(map[string][]string{ ctx.SetValues(map[string][]string{
"pdfFormat": {
gotenberg.PdfA1a,
},
"pdfa": { "pdfa": {
gotenberg.PdfA1a, gotenberg.PdfA1a,
}, },

View File

@@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"sync"
"go.uber.org/zap" "go.uber.org/zap"
@@ -52,23 +51,6 @@ func (engine *PdfTk) Validate() error {
return nil return nil
} }
// Metrics returns the metrics.
func (engine *PdfTk) Metrics() ([]gotenberg.Metric, error) {
// TODO: remove deprecated.
return []gotenberg.Metric{
{
Name: "pdftk_active_instances_count",
Description: "Current number of active PDFtk instances - deprecated.",
Read: func() float64 {
activeInstancesCountMu.RLock()
defer activeInstancesCountMu.RUnlock()
return activeInstancesCount
},
},
}, nil
}
// Merge combines multiple PDFs into a single PDF. // Merge combines multiple PDFs into a single PDF.
func (engine *PdfTk) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { func (engine *PdfTk) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
var args []string var args []string
@@ -80,16 +62,7 @@ func (engine *PdfTk) Merge(ctx context.Context, logger *zap.Logger, inputPaths [
return fmt.Errorf("create command: %w", err) return fmt.Errorf("create command: %w", err)
} }
activeInstancesCountMu.Lock()
activeInstancesCount += 1
activeInstancesCountMu.Unlock()
_, err = cmd.Exec() _, err = cmd.Exec()
activeInstancesCountMu.Lock()
activeInstancesCount -= 1
activeInstancesCountMu.Unlock()
if err == nil { if err == nil {
return nil return nil
} }
@@ -102,16 +75,10 @@ func (engine *PdfTk) Convert(ctx context.Context, logger *zap.Logger, formats go
return fmt.Errorf("convert PDF to '%+v' with PDFtk: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported) return fmt.Errorf("convert PDF to '%+v' with PDFtk: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
} }
var (
activeInstancesCount float64
activeInstancesCountMu sync.RWMutex
)
// Interface guards. // Interface guards.
var ( var (
_ gotenberg.Module = (*PdfTk)(nil) _ gotenberg.Module = (*PdfTk)(nil)
_ gotenberg.Provisioner = (*PdfTk)(nil) _ gotenberg.Provisioner = (*PdfTk)(nil)
_ gotenberg.Validator = (*PdfTk)(nil) _ gotenberg.Validator = (*PdfTk)(nil)
_ gotenberg.MetricsProvider = (*PdfTk)(nil) _ gotenberg.PdfEngine = (*PdfTk)(nil)
_ gotenberg.PdfEngine = (*PdfTk)(nil)
) )

View File

@@ -71,22 +71,6 @@ func TestPdfTk_Validate(t *testing.T) {
} }
} }
func TestPdfTk_Metrics(t *testing.T) {
metrics, err := new(PdfTk).Metrics()
if err != nil {
t.Fatalf("expected no error but got: %v", err)
}
if len(metrics) != 1 {
t.Fatalf("expected %d metrics, but got %d", 1, len(metrics))
}
actual := metrics[0].Read()
if actual != 0 {
t.Errorf("expected %d PDFtk instances, but got %f", 0, actual)
}
}
func TestPdfTk_Merge(t *testing.T) { func TestPdfTk_Merge(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
scenario string scenario string

View File

@@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"sync"
"go.uber.org/zap" "go.uber.org/zap"
@@ -52,23 +51,6 @@ func (engine *QPdf) Validate() error {
return nil return nil
} }
// Metrics returns the metrics.
func (engine *QPdf) Metrics() ([]gotenberg.Metric, error) {
// TODO: remove deprecated.
return []gotenberg.Metric{
{
Name: "qpdf_active_instances_count",
Description: "Current number of active QPDF instances - deprecated.",
Read: func() float64 {
activeInstancesCountMu.RLock()
defer activeInstancesCountMu.RUnlock()
return activeInstancesCount
},
},
}, nil
}
// Merge combines multiple PDFs into a single PDF. // Merge combines multiple PDFs into a single PDF.
func (engine *QPdf) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { func (engine *QPdf) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
var args []string var args []string
@@ -82,16 +64,7 @@ func (engine *QPdf) Merge(ctx context.Context, logger *zap.Logger, inputPaths []
return fmt.Errorf("create command: %w", err) return fmt.Errorf("create command: %w", err)
} }
activeInstancesCountMu.Lock()
activeInstancesCount += 1
activeInstancesCountMu.Unlock()
_, err = cmd.Exec() _, err = cmd.Exec()
activeInstancesCountMu.Lock()
activeInstancesCount -= 1
activeInstancesCountMu.Unlock()
if err == nil { if err == nil {
return nil return nil
} }
@@ -105,14 +78,8 @@ func (engine *QPdf) Convert(ctx context.Context, logger *zap.Logger, formats got
} }
var ( var (
activeInstancesCount float64 _ gotenberg.Module = (*QPdf)(nil)
activeInstancesCountMu sync.RWMutex _ gotenberg.Provisioner = (*QPdf)(nil)
) _ gotenberg.Validator = (*QPdf)(nil)
_ gotenberg.PdfEngine = (*QPdf)(nil)
var (
_ gotenberg.Module = (*QPdf)(nil)
_ gotenberg.Provisioner = (*QPdf)(nil)
_ gotenberg.Validator = (*QPdf)(nil)
_ gotenberg.MetricsProvider = (*QPdf)(nil)
_ gotenberg.PdfEngine = (*QPdf)(nil)
) )

View File

@@ -71,22 +71,6 @@ func TestQPdf_Validate(t *testing.T) {
} }
} }
func TestQPdf_Metrics(t *testing.T) {
metrics, err := new(QPdf).Metrics()
if err != nil {
t.Errorf("expected no error but got: %v", err)
}
if len(metrics) != 1 {
t.Errorf("expected %d metrics, but got %d", 1, len(metrics))
}
actual := metrics[0].Read()
if actual != 0 {
t.Errorf("expected %d QPdf instances, but got %f", 0, actual)
}
}
func TestQPdf_Merge(t *testing.T) { func TestQPdf_Merge(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
scenario string scenario string

View File

@@ -1,12 +1,10 @@
package webhook package webhook
import ( import (
"fmt"
"regexp" "regexp"
"time" "time"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"go.uber.org/multierr"
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg" "github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
"github.com/gotenberg/gotenberg/v7/pkg/modules/api" "github.com/gotenberg/gotenberg/v7/pkg/modules/api"
@@ -36,31 +34,6 @@ func (w *Webhook) Descriptor() gotenberg.ModuleDescriptor {
ID: "webhook", ID: "webhook",
FlagSet: func() *flag.FlagSet { FlagSet: func() *flag.FlagSet {
fs := flag.NewFlagSet("webhook", flag.ExitOnError) fs := flag.NewFlagSet("webhook", flag.ExitOnError)
// Deprecated flags.
fs.String("api-webhook-allow-list", "", "Set the allowed URLs for the webhook feature using a regular expression")
fs.String("api-webhook-deny-list", "", "Set the denied URLs for the webhook feature using a regular expression")
fs.String("api-webhook-error-allow-list", "", "Set the allowed URLs in case of an error for the webhook feature using a regular expression")
fs.String("api-webhook-error-deny-list", "", "Set the denied URLs in case of an error for the webhook feature using a regular expression")
fs.Int("api-webhook-max-retry", 4, "Set the maximum number of retries for the webhook feature")
fs.Duration("api-webhook-retry-min-wait", time.Duration(1)*time.Second, "Set the minimum duration to wait before trying to call the webhook again")
fs.Duration("api-webhook-retry-max-wait", time.Duration(30)*time.Second, "Set the maximum duration to wait before trying to call the webhook again")
fs.Bool("api-disable-webhook", false, "Disable the webhook feature")
var err error
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-allow-list", "use webhook-allow-list instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-deny-list", "use webhook-deny-list instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-error-allow-list", "use webhook-error-allow-list instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-error-deny-list", "use webhook-error-deny-list instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-max-retry", "use webhook-max-retry instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-retry-min-wait", "use webhook-retry-min-wait instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-webhook-retry-max-wait", "use webhook-retry-max-wait instead"))
err = multierr.Append(err, fs.MarkDeprecated("api-disable-webhook", "use webhook-disable instead"))
if err != nil {
panic(fmt.Errorf("create deprecated flags for the webhook module: %v", err))
}
// New flags.
fs.String("webhook-allow-list", "", "Set the allowed URLs for the webhook feature using a regular expression") fs.String("webhook-allow-list", "", "Set the allowed URLs for the webhook feature using a regular expression")
fs.String("webhook-deny-list", "", "Set the denied URLs for the webhook feature using a regular expression") fs.String("webhook-deny-list", "", "Set the denied URLs for the webhook feature using a regular expression")
fs.String("webhook-error-allow-list", "", "Set the allowed URLs in case of an error for the webhook feature using a regular expression") fs.String("webhook-error-allow-list", "", "Set the allowed URLs in case of an error for the webhook feature using a regular expression")
@@ -80,15 +53,15 @@ func (w *Webhook) Descriptor() gotenberg.ModuleDescriptor {
// Provision sets the module properties. // Provision sets the module properties.
func (w *Webhook) Provision(ctx *gotenberg.Context) error { func (w *Webhook) Provision(ctx *gotenberg.Context) error {
flags := ctx.ParsedFlags() flags := ctx.ParsedFlags()
w.allowList = flags.MustDeprecatedRegexp("api-webhook-allow-list", "webhook-allow-list") w.allowList = flags.MustRegexp("webhook-allow-list")
w.denyList = flags.MustDeprecatedRegexp("api-webhook-deny-list", "webhook-deny-list") w.denyList = flags.MustRegexp("webhook-deny-list")
w.errorAllowList = flags.MustDeprecatedRegexp("api-webhook-error-allow-list", "webhook-error-allow-list") w.errorAllowList = flags.MustRegexp("webhook-error-allow-list")
w.errorDenyList = flags.MustDeprecatedRegexp("api-webhook-error-deny-list", "webhook-error-deny-list") w.errorDenyList = flags.MustRegexp("webhook-error-deny-list")
w.maxRetry = flags.MustDeprecatedInt("api-webhook-max-retry", "webhook-max-retry") w.maxRetry = flags.MustInt("webhook-max-retry")
w.retryMinWait = flags.MustDeprecatedDuration("api-webhook-retry-min-wait", "webhook-retry-min-wait") w.retryMinWait = flags.MustDuration("webhook-retry-min-wait")
w.retryMaxWait = flags.MustDeprecatedDuration("api-webhook-retry-min-wait", "webhook-retry-max-wait") w.retryMaxWait = flags.MustDuration("webhook-retry-max-wait")
w.clientTimeout = flags.MustDuration("webhook-client-timeout") w.clientTimeout = flags.MustDuration("webhook-client-timeout")
w.disable = flags.MustDeprecatedBool("api-disable-webhook", "webhook-disable") w.disable = flags.MustBool("webhook-disable")
return nil return nil
} }