diff --git a/pkg/modules/api/api.go b/pkg/modules/api/api.go index bb4b9d42..84b7cdd9 100644 --- a/pkg/modules/api/api.go +++ b/pkg/modules/api/api.go @@ -29,8 +29,6 @@ func init() { // middlewares or health checks. type Api struct { port int - readTimeout time.Duration - writeTimeout time.Duration timeout time.Duration rootPath string traceHeader string @@ -157,23 +155,11 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor { fs := flag.NewFlagSet("api", flag.ExitOnError) 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.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.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.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 }(), 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 { flags := ctx.ParsedFlags() a.port = flags.MustInt("api-port") - a.readTimeout = flags.MustDeprecatedDuration("api-read-timeout", "api-timeout") - a.writeTimeout = flags.MustDeprecatedDuration("api-write-timeout", "api-timeout") - a.timeout = flags.MustDeprecatedDuration("api-process-timeout", "api-timeout") + a.timeout = flags.MustDuration("api-timeout") a.rootPath = flags.MustString("api-root-path") a.traceHeader = flags.MustString("api-trace-header") a.disableHealthCheckLogging = flags.MustBool("api-disable-health-check-logging") @@ -373,10 +357,10 @@ func (a *Api) Start() error { a.srv = echo.New() a.srv.HideBanner = true a.srv.HidePort = true - a.srv.Server.ReadTimeout = a.readTimeout + a.srv.Server.ReadTimeout = a.timeout a.srv.Server.IdleTimeout = a.timeout // 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() // Let's prepare the modules' routes. diff --git a/pkg/modules/chromium/chromium.go b/pkg/modules/chromium/chromium.go index 8fc8826b..fc9a9735 100644 --- a/pkg/modules/chromium/chromium.go +++ b/pkg/modules/chromium/chromium.go @@ -9,7 +9,6 @@ import ( "github.com/alexliesenfeld/health" flag "github.com/spf13/pflag" - "go.uber.org/multierr" "go.uber.org/zap" "github.com/gotenberg/gotenberg/v7/pkg/gotenberg" @@ -217,18 +216,6 @@ func (mod *Chromium) Descriptor() gotenberg.ModuleDescriptor { ID: "chromium", FlagSet: func() *flag.FlagSet { 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.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") @@ -359,22 +346,6 @@ func (mod *Chromium) Stop(ctx context.Context) error { // Metrics returns the metrics. func (mod *Chromium) Metrics() ([]gotenberg.Metric, error) { 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", Description: "Current number of Chromium conversion requests waiting to be treated.", diff --git a/pkg/modules/chromium/chromium_test.go b/pkg/modules/chromium/chromium_test.go index f66156a0..b35aacd8 100644 --- a/pkg/modules/chromium/chromium_test.go +++ b/pkg/modules/chromium/chromium_test.go @@ -334,26 +334,16 @@ func TestChromium_Metrics(t *testing.T) { t.Fatalf("expected no error but got: %v", err) } - if len(metrics) != 4 { - t.Fatalf("expected %d metrics, but got %d", 4, len(metrics)) + if len(metrics) != 2 { + t.Fatalf("expected %d metrics, but got %d", 2, len(metrics)) } 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) { 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) { t.Errorf("expected %f for chromium_restarts_count, but got %f", float64(0), actual) } diff --git a/pkg/modules/chromium/routes.go b/pkg/modules/chromium/routes.go index fbc4107a..83e8e80b 100644 --- a/pkg/modules/chromium/routes.go +++ b/pkg/modules/chromium/routes.go @@ -31,7 +31,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) { waitDelay time.Duration waitWindowStatus string waitForExpression string - userAgent string extraHttpHeaders map[string]string emulatedMediaType string landscape, printBackground, omitBackground bool @@ -47,7 +46,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) { Duration("waitDelay", &waitDelay, defaultOptions.WaitDelay). String("waitWindowStatus", &waitWindowStatus, defaultOptions.WaitWindowStatus). String("waitForExpression", &waitForExpression, defaultOptions.WaitForExpression). - String("userAgent", &userAgent, ""). // FIXME: deprecated. Custom("extraHttpHeaders", func(value string) error { if value == "" { extraHttpHeaders = defaultOptions.ExtraHttpHeaders @@ -92,17 +90,6 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) { Content("footer.html", &footerTemplate, defaultOptions.FooterTemplate). 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{ FailOnConsoleExceptions: failOnConsoleExceptions, 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. func FormDataChromiumPdfFormats(ctx *api.Context) gotenberg.PdfFormats { var ( - pdfFormat string - pdfa string - pdfua bool + pdfa string + pdfua bool ) ctx.FormData(). - String("pdfFormat", &pdfFormat, ""). String("pdfa", &pdfa, ""). 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{ - PdfA: actualPdfArchive, + PdfA: pdfa, PdfUa: pdfua, } } diff --git a/pkg/modules/chromium/routes_test.go b/pkg/modules/chromium/routes_test.go index d215730d..f1e8cace 100644 --- a/pkg/modules/chromium/routes_test.go +++ b/pkg/modules/chromium/routes_test.go @@ -28,25 +28,6 @@ func TestFormDataChromiumPdfOptions(t *testing.T) { ctx: &api.ContextMock{Context: new(api.Context)}, 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", ctx: func() *api.ContextMock { @@ -132,19 +113,6 @@ func TestFormDataChromiumPdfFormats(t *testing.T) { ctx: &api.ContextMock{Context: new(api.Context)}, 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", ctx: func() *api.ContextMock { @@ -726,7 +694,7 @@ func TestConvertUrl(t *testing.T) { expectOutputPathsCount: 0, }, { - scenario: "success with pdfFormat form field", + scenario: "success with pdfa form field", ctx: &api.ContextMock{Context: new(api.Context)}, api: &ApiMock{func(ctx context.Context, logger *zap.Logger, url, outputPath string, options Options) error { return nil diff --git a/pkg/modules/libreoffice/api/api.go b/pkg/modules/libreoffice/api/api.go index b5ac69d1..5faef49b 100644 --- a/pkg/modules/libreoffice/api/api.go +++ b/pkg/modules/libreoffice/api/api.go @@ -47,7 +47,6 @@ type Options struct { Landscape bool // PageRanges allows to select the pages to convert. - // TODO: should prefer a method form PdfEngine. // Optional. PageRanges string @@ -80,21 +79,6 @@ func (a *Api) Descriptor() gotenberg.ModuleDescriptor { ID: "libreoffice-api", FlagSet: func() *flag.FlagSet { 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.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") @@ -123,7 +107,7 @@ func (a *Api) Provision(ctx *gotenberg.Context) error { a.args = libreOfficeArguments{ binPath: libreOfficeBinPath, unoBinPath: unoBinPath, - startTimeout: flags.MustDeprecatedDuration("uno-listener-start-timeout", "libreoffice-start-timeout"), + startTimeout: flags.MustDuration("libreoffice-start-timeout"), } // Logger. @@ -139,7 +123,7 @@ func (a *Api) Provision(ctx *gotenberg.Context) error { // Process. 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 } @@ -204,46 +188,6 @@ func (a *Api) Stop(ctx context.Context) error { // Metrics returns the metrics. func (a *Api) Metrics() ([]gotenberg.Metric, error) { 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", Description: "Current number of LibreOffice conversion requests waiting to be treated.", diff --git a/pkg/modules/libreoffice/api/api_test.go b/pkg/modules/libreoffice/api/api_test.go index aa220fb7..44d4d014 100644 --- a/pkg/modules/libreoffice/api/api_test.go +++ b/pkg/modules/libreoffice/api/api_test.go @@ -284,41 +284,16 @@ func TestApi_Metrics(t *testing.T) { t.Fatalf("expected no error but got: %v", err) } - if len(metrics) != 7 { - t.Fatalf("expected %d metrics, but got %d", 7, len(metrics)) + if len(metrics) != 2 { + t.Fatalf("expected %d metrics, but got %d", 2, len(metrics)) } 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) { 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) { t.Errorf("expected %f for libreoffice_restarts_count, but got %f", float64(0), actual) } diff --git a/pkg/modules/libreoffice/routes.go b/pkg/modules/libreoffice/routes.go index 7f749f63..9154cc54 100644 --- a/pkg/modules/libreoffice/routes.go +++ b/pkg/modules/libreoffice/routes.go @@ -24,25 +24,19 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap // Let's get the data from the form and validate them. var ( - inputPaths []string - landscape bool - nativePageRanges string - nativePdfA1aFormat bool - nativePdfFormat string - pdfFormat string - pdfa string - pdfua bool - nativePdfFormats bool - merge bool + inputPaths []string + landscape bool + nativePageRanges string + pdfa string + pdfua bool + nativePdfFormats bool + merge bool ) err := ctx.FormData(). MandatoryPaths(libreOffice.Extensions(), &inputPaths). Bool("landscape", &landscape, false). String("nativePageRanges", &nativePageRanges, ""). - Bool("nativePdfA1aFormat", &nativePdfA1aFormat, false). - String("nativePdfFormat", &nativePdfFormat, ""). - String("pdfFormat", &pdfFormat, ""). String("pdfa", &pdfa, ""). Bool("pdfua", &pdfua, false). 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) } - // 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{ - PdfA: actualPdfArchive, + PdfA: pdfa, PdfUa: pdfua, } @@ -101,7 +61,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap PageRanges: nativePageRanges, } - if nativeFormats { + if nativePdfFormats { 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 // PDF to specific PDF formats. zeroValued := gotenberg.PdfFormats{} - if !nativeFormats && pdfFormats != zeroValued { + if !nativePdfFormats && pdfFormats != zeroValued { convertInputPath := outputPath 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 // want to convert each PDF to a specific PDF format. zeroValued := gotenberg.PdfFormats{} - if !nativeFormats && pdfFormats != zeroValued { + if !nativePdfFormats && pdfFormats != zeroValued { convertOutputPaths := make([]string, len(outputPaths)) for i, outputPath := range outputPaths { diff --git a/pkg/modules/libreoffice/routes_test.go b/pkg/modules/libreoffice/routes_test.go index b3d42b43..3d4687e8 100644 --- a/pkg/modules/libreoffice/routes_test.go +++ b/pkg/modules/libreoffice/routes_test.go @@ -88,9 +88,12 @@ func TestConvertRoute(t *testing.T) { "document.docx": "/document.docx", }) ctx.SetValues(map[string][]string{ - "pdfFormat": { + "pdfa": { "foo", }, + "nativePdfFormats": { + "false", + }, }) return ctx }(), @@ -120,9 +123,12 @@ func TestConvertRoute(t *testing.T) { "document.docx": "/document.docx", }) ctx.SetValues(map[string][]string{ - "pdfFormat": { + "pdfa": { gotenberg.PdfA1a, }, + "nativePdfFormats": { + "false", + }, }) return ctx }(), @@ -209,7 +215,7 @@ func TestConvertRoute(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ @@ -219,6 +225,9 @@ func TestConvertRoute(t *testing.T) { "pdfa": { gotenberg.PdfA1a, }, + "pdfua": { + "true", + }, "nativePdfFormats": { "false", }, @@ -243,31 +252,19 @@ func TestConvertRoute(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ "document.docx": "/document.docx", }) ctx.SetValues(map[string][]string{ - "nativePdfA1aFormat": { - "true", - }, - "pdfFormat": { - gotenberg.PdfA1a, - }, - "nativePdfFormat": { - gotenberg.PdfA1a, - }, "pdfa": { gotenberg.PdfA1a, }, "pdfua": { "true", }, - "nativePdfFormats": { - "false", - }, }) return ctx }(), @@ -469,7 +466,7 @@ func TestConvertRoute(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ @@ -483,6 +480,53 @@ func TestConvertRoute(t *testing.T) { "pdfa": { 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": { "false", }, diff --git a/pkg/modules/pdfengines/pdfengines.go b/pkg/modules/pdfengines/pdfengines.go index 0b8954b9..7cfa0550 100644 --- a/pkg/modules/pdfengines/pdfengines.go +++ b/pkg/modules/pdfengines/pdfengines.go @@ -54,18 +54,6 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error { names := flags.MustStringSlice("pdfengines-engines") 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)) if err != nil { return fmt.Errorf("get PDF engines: %w", err) @@ -81,13 +69,13 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error { // Selection from user. mod.names = names - for i, name := range names { - // FIXME: deprecated. - if name == "unoconv-pdfengine" || name == "uno-pdfengine" { - logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name)) - mod.names[i] = "libreoffice-pdfengine" - } - } + // Example in case of deprecated module name. + //for i, name := range names { + // if name == "unoconv-pdfengine" || name == "uno-pdfengine" { + // logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name)) + // mod.names[i] = "libreoffice-pdfengine" + // } + //} return nil } diff --git a/pkg/modules/pdfengines/pdfengines_test.go b/pkg/modules/pdfengines/pdfengines_test.go index 1f785f3d..f85d91b2 100644 --- a/pkg/modules/pdfengines/pdfengines_test.go +++ b/pkg/modules/pdfengines/pdfengines_test.go @@ -6,8 +6,6 @@ import ( "strings" "testing" - "go.uber.org/zap" - "github.com/gotenberg/gotenberg/v7/pkg/gotenberg" ) @@ -34,16 +32,12 @@ func TestPdfEngines_Provision(t *testing.T) { 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 @@ -75,17 +69,12 @@ func TestPdfEngines_Provision(t *testing.T) { 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 - } - engine1 := &struct { gotenberg.ModuleMock gotenberg.ValidatorMock @@ -130,108 +119,17 @@ func TestPdfEngines_Provision(t *testing.T) { expectedPdfEngines: []string{"b", "a"}, 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", 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 diff --git a/pkg/modules/pdfengines/routes.go b/pkg/modules/pdfengines/routes.go index ecf002f6..c55a12e9 100644 --- a/pkg/modules/pdfengines/routes.go +++ b/pkg/modules/pdfengines/routes.go @@ -23,14 +23,12 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route { // Let's get the data from the form and validate them. var ( inputPaths []string - pdfFormat string pdfa string pdfua bool ) err := ctx.FormData(). MandatoryPaths([]string{".pdf"}, &inputPaths). - String("pdfFormat", &pdfFormat, ""). String("pdfa", &pdfa, ""). Bool("pdfua", &pdfua, false). Validate() @@ -38,20 +36,8 @@ func mergeRoute(engine gotenberg.PdfEngine) api.Route { 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{ - PdfA: actualPdfArchive, + PdfA: pdfa, PdfUa: pdfua, } @@ -118,14 +104,12 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route { // Let's get the data from the form and validate them. var ( inputPaths []string - pdfFormat string pdfa string pdfua bool ) err := ctx.FormData(). MandatoryPaths([]string{".pdf"}, &inputPaths). - String("pdfFormat", &pdfFormat, ""). String("pdfa", &pdfa, ""). Bool("pdfua", &pdfua, false). Validate() @@ -133,20 +117,8 @@ func convertRoute(engine gotenberg.PdfEngine) api.Route { 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{ - PdfA: actualPdfArchive, + PdfA: pdfa, PdfUa: pdfua, } diff --git a/pkg/modules/pdfengines/routes_test.go b/pkg/modules/pdfengines/routes_test.go index cf71be10..41f6e52f 100644 --- a/pkg/modules/pdfengines/routes_test.go +++ b/pkg/modules/pdfengines/routes_test.go @@ -145,7 +145,7 @@ func TestMergeHandler(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ @@ -153,9 +153,6 @@ func TestMergeHandler(t *testing.T) { "file2.pdf": "/file2.pdf", }) ctx.SetValues(map[string][]string{ - "pdfFormat": { - gotenberg.PdfA1a, - }, "pdfa": { gotenberg.PdfA1a, }, @@ -322,16 +319,13 @@ func TestConvertHandler(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ "file.pdf": "/file.pdf", }) ctx.SetValues(map[string][]string{ - "pdfFormat": { - gotenberg.PdfA1a, - }, "pdfa": { gotenberg.PdfA1a, }, @@ -351,7 +345,7 @@ func TestConvertHandler(t *testing.T) { 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 := &api.ContextMock{Context: new(api.Context)} ctx.SetFiles(map[string]string{ @@ -359,9 +353,6 @@ func TestConvertHandler(t *testing.T) { "file2.pdf": "/file2.pdf", }) ctx.SetValues(map[string][]string{ - "pdfFormat": { - gotenberg.PdfA1a, - }, "pdfa": { gotenberg.PdfA1a, }, diff --git a/pkg/modules/pdftk/pdftk.go b/pkg/modules/pdftk/pdftk.go index f3e2e2ff..f5e60f52 100644 --- a/pkg/modules/pdftk/pdftk.go +++ b/pkg/modules/pdftk/pdftk.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "os" - "sync" "go.uber.org/zap" @@ -52,23 +51,6 @@ func (engine *PdfTk) Validate() error { 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. func (engine *PdfTk) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { 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) } - activeInstancesCountMu.Lock() - activeInstancesCount += 1 - activeInstancesCountMu.Unlock() - _, err = cmd.Exec() - - activeInstancesCountMu.Lock() - activeInstancesCount -= 1 - activeInstancesCountMu.Unlock() - if err == 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) } -var ( - activeInstancesCount float64 - activeInstancesCountMu sync.RWMutex -) - // Interface guards. var ( - _ gotenberg.Module = (*PdfTk)(nil) - _ gotenberg.Provisioner = (*PdfTk)(nil) - _ gotenberg.Validator = (*PdfTk)(nil) - _ gotenberg.MetricsProvider = (*PdfTk)(nil) - _ gotenberg.PdfEngine = (*PdfTk)(nil) + _ gotenberg.Module = (*PdfTk)(nil) + _ gotenberg.Provisioner = (*PdfTk)(nil) + _ gotenberg.Validator = (*PdfTk)(nil) + _ gotenberg.PdfEngine = (*PdfTk)(nil) ) diff --git a/pkg/modules/pdftk/pdftk_test.go b/pkg/modules/pdftk/pdftk_test.go index 3defe0a1..27a71b71 100644 --- a/pkg/modules/pdftk/pdftk_test.go +++ b/pkg/modules/pdftk/pdftk_test.go @@ -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) { for _, tc := range []struct { scenario string diff --git a/pkg/modules/qpdf/qpdf.go b/pkg/modules/qpdf/qpdf.go index 23a0ebcb..1f9fc8ae 100644 --- a/pkg/modules/qpdf/qpdf.go +++ b/pkg/modules/qpdf/qpdf.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "os" - "sync" "go.uber.org/zap" @@ -52,23 +51,6 @@ func (engine *QPdf) Validate() error { 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. func (engine *QPdf) Merge(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { 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) } - activeInstancesCountMu.Lock() - activeInstancesCount += 1 - activeInstancesCountMu.Unlock() - _, err = cmd.Exec() - - activeInstancesCountMu.Lock() - activeInstancesCount -= 1 - activeInstancesCountMu.Unlock() - if err == nil { return nil } @@ -105,14 +78,8 @@ func (engine *QPdf) Convert(ctx context.Context, logger *zap.Logger, formats got } var ( - activeInstancesCount float64 - activeInstancesCountMu sync.RWMutex -) - -var ( - _ gotenberg.Module = (*QPdf)(nil) - _ gotenberg.Provisioner = (*QPdf)(nil) - _ gotenberg.Validator = (*QPdf)(nil) - _ gotenberg.MetricsProvider = (*QPdf)(nil) - _ gotenberg.PdfEngine = (*QPdf)(nil) + _ gotenberg.Module = (*QPdf)(nil) + _ gotenberg.Provisioner = (*QPdf)(nil) + _ gotenberg.Validator = (*QPdf)(nil) + _ gotenberg.PdfEngine = (*QPdf)(nil) ) diff --git a/pkg/modules/qpdf/qpdf_test.go b/pkg/modules/qpdf/qpdf_test.go index 34199230..bd7e7050 100644 --- a/pkg/modules/qpdf/qpdf_test.go +++ b/pkg/modules/qpdf/qpdf_test.go @@ -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) { for _, tc := range []struct { scenario string diff --git a/pkg/modules/webhook/webhook.go b/pkg/modules/webhook/webhook.go index 881078c3..fe3add36 100644 --- a/pkg/modules/webhook/webhook.go +++ b/pkg/modules/webhook/webhook.go @@ -1,12 +1,10 @@ package webhook import ( - "fmt" "regexp" "time" flag "github.com/spf13/pflag" - "go.uber.org/multierr" "github.com/gotenberg/gotenberg/v7/pkg/gotenberg" "github.com/gotenberg/gotenberg/v7/pkg/modules/api" @@ -36,31 +34,6 @@ func (w *Webhook) Descriptor() gotenberg.ModuleDescriptor { ID: "webhook", FlagSet: func() *flag.FlagSet { 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-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") @@ -80,15 +53,15 @@ func (w *Webhook) Descriptor() gotenberg.ModuleDescriptor { // Provision sets the module properties. func (w *Webhook) Provision(ctx *gotenberg.Context) error { flags := ctx.ParsedFlags() - w.allowList = flags.MustDeprecatedRegexp("api-webhook-allow-list", "webhook-allow-list") - w.denyList = flags.MustDeprecatedRegexp("api-webhook-deny-list", "webhook-deny-list") - w.errorAllowList = flags.MustDeprecatedRegexp("api-webhook-error-allow-list", "webhook-error-allow-list") - w.errorDenyList = flags.MustDeprecatedRegexp("api-webhook-error-deny-list", "webhook-error-deny-list") - w.maxRetry = flags.MustDeprecatedInt("api-webhook-max-retry", "webhook-max-retry") - w.retryMinWait = flags.MustDeprecatedDuration("api-webhook-retry-min-wait", "webhook-retry-min-wait") - w.retryMaxWait = flags.MustDeprecatedDuration("api-webhook-retry-min-wait", "webhook-retry-max-wait") + w.allowList = flags.MustRegexp("webhook-allow-list") + w.denyList = flags.MustRegexp("webhook-deny-list") + w.errorAllowList = flags.MustRegexp("webhook-error-allow-list") + w.errorDenyList = flags.MustRegexp("webhook-error-deny-list") + w.maxRetry = flags.MustInt("webhook-max-retry") + w.retryMinWait = flags.MustDuration("webhook-retry-min-wait") + w.retryMaxWait = flags.MustDuration("webhook-retry-max-wait") w.clientTimeout = flags.MustDuration("webhook-client-timeout") - w.disable = flags.MustDeprecatedBool("api-disable-webhook", "webhook-disable") + w.disable = flags.MustBool("webhook-disable") return nil }