mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-10-25 11:17:28 +02:00 
			
		
		
		
	api changes
This commit is contained in:
		
							parent
							
								
									4a579c00ce
								
							
						
					
					
						commit
						891f9e2252
					
				| @ -178,6 +178,7 @@ Using the same method you can also change | ||||
| - Disable and remove endpoints and functionality from Stirling-PDF. Currently the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma seperated lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image to pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Frooodle/Stirling-PDF/blob/main/groups.md)  | ||||
| - Change the max file size allowed through the server with the environment variable MAX_FILE_SIZE. default  2000MB | ||||
| - Customise static files such as app logo by placing files in the /customFiles/static/ directory. Example to customise app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF | ||||
| - Enable/Disable metric api endpoints with ENABLE_API_METRICS. Default enabled | ||||
| 
 | ||||
| ## API | ||||
| For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation | ||||
|  | ||||
| @ -8,7 +8,7 @@ plugins { | ||||
| } | ||||
| 
 | ||||
| group = 'stirling.software' | ||||
| version = '0.12.1' | ||||
| version = '0.12.2' | ||||
| sourceCompatibility = '17' | ||||
| 
 | ||||
| repositories { | ||||
|  | ||||
| @ -1,8 +1,16 @@ | ||||
| package stirling.software.SPDF.controller.web; | ||||
| import java.time.Duration; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Comparator; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RequestParam; | ||||
| @ -14,6 +22,8 @@ import io.micrometer.core.instrument.MeterRegistry; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import io.swagger.v3.oas.annotations.Parameter; | ||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||
| import jakarta.annotation.PostConstruct; | ||||
| import stirling.software.SPDF.config.StartupApplicationListener; | ||||
| 
 | ||||
| @RestController | ||||
| @RequestMapping("/api/v1") | ||||
| @ -22,6 +32,20 @@ public class MetricsController { | ||||
| 
 | ||||
|     private final MeterRegistry meterRegistry; | ||||
| 
 | ||||
|     private boolean isEndpointEnabled; | ||||
|      | ||||
|     @PostConstruct | ||||
|     public void init() { | ||||
|         String isEndpointEnabled = System.getProperty("ENABLE_API_METRICS"); | ||||
|         if (isEndpointEnabled == null) { | ||||
|         	isEndpointEnabled = System.getenv("ENABLE_API_METRICS"); | ||||
|         	if (isEndpointEnabled == null) { | ||||
|         		isEndpointEnabled = "true"; | ||||
|         	} | ||||
|         } | ||||
|         this.isEndpointEnabled = "true".equalsIgnoreCase(isEndpointEnabled); | ||||
|     } | ||||
|      | ||||
|     public MetricsController(MeterRegistry meterRegistry) { | ||||
|         this.meterRegistry = meterRegistry; | ||||
|     } | ||||
| @ -29,18 +53,25 @@ public class MetricsController { | ||||
|     @GetMapping("/status") | ||||
|     @Operation(summary = "Application status and version", | ||||
|             description = "This endpoint returns the status of the application and its version number.") | ||||
|     public Map<String, String> getStatus() { | ||||
|     public ResponseEntity<?> getStatus() { | ||||
|         if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, String> status = new HashMap<>(); | ||||
|         status.put("status", "UP"); | ||||
|         status.put("version", getClass().getPackage().getImplementationVersion()); | ||||
|         return status; | ||||
|         return ResponseEntity.ok(status); | ||||
|     } | ||||
|      | ||||
|     @GetMapping("/loads") | ||||
|     @Operation(summary = "GET request count", | ||||
|             description = "This endpoint returns the total count of GET requests or the count of GET requests for a specific endpoint.") | ||||
|     public Double getPageLoads(@RequestParam(required = false,  name = "endpoint") @Parameter(description = "endpoint") Optional<String> endpoint) { | ||||
|         try { | ||||
|     public ResponseEntity<?> getPageLoads(@RequestParam(required = false,  name = "endpoint") @Parameter(description = "endpoint") Optional<String> endpoint) { | ||||
|     	if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
|     	try { | ||||
| 
 | ||||
|             double count = 0.0; | ||||
|              | ||||
| @ -68,36 +99,165 @@ public class MetricsController { | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return count; | ||||
|             return ResponseEntity.ok(count); | ||||
|         } catch (Exception e) { | ||||
|             return -1.0; | ||||
|             return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @GetMapping("/loads/all") | ||||
|     @Operation(summary = "GET requests count for all endpoints", | ||||
|             description = "This endpoint returns the count of GET requests for each endpoint.") | ||||
|     public ResponseEntity<?> getAllEndpointLoads() { | ||||
|     	if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
|         try { | ||||
|             Map<String, Double> counts = new HashMap<>(); | ||||
| 
 | ||||
|             for (Meter meter : meterRegistry.getMeters()) { | ||||
|                 if (meter.getId().getName().equals("http.requests")) { | ||||
|                     String method = meter.getId().getTag("method"); | ||||
|                     if (method != null && method.equals("GET")) { | ||||
|                         String uri = meter.getId().getTag("uri"); | ||||
|                         if (uri != null) { | ||||
|                             double currentCount = counts.getOrDefault(uri, 0.0); | ||||
|                             if (meter instanceof Counter) { | ||||
|                                 currentCount += ((Counter) meter).count(); | ||||
|                             } | ||||
|                             counts.put(uri, currentCount); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             List<EndpointCount> results = counts.entrySet().stream() | ||||
|                 .map(entry -> new EndpointCount(entry.getKey(), entry.getValue())) | ||||
|                 .sorted(Comparator.comparing(EndpointCount::getCount).reversed()) | ||||
|                 .collect(Collectors.toList()); | ||||
| 
 | ||||
|             return ResponseEntity.ok(results); | ||||
|         } catch (Exception e) { | ||||
|             return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class EndpointCount { | ||||
|         private String endpoint; | ||||
|         private double count; | ||||
|          | ||||
|         public EndpointCount(String endpoint, double count) { | ||||
|         	this.endpoint = endpoint; | ||||
|         	this.count = count; | ||||
|         } | ||||
| 		public String getEndpoint() { | ||||
| 			return endpoint; | ||||
| 		} | ||||
| 		public void setEndpoint(String endpoint) { | ||||
| 			this.endpoint = endpoint; | ||||
| 		} | ||||
| 		public double getCount() { | ||||
| 			return count; | ||||
| 		} | ||||
| 		public void setCount(double count) { | ||||
| 			this.count = count; | ||||
| 		} | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @GetMapping("/requests") | ||||
|     @Operation(summary = "POST request count", | ||||
|             description = "This endpoint returns the total count of POST requests or the count of POST requests for a specific endpoint.") | ||||
|     public Double getTotalRequests(@RequestParam(required = false,  name = "endpoint") @Parameter(description = "endpoint") Optional<String> endpoint) { | ||||
|         try { | ||||
|             Counter counter; | ||||
|             if (endpoint.isPresent() && !endpoint.get().isBlank()) { | ||||
|             	if(!endpoint.get().startsWith("/")) { | ||||
|         			endpoint =  Optional.of("/" + endpoint.get()); | ||||
|         		} | ||||
|             	 | ||||
|             	System.out.println("loads " + endpoint.get() +  " vs " + meterRegistry.get("http.requests").tags("uri", endpoint.get()).toString()); | ||||
|                 counter = meterRegistry.get("http.requests") | ||||
|                     .tags("method", "POST", "uri", endpoint.get()).counter(); | ||||
|             } else { | ||||
|                 counter = meterRegistry.get("http.requests") | ||||
|                     .tags("method", "POST").counter(); | ||||
|             } | ||||
|             return counter.count(); | ||||
|         } catch (Exception e) { | ||||
|         	e.printStackTrace(); | ||||
|             return 0.0; | ||||
|     public ResponseEntity<?> getTotalRequests(@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint") Optional<String> endpoint) { | ||||
|     	if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
|     	try { | ||||
|             double count = 0.0; | ||||
| 
 | ||||
|             for (Meter meter : meterRegistry.getMeters()) { | ||||
|                 if (meter.getId().getName().equals("http.requests")) { | ||||
|                     String method = meter.getId().getTag("method"); | ||||
|                     if (method != null && method.equals("POST")) { | ||||
|                         if (endpoint.isPresent() && !endpoint.get().isBlank()) { | ||||
|                             if (!endpoint.get().startsWith("/")) { | ||||
|                                 endpoint = Optional.of("/" + endpoint.get()); | ||||
|                             } | ||||
|                             if (endpoint.get().equals(meter.getId().getTag("uri"))) { | ||||
|                                 if (meter instanceof Counter) { | ||||
|                                     count += ((Counter) meter).count(); | ||||
|                                 } | ||||
|                             } | ||||
|                         } else { | ||||
|                             if (meter instanceof Counter) { | ||||
|                                 count += ((Counter) meter).count(); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return ResponseEntity.ok(count);	 | ||||
|         } catch (Exception e) { | ||||
|         	return ResponseEntity.ok(-1); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @GetMapping("/requests/all") | ||||
|     @Operation(summary = "POST requests count for all endpoints", | ||||
|             description = "This endpoint returns the count of POST requests for each endpoint.") | ||||
|     public ResponseEntity<?> getAllPostRequests() { | ||||
|     	if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
|         try { | ||||
|             Map<String, Double> counts = new HashMap<>(); | ||||
| 
 | ||||
|             for (Meter meter : meterRegistry.getMeters()) { | ||||
|                 if (meter.getId().getName().equals("http.requests")) { | ||||
|                     String method = meter.getId().getTag("method"); | ||||
|                     if (method != null && method.equals("POST")) { | ||||
|                         String uri = meter.getId().getTag("uri"); | ||||
|                         if (uri != null) { | ||||
|                             double currentCount = counts.getOrDefault(uri, 0.0); | ||||
|                             if (meter instanceof Counter) { | ||||
|                                 currentCount += ((Counter) meter).count(); | ||||
|                             } | ||||
|                             counts.put(uri, currentCount); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             List<EndpointCount> results = counts.entrySet().stream() | ||||
|                 .map(entry -> new EndpointCount(entry.getKey(), entry.getValue())) | ||||
|                 .sorted(Comparator.comparing(EndpointCount::getCount).reversed()) | ||||
|                 .collect(Collectors.toList()); | ||||
| 
 | ||||
|             return ResponseEntity.ok(results); | ||||
|         } catch (Exception e) { | ||||
|             return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     @GetMapping("/uptime") | ||||
|     public ResponseEntity<?> getUptime() { | ||||
|         if (!isEndpointEnabled) { | ||||
|             return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled."); | ||||
|         } | ||||
| 
 | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
|         Duration uptime = Duration.between(StartupApplicationListener.startTime, now); | ||||
|         return ResponseEntity.ok(formatDuration(uptime)); | ||||
|     } | ||||
| 
 | ||||
|     private String formatDuration(Duration duration) { | ||||
|         long days = duration.toDays(); | ||||
|         long hours = duration.toHoursPart(); | ||||
|         long minutes = duration.toMinutesPart(); | ||||
|         long seconds = duration.toSecondsPart(); | ||||
|         return String.format("%dd %dh %dm %ds", days, hours, minutes, seconds); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user