Skip to content

Commit 0f9ee69

Browse files
committed
Started work on server. Fails the integration test.
1 parent 16d2051 commit 0f9ee69

File tree

11 files changed

+291
-57
lines changed

11 files changed

+291
-57
lines changed

ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package eu.chargetime.ocpp.test;
22

33
import eu.chargetime.ocpp.JSONServer;
4+
import eu.chargetime.ocpp.SOAPServer;
5+
import eu.chargetime.ocpp.Server;
46
import eu.chargetime.ocpp.ServerEvents;
57
import eu.chargetime.ocpp.feature.profile.ServerCoreEventHandler;
68
import eu.chargetime.ocpp.feature.profile.ServerCoreProfile;
@@ -40,7 +42,7 @@ public class FakeCentralSystem
4042
{
4143
private Request receivedRequest;
4244
private Confirmation receivedConfirmation;
43-
private JSONServer server;
45+
private Server server;
4446

4547
private int sessionIndex;
4648

@@ -156,6 +158,9 @@ public StopTransactionConfirmation handleStopTransactionRequest(int sessionIndex
156158
case JSON:
157159
server = new JSONServer(serverCoreProfile);
158160
break;
161+
case SOAP:
162+
server = new SOAPServer(serverCoreProfile);
163+
break;
159164
}
160165

161166
server.open("localhost", 8887, new ServerEvents() {

ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public UnlockConnectorConfirmation handleUnlockConnectorRequest(UnlockConnectorR
128128

129129
public void connect() {
130130
try {
131-
client.connect("ws://localhost:8887");
131+
client.connect("http://localhost:8887");
132132
} catch (Exception ex) {
133133
ex.printStackTrace();
134134
}

ocpp-v1_6-test/src/test/groovy/eu/chargetime/ocpp/test/core/AuthorizeSpec.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ class AuthorizeSpec extends Specification
1111
{
1212
@Shared
1313
FakeCentralSystem centralSystem = FakeCentralSystem.instance;
14-
@Shared FakeChargePoint chargePoint = new FakeChargePoint();
14+
@Shared
15+
FakeChargePoint chargePoint = new FakeChargePoint(FakeChargePoint.clientType.SOAP);
1516

1617
def setupSpec() {
1718
// When a Central System is running
18-
centralSystem.started();
19+
centralSystem.started(FakeCentralSystem.serverType.SOAP);
1920
}
2021

2122
def setup() {

ocpp-v1_6/src/main/java/eu/chargetime/ocpp/SOAPClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package eu.chargetime.ocpp;/*
1+
package eu.chargetime.ocpp;
2+
/*
23
ChargeTime.eu - Java-OCA-OCPP
34
45
MIT License

ocpp-v1_6/src/main/java/eu/chargetime/ocpp/SOAPCommunicator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ private class SOAPParser {
184184
public SOAPParser(SOAPMessage message) {
185185
try {
186186
soapMessage = message;
187-
soapHeader = message.getSOAPHeader();
187+
soapHeader = message.getSOAPPart().getEnvelope().getHeader();
188188
} catch (SOAPException e) {
189189
e.printStackTrace();
190190
}
@@ -227,7 +227,7 @@ private CallMessage parseCall() {
227227
CallMessage message = new CallMessage();
228228

229229
String action = getElementValue(HEADER_ACTION);
230-
if (action != null && "".equals(action))
230+
if (action != null && !"".equals(action))
231231
message.setAction(action.substring(1));
232232

233233
String id = getElementValue(HEADER_MESSAGEID);
@@ -238,10 +238,10 @@ private CallMessage parseCall() {
238238

239239
private String getElementValue(String tagName) {
240240
String value = null;
241-
NodeList elements = soapHeader.getElementsByTagName(tagName);
241+
NodeList elements = soapHeader.getElementsByTagNameNS("*", tagName);
242242

243243
if (elements.getLength() > 0)
244-
value = elements.item(0).getNodeValue();
244+
value = elements.item(0).getChildNodes().item(0).getNodeValue();
245245

246246
return value;
247247
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package eu.chargetime.ocpp;
2+
/*
3+
ChargeTime.eu - Java-OCA-OCPP
4+
5+
MIT License
6+
7+
Copyright (C) 2016 Thomas Volden <[email protected]>
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in all
17+
copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
SOFTWARE.
26+
*/
27+
28+
import javax.xml.soap.SOAPConnection;
29+
import javax.xml.soap.SOAPConnectionFactory;
30+
import javax.xml.soap.SOAPException;
31+
import javax.xml.soap.SOAPMessage;
32+
33+
public class SOAPReceiver extends SOAPSyncHelper implements Receiver {
34+
private RadioEvents events;
35+
SOAPConnection soapConnection;
36+
private String url;
37+
38+
public SOAPReceiver(String url) {
39+
this.url = url;
40+
}
41+
42+
@Override
43+
public void disconnect() {
44+
try {
45+
soapConnection.close();
46+
} catch (SOAPException e) {
47+
e.printStackTrace();
48+
}
49+
}
50+
51+
@Override
52+
public void accept(RadioEvents events) {
53+
this.events = events;
54+
try {
55+
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
56+
soapConnection = soapConnectionFactory.createConnection();
57+
} catch (SOAPException e) {
58+
e.printStackTrace();
59+
}
60+
}
61+
62+
@Override
63+
void forwardMessage(SOAPMessage message) {
64+
events.receivedMessage(message);
65+
}
66+
67+
@Override
68+
void sendRequest(SOAPMessage message) {
69+
try {
70+
events.receivedMessage(soapConnection.call(message, url));
71+
} catch (SOAPException e) {
72+
e.printStackTrace();
73+
}
74+
}
75+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package eu.chargetime.ocpp;
2+
/*
3+
ChargeTime.eu - Java-OCA-OCPP
4+
5+
MIT License
6+
7+
Copyright (C) 2016 Thomas Volden <[email protected]>
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in all
17+
copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
SOFTWARE.
26+
*/
27+
28+
import eu.chargetime.ocpp.feature.profile.ServerCoreProfile;
29+
30+
public class SOAPServer extends Server {
31+
32+
public SOAPServer(ServerCoreProfile coreProfile) {
33+
super(new WebServiceListener());
34+
addFeatureProfile(coreProfile);
35+
}
36+
37+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package eu.chargetime.ocpp;/*
2+
ChargeTime.eu - Java-OCA-OCPP
3+
4+
MIT License
5+
6+
Copyright (C) 2016 Thomas Volden <[email protected]>
7+
8+
Permission is hereby granted, free of charge, to any person obtaining a copy
9+
of this software and associated documentation files (the "Software"), to deal
10+
in the Software without restriction, including without limitation the rights
11+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
copies of the Software, and to permit persons to whom the Software is
13+
furnished to do so, subject to the following conditions:
14+
15+
The above copyright notice and this permission notice shall be included in all
16+
copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
SOFTWARE.
25+
*/
26+
27+
import org.w3c.dom.NodeList;
28+
29+
import javax.xml.soap.SOAPException;
30+
import javax.xml.soap.SOAPHeader;
31+
import javax.xml.soap.SOAPMessage;
32+
import java.util.HashMap;
33+
import java.util.concurrent.CompletableFuture;
34+
35+
public abstract class SOAPSyncHelper {
36+
37+
private HashMap<String, CompletableFuture<SOAPMessage>> promises;
38+
39+
public SOAPSyncHelper() {
40+
promises = new HashMap<>();
41+
}
42+
43+
public static String getHeaderValue(SOAPMessage message, String tagName) {
44+
String value = null;
45+
try {
46+
SOAPHeader header = message.getSOAPPart().getEnvelope().getHeader();
47+
NodeList elements = header.getElementsByTagNameNS("*", tagName);
48+
if (elements.getLength() > 0)
49+
value = elements.item(0).getChildNodes().item(0).getNodeValue();
50+
} catch (SOAPException e) {
51+
e.printStackTrace();
52+
}
53+
return value;
54+
}
55+
56+
abstract void forwardMessage(SOAPMessage message);
57+
58+
public CompletableFuture<SOAPMessage> relay(SOAPMessage message) {
59+
forwardMessage(message);
60+
CompletableFuture<SOAPMessage> promise = null;
61+
String uniqueID = getHeaderValue(message, "MessageID");
62+
if (uniqueID != null) {
63+
promise = new CompletableFuture<>();
64+
promises.put(uniqueID, promise);
65+
}
66+
67+
return promise;
68+
}
69+
70+
abstract void sendRequest(SOAPMessage message);
71+
72+
public void send(Object message) throws NotConnectedException {
73+
SOAPMessage soapMessage = (SOAPMessage) message;
74+
75+
String relatesTo = getHeaderValue(soapMessage, "RelatesTo");
76+
if (relatesTo != null && promises.containsKey(relatesTo)) {
77+
promises.get(relatesTo).complete(soapMessage);
78+
} else {
79+
sendRequest(soapMessage);
80+
}
81+
}
82+
}

ocpp-v1_6/src/main/java/eu/chargetime/ocpp/WSHttpHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ public void handle(HttpExchange httpExchange) throws IOException {
5353
SOAPMessage confirmation = events.incomingRequest(request);
5454
OutputStream responseStream = httpExchange.getResponseBody();
5555
try {
56-
confirmation.writeTo(responseStream);
56+
httpExchange.getResponseHeaders().add("Content-Type", "text/xml; charset=utf-8");
5757
httpExchange.sendResponseHeaders(200, 0);
58+
confirmation.writeTo(responseStream);
5859
} catch (SOAPException e) {
5960
httpExchange.sendResponseHeaders(500, 0);
6061
e.printStackTrace();

ocpp-v1_6/src/main/java/eu/chargetime/ocpp/WebServiceListener.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,29 @@ of this software and associated documentation files (the "Software"), to deal
2727

2828
import com.sun.net.httpserver.HttpServer;
2929

30+
import javax.xml.soap.SOAPException;
31+
import javax.xml.soap.SOAPMessage;
32+
import java.io.ByteArrayOutputStream;
3033
import java.io.IOException;
3134
import java.net.InetSocketAddress;
35+
import java.util.HashMap;
36+
import java.util.concurrent.ExecutionException;
3237

3338
public class WebServiceListener implements Listener {
3439

3540
final private String WSDL_CENTRAL_SYSTEM = "eu/chargetime/ocpp/OCPP_CentralSystemService_1.6.wsdl";
3641

42+
private ListenerEvents events;
43+
private String fromUrl = null;
44+
3745
@Override
3846
public void open(String hostname, int port, ListenerEvents listenerEvents) {
47+
events = listenerEvents;
48+
fromUrl = String.format("http://%s:%d", hostname, port);
3949
try {
4050
HttpServer server = HttpServer.create(new InetSocketAddress(hostname, port), 0);
41-
server.createContext("/", new WSHttpHandler(WSDL_CENTRAL_SYSTEM, message -> null));
51+
server.createContext("/", new WSHttpHandler(WSDL_CENTRAL_SYSTEM, new WSHttpEventHandler()));
52+
4253
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
4354
server.start();
4455
} catch (IOException e) {
@@ -50,4 +61,49 @@ public void open(String hostname, int port, ListenerEvents listenerEvents) {
5061
public void close() {
5162

5263
}
64+
65+
private class WSHttpEventHandler implements WSHttpHandlerEvents {
66+
67+
HashMap<String, SOAPReceiver> chargeboxes;
68+
69+
public WSHttpEventHandler() {
70+
chargeboxes = new HashMap<>();
71+
}
72+
73+
@Override
74+
public SOAPMessage incomingRequest(SOAPMessage message) {
75+
String identity = SOAPSyncHelper.getHeaderValue(message, "chargeBoxIdentity");
76+
if (!chargeboxes.containsKey(identity)) {
77+
String toUrl = SOAPSyncHelper.getHeaderValue(message, "From");
78+
SOAPReceiver soapReceiver = new SOAPReceiver(toUrl);
79+
SOAPCommunicator communicator = new SOAPCommunicator(identity, fromUrl, soapReceiver);
80+
communicator.setToUrl(toUrl);
81+
events.newSession(new Session(communicator, new Queue()));
82+
chargeboxes.put(identity, soapReceiver);
83+
}
84+
85+
SOAPMessage confirmation = null;
86+
try {
87+
confirmation = chargeboxes.get(identity).relay(message).get();
88+
} catch (InterruptedException e) {
89+
e.printStackTrace();
90+
} catch (ExecutionException e) {
91+
e.printStackTrace();
92+
}
93+
94+
try {
95+
ByteArrayOutputStream out = new ByteArrayOutputStream();
96+
message.writeTo(out);
97+
String strMsg = new String(out.toByteArray());
98+
System.out.print(strMsg);
99+
} catch (SOAPException e) {
100+
e.printStackTrace();
101+
} catch (IOException e) {
102+
e.printStackTrace();
103+
}
104+
105+
return confirmation;
106+
}
107+
}
108+
53109
}

0 commit comments

Comments
 (0)