Add webhook plugin integration and configuration changes#1983
Add webhook plugin integration and configuration changes#1983AttriPardeep wants to merge 1 commit intosteve-community:masterfrom
Conversation
Review Summary by QodoAdd webhook plugin integration with async sender and retry mechanism
WalkthroughsDescription• Add comprehensive webhook plugin for OCPP event integration • Implement async webhook sender with HMAC-SHA256 signing and retry logic • Create event models for connector status, transactions, and meter values • Configure HTTP client with connection pooling and smart meter filtering • Update production configuration with webhook settings and REST API endpoints Diagramflowchart LR
OCPP["OCPP Events<br/>StatusNotification<br/>StartTransaction<br/>StopTransaction<br/>MeterValues"]
Listener["OcppEventListener<br/>Converts to webhook events"]
Sender["WebhookSender<br/>HMAC-SHA256 signing<br/>Async execution"]
Retry["WebhookRetryQueue<br/>Exponential backoff<br/>Max 3 attempts"]
Backend["VoltStartEV Backend<br/>Webhook endpoint"]
OCPP -->|Spring events| Listener
Listener -->|sendAsync| Sender
Sender -->|success| Backend
Sender -->|failure| Retry
Retry -->|scheduled retry| Sender
File Changes1. steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/SteveWebhookPluginApplication.java
|
Code Review by Qodo
1. db.password plaintext in prod
|
| db.schema = stevedb | ||
| db.user = steve | ||
| db.password = changeme | ||
| db.password = StevePass2026! |
There was a problem hiding this comment.
1. db.password plaintext in prod 📘 Rule violation ⛨ Security
The production properties file now contains a hardcoded database password in plaintext. This violates boundary security hardening requirements and risks credential leakage via source control or deployments.
Agent Prompt
## Issue description
`application-prod.properties` contains a plaintext database password (`db.password`), which is prohibited for production secret storage.
## Issue Context
Compliance requires secrets not be persisted in plaintext in repo-tracked configuration.
## Fix Focus Areas
- src/main/resources/application-prod.properties[13-13]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
||
| # SteVe Webhook Plugin Environment Variables | ||
| voltstartev.webhook.url=http://localhost:3000/api/webhooks/steve | ||
| voltstartev.webhook.secret=your-super-secret-webhook-key-min-32-characters |
There was a problem hiding this comment.
2. voltstartev.webhook.secret in prod 📘 Rule violation ⛨ Security
The production configuration adds a webhook shared secret value directly in the properties file. Storing shared secrets in plaintext configuration violates secret storage hardening and increases leak risk.
Agent Prompt
## Issue description
Production config stores `voltstartev.webhook.secret` as plaintext in a repo-tracked properties file.
## Issue Context
Webhook shared secrets should be injected at runtime (env var / secret manager), not committed.
## Fix Focus Areas
- src/main/resources/application-prod.properties[83-83]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| # Shared secret for HMAC-SHA256 signature (MUST MATCH backend) | ||
| voltstartev.webhook.secret=4c89055d36eefb7fd2422483544bd7a39dbb62d06b0b3c04bdc9dd709bf46fc8 | ||
|
|
There was a problem hiding this comment.
3. webhook.secret committed in plugin 📘 Rule violation ⛨ Security
The plugin’s application.properties commits a concrete HMAC secret value. This is plaintext secret persistence and risks credential exposure if the repository or artifacts are shared.
Agent Prompt
## Issue description
A real webhook HMAC secret is committed in `steve-webhook-plugin/src/main/resources/application.properties`.
## Issue Context
Per compliance, secrets must not be persisted in plaintext in repository configuration.
## Fix Focus Areas
- steve-webhook-plugin/src/main/resources/application.properties[8-10]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| #webapi.key = STEVE-API-KEY | ||
| #webapi.value = |
There was a problem hiding this comment.
4. Unresolved webapi placeholders 🐞 Bug ✓ Correctness
In prod, webapi.key and webapi.value are commented out, but application.yml still requires
${webapi.key}/${webapi.value}, which can prevent Spring from resolving placeholders and stop SteVe
from starting in the prod profile.
Agent Prompt
### Issue description
Prod profile comments out `webapi.key`/`webapi.value`, but `application.yml` still references `${webapi.key}`/`${webapi.value}`. This can lead to unresolved placeholders and application startup failure.
### Issue Context
`steve.auth.web-api-key` and `steve.auth.web-api-secret` are bound from these placeholders.
### Fix Focus Areas
- src/main/resources/application-prod.properties[20-25]
- src/main/resources/application.yml[38-47]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| #server.host = 0.0.0.0 | ||
| server.address = 0.0.0.0 | ||
| server.port = 8080 | ||
| server.gzip.enabled = true |
There was a problem hiding this comment.
5. Prod service exposed publicly 🐞 Bug ⛨ Security
application-prod.properties binds the server to 0.0.0.0 and enables extensive DEBUG logging, increasing exposure of the admin interface and sensitive operational data in logs.
Agent Prompt
### Issue description
Prod config binds on `0.0.0.0` and enables DEBUG logging broadly, while retaining weak default admin credentials.
### Issue Context
This combination significantly increases attack surface and risks log-based data exposure.
### Fix Focus Areas
- src/main/resources/application-prod.properties[15-19]
- src/main/resources/application-prod.properties[32-37]
- src/main/resources/application-prod.properties[90-98]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| <dependencies> | ||
| <!-- Spring Boot --> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-web</artifactId> | ||
| </dependency> | ||
|
|
||
| <!-- HTTP Client with connection pooling --> | ||
| <dependency> | ||
| <groupId>org.apache.httpcomponents.client5</groupId> | ||
| <artifactId>httpclient5</artifactId> | ||
| <version>5.2.1</version> | ||
| </dependency> | ||
|
|
||
| <!-- JSON Processing --> | ||
| <dependency> | ||
| <groupId>com.fasterxml.jackson.core</groupId> | ||
| <artifactId>jackson-databind</artifactId> | ||
| </dependency> | ||
|
|
||
| <!-- Metrics (optional) --> | ||
| <dependency> | ||
| <groupId>io.micrometer</groupId> | ||
| <artifactId>micrometer-registry-prometheus</artifactId> | ||
| </dependency> | ||
|
|
||
| <!-- SteVe Core (provided by SteVe runtime) --> | ||
| <dependency> | ||
| <groupId>de.rwth.idsg</groupId> | ||
| <artifactId>steve</artifactId> | ||
| <version>3.11.0</version> | ||
| <scope>provided</scope> | ||
| </dependency> | ||
| </dependencies> |
There was a problem hiding this comment.
6. Missing lombok dependency 🐞 Bug ✓ Correctness
steve-webhook-plugin uses Lombok annotations (@Data, @AllArgsConstructor, etc.) but does not declare Lombok in its pom.xml, which will fail compilation of the plugin module.
Agent Prompt
### Issue description
Plugin module uses Lombok annotations but does not depend on Lombok, causing compilation failure.
### Issue Context
Multiple plugin classes rely on Lombok-generated methods/constructors.
### Fix Focus Areas
- steve-webhook-plugin/pom.xml[19-56]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/config/WebhookProperties.java[17-24]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @Bean(name = "webhookExecutor") | ||
| public Executor webhookExecutor() { | ||
| ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||
| executor.setCorePoolSize(10); | ||
| executor.setMaxPoolSize(20); | ||
| executor.setQueueCapacity(100); | ||
| executor.setThreadNamePrefix("webhook-"); | ||
| executor.setRejectedExecutionHandler( | ||
| new ThreadPoolExecutor.CallerRunsPolicy() // Backpressure: run in caller thread if queue full | ||
| ); |
There was a problem hiding this comment.
7. Missing imports break plugin 🐞 Bug ✓ Correctness
steve-webhook-plugin references ThreadPoolExecutor and WebhookProperties without importing them, which prevents the module from compiling.
Agent Prompt
### Issue description
Plugin sources reference types that are not imported, causing compilation to fail.
### Issue Context
`AsyncConfig` uses `ThreadPoolExecutor.CallerRunsPolicy`, and multiple classes reference `WebhookProperties` without importing it.
### Fix Focus Areas
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/config/AsyncConfig.java[17-46]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/listener/OcppEventListener.java[17-42]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/retry/WebhookRetryQueue.java[17-38]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| public WebhookSender(RestTemplate restTemplate, | ||
| WebhookProperties properties, | ||
| WebhookRetryQueue retryQueue, | ||
| ObjectMapper objectMapper, | ||
| MeterRegistry meterRegistry) { | ||
| this.restTemplate = restTemplate; | ||
| this.properties = properties; | ||
| this.retryQueue = retryQueue; | ||
| this.objectMapper = objectMapper; | ||
| this.meterRegistry = meterRegistry; | ||
|
|
There was a problem hiding this comment.
8. Meterregistry di failure 🐞 Bug ⛯ Reliability
WebhookSender requires a MeterRegistry bean, but the plugin module doesn’t include Spring Boot actuator autoconfiguration and defines no MeterRegistry bean, so the plugin will fail at startup with an unsatisfied dependency.
Agent Prompt
### Issue description
`WebhookSender` requires `MeterRegistry`, but the plugin does not ensure a `MeterRegistry` bean exists.
### Issue Context
Without actuator autoconfiguration or an explicit `@Bean`, Spring will fail to create `WebhookSender`.
### Fix Focus Areas
- steve-webhook-plugin/pom.xml[43-48]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/service/WebhookSender.java[57-67]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @EventListener | ||
| public void onConnectorStatus(ConnectorStatusUpdate event) { | ||
| ConnectorStatusEvent webhookEvent = new ConnectorStatusEvent( | ||
| event.getChargeBoxId(), | ||
| event.getConnectorId(), | ||
| event.getStatus().getValue(), | ||
| event.getErrorCode() != null ? event.getErrorCode().getValue() : null, | ||
| event.getInfo(), | ||
| event.getTimestamp(), // OCPP timestamp | ||
| Instant.now() // Received at SteVe | ||
| ); | ||
|
|
||
| webhookSender.sendAsync("connector.status", webhookEvent); | ||
| } | ||
|
|
||
| /** | ||
| * Handle StartTransaction | ||
| */ | ||
| @EventListener | ||
| public void onTransactionStart(TransactionStart event) { | ||
| TransactionStartedEvent webhookEvent = new TransactionStartedEvent( | ||
| event.getChargeBoxId(), | ||
| event.getConnectorId(), | ||
| event.getTransactionId(), | ||
| event.getIdTag(), | ||
| event.getStartMeterValue(), | ||
| event.getStartTimestamp(), | ||
| Instant.now(), | ||
| event.getReservationId() | ||
| ); | ||
|
|
||
| webhookSender.sendAsync("transaction.started", webhookEvent); | ||
| } | ||
|
|
||
| /** | ||
| * Handle StopTransaction | ||
| */ | ||
| @EventListener | ||
| public void onTransactionStop(TransactionStop event) { | ||
| // Convert transaction data if present | ||
| List<TransactionStoppedEvent.MeterValue> transactionData = null; | ||
| if (event.getTransactionData() != null && !event.getTransactionData().isEmpty()) { |
There was a problem hiding this comment.
9. Webhook integration not triggered 🐞 Bug ✓ Correctness
The plugin’s components are in package com.voltstartev..., which SteVe won’t component-scan, and the listener subscribes to event types that SteVe doesn’t publish (and MeterValues publishes no event), so webhook sending will never run in the SteVe runtime.
Agent Prompt
### Issue description
Webhook plugin code is not executed because it is neither discovered by SteVe’s component scan nor subscribed to events that SteVe actually publishes.
### Issue Context
SteVe publishes `OcppTransactionStarted`/`OcppTransactionEnded` and does not publish a MeterValues Spring event.
### Fix Focus Areas
- src/main/java/de/rwth/idsg/steve/SteveApplication.java[19-36]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/listener/OcppEventListener.java[47-88]
- steve-webhook-plugin/src/main/java/com/voltstartev/steve/plugin/listener/OcppEventListener.java[125-128]
- src/main/java/de/rwth/idsg/steve/service/CentralSystemService16_Service.java[174-185]
- src/main/java/de/rwth/idsg/steve/service/CentralSystemService16_Service.java[215-223]
- src/main/java/de/rwth/idsg/steve/service/CentralSystemService16_Service.java[248-255]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
No description provided.