Request API - FreshPerf/PVE4J GitHub Wiki
This guide explains the fluent request API in PVE4J.
- ProxmoxRequest
- Request Execution
- Retry Configuration
- Task Transformers
- Request Patterns
- Advanced Request Handling
All PVE4J API calls return a ProxmoxRequest<T> object, which provides a fluent interface for configuring and executing requests.
ProxmoxRequest<PveVersion> request = proxmox.getVersion();
PveVersion version = request.execute();PveTask task = proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.start()
.waitForCompletion(proxmox)
.execute();Execute the request immediately:
try {
PveVersion version = proxmox.getVersion().execute();
System.out.println("Version: " + version.getVersion());
} catch (ProxmoxAPIError | InterruptedException e) {
e.printStackTrace();
}Store the request and execute later:
ProxmoxRequest<PveVersion> versionRequest = proxmox.getVersion();
// Later...
PveVersion version = versionRequest.execute();PVE4J supports automatic retries for transient failures.
PveVersion version = proxmox.getVersion()
.retry(3) // Retry up to 3 times on failure
.execute();import java.time.Duration;
PveVersion version = proxmox.getVersion()
.retry(3)
.retryDelay(2000) // Wait 2 seconds between retries
.execute();
// Or using Duration
PveVersion version = proxmox.getVersion()
.retry(3)
.retryDelay(Duration.ofSeconds(5))
.execute();Retries are automatically triggered for:
- HTTP 429 (Too Many Requests)
- HTTP 503 (Service Unavailable)
- HTTP 5xx (Server Errors)
For operations that return tasks, PVE4J provides transformation options.
Block until the task completes:
PveTask task = proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.start()
.waitForCompletion(proxmox)
.execute();
// Task is guaranteed to be completed hereBy default, task status is checked every second. You can customize this:
import java.time.Duration;
PveTask task = proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.start()
.waitForCompletion(proxmox)
.taskCheckDelay(5000) // Check every 5 seconds
.execute();
// Or using Duration
PveTask task = proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.cloneVm(200)
.waitForCompletion(proxmox)
.taskCheckDelay(Duration.ofSeconds(10)) // Check every 10 seconds for long operations
.execute();Set a maximum time to wait for task completion:
PveTask task = proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.cloneVm(200)
.waitForCompletion(proxmox)
.taskTimeout(Duration.ofMinutes(5))
.taskCheckDelay(Duration.ofSeconds(2))
.execute();Execute a callback when the task completes:
proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(100)
.start()
.onCompletion((task, status) -> {
if (status.isSuccessful()) {
System.out.println("Task completed successfully!");
} else {
System.err.println("Task failed: " + status.getExitstatus());
}
}, proxmox)
.execute();
// Continues immediately while task runs in backgroundYou can also wait for a task after execution using the static method:
import fr.freshperf.pve4j.request.ProxmoxRequest;
PveTask task = vm.start().execute();
// Wait for the task with default 1 second polling
ProxmoxRequest.waitForCompletion(proxmox, task);
// Or with custom polling interval
ProxmoxRequest.waitForCompletion(proxmox, task, 5000); // 5 second polling
// Or with Duration and timeout
ProxmoxRequest.waitForCompletion(proxmox, task, Duration.ofSeconds(2), Duration.ofMinutes(5));// Execute immediately
PveVersion version = proxmox.getVersion().execute();Use case: Quick operations where you need the result immediately.
ProxmoxRequest<PveQemuStatus> statusRequest = vm.getStatus();
if (someCondition) {
PveQemuStatus status = statusRequest.execute();
// Use status
}Use case: Execute based on runtime conditions.
List<ProxmoxRequest<PveQemuStatus>> requests = new ArrayList<>();
for (int vmid : vmids) {
requests.add(proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(vmid)
.getStatus());
}
// Execute all requests
for (ProxmoxRequest<PveQemuStatus> request : requests) {
PveQemuStatus status = request.execute();
// Process status
}Use case: Prepare multiple requests and execute in batch.
try {
PveVersion version = proxmox.getVersion().execute();
List<PveNodesIndex> nodes = proxmox.getNodes().getIndex().execute();
// Continue with more operations
} catch (ProxmoxAPIError e) {
// Handle all errors in one place
System.err.println("API Error: " + e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}Use case: Chain multiple operations with unified error handling.
Execute multiple requests in parallel using streams:
import java.util.concurrent.*;
import java.util.stream.*;
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Integer> vmids = Arrays.asList(100, 101, 102, 103, 104);
List<CompletableFuture<PveQemuStatus>> futures = vmids.stream()
.map(vmid -> CompletableFuture.supplyAsync(() -> {
try {
return proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(vmid)
.getStatus()
.execute();
} catch (Exception e) {
throw new RuntimeException(e);
}
}, executor))
.collect(Collectors.toList());
// Wait for all to complete
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
// Get results
List<PveQemuStatus> statuses = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
executor.shutdown();Compose multiple requests into a workflow:
public PveQemuStatus ensureVMRunning(Proxmox proxmox, String node, int vmid)
throws ProxmoxAPIError, InterruptedException {
// Get current status
PveQemuStatus status = proxmox.getNodes()
.get(node)
.getQemu()
.get(vmid)
.getStatus()
.execute();
// Start if not running
if (!"running".equals(status.getStatus())) {
proxmox.getNodes()
.get(node)
.getQemu()
.get(vmid)
.start()
.waitForCompletion(proxmox)
.execute();
// Get updated status
status = proxmox.getNodes()
.get(node)
.getQemu()
.get(vmid)
.getStatus()
.execute();
}
return status;
}public class VMWorkflow {
public void deployVM(Proxmox proxmox, int templateId, int newVmid)
throws ProxmoxAPIError, InterruptedException {
// Clone from template
proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(templateId)
.cloneVm(newVmid)
.waitForCompletion(proxmox)
.execute();
// Update configuration
PveQemuConfigUpdateOptions config = PveQemuConfigUpdateOptions.builder()
.memory(4096)
.cores(2)
.build();
proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(newVmid)
.updateConfig(config)
.waitForCompletion(proxmox)
.execute();
// Start the VM
proxmox.getNodes()
.get("pve-node-01")
.getQemu()
.get(newVmid)
.start()
.waitForCompletion(proxmox)
.execute();
System.out.println("VM " + newVmid + " deployed successfully");
}
}// Define request once
ProxmoxRequest<PveQemuStatus> statusRequest = vm.getStatus();
// Execute multiple times if needed
PveQemuStatus status1 = statusRequest.execute();
Thread.sleep(5000);
PveQemuStatus status2 = statusRequest.execute();1. Request Creation
↓
2. Configuration (optional)
- retry() / retryDelay()
- waitForCompletion() / taskTimeout() / taskCheckDelay()
- onCompletion()
↓
3. Execution
- execute()
↓
4. HTTP Request
↓
5. Response Processing
↓
6. Result/Exception
- Task Handling - Detailed task management
- Error Handling - Exception handling strategies
- VM Management - Practical request examples