diff options
Diffstat (limited to 'BKUOnline/src/main')
7 files changed, 518 insertions, 283 deletions
diff --git a/BKUOnline/src/main/custom-binding/stalservice-custom.xml b/BKUOnline/src/main/custom-binding/stalservice-custom.xml index 384b04f7..9c35cbdf 100644 --- a/BKUOnline/src/main/custom-binding/stalservice-custom.xml +++ b/BKUOnline/src/main/custom-binding/stalservice-custom.xml @@ -42,6 +42,20 @@ </bindings> <!-- wsdl:portType operation customization --> + <bindings node="wsdl:definitions/wsdl:portType[@name='STALPortType']/wsdl:operation[@name='connect']"> + <!-- rename method name --> + <method name="connect"> + <javadoc>Initial connection, get the first request.</javadoc> + </method> + + <!-- rename method params --> + <parameter part="wsdl:definitions/wsdl:message[@name='ConnectRequest']/wsdl:part[@name='part1']" name="sessionId" /> + + <!-- override default settings --> + <enableWrapperStyle>true</enableWrapperStyle> + <enableAsyncMapping>false</enableAsyncMapping> + </bindings> + <bindings node="wsdl:definitions/wsdl:portType[@name='STALPortType']/wsdl:operation[@name='nextRequest']"> <!-- rename method name --> <method name="getNextRequest"> diff --git a/BKUOnline/src/main/custom-binding/staltypes-custom.xml b/BKUOnline/src/main/custom-binding/staltypes-custom.xml index 2ea42082..3e150363 100644 --- a/BKUOnline/src/main/custom-binding/staltypes-custom.xml +++ b/BKUOnline/src/main/custom-binding/staltypes-custom.xml @@ -35,36 +35,13 @@ <bindings scd="x-schema::stal" xmlns:stal="http://www.egiz.gv.at/stal"> <schemaBindings> <!-- generate all classes to at.gv.egiz.stal, then move service-only classes to at.gv.egiz.stal.service --> - <package name="at.gv.egiz.stal"/> + <package name="at.gv.egiz.stal.service.types"/> </schemaBindings> </bindings> - <bindings scd="/type::stal:RequestType"> + <!--bindings scd="/type::stal:RequestType"> <class name="STALRequest"/> </bindings> <bindings scd="/type::stal:ResponseType"> <class name="STALResponse"/> - </bindings> - <bindings scd="/type::stal:InfoboxReadResponseType"> - <class name="InfoboxReadResponse"/> - </bindings> - <bindings scd="/type::stal:SignResponseType"> - <class name="SignResponse"/> - </bindings> - <bindings scd="/type::stal:ErrorResponseType"> - <class name="ErrorResponse"/> - <!--class implClass="at.gv.egiz.stal.types.ErrorResponse"/--> - </bindings> - <bindings scd="/type::stal:InfoboxReadRequestType" > - <class name="InfoboxReadRequest"/> - </bindings> - <bindings scd="/type::stal:SignRequestType" > - <class name="SignRequest"/> - <!--class implClass="at.gv.egiz.stal.types.SignRequest"/--> - </bindings> - <bindings scd="/type::stal:QuitRequestType" > - <class name="QuitRequest"/> - </bindings> - <!--bindings scd="/type::stal:GetHashDataInputFaultType" > - <class name="GetHashDataInputFault"/> </bindings--> </bindings> diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBroker.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBroker.java index 560282ac..af886eec 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBroker.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBroker.java @@ -22,8 +22,8 @@ package at.gv.egiz.stal.service.impl; import at.gv.egiz.stal.HashDataInput; import at.gv.egiz.stal.STAL; -import at.gv.egiz.stal.STALRequest; -import at.gv.egiz.stal.STALResponse; +import at.gv.egiz.stal.service.types.RequestType; +import at.gv.egiz.stal.service.types.ResponseType; import java.util.List; /** @@ -35,7 +35,9 @@ public interface STALRequestBroker extends STAL { public static final int ERR_6000 = 6000; public static final long DEFAULT_TIMEOUT_MS = 1000*60*5; //5mn - public List<STALRequest> nextRequest(List<STALResponse> response); + public List<RequestType> connect(); + + public List<RequestType> nextRequest(List<ResponseType> response); public List<HashDataInput> getHashDataInput(); } diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java index dc3cc6d3..bfa83dd4 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java @@ -22,10 +22,17 @@ package at.gv.egiz.stal.service.impl; import at.gv.egiz.stal.ErrorResponse; import at.gv.egiz.stal.HashDataInput; +import at.gv.egiz.stal.InfoboxReadRequest; import at.gv.egiz.stal.QuitRequest; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.service.types.InfoboxReadRequestType; +import at.gv.egiz.stal.service.types.QuitRequestType; +import at.gv.egiz.stal.service.types.RequestType; +import at.gv.egiz.stal.service.types.ResponseType; +import at.gv.egiz.stal.service.types.SignRequestType; +import at.gv.egiz.stal.util.STALTranslator; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -48,18 +55,26 @@ public class STALRequestBrokerImpl implements STALRequestBroker { private static final Log log = LogFactory.getLog(STALRequestBrokerImpl.class); - private boolean expectingResponse = false; +// private boolean expectingResponse = false; private boolean interrupted = false; - private final RequestsMonitor reqMon = new RequestsMonitor(); - private final ResponsesMonitor respMon = new ResponsesMonitor(); +// private final RequestsMonitor reqMon = new RequestsMonitor(); +// private final ResponsesMonitor respMon = new ResponsesMonitor(); + + protected ArrayList<RequestType> requests; + protected ArrayList<ResponseType> responses; + + protected ArrayList<HashDataInput> hashDataInputs; private long timeout; public STALRequestBrokerImpl(long timeoutMillisec) { if (timeoutMillisec <= 0) timeoutMillisec = DEFAULT_TIMEOUT_MS; - this.timeout = timeoutMillisec; + timeout = timeoutMillisec; + requests = new ArrayList<RequestType>(); + responses = new ArrayList<ResponseType>(); + hashDataInputs = new ArrayList<HashDataInput>(); } /** @@ -73,52 +88,80 @@ public class STALRequestBrokerImpl implements STALRequestBroker { * @pre requests: either single SignRequest, QuitRequest or multiple ReadInfoboxRequests */ @Override - public List<STALResponse> handleRequest(List<STALRequest> requests) { + public List<STALResponse> handleRequest(List<STALRequest> stalRequests) { if (interrupted) { return null; } try { - synchronized (reqMon) { + synchronized (requests) { log.trace("produce request"); - reqMon.produce(requests); - reqMon.setHashDataInput(null); - for (STALRequest request : requests) { - if (request instanceof SignRequest) { - log.trace("Received SignRequest, keep HashDataInput."); - reqMon.setHashDataInput(((SignRequest) request).getHashDataInput()); - break; - } else if (request instanceof QuitRequest) { - log.trace("Received QuitRequest, do not wait for responses."); - log.trace("notifying request consumers"); - reqMon.notify(); - return new ArrayList<STALResponse>(); - } else if (log.isTraceEnabled()) { - log.trace("Received STAL request: " + request.getClass().getName()); + requests.clear(); + hashDataInputs.clear(); +// reqMon.produce(requests); +// reqMon.setHashDataInput(null); + + for (STALRequest stalRequest : stalRequests) { + if (stalRequest instanceof SignRequest) { + log.trace("Received SignRequest, keep HashDataInput."); + SignRequestType req = new SignRequestType(); + req.setKeyIdentifier(((SignRequest) stalRequest).getKeyIdentifier()); + req.setSignedInfo(((SignRequest) stalRequest).getSignedInfo()); + requests.add(req); + hashDataInputs.addAll(((SignRequest) stalRequest).getHashDataInput()); + break; + } else if (stalRequest instanceof InfoboxReadRequest) { + log.trace("Received InfoboxReadRequest"); + InfoboxReadRequestType req = new InfoboxReadRequestType(); + req.setInfoboxIdentifier(((InfoboxReadRequest) stalRequest).getInfoboxIdentifier()); + req.setDomainIdentifier(((InfoboxReadRequest) stalRequest).getDomainIdentifier()); + requests.add(req); + } else if (stalRequest instanceof QuitRequest) { + log.trace("Received QuitRequest, do not wait for responses."); + requests.add(new QuitRequestType()); + log.trace("notifying request consumers"); + requests.notify(); +// reqMon.notify(); + return new ArrayList<STALResponse>(); + } else { + log.error("Received unsupported STAL request: " + stalRequest.getClass().getName() + ", send QUIT"); + requests.clear(); + requests.add(new QuitRequestType()); + log.trace("notifying request consumers"); + requests.notify(); + return new ArrayList<STALResponse>(); } } log.trace("notifying request consumers"); - reqMon.notify(); + requests.notify(); +// reqMon.notify(); } - synchronized (respMon) { + synchronized (responses) { //respMon) { long beforeWait = System.currentTimeMillis(); - while (respMon.responses == null) { +// while (respMon.responses == null) { + while (responses.isEmpty()) { log.trace("waiting to consume response"); - respMon.wait(timeout); +// respMon.wait(timeout); + responses.wait(timeout); if (System.currentTimeMillis() - beforeWait >= timeout) { log.warn("timeout while waiting to consume response, cleanup requests"); - reqMon.consume(); //TODO check deadlock? - reqMon.setHashDataInput(null); +// reqMon.consume(); //TODO check deadlock? +// reqMon.setHashDataInput(null); + requests.clear(); //TODO sync on requests? + hashDataInputs.clear(); return Collections.singletonList((STALResponse) new ErrorResponse(ERR_6000)); } } log.trace("consuming responses"); - List<STALResponse> responses = respMon.consume(); +// List<STALResponse> responses = respMon.consume(); + List<STALResponse> resps = STALTranslator.toSTAL(responses); + responses.clear(); log.trace("notifying response producers"); - respMon.notify(); + responses.notify(); +// respMon.notify(); - return responses; + return resps; } } catch (InterruptedException ex) { log.warn("interrupt in handleRequest(): " + ex.getMessage()); @@ -127,6 +170,36 @@ public class STALRequestBrokerImpl implements STALRequestBroker { } } + @Override + public List<RequestType> connect() { + if (interrupted) { + return null; + } + try { + synchronized (requests) { + long beforeWait = System.currentTimeMillis(); + while (requests.isEmpty()) { + log.trace("waiting to consume request"); + requests.wait(timeout); + if (System.currentTimeMillis() - beforeWait >= timeout) { + log.warn("timeout while waiting to consume request"); + return Collections.singletonList((RequestType) new QuitRequestType()); + } + } + log.trace("consume request"); + List<RequestType> reqs = new ArrayList<RequestType>(); + reqs.addAll(requests); + + requests.clear(); + return reqs; + } + } catch (InterruptedException ex) { + log.warn("interrupt in nextRequest(): " + ex.getMessage()); + interrupted = true; + return null; + } + } + /** * This method is thread-safe, except for * an 'initial' call to nextRequest(null) followed by a @@ -139,63 +212,74 @@ public class STALRequestBrokerImpl implements STALRequestBroker { * @return QUIT if expected responses are not provided */ @Override - public List<STALRequest> nextRequest(List<STALResponse> responses) { + public List<RequestType> nextRequest(List<ResponseType> resps) { if (interrupted) { return null; } try { - synchronized (respMon) { - if (responses != null && responses.size() > 0) { - if (!expectingResponse) { - log.warn("Received unexpected response in nextRequest(), return QUIT"); - return Collections.singletonList((STALRequest) new QuitRequest()); - } + synchronized (responses) { //respMon) { + if (resps != null && resps.size() > 0) { +// if (!expectingResponse) { +// log.warn("Received unexpected response in nextRequest(), return QUIT"); +// return Collections.singletonList((RequestType) new QuitRequestType()); +// } long beforeWait = System.currentTimeMillis(); - while (respMon.responses != null) { +// while (respMon.responses != null) { + while (!responses.isEmpty()) { log.trace("waiting to produce response"); - respMon.wait(timeout); +// respMon.wait(timeout); + responses.wait(timeout); if (System.currentTimeMillis() - beforeWait >= timeout) { log.warn("timeout while waiting to produce response"); - return Collections.singletonList((STALRequest) new QuitRequest()); + return Collections.singletonList((RequestType) new QuitRequestType()); } } log.trace("produce response"); - respMon.produce(responses); +// respMon.produce(resps); + responses.addAll(resps); //reset HashDataInputCallback iff SignResponse if (log.isTraceEnabled()) { - for (STALResponse response : responses) { + for (ResponseType response : resps) { log.trace("Received STAL response: " + response.getClass().getName()); } } log.trace("notifying response consumers"); - respMon.notify(); +// respMon.notify(); + responses.notify(); } else { - if (expectingResponse) { - log.warn("Did not receive expected response(s) in nextRequest(), return QUIT"); - return Collections.singletonList((STALRequest) new QuitRequest()); - } - log.trace("expecting non-null response in next nextRequest(response)"); - expectingResponse = true; +// if (expectingResponse) { +// log.warn("Did not receive expected response(s) in nextRequest(), return QUIT"); +// return Collections.singletonList((RequestType) new QuitRequestType()); +// } +// log.trace("expecting non-null response in next nextRequest(response)"); +// expectingResponse = true; + log.error("Received NextRequest without responses, return QUIT"); + return Collections.singletonList((RequestType) new QuitRequestType()); } } - synchronized (reqMon) { + synchronized (requests) { //reqMon) { long beforeWait = System.currentTimeMillis(); - while (reqMon.requests == null) { +// while (reqMon.requests == null) { + while (requests.isEmpty()) { log.trace("waiting to consume request"); - reqMon.wait(timeout); +// reqMon.wait(timeout); + requests.wait(timeout); if (System.currentTimeMillis() - beforeWait >= timeout) { log.warn("timeout while waiting to consume request"); - return Collections.singletonList((STALRequest) new QuitRequest()); + return Collections.singletonList((RequestType) new QuitRequestType()); } } log.trace("consume request"); - List<STALRequest> requests = reqMon.consume(); - if (requests.size() > 0 && requests.get(0) instanceof QuitRequest) { - log.trace("expecting no response in next nextRequest()"); - expectingResponse = false; - } - return requests; + List<RequestType> reqs = new ArrayList<RequestType>(); // reqMon.consume(); + reqs.addAll(requests); + +// if (requests.size() > 0 && requests.get(0) instanceof QuitRequestType) { +// log.trace("expecting no response in next nextRequest()"); +// expectingResponse = false; +// } + requests.clear(); + return reqs; } } catch (InterruptedException ex) { log.warn("interrupt in nextRequest(): " + ex.getMessage()); @@ -205,49 +289,95 @@ public class STALRequestBrokerImpl implements STALRequestBroker { } @Override - public synchronized List<HashDataInput> getHashDataInput() { - log.trace("return " + reqMon.hashDataInput.size() + " current HashDataInput(s) "); - return reqMon.getHashDataInput(); + public List<HashDataInput> getHashDataInput() { + synchronized (requests) { + log.trace("return " + hashDataInputs.size() + " current HashDataInput(s) "); + return hashDataInputs; //reqMon.getHashDataInput(); + } } @Override public void setLocale(Locale locale) { } - class RequestsMonitor { - List<STALRequest> requests; - List<HashDataInput> hashDataInput; - - void produce(List<STALRequest> req) { - requests = req; - } - - synchronized List<STALRequest> consume() { - List<STALRequest> reqs = requests; - requests = null; - return reqs; - } - - void setHashDataInput(List<HashDataInput> hdi) { - hashDataInput = hdi; - } - - List<HashDataInput> getHashDataInput() { - return hashDataInput; - } - } - - class ResponsesMonitor { - List<STALResponse> responses; - - void produce(List<STALResponse> resp) { - responses = resp; - } - - synchronized List<STALResponse> consume() { - List<STALResponse> resps = responses; - responses = null; - return resps; - } - } +// class RequestsMonitor { +// List<STALRequest> requests; +// List<HashDataInput> hashDataInput; +// +// void produce(List<STALRequest> req) { +// requests = req; +// } +// +// synchronized List<at.gv.egiz.stal.service.types.STALRequest> consume() { +// List<at.gv.egiz.stal.service.types.STALRequest> reqs = new ArrayList<at.gv.egiz.stal.service.types.STALRequest>(); +// for (STALRequest request : requests) { +// if (request instanceof SignRequest) { +// at.gv.egiz.stal.service.types.SignRequest r = new at.gv.egiz.stal.service.types.SignRequest(); +// r.setKeyIdentifier(((SignRequest) request).getKeyIdentifier()); +// r.setSignedInfo(((SignRequest) request).getSignedInfo()); +// reqs.add(r); +// } else if (request instanceof InfoboxReadRequest) { +// at.gv.egiz.stal.service.types.InfoboxReadRequest r = new at.gv.egiz.stal.service.types.InfoboxReadRequest(); +// r.setDomainIdentifier(((InfoboxReadRequest) request).getDomainIdentifier()); +// r.setInfoboxIdentifier(((InfoboxReadRequest) request).getInfoboxIdentifier()); +// reqs.add(r); +// } else if (request instanceof QuitRequest) { +// at.gv.egiz.stal.service.types.QuitRequest r = new at.gv.egiz.stal.service.types.QuitRequest(); +// reqs.add(r); +// } else { +// log.error("unknown STAL request type: " + request.getClass()); +// requests = null; +// return Collections.singletonList((at.gv.egiz.stal.service.types.STALRequest) new at.gv.egiz.stal.service.types.QuitRequest()); +// } +// } +// requests = null; +// return reqs; +// } +// +// void setHashDataInput(List<HashDataInput> hdi) { +// hashDataInput = hdi; +// } +// +// List<HashDataInput> getHashDataInput() { +// return hashDataInput; +// } +// } +// +// /** TODO: now, that responses are not nulled, synchronize directly on responses? */ +// class ResponsesMonitor { +// List<at.gv.egiz.stal.service.types.STALResponse> responses; +// +// void produce(List<at.gv.egiz.stal.service.types.STALResponse> resp) { +// responses = resp; +// } +// +// synchronized List<STALResponse> consume() { +// List<STALResponse> resps = new ArrayList<STALResponse>(); +// +// for (at.gv.egiz.stal.service.types.STALResponse response : responses) { +// if (response instanceof at.gv.egiz.stal.service.types.InfoboxReadResponse) { +// InfoboxReadResponse r = new InfoboxReadResponse(); +// r.setInfoboxValue(((at.gv.egiz.stal.service.types.InfoboxReadResponse) response).getInfoboxValue()); +// resps.add(r); +// } else if (response instanceof at.gv.egiz.stal.service.types.SignResponse) { +// SignResponse r = new SignResponse(); +// r.setSignatureValue(((at.gv.egiz.stal.service.types.SignResponse) response).getSignatureValue()); +// resps.add(r); +// } else if (response instanceof at.gv.egiz.stal.service.types.ErrorResponse) { +// ErrorResponse r = new ErrorResponse(); +// r.setErrorCode(((at.gv.egiz.stal.service.types.ErrorResponse) response).getErrorCode()); +// r.setErrorMessage(((at.gv.egiz.stal.service.types.ErrorResponse) response).getErrorMessage()); +// resps.add(r); +// } else { +// log.error("unknown STAL response type: " + response.getClass()); +// ErrorResponse r = new ErrorResponse(4000); +// r.setErrorMessage("unknown STAL response type: " + response.getClass()); +// responses = null; +// return Collections.singletonList((STALResponse) r); +// } +// } +// responses = null; +// return resps; +// } +// } } diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java index d3d6c8db..bcee1e77 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java @@ -22,22 +22,27 @@ package at.gv.egiz.stal.service.impl; import at.gv.egiz.bku.binding.BindingProcessor; import at.gv.egiz.bku.binding.BindingProcessorManager; -import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.stal.service.*; import at.gv.egiz.bku.binding.Id; import at.gv.egiz.bku.binding.IdFactory; -import at.gv.egiz.stal.ErrorResponse; -import at.gv.egiz.stal.STALRequest; -import at.gv.egiz.stal.STALResponse; -import at.gv.egiz.stal.InfoboxReadRequest; -import at.gv.egiz.stal.QuitRequest; -import at.gv.egiz.stal.SignRequest; - -import java.io.ByteArrayInputStream; + +import at.gv.egiz.stal.HashDataInput; +import at.gv.egiz.stal.service.GetHashDataInputFault; +import at.gv.egiz.stal.service.STALPortType; +import at.gv.egiz.stal.service.types.ErrorResponseType; +import at.gv.egiz.stal.service.types.GetHashDataInputFaultType; +import at.gv.egiz.stal.service.types.GetHashDataInputResponseType; +import at.gv.egiz.stal.service.types.GetHashDataInputType; +import at.gv.egiz.stal.service.types.GetNextRequestResponseType; +import at.gv.egiz.stal.service.types.GetNextRequestType; +import at.gv.egiz.stal.service.types.InfoboxReadRequestType; +import at.gv.egiz.stal.service.types.QuitRequestType; +import at.gv.egiz.stal.service.types.RequestType; +import at.gv.egiz.stal.service.types.ResponseType; +import at.gv.egiz.stal.service.types.SignRequestType; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Collections; +import java.nio.charset.Charset; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,57 +68,90 @@ public class STALServiceImpl implements STALPortType { WebServiceContext wsContext; protected IdFactory idF = IdFactory.getInstance(); + @Override - public GetNextRequestResponseType getNextRequest(GetNextRequestType request) { - - Id sessionId = idF.createId(request.getSessionId()); - - List<STALResponse> responsesIn = request.getResponse(); - - GetNextRequestResponseType response = new GetNextRequestResponseType(); - response.setSessionId(sessionId.toString()); + public GetNextRequestResponseType connect(String sessId) { + + if (sessId == null) { + throw new NullPointerException("No session id provided"); + } + + Id sessionId = idF.createId(sessId); + if (log.isDebugEnabled()) { + log.debug("Received Connect [" + sessionId + "]"); + } + if (TEST_SESSION_ID.equals(sessionId)) { - if (responsesIn.size() > 0 && responsesIn.get(0) instanceof ErrorResponse) { - log.info("Received TestSession GetNextRequest(ErrorResponse), returning QuitRequest"); - response.getRequest().add(new QuitRequest()); - } else { - log.info("Received TestSession GetNextRequest, returning InfoboxReadRequest "); - SignRequest sig = new SignRequest(); - sig.setKeyIdentifier("SecureSignatureKeypair"); - sig.setSignedInfo("<dsig:SignedInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:xpf=\"http://www.w3.org/2002/06/xmldsig-filter2\"><dsig:CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /> <dsig:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1\" /> <dsig:Reference Id=\"signed-data-reference-0-1214921968-27971781-24309\" URI=\"#signed-data-object-0-1214921968-27971781-13578\"><dsig:Transforms> <dsig:Transform Algorithm=\"http://www.w3.org/2002/06/xmldsig-filter2\"> <xpf:XPath xmlns:xpf=\"http://www.w3.org/2002/06/xmldsig-filter2\" Filter=\"intersect\">id('signed-data-object-0-1214921968-27971781-13578')/node()</xpf:XPath></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /> <dsig:DigestValue>H1IePEEfGQ2SG03H6LTzw1TpCuM=</dsig:DigestValue></dsig:Reference><dsig:Reference Id=\"etsi-data-reference-0-1214921968-27971781-25439\" Type=\"http://uri.etsi.org/01903/v1.1.1#SignedProperties\" URI=\"#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-data-object-0-1214921968-27971781-3095')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)\"><dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><dsig:DigestValue>yV6Q+I60buqR4mMaxA7fi+CV35A=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo>".getBytes()); - response.getRequest().add(sig); - InfoboxReadRequest req = new InfoboxReadRequest(); - req.setInfoboxIdentifier("IdentityLink"); - req.setDomainIdentifier("hansiwurzel"); - response.getRequest().add(req); - req = new InfoboxReadRequest(); - req.setInfoboxIdentifier("CertifiedKeypair"); - response.getRequest().add(req); - req = new InfoboxReadRequest(); - req.setInfoboxIdentifier("SecureSignatureKeypair"); - response.getRequest().add(req); - } - return response; + return getTestSessionNextRequestResponse(null); } + + GetNextRequestResponseType response = new GetNextRequestResponseType(); + response.setSessionId(sessionId.toString()); STALRequestBroker stal = getStal(sessionId); if (stal != null) { + + List<RequestType> requestsOut = ((STALRequestBroker) stal).connect(); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().addAll(requestsOut); + if (log.isDebugEnabled()) { - StringBuilder sb = new StringBuilder("Received GetNextRequest ["); + StringBuilder sb = new StringBuilder("Returning initial GetNextRequestResponse ["); sb.append(sessionId.toString()); sb.append("] containing "); - sb.append(responsesIn.size()); - sb.append(" responses: "); - for (STALResponse respIn : responsesIn) { - sb.append(respIn); + sb.append(requestsOut.size()); + sb.append(" requests: "); + for (RequestType reqOut : requestsOut) { + sb.append(reqOut.getClass()); sb.append(' '); } + log.debug(sb.toString()); } + } else { + log.error("Failed to get STAL for session " + sessionId + ", returning QuitRequest"); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(new QuitRequestType()); + } + return response; + } + + @Override + public GetNextRequestResponseType getNextRequest(GetNextRequestType request) { + + if (request.getSessionId() == null) { + throw new NullPointerException("No session id provided"); + } + + Id sessionId = idF.createId(request.getSessionId()); + + List<ResponseType> responsesIn = request.getInfoboxReadResponseOrSignResponseOrErrorResponse();//getResponse(); + + if (log.isDebugEnabled()) { + StringBuilder sb = new StringBuilder("Received GetNextRequest ["); + sb.append(sessionId.toString()); + sb.append("] containing "); + sb.append(responsesIn.size()); + sb.append(" responses: "); + for (ResponseType respIn : responsesIn) { + sb.append(respIn.getClass()); + sb.append(' '); + } + log.debug(sb.toString()); + } + + if (TEST_SESSION_ID.equals(sessionId)) { + return getTestSessionNextRequestResponse(responsesIn); + } - List<STALRequest> requestsOut = ((STALRequestBroker) stal).nextRequest(responsesIn); - response.getRequest().addAll(requestsOut); + GetNextRequestResponseType response = new GetNextRequestResponseType(); + response.setSessionId(sessionId.toString()); + + STALRequestBroker stal = getStal(sessionId); + + if (stal != null) { + + List<RequestType> requestsOut = ((STALRequestBroker) stal).nextRequest(responsesIn); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().addAll(requestsOut); if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder("Returning GetNextRequestResponse ["); @@ -121,14 +159,15 @@ public class STALServiceImpl implements STALPortType { sb.append("] containing "); sb.append(requestsOut.size()); sb.append(" requests: "); - for (STALRequest reqOut : requestsOut) { - sb.append(reqOut); + for (RequestType reqOut : requestsOut) { + sb.append(reqOut.getClass()); sb.append(' '); } + log.debug(sb.toString()); } } else { log.error("Failed to get STAL for session " + sessionId + ", returning QuitRequest"); - response.getRequest().add(new QuitRequest()); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(new QuitRequestType()); } return response; } @@ -136,6 +175,10 @@ public class STALServiceImpl implements STALPortType { @Override public GetHashDataInputResponseType getHashDataInput(GetHashDataInputType request) throws GetHashDataInputFault { + if (request.getSessionId() == null) { + throw new NullPointerException("No session id provided"); + } + Id sessionId = idF.createId(request.getSessionId()); if (log.isDebugEnabled()) { @@ -150,8 +193,17 @@ public class STALServiceImpl implements STALPortType { GetHashDataInputResponseType.Reference ref = new GetHashDataInputResponseType.Reference(); ref.setID("Reference-" + TEST_SESSION_ID + "-001"); ref.setMimeType("text/plain"); - ref.setEncoding("UTF-8"); - ref.setValue("hashdatainput-öäüß@€-00000000001".getBytes()); + + Charset charset; + try { + charset = Charset.forName("iso-8859-15"); + ref.setEncoding("iso-8859-15"); + } catch (Exception ex) { + log.warn(ex.getMessage()); + charset = Charset.defaultCharset(); + ref.setEncoding(charset.toString()); + } + ref.setValue("hashdatainput-öäüß@€-00000000001".getBytes(charset)); response.getReference().add(ref); return response; } else { @@ -244,10 +296,40 @@ public class STALServiceImpl implements STALPortType { } private STALRequestBroker getStal(Id sessionId) { + if (log.isTraceEnabled()) { + log.trace("resolve STAL for session " + sessionId); + } MessageContext mCtx = wsContext.getMessageContext(); ServletContext sCtx = (ServletContext) mCtx.get(MessageContext.SERVLET_CONTEXT); BindingProcessorManager bpMgr = (BindingProcessorManager) sCtx.getAttribute(BINDING_PROCESSOR_MANAGER); BindingProcessor bp = bpMgr.getBindingProcessor(sessionId); return (bp == null) ? null : (bp.isFinished() ? null : (STALRequestBroker) bp.getSTAL()); } + + private GetNextRequestResponseType getTestSessionNextRequestResponse(List<ResponseType> responsesIn) { + GetNextRequestResponseType response = new GetNextRequestResponseType(); + response.setSessionId(TEST_SESSION_ID.toString()); + + if (responsesIn != null && responsesIn.size() > 0 && responsesIn.get(0) instanceof ErrorResponseType) { + log.info("Received TestSession GetNextRequest(ErrorResponse), returning QuitRequest"); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(new QuitRequestType()); + } else { + log.info("Received TestSession GetNextRequest, returning InfoboxReadRequest "); + SignRequestType sig = new SignRequestType(); + sig.setKeyIdentifier("SecureSignatureKeypair"); + sig.setSignedInfo("<dsig:SignedInfo xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:xpf=\"http://www.w3.org/2002/06/xmldsig-filter2\"><dsig:CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /> <dsig:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1\" /> <dsig:Reference Id=\"signed-data-reference-0-1214921968-27971781-24309\" URI=\"#signed-data-object-0-1214921968-27971781-13578\"><dsig:Transforms> <dsig:Transform Algorithm=\"http://www.w3.org/2002/06/xmldsig-filter2\"> <xpf:XPath xmlns:xpf=\"http://www.w3.org/2002/06/xmldsig-filter2\" Filter=\"intersect\">id('signed-data-object-0-1214921968-27971781-13578')/node()</xpf:XPath></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /> <dsig:DigestValue>H1IePEEfGQ2SG03H6LTzw1TpCuM=</dsig:DigestValue></dsig:Reference><dsig:Reference Id=\"etsi-data-reference-0-1214921968-27971781-25439\" Type=\"http://uri.etsi.org/01903/v1.1.1#SignedProperties\" URI=\"#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-data-object-0-1214921968-27971781-3095')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)\"><dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><dsig:DigestValue>yV6Q+I60buqR4mMaxA7fi+CV35A=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo>".getBytes()); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(sig); + InfoboxReadRequestType req = new InfoboxReadRequestType(); + req.setInfoboxIdentifier("IdentityLink"); + req.setDomainIdentifier("hansiwurzel"); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(req); + req = new InfoboxReadRequestType(); + req.setInfoboxIdentifier("CertifiedKeypair"); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(req); + req = new InfoboxReadRequestType(); + req.setInfoboxIdentifier("SecureSignatureKeypair"); + response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(req); + } + return response; + } } diff --git a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.wsdl b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.wsdl index a9f16a12..344e5ce2 100644 --- a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.wsdl +++ b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.wsdl @@ -24,6 +24,9 @@ <xsd:import namespace="http://www.egiz.gv.at/stal" schemaLocation="stal.xsd"/> </xsd:schema> </types> + <message name="ConnectRequest"> + <part name="part1" element="ns:SessionId"/> + </message> <message name="NextRequestRequest"> <part name="part1" element="ns:GetNextRequest"/> </message> @@ -40,6 +43,10 @@ <part name="part1" element="ns:GetHashDataInputFault"/> </message> <portType name="STALPortType"> + <operation name="connect"> + <input name="input3" message="tns:ConnectRequest"/> + <output name="output3" message="tns:NextRequestResponse"/> + </operation> <operation name="nextRequest"> <input name="input1" message="tns:NextRequestRequest"/> <output name="output1" message="tns:NextRequestResponse"/> @@ -52,6 +59,14 @@ </portType> <binding name="STALBinding" type="tns:STALPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="connect"> + <input name="input3"> + <soap:body use="literal"/> + </input> + <output name="output3"> + <soap:body use="literal"/> + </output> + </operation> <operation name="nextRequest"> <soap:operation/> <input name="input1"> diff --git a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd index b3c4841a..6f3946dc 100644 --- a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd +++ b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd @@ -18,121 +18,136 @@ <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.egiz.gv.at/stal" xmlns:tns="http://www.egiz.gv.at/stal" elementFormDefault="qualified"> - <element name="GetNextRequest" type="tns:GetNextRequestType"/> - <element name="GetNextRequestResponse" type="tns:GetNextRequestResponseType"/> - <element name="GetHashDataInput" type="tns:GetHashDataInputType"/> - <element name="GetHashDataInputResponse" type="tns:GetHashDataInputResponseType"/> - <element name="GetHashDataInputFault" type="tns:GetHashDataInputFaultType"/> - <complexType name="GetNextRequestType"> + <element name="SessionId" type="string"/> + <element name="GetNextRequest" type="tns:GetNextRequestType"/> + <element name="GetNextRequestResponse" type="tns:GetNextRequestResponseType"/> + <element name="GetHashDataInput" type="tns:GetHashDataInputType"/> + <element name="GetHashDataInputResponse" type="tns:GetHashDataInputResponseType"/> + <element name="GetHashDataInputFault" type="tns:GetHashDataInputFaultType"/> + <complexType name="GetNextRequestType"> + <!-- abstract Request/Response type not supported by JAX-WS 2.0 (jdk < 1.6.0_04) <sequence> <element name="Response" type="tns:ResponseType" minOccurs="0" maxOccurs="unbounded"/> + </sequence--> + <choice maxOccurs="unbounded"> + <element name="InfoboxReadResponse" type="tns:InfoboxReadResponseType"/> + <element name="SignResponse" type="tns:SignResponseType"/> + <element name="ErrorResponse" type="tns:ErrorResponseType"/> + </choice> + <attribute name="SessionId" type="string"/> + </complexType> + <complexType name="ResponseType" abstract="true" /> + <complexType name="InfoboxReadResponseType"> + <complexContent> + <extension base="tns:ResponseType"> + <sequence> + <element name="InfoboxValue" type="base64Binary"/> </sequence> - <attribute name="sessionId" type="string"/> - <!--choice maxOccurs="unbounded"> - <element name="InfoboxReadResponse" type="tns:InfoboxReadResponseType"/> - <element name="SignResponse" type="tns:SignResponseType"/> - <element name="ErrorResponse" type="tns:ErrorResponseType"/> - </choice--> - </complexType> - <complexType name="ResponseType" abstract="true"> - <attribute name="Id" type="ID"/> - </complexType> - <complexType name="InfoboxReadResponseType"> - <complexContent> - <extension base="tns:ResponseType"> - <sequence> - <element name="InfoboxValue" type="base64Binary"/> - </sequence> - </extension> - </complexContent> - </complexType> - <complexType name="SignResponseType"> - <complexContent> - <extension base="tns:ResponseType"> - <sequence> - <element name="SignatureValue" type="base64Binary"/> - </sequence> - </extension> - </complexContent> - </complexType> - <complexType name="ErrorResponseType"> - <complexContent> - <extension base="tns:ResponseType"> - <sequence> - <element name="ErrorCode" type="int"/> - <element name="ErrorMessage" type="string"/> - </sequence> - </extension> - </complexContent> - </complexType> - <complexType name="GetNextRequestResponseType"> + </extension> + </complexContent> + </complexType> + <complexType name="SignResponseType"> + <complexContent> + <extension base="tns:ResponseType"> <sequence> - <element name="Request" type="tns:RequestType" minOccurs="0" maxOccurs="unbounded"/> + <element name="SignatureValue" type="base64Binary"/> </sequence> - <attribute name="sessionId" type="string"/> - <!--choice maxOccurs="unbounded"> - <element name="InfoboxReadRequest" type="tns:InfoboxReadRequestType"/> - <element name="SignRequest" type="tns:SignRequestType"/> - <element name="QuitRequest" type="tns:QuitRequestType"/> - </choice--> - </complexType> - <complexType name="RequestType" abstract="true"/> - <complexType name="InfoboxReadRequestType"> - <complexContent> - <extension base="tns:RequestType"> - <sequence> - <!-- enumeration IdentityLink, CertifiedKeyPair --> - <element name="InfoboxIdentifier" type="string"/> - <element name="DomainIdentifier" type="string" minOccurs="0"/> - </sequence> - </extension> - </complexContent> - </complexType> - <complexType name="SignRequestType"> - <complexContent> - <extension base="tns:RequestType"> - <sequence> - <element name="KeyIdentifier" type="string"/> - <element name="SignedInfo" type="base64Binary"/> - </sequence> - </extension> - </complexContent> - </complexType> - <complexType name="QuitRequestType"> - <complexContent> - <extension base="tns:RequestType"/> - </complexContent> - </complexType> - <complexType name="GetHashDataInputType"> + </extension> + </complexContent> + </complexType> + <complexType name="ErrorResponseType"> + <complexContent> + <extension base="tns:ResponseType"> <sequence> - <element name="Reference" maxOccurs="unbounded"> - <complexType> - <attribute name="ID" type="string"/> - </complexType> - </element> + <element name="ErrorCode" type="int"/> + <element name="ErrorMessage" type="string"/> </sequence> - <attribute name="sessionId" type="string"/> - </complexType> - <complexType name="GetHashDataInputResponseType"> + </extension> + </complexContent> + </complexType> + <complexType name="GetNextRequestResponseType"> + <!-- abstract Request/Response type not supported by JAX-WS 2.0 (jdk < 1.6.0_04) <sequence> - <element name="Reference" maxOccurs="unbounded"> - <complexType> - <simpleContent> - <extension base="base64Binary"> - <attribute name="ID" type="string"/> - <attribute name="MimeType" type="string" use="optional"/> - <attribute name="Encoding" type="string" use="optional"/> - </extension> - </simpleContent> - </complexType> - </element> + <element name="Request" type="tns:RequestType" minOccurs="0" maxOccurs="unbounded"/> + </sequence--> + <choice maxOccurs="unbounded"> + <element name="InfoboxReadRequest" type="tns:InfoboxReadRequestType"/> + <element name="SignRequest" type="tns:SignRequestType"/> + <element name="QuitRequest" type="tns:QuitRequestType"/> + </choice> + <attribute name="SessionId" type="string"/> + </complexType> + <complexType name="RequestType" abstract="true"/> + <complexType name="InfoboxReadRequestType"> + <complexContent> + <extension base="tns:RequestType"> + <sequence> + <element name="InfoboxIdentifier"> + <simpleType> + <restriction base="string"> + <enumeration value="Certificates"/> + <enumeration value="IdentityLink"/> + <enumeration value="Mandates"/> + </restriction> + </simpleType> + </element> + <element name="DomainIdentifier" type="anyURI" minOccurs="0"/> </sequence> - <attribute name="sessionId" type="string"/> - </complexType> - <complexType name="GetHashDataInputFaultType"> + </extension> + </complexContent> + </complexType> + <complexType name="SignRequestType"> + <complexContent> + <extension base="tns:RequestType"> <sequence> - <element name="ErrorCode" type="int"/> - <element name="ErrorMessage" type="string"/> + <element name="KeyIdentifier"> + <simpleType> + <restriction base="string"> + <enumeration value="SecureSignatureKeypair"/> + <enumeration value="CertifiedKeypair"/> + </restriction> + </simpleType> + </element> + <element name="SignedInfo" type="base64Binary"/> </sequence> - </complexType> + </extension> + </complexContent> + </complexType> + <complexType name="QuitRequestType"> + <complexContent> + <extension base="tns:RequestType"/> + </complexContent> + </complexType> + <complexType name="GetHashDataInputType"> + <sequence> + <element name="Reference" maxOccurs="unbounded"> + <complexType> + <attribute name="ID" type="string"/> + </complexType> + </element> + </sequence> + <attribute name="SessionId" type="string"/> + </complexType> + <complexType name="GetHashDataInputResponseType"> + <sequence> + <element name="Reference" maxOccurs="unbounded"> + <complexType> + <simpleContent> + <extension base="base64Binary"> + <attribute name="ID" type="string"/> + <attribute name="MimeType" type="string" use="optional"/> + <attribute name="Encoding" type="string" use="optional"/> + </extension> + </simpleContent> + </complexType> + </element> + </sequence> + <attribute name="SessionId" type="string"/> + </complexType> + <complexType name="GetHashDataInputFaultType"> + <sequence> + <element name="ErrorCode" type="int"/> + <element name="ErrorMessage" type="string"/> + </sequence> + </complexType> </schema> |