|  | 
| 1 | 1 | package net.laprun.sustainability.power.sensors.macos.powermetrics; | 
| 2 | 2 | 
 | 
| 3 |  | -import java.io.ByteArrayInputStream; | 
| 4 |  | -import java.io.InputStream; | 
| 5 |  | -import java.nio.ByteBuffer; | 
| 6 |  | -import java.util.Arrays; | 
| 7 |  | -import java.util.concurrent.CompletableFuture; | 
| 8 |  | -import java.util.concurrent.Future; | 
| 9 |  | -import java.util.concurrent.TimeUnit; | 
| 10 |  | - | 
| 11 |  | -import com.zaxxer.nuprocess.NuAbstractProcessHandler; | 
| 12 |  | -import com.zaxxer.nuprocess.NuProcess; | 
| 13 |  | - | 
| 14 |  | -public class PowermetricsProcessHandler extends NuAbstractProcessHandler { | 
| 15 |  | -    private String errorMsg; | 
| 16 |  | -    private NuProcess process; | 
| 17 |  | -    private final String[] command; | 
| 18 |  | -    private final GrowableBuffer stdOutBuffer = new GrowableBuffer(); | 
| 19 |  | -    private final CompletableFuture<InputStream> output = new CompletableFuture<>(); | 
|  | 3 | +import net.laprun.sustainability.power.nuprocess.BaseProcessHandler; | 
| 20 | 4 | 
 | 
|  | 5 | +public class PowermetricsProcessHandler extends BaseProcessHandler { | 
| 21 | 6 |     public PowermetricsProcessHandler(String... command) { | 
| 22 |  | -        if (command == null || command.length == 0) { | 
| 23 |  | -            throw new IllegalArgumentException("No powermetrics options specified"); | 
| 24 |  | -        } | 
|  | 7 | +        super(command); | 
|  | 8 | +    } | 
|  | 9 | + | 
|  | 10 | +    @Override | 
|  | 11 | +    protected String[] initCommand(String... command) { | 
| 25 | 12 |         final var additionalArgsCardinality = 3; | 
| 26 | 13 |         final var args = new String[command.length + additionalArgsCardinality]; | 
| 27 | 14 |         args[0] = "sudo"; | 
| 28 | 15 |         args[1] = "powermetrics"; | 
| 29 | 16 |         args[2] = "--samplers"; | 
| 30 | 17 |         System.arraycopy(command, 0, args, additionalArgsCardinality, command.length); | 
| 31 |  | -        this.command = args; | 
| 32 |  | -    } | 
| 33 |  | - | 
| 34 |  | -    public String[] command() { | 
| 35 |  | -        return command; | 
| 36 |  | -    } | 
| 37 |  | - | 
| 38 |  | -    @Override | 
| 39 |  | -    public void onPreStart(NuProcess nuProcess) { | 
| 40 |  | -        this.process = nuProcess; | 
| 41 |  | -    } | 
| 42 |  | - | 
| 43 |  | -    @Override | 
| 44 |  | -    public void onExit(int statusCode) { | 
| 45 |  | -        if (Integer.MIN_VALUE == statusCode) { | 
| 46 |  | -            throw new IllegalArgumentException("Unknown command " + Arrays.toString(command)); | 
| 47 |  | -        } | 
| 48 |  | -        if (statusCode != 0) { | 
| 49 |  | -            throw new RuntimeException("Couldn't execute command " + Arrays.toString(command) | 
| 50 |  | -                    + ". Error code: " + statusCode + ", message: " + errorMsg); | 
| 51 |  | -        } | 
| 52 |  | -    } | 
| 53 |  | - | 
| 54 |  | -    public void stop() { | 
| 55 |  | -        if (process.isRunning()) { | 
| 56 |  | -            process.destroy(false); | 
| 57 |  | -            try { | 
| 58 |  | -                process.waitFor(5, TimeUnit.SECONDS); | 
| 59 |  | -            } catch (InterruptedException e) { | 
| 60 |  | -                throw new RuntimeException(e); | 
| 61 |  | -            } finally { | 
| 62 |  | -                process.destroy(true); | 
| 63 |  | -            } | 
| 64 |  | -        } | 
| 65 |  | -    } | 
| 66 |  | - | 
| 67 |  | -    @Override | 
| 68 |  | -    public void onStdout(ByteBuffer buffer, boolean closed) { | 
| 69 |  | -        if (buffer.hasRemaining()) { | 
| 70 |  | -            stdOutBuffer.put(buffer); | 
| 71 |  | -        } | 
| 72 |  | - | 
| 73 |  | -        if (closed) { | 
| 74 |  | -            output.complete(new ByteArrayInputStream(stdOutBuffer.array())); | 
| 75 |  | -        } | 
| 76 |  | -    } | 
| 77 |  | - | 
| 78 |  | -    @Override | 
| 79 |  | -    public void onStderr(ByteBuffer buffer, boolean closed) { | 
| 80 |  | -        if (!closed) { | 
| 81 |  | -            byte[] bytes = new byte[buffer.remaining()]; | 
| 82 |  | -            buffer.get(bytes); | 
| 83 |  | -            errorMsg = new String(bytes); | 
| 84 |  | -        } | 
| 85 |  | -        super.onStderr(buffer, closed); | 
| 86 |  | -    } | 
| 87 |  | - | 
| 88 |  | -    public Future<InputStream> getInputStream() { | 
| 89 |  | -        return output; | 
| 90 |  | -    } | 
| 91 |  | - | 
| 92 |  | -    public boolean isRunning() { | 
| 93 |  | -        return process != null && process.isRunning(); | 
|  | 18 | +        return args; | 
| 94 | 19 |     } | 
| 95 | 20 | } | 
0 commit comments