Skip to content

Commit 2d12fef

Browse files
authored
Merge pull request #1865 from steve-community/refactor-repository-service
Refactor repository/service layers
2 parents 3d05723 + b814f9d commit 2d12fef

30 files changed

+715
-684
lines changed

src/main/java/de/rwth/idsg/steve/config/WebSocketConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12WebSocketEndpoint;
2424
import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15WebSocketEndpoint;
2525
import de.rwth.idsg.steve.ocpp.ws.ocpp16.Ocpp16WebSocketEndpoint;
26-
import de.rwth.idsg.steve.service.ChargePointRegistrationService;
26+
import de.rwth.idsg.steve.service.ChargePointService;
2727
import de.rwth.idsg.steve.web.validation.ChargeBoxIdValidator;
2828
import lombok.RequiredArgsConstructor;
2929
import lombok.extern.slf4j.Slf4j;
@@ -48,7 +48,7 @@
4848
@Slf4j
4949
public class WebSocketConfiguration implements WebSocketConfigurer {
5050

51-
private final ChargePointRegistrationService chargePointRegistrationService;
51+
private final ChargePointService chargePointService;
5252
private final ChargeBoxIdValidator chargeBoxIdValidator;
5353
private final Ocpp12WebSocketEndpoint ocpp12WebSocketEndpoint;
5454
private final Ocpp15WebSocketEndpoint ocpp15WebSocketEndpoint;
@@ -65,7 +65,7 @@ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
6565
chargeBoxIdValidator,
6666
handshakeHandler(),
6767
Lists.newArrayList(ocpp16WebSocketEndpoint, ocpp15WebSocketEndpoint, ocpp12WebSocketEndpoint),
68-
chargePointRegistrationService
68+
chargePointService
6969
);
7070

7171
registry.addHandler(handshakeHandler.getDummyWebSocketHandler(), PATH_INFIX + "*")

src/main/java/de/rwth/idsg/steve/ocpp/soap/MessageHeaderInterceptor.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import de.rwth.idsg.steve.ocpp.OcppProtocol;
2222
import de.rwth.idsg.steve.repository.OcppServerRepository;
2323
import de.rwth.idsg.steve.repository.impl.ChargePointRepositoryImpl;
24-
import de.rwth.idsg.steve.service.ChargePointRegistrationService;
24+
import de.rwth.idsg.steve.service.ChargePointService;
2525
import lombok.extern.slf4j.Slf4j;
2626
import ocpp.cs._2015._10.RegistrationStatus;
2727
import org.apache.cxf.binding.soap.Soap12;
@@ -50,7 +50,7 @@
5050
* 2. Intercepts incoming OCPP messages to update the endpoint address ("From" field of the WS-A header) in DB.
5151
* And the absence of the field is not a deal breaker anymore. But, as a side effect, the user will not be able
5252
* to send commands to the charging station, since the DB call to list the charge points will filter it out. See
53-
* {@link ChargePointRepositoryImpl#getChargePointSelect(OcppProtocol, java.util.List)}.
53+
* {@link ChargePointRepositoryImpl#getChargePointSelect(OcppProtocol, java.util.List, java.util.List)}.
5454
*
5555
* @author Sevket Goekay <[email protected]>
5656
* @since 15.06.2015
@@ -60,18 +60,18 @@
6060
public class MessageHeaderInterceptor extends AbstractPhaseInterceptor<Message> {
6161

6262
private final OcppServerRepository ocppServerRepository;
63-
private final ChargePointRegistrationService chargePointRegistrationService;
63+
private final ChargePointService chargePointService;
6464
private final TaskExecutor taskExecutor;
6565

6666
private static final String BOOT_OPERATION_NAME = "BootNotification";
6767
private static final String CHARGEBOX_ID_HEADER = "ChargeBoxIdentity";
6868

6969
public MessageHeaderInterceptor(OcppServerRepository ocppServerRepository,
70-
ChargePointRegistrationService chargePointRegistrationService,
70+
ChargePointService chargePointService,
7171
TaskExecutor taskExecutor) {
7272
super(Phase.PRE_INVOKE);
7373
this.ocppServerRepository = ocppServerRepository;
74-
this.chargePointRegistrationService = chargePointRegistrationService;
74+
this.chargePointService = chargePointService;
7575
this.taskExecutor = taskExecutor;
7676
}
7777

@@ -86,7 +86,7 @@ public void handleMessage(Message message) throws Fault {
8686
QName opName = message.getExchange().getBindingOperationInfo().getOperationInfo().getName();
8787

8888
if (!BOOT_OPERATION_NAME.equals(opName.getLocalPart())) {
89-
Optional<RegistrationStatus> status = chargePointRegistrationService.getRegistrationStatus(chargeBoxId);
89+
Optional<RegistrationStatus> status = chargePointService.getRegistrationStatus(chargeBoxId);
9090
boolean allow = status.isPresent() && status.get() != RegistrationStatus.REJECTED;
9191
if (!allow) {
9292
throw createAuthFault(opName);

src/main/java/de/rwth/idsg/steve/ocpp/ws/AbstractWebSocketEndpoint.java

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@
1919
package de.rwth.idsg.steve.ocpp.ws;
2020

2121
import com.google.common.base.Strings;
22-
import de.rwth.idsg.steve.config.SteveProperties;
2322
import de.rwth.idsg.steve.config.WebSocketConfiguration;
2423
import de.rwth.idsg.steve.ocpp.OcppTransport;
2524
import de.rwth.idsg.steve.ocpp.OcppVersion;
2625
import de.rwth.idsg.steve.ocpp.ws.data.CommunicationContext;
27-
import de.rwth.idsg.steve.ocpp.ws.data.SessionContext;
2826
import de.rwth.idsg.steve.ocpp.ws.pipeline.Deserializer;
2927
import de.rwth.idsg.steve.ocpp.ws.pipeline.IncomingPipeline;
3028
import de.rwth.idsg.steve.ocpp.ws.pipeline.OcppCallHandler;
@@ -47,9 +45,7 @@
4745
import java.time.Instant;
4846
import java.util.ArrayList;
4947
import java.util.Collections;
50-
import java.util.Deque;
5148
import java.util.List;
52-
import java.util.Map;
5349
import java.util.concurrent.ScheduledFuture;
5450
import java.util.function.Consumer;
5551

@@ -76,13 +72,13 @@ public AbstractWebSocketEndpoint(TaskScheduler taskScheduler,
7672
OcppServerRepository ocppServerRepository,
7773
FutureResponseContextStore futureResponseContextStore,
7874
ApplicationEventPublisher applicationEventPublisher,
79-
SteveProperties steveProperties,
75+
SessionContextStoreHolder sessionContextStoreHolder,
8076
AbstractTypeStore typeStore) {
8177
this.taskScheduler = taskScheduler;
8278
this.ocppServerRepository = ocppServerRepository;
8379
this.futureResponseContextStore = futureResponseContextStore;
8480
this.pipeline = new IncomingPipeline(new Deserializer(futureResponseContextStore, typeStore), this);
85-
this.sessionContextStore = new SessionContextStoreImpl(steveProperties.getOcpp().getWsSessionSelectStrategy());
81+
this.sessionContextStore = sessionContextStoreHolder.getOrCreate(getVersion());
8682

8783
connectedCallbackList.add((chargeBoxId) -> applicationEventPublisher.publishEvent(new OcppStationWebSocketConnected(chargeBoxId)));
8884
disconnectedCallbackList.add((chargeBoxId) -> applicationEventPublisher.publishEvent(new OcppStationWebSocketDisconnected(chargeBoxId)));
@@ -210,28 +206,4 @@ protected String getChargeBoxId(WebSocketSession session) {
210206
return (String) session.getAttributes().get(CHARGEBOX_ID_KEY);
211207
}
212208

213-
protected void registerConnectedCallback(Consumer<String> consumer) {
214-
connectedCallbackList.add(consumer);
215-
}
216-
217-
protected void registerDisconnectedCallback(Consumer<String> consumer) {
218-
disconnectedCallbackList.add(consumer);
219-
}
220-
221-
public List<String> getChargeBoxIdList() {
222-
return sessionContextStore.getChargeBoxIdList();
223-
}
224-
225-
public int getNumberOfChargeBoxes() {
226-
return sessionContextStore.getNumberOfChargeBoxes();
227-
}
228-
229-
public Map<String, Deque<SessionContext>> getACopy() {
230-
return sessionContextStore.getACopy();
231-
}
232-
233-
public WebSocketSession getSession(String chargeBoxId) {
234-
return sessionContextStore.getSession(chargeBoxId);
235-
}
236-
237209
}

src/main/java/de/rwth/idsg/steve/ocpp/ws/ChargePointServiceJsonInvoker.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@
2626
import de.rwth.idsg.steve.ocpp.ws.data.FutureResponseContext;
2727
import de.rwth.idsg.steve.ocpp.ws.data.OcppJsonCall;
2828
import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12TypeStore;
29-
import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12WebSocketEndpoint;
3029
import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15TypeStore;
31-
import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15WebSocketEndpoint;
3230
import de.rwth.idsg.steve.ocpp.ws.ocpp16.Ocpp16TypeStore;
33-
import de.rwth.idsg.steve.ocpp.ws.ocpp16.Ocpp16WebSocketEndpoint;
3431
import de.rwth.idsg.steve.ocpp.ws.pipeline.OutgoingCallPipeline;
3532
import de.rwth.idsg.steve.repository.dto.ChargePointSelect;
3633
import lombok.RequiredArgsConstructor;
@@ -49,10 +46,7 @@
4946
public class ChargePointServiceJsonInvoker {
5047

5148
private final OutgoingCallPipeline outgoingCallPipeline;
52-
53-
private final Ocpp12WebSocketEndpoint ocpp12WebSocketEndpoint;
54-
private final Ocpp15WebSocketEndpoint ocpp15WebSocketEndpoint;
55-
private final Ocpp16WebSocketEndpoint ocpp16WebSocketEndpoint;
49+
private final SessionContextStoreHolder sessionContextStoreHolder;
5650

5751
/**
5852
* Just a wrapper to make try-catch block and exception handling stand out
@@ -73,11 +67,7 @@ public void runPipeline(ChargePointSelect cps, CommunicationTask task) {
7367
private void run(ChargePointSelect cps, CommunicationTask task) {
7468
var chargeBoxId = cps.getChargeBoxId();
7569

76-
var endpoint = switch (cps.getOcppProtocol().getVersion()) {
77-
case V_12 -> ocpp12WebSocketEndpoint;
78-
case V_15 -> ocpp15WebSocketEndpoint;
79-
case V_16 -> ocpp16WebSocketEndpoint;
80-
};
70+
var sessionStore = sessionContextStoreHolder.getOrCreate(cps.getOcppProtocol().getVersion());
8171

8272
var typeStore = switch (cps.getOcppProtocol().getVersion()) {
8373
case V_12 -> Ocpp12TypeStore.INSTANCE;
@@ -103,7 +93,7 @@ private void run(ChargePointSelect cps, CommunicationTask task) {
10393

10494
FutureResponseContext frc = new FutureResponseContext(task, pair.getResponseClass());
10595

106-
CommunicationContext context = new CommunicationContext(endpoint.getSession(chargeBoxId), chargeBoxId);
96+
CommunicationContext context = new CommunicationContext(sessionStore.getSession(chargeBoxId), chargeBoxId);
10797
context.setOutgoingMessage(call);
10898
context.setFutureResponseContext(frc);
10999

src/main/java/de/rwth/idsg/steve/ocpp/ws/OcppWebSocketHandshakeHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
package de.rwth.idsg.steve.ocpp.ws;
2020

21-
import de.rwth.idsg.steve.service.ChargePointRegistrationService;
21+
import de.rwth.idsg.steve.service.ChargePointService;
2222
import de.rwth.idsg.steve.web.validation.ChargeBoxIdValidator;
2323
import lombok.RequiredArgsConstructor;
2424
import lombok.extern.slf4j.Slf4j;
@@ -51,7 +51,7 @@ public class OcppWebSocketHandshakeHandler implements HandshakeHandler {
5151
private final ChargeBoxIdValidator chargeBoxIdValidator;
5252
private final DefaultHandshakeHandler delegate;
5353
private final List<AbstractWebSocketEndpoint> endpoints;
54-
private final ChargePointRegistrationService chargePointRegistrationService;
54+
private final ChargePointService chargePointService;
5555

5656
/**
5757
* We need some WebSocketHandler just for Spring to register it for the path. We will not use it for the actual
@@ -78,7 +78,7 @@ public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse respons
7878
return false;
7979
}
8080

81-
Optional<RegistrationStatus> status = chargePointRegistrationService.getRegistrationStatus(chargeBoxId);
81+
Optional<RegistrationStatus> status = chargePointService.getRegistrationStatus(chargeBoxId);
8282

8383
// Allow connections, if station is in db (registration_status field from db does not matter)
8484
boolean allowConnection = status.isPresent();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* SteVe - SteckdosenVerwaltung - https://github.com/steve-community/steve
3+
* Copyright (C) 2013-2025 SteVe Community Team
4+
* All Rights Reserved.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package de.rwth.idsg.steve.ocpp.ws;
20+
21+
import de.rwth.idsg.steve.config.SteveProperties;
22+
import de.rwth.idsg.steve.ocpp.OcppVersion;
23+
import de.rwth.idsg.steve.ocpp.ws.custom.WsSessionSelectStrategy;
24+
import org.springframework.stereotype.Component;
25+
26+
import java.util.concurrent.ConcurrentHashMap;
27+
28+
/**
29+
* @author Sevket Goekay <[email protected]>
30+
* @since 29.10.2025
31+
*/
32+
@Component
33+
public class SessionContextStoreHolder {
34+
35+
private final ConcurrentHashMap<OcppVersion, SessionContextStore> storesPerVersion = new ConcurrentHashMap<>();
36+
37+
private final WsSessionSelectStrategy wsSessionSelectStrategy;
38+
39+
public SessionContextStoreHolder(SteveProperties steveProperties) {
40+
wsSessionSelectStrategy = steveProperties.getOcpp().getWsSessionSelectStrategy();
41+
}
42+
43+
public SessionContextStore getOrCreate(OcppVersion version) {
44+
return storesPerVersion.computeIfAbsent(version, k -> new SessionContextStoreImpl(wsSessionSelectStrategy));
45+
}
46+
}

src/main/java/de/rwth/idsg/steve/ocpp/ws/ocpp12/Ocpp12WebSocketEndpoint.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
import de.rwth.idsg.ocpp.jaxb.RequestType;
2222
import de.rwth.idsg.ocpp.jaxb.ResponseType;
23-
import de.rwth.idsg.steve.config.SteveProperties;
2423
import de.rwth.idsg.steve.ocpp.OcppProtocol;
2524
import de.rwth.idsg.steve.ocpp.OcppVersion;
2625
import de.rwth.idsg.steve.ocpp.soap.CentralSystemService12_SoapServer;
2726
import de.rwth.idsg.steve.ocpp.ws.AbstractWebSocketEndpoint;
2827
import de.rwth.idsg.steve.ocpp.ws.FutureResponseContextStore;
28+
import de.rwth.idsg.steve.ocpp.ws.SessionContextStoreHolder;
2929
import de.rwth.idsg.steve.repository.OcppServerRepository;
3030
import ocpp.cs._2010._08.AuthorizeRequest;
3131
import ocpp.cs._2010._08.BootNotificationRequest;
@@ -54,8 +54,8 @@ public Ocpp12WebSocketEndpoint(TaskScheduler taskScheduler,
5454
FutureResponseContextStore futureResponseContextStore,
5555
ApplicationEventPublisher applicationEventPublisher,
5656
CentralSystemService12_SoapServer server,
57-
SteveProperties steveProperties) {
58-
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, steveProperties, Ocpp12TypeStore.INSTANCE);
57+
SessionContextStoreHolder sessionContextStoreHolder) {
58+
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, sessionContextStoreHolder, Ocpp12TypeStore.INSTANCE);
5959
this.server = server;
6060
}
6161

src/main/java/de/rwth/idsg/steve/ocpp/ws/ocpp15/Ocpp15WebSocketEndpoint.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
import de.rwth.idsg.ocpp.jaxb.RequestType;
2222
import de.rwth.idsg.ocpp.jaxb.ResponseType;
23-
import de.rwth.idsg.steve.config.SteveProperties;
2423
import de.rwth.idsg.steve.ocpp.OcppProtocol;
2524
import de.rwth.idsg.steve.ocpp.OcppVersion;
2625
import de.rwth.idsg.steve.ocpp.soap.CentralSystemService15_SoapServer;
2726
import de.rwth.idsg.steve.ocpp.ws.AbstractWebSocketEndpoint;
2827
import de.rwth.idsg.steve.ocpp.ws.FutureResponseContextStore;
28+
import de.rwth.idsg.steve.ocpp.ws.SessionContextStoreHolder;
2929
import de.rwth.idsg.steve.repository.OcppServerRepository;
3030
import ocpp.cs._2012._06.AuthorizeRequest;
3131
import ocpp.cs._2012._06.BootNotificationRequest;
@@ -55,8 +55,8 @@ public Ocpp15WebSocketEndpoint(TaskScheduler taskScheduler,
5555
FutureResponseContextStore futureResponseContextStore,
5656
ApplicationEventPublisher applicationEventPublisher,
5757
CentralSystemService15_SoapServer server,
58-
SteveProperties steveProperties) {
59-
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, steveProperties, Ocpp15TypeStore.INSTANCE);
58+
SessionContextStoreHolder sessionContextStoreHolder) {
59+
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, sessionContextStoreHolder, Ocpp15TypeStore.INSTANCE);
6060
this.server = server;
6161
}
6262

src/main/java/de/rwth/idsg/steve/ocpp/ws/ocpp16/Ocpp16WebSocketEndpoint.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
import de.rwth.idsg.ocpp.jaxb.RequestType;
2222
import de.rwth.idsg.ocpp.jaxb.ResponseType;
23-
import de.rwth.idsg.steve.config.SteveProperties;
2423
import de.rwth.idsg.steve.ocpp.OcppProtocol;
2524
import de.rwth.idsg.steve.ocpp.OcppVersion;
2625
import de.rwth.idsg.steve.ocpp.soap.CentralSystemService16_SoapServer;
2726
import de.rwth.idsg.steve.ocpp.ws.AbstractWebSocketEndpoint;
2827
import de.rwth.idsg.steve.ocpp.ws.FutureResponseContextStore;
28+
import de.rwth.idsg.steve.ocpp.ws.SessionContextStoreHolder;
2929
import de.rwth.idsg.steve.repository.OcppServerRepository;
3030
import ocpp.cs._2015._10.AuthorizeRequest;
3131
import ocpp.cs._2015._10.BootNotificationRequest;
@@ -55,8 +55,8 @@ public Ocpp16WebSocketEndpoint(TaskScheduler taskScheduler,
5555
FutureResponseContextStore futureResponseContextStore,
5656
ApplicationEventPublisher applicationEventPublisher,
5757
CentralSystemService16_SoapServer server,
58-
SteveProperties steveProperties) {
59-
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, steveProperties, Ocpp16TypeStore.INSTANCE);
58+
SessionContextStoreHolder sessionContextStoreHolder) {
59+
super(taskScheduler, ocppServerRepository, futureResponseContextStore, applicationEventPublisher, sessionContextStoreHolder, Ocpp16TypeStore.INSTANCE);
6060
this.server = server;
6161
}
6262

src/main/java/de/rwth/idsg/steve/repository/ChargePointRepository.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,12 @@ public interface ChargePointRepository {
4141

4242
List<ChargePointSelect> getChargePointSelect(OcppProtocol protocol, List<String> inStatusFilter, List<String> chargeBoxIdFilter);
4343

44-
default List<ChargePointSelect> getChargePointSelect(OcppProtocol protocol, List<String> inStatusFilter) {
45-
return getChargePointSelect(protocol, inStatusFilter, Collections.emptyList());
46-
}
47-
4844
List<String> getChargeBoxIds();
4945
Map<String, Integer> getChargeBoxIdPkPair(List<String> chargeBoxIdList);
5046

5147
List<ChargePoint.Overview> getOverview(ChargePointQueryForm form);
5248
ChargePoint.Details getDetails(int chargeBoxPk);
5349

54-
default List<ConnectorStatus> getChargePointConnectorStatus() {
55-
return getChargePointConnectorStatus(null);
56-
}
57-
5850
List<ConnectorStatus> getChargePointConnectorStatus(@Nullable ConnectorStatusForm form);
5951

6052
List<Integer> getNonZeroConnectorIds(String chargeBoxId);

0 commit comments

Comments
 (0)