TunnelSoapUtils.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.message.soap;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.List;
- import javax.activation.DataHandler;
- import javax.mail.util.ByteArrayDataSource;
- import javax.xml.namespace.QName;
- import javax.xml.soap.AttachmentPart;
- import javax.xml.soap.SOAPBody;
- import javax.xml.soap.SOAPElement;
- import javax.xml.soap.SOAPEnvelope;
- import javax.xml.soap.SOAPFault;
- import javax.xml.transform.Source;
- import javax.xml.transform.dom.DOMSource;
- import org.apache.commons.io.output.CountingOutputStream;
- import org.openspcoop2.message.OpenSPCoop2DataContentHandler;
- import org.openspcoop2.message.OpenSPCoop2DataContentHandlerInputStream;
- import org.openspcoop2.message.OpenSPCoop2Message;
- import org.openspcoop2.message.OpenSPCoop2MessageFactory;
- import org.openspcoop2.message.OpenSPCoop2SoapMessage;
- import org.openspcoop2.message.constants.Costanti;
- import org.openspcoop2.message.constants.MessageRole;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.constants.ServiceBinding;
- import org.openspcoop2.message.exception.MessageException;
- import org.openspcoop2.message.exception.MessageNotSupportedException;
- import org.openspcoop2.message.xml.MessageXMLUtils;
- import org.openspcoop2.utils.CopyStream;
- import org.openspcoop2.utils.UtilsException;
- import org.openspcoop2.utils.transport.http.HttpConstants;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- /**
- * Libreria contenente metodi utili per la gestione della busta Soap.
- *
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class TunnelSoapUtils {
-
-
-
-
- /* ******** ALLEGA BODY ******** */
-
- public static void allegaBody(OpenSPCoop2Message message, String ns) throws MessageException{
-
- if(ServiceBinding.SOAP.equals(message.getServiceBinding())==false){
- throw new MessageException("Funzionalita 'ScartaBody' valida solamente per Service Binding SOAP");
- }
- OpenSPCoop2SoapMessage soapMessage = message.castAsSoap();
-
- try{
-
- // E' permesso SOLO per messaggi senza attachment
- if (soapMessage.countAttachments() > 0) {
- throw new MessageException("La funzionalita' non e' permessa per messaggi SOAP With Attachments");
- }
-
- SOAPBody body = soapMessage.getSOAPPart().getEnvelope().getBody();
- if(body==null){
- throw new Exception("Body non presente");
- }
- if(body.hasFault()){
- throw new Exception("Body contenente un SOAPFault");
- }
- List<Node> listNode = SoapUtils.getNotEmptyChildNodes(message.getFactory(), body, false);
- boolean bodyWithMultiRootElement = false;
- if(listNode!=null && listNode.size()>1){
- //System.out.println("MULTI ELEMENT: "+listNode.size());
- bodyWithMultiRootElement = true;
- }
- byte[] bodySbustato = TunnelSoapUtils.sbustamentoSOAPEnvelope(message.getFactory(), soapMessage.getSOAPPart().getEnvelope());
- AttachmentPart ap = null;
- if(bodyWithMultiRootElement){
- //System.out.println("OCTECT");
- org.openspcoop2.utils.dch.InputStreamDataSource isSource = new org.openspcoop2.utils.dch.InputStreamDataSource("MultiRootElement",
- HttpConstants.CONTENT_TYPE_APPLICATION_OCTET_STREAM, bodySbustato);
- ap = soapMessage.createAttachmentPart(new DataHandler(isSource));
- }else{
- //System.out.println("XML");
- Element e = null;
- try{
- e = MessageXMLUtils.getInstance(message.getFactory()).newElement(bodySbustato);
- Source streamSource = new DOMSource(e);
- ap = soapMessage.createAttachmentPart();
- ap.setContent(streamSource, HttpConstants.CONTENT_TYPE_TEXT_XML);
- }catch(Exception eParse){
- org.openspcoop2.utils.dch.InputStreamDataSource isSource = new org.openspcoop2.utils.dch.InputStreamDataSource("BodyNotParsable",
- HttpConstants.CONTENT_TYPE_APPLICATION_OCTET_STREAM, bodySbustato);
- ap = soapMessage.createAttachmentPart(new DataHandler(isSource));
- }
- }
- ap.setContentId(soapMessage.createContentID(ns));
- soapMessage.addAttachmentPart(ap);
-
- // Aggiungo contentID all'attachmet contenente la SOAPEnvelope
- // Necessario per essere compatibile con alcune implementazioni, es axis14,
- // altrimenti essendo il ContentType senza Start element, Axis14 utilizza come xml per costruire la SOAPEnvelope
- // il primo attachment nel messaggio MIME che contiene il ContentID.
- soapMessage.getSOAPPart().addMimeHeader(HttpConstants.CONTENT_ID, soapMessage.createContentID(ns));
-
- // Rimuovo contenuti del body
- soapMessage.getSOAPBody().removeContents();
-
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
-
-
-
-
-
-
- /* ******** S B U S T A M E N T O M E S S A G G I ******** */
- public static boolean isTunnelOpenSPCoopSoap(OpenSPCoop2SoapMessage message) throws MessageException, MessageNotSupportedException{
- return isTunnelOpenSPCoopSoap(message.getFactory(), message.getSOAPBody());
- }
- public static boolean isTunnelOpenSPCoopSoap(OpenSPCoop2MessageFactory messageFactory, SOAPBody body){
- List<Node> bodyChildren = SoapUtils.getNotEmptyChildNodes(messageFactory, body);
- if(body!=null &&
- bodyChildren.size() > 0 &&
- bodyChildren.get(0)!=null &&
- "SOAPTunnel".equals(bodyChildren.get(0).getLocalName()) &&
- "http://www.govway.org/out/xml2soap".equals(bodyChildren.get(0).getNamespaceURI()) &&
- org.openspcoop2.utils.Costanti.OPENSPCOOP2.equals(bodyChildren.get(0).getPrefix())){
- return true;
- }else{
- return false;
- }
- }
-
- public static String getContentTypeTunnelOpenSPCoopSoap(SOAPBody body) throws MessageException {
- if(body!=null && body.hasChildNodes()){
- return ((SOAPElement)body.getChildElements().next()).getValue();
- }else{
- throw new MessageException("Body non presente");
- }
- }
-
- public static void sbustamentoMessaggio(OpenSPCoop2Message msgParam,OutputStream streamParam) throws MessageException, MessageNotSupportedException{
- if(!MessageType.SOAP_11.equals(msgParam.getMessageType()) && !MessageType.SOAP_12.equals(msgParam.getMessageType())){
- throw MessageNotSupportedException.newMessageNotSupportedException(msgParam.getMessageType());
- }
- OpenSPCoop2SoapMessage msg = msgParam.castAsSoap();
-
- CountingOutputStream cout = null;
- try{
-
- // Nota: non viene usato DocumentToStream, poiche' altrimenti viene prodotto l'<?xml ... />
- cout = new CountingOutputStream(streamParam);
-
- // Sbustamento Senza Attachments
- if(msg.countAttachments() == 0){
- SOAPBody bd = msg.getSOAPBody();
- if(bd.hasFault()){
- SOAPFault fault = bd.getFault();
- cout.write(msg.getAsByte(fault, true));
- }else{
- java.util.Iterator<?> it = bd.getChildElements();
- while(it.hasNext()){
- Object bodyObject = it.next();
- if(!(bodyObject instanceof SOAPElement)) continue;
- SOAPElement bodyElement = (SOAPElement) bodyObject;
- cout.write(msg.getAsByte(bodyElement, true));
- }
- }
- }
- // Sbustamento Con Attachmnets
- else{
- SOAPBody body = msg.getSOAPBody();
- if(TunnelSoapUtils.isTunnelOpenSPCoopSoap(msgParam.getFactory(), body)){
- // Sbustamento OpenSPCoop
- AttachmentPart ap = (AttachmentPart) msg.getAttachments().next();
- Object o = ap.getContent();
- //DataHandler dh = ap.getDataHandler();
- //InputStream inputDH = (InputStream) dh.getContent();
- InputStream inputDH = null;
- if(o instanceof OpenSPCoop2DataContentHandlerInputStream){
- inputDH = (OpenSPCoop2DataContentHandlerInputStream) o;
- }
- else if(o instanceof InputStream){
- inputDH = (InputStream) OpenSPCoop2DataContentHandler.getContent((InputStream)o);
- }
- else if(o instanceof byte[]){
- inputDH = (InputStream) OpenSPCoop2DataContentHandler.getContent(new ByteArrayInputStream((byte[]) o));
- } else {
- throw new Exception("Tipo non gestito: "+o.getClass().getName());
- }
- java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
- byte [] readB = new byte[8192];
- int readByte = 0;
- while((readByte = inputDH.read(readB))!= -1)
- bout.write(readB,0,readByte);
- inputDH.close();
- bout.close();
- cout.write(bout.toByteArray());
- }else{
-
- ByteArrayOutputStream sbustamentoAttachments = new ByteArrayOutputStream();
- msg.writeTo(sbustamentoAttachments, true);
- String msgString = sbustamentoAttachments.toString();
- byte [] msgByte = sbustamentoAttachments.toByteArray();
- String soapEnvelopeStart = "<" + msg.getSOAPPart().getEnvelope().getPrefix() + ":" + msg.getSOAPPart().getEnvelope().getLocalName();
- String xmlTagDecode = "<?xml";
- String soapEnvelopeStop = "</" + msg.getSOAPPart().getEnvelope().getPrefix() + ":" + msg.getSOAPPart().getEnvelope().getLocalName()+">";
- //System.out.println("SoapStart: "+soapEnvelopeStart);
- //System.out.println("SoapStartIndexOf: "+msgString.indexOf(soapEnvelopeStart));
- //System.out.println("SoapStop: "+soapEnvelopeStop);
- //System.out.println("SoapStopIndexOf: "+msgString.indexOf(soapEnvelopeStop));
- // Prima parte del Multipart
- if(msgString.indexOf(xmlTagDecode)!=-1){
- cout.write(msgByte,0,msgString.indexOf(xmlTagDecode));
- }else{
- cout.write(msgByte,0,msgString.indexOf(soapEnvelopeStart));
- }
- // Body
- SOAPBody bd = msg.getSOAPBody();
- if(bd.hasFault()){
- SOAPFault fault = bd.getFault();
- cout.write(msg.getAsByte(fault, true));
- }else{
- cout.write(msg.getAsByte(msg.getFirstChildElement(bd), true));
- }
- // Resto degli attachments
- int indexOf = msgString.indexOf(soapEnvelopeStop)+soapEnvelopeStop.length();
- cout.write(msgByte,indexOf,msgByte.length - indexOf);
- }
- }
-
- // Aggiorno le lunghezze del messaggio (normalmente le aggiorna la writeTo)
- msg.updateIncomingMessageContentLength();
- // Come dimensione di uscita utilizzo i bytes che produco
- cout.flush();
- msg.updateOutgoingMessageContentLength(cout.getByteCount());
-
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch (Exception e){
- throw new MessageException("Sbustamento msg_inputStream non riuscito: "+e.getMessage(),e);
- }finally{
- try{
- if(cout!=null)
- cout.close();
- }catch(Exception e){
- // close
- }
- }
-
-
- }
-
- /**
- * Ritorna i bytes del contenuto del messaggio Soap passato come parametro
- *
- * @param msg Messaggio Soap da sbustare
- * @return byte del contenuto (sbustati dalla SoapEnvelope).
- *
- */
- public static byte[] sbustamentoMessaggio(OpenSPCoop2Message msg) throws MessageException, MessageNotSupportedException{
- ByteArrayOutputStream bodySbustato = new ByteArrayOutputStream();
- try{
- TunnelSoapUtils.sbustamentoMessaggio(msg,bodySbustato);
- return bodySbustato.toByteArray();
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch(Exception e){
- try{
- if(bodySbustato!=null)
- bodySbustato.close();
- }catch(Exception eis){
- // close
- }
- throw new MessageException("Sbustamento msg non riuscito: "+e.getMessage(),e);
- }
- }
- /**
- * Ritorna i bytes del contenuto del messaggio Soap passato come parametro
- *
- * @param env SoapEnvelope da sbustare
- *
- */
- public static byte[] sbustamentoSOAPEnvelope(OpenSPCoop2MessageFactory messageFactory, SOAPEnvelope env) throws MessageException, MessageNotSupportedException{
- return sbustamentoSOAPEnvelope(messageFactory, env, true);
- }
- public static byte[] sbustamentoSOAPEnvelope(OpenSPCoop2MessageFactory messageFactory, SOAPEnvelope env, boolean consume) throws MessageException, MessageNotSupportedException{
- ByteArrayOutputStream bout = null;
-
- try{
- SOAPBody bd = env.getBody();
- byte[] body = null;
- if(bd.hasFault()){
- SOAPFault fault = bd.getFault();
- body = OpenSPCoop2MessageFactory.getAsByte(messageFactory, fault, consume);
- }else{
- bout = new ByteArrayOutputStream();
- java.util.Iterator<?> it = bd.getChildElements();
- while(it.hasNext()){
- Object bodyElementObj = it.next();
- if(!(bodyElementObj instanceof SOAPElement)){
- continue;
- }
- SOAPElement bodyElement = (SOAPElement) bodyElementObj;
- bout.write(OpenSPCoop2MessageFactory.getAsByte(messageFactory, bodyElement, consume));
- }
- bout.flush();
- bout.close();
- body = bout.toByteArray();
- bout = null;
- }
- return body;
- }
- catch (Exception e){
- throw new MessageException("Sbustamento SoapEnvelope non riuscito: "+e.getMessage(),e);
- }
- finally{
- try{
- if(bout!=null)
- bout.close();
- }catch(Exception eis){
- // close
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
- /* ******** I M B U S T A M E N T O M E S S A G G I ******** */
- /**
- * Ritorna un messaggio che contiene i bytes in un attachment
- *
- * @param inputBody contenuto.
- * @return msg Messaggio Soap imbustato
- *
- */
- public static OpenSPCoop2Message imbustamentoMessaggioConAttachment(OpenSPCoop2MessageFactory messageFactory, MessageType messageType, MessageRole messageRole,
- InputStream inputBody,String tipoAttachment,boolean buildAsDataHandler,String contentTypeMessaggioOriginale, String ns) throws MessageException, MessageNotSupportedException{
-
- if(!MessageType.SOAP_11.equals(messageType) && !MessageType.SOAP_12.equals(messageType)){
- throw MessageNotSupportedException.newMessageNotSupportedException(messageType);
- }
- try{
- // Metto inputBody in un byte[] proprio perche' il ByteArrayInputStream non deve essere chiuso.
- java.io.ByteArrayOutputStream byteBuffer = new java.io.ByteArrayOutputStream();
- // byte [] readB = new byte[Utilities.DIMENSIONE_BUFFER];
- // int readByte = 0;
- // while((readByte = inputBody.read(readB))!= -1){
- // byteBuffer.write(readB,0,readByte);
- // }
- CopyStream.copy(inputBody, byteBuffer);
- inputBody.close();
- if(byteBuffer.size()==0){
- throw new MessageException("Contenuto da imbustare non presente");
- }
-
- return TunnelSoapUtils.imbustamentoMessaggioConAttachment(messageFactory, messageType, messageRole, byteBuffer.toByteArray(), tipoAttachment, buildAsDataHandler, contentTypeMessaggioOriginale, ns);
-
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch (Exception e){
- throw new MessageException("Imbustamento msgConAttachment_inputStream non riuscito: "+e.getMessage(),e);
- }
- }
-
- public static OpenSPCoop2Message imbustamentoMessaggioConAttachment(OpenSPCoop2MessageFactory messageFactory, MessageType messageType, MessageRole messageRole,
- byte [] inputBody,String tipoAttachment,boolean buildAsDataHandler,String contentTypeMessaggioOriginale, String ns) throws MessageException, MessageNotSupportedException{
-
- if(!MessageType.SOAP_11.equals(messageType) && !MessageType.SOAP_12.equals(messageType)){
- throw MessageNotSupportedException.newMessageNotSupportedException(messageType);
- }
- OpenSPCoop2Message msg = null;
- try{
- msg = messageFactory.createEmptyMessage(messageType,messageRole);
- return imbustamentoMessaggioConAttachment(msg, inputBody, tipoAttachment, buildAsDataHandler, contentTypeMessaggioOriginale, ns);
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch (Exception e){
- throw new MessageException("Imbustamento msgConAttachment_inputStream non riuscito: "+e.getMessage(),e);
- }
- }
- public static OpenSPCoop2Message imbustamentoMessaggioConAttachment(OpenSPCoop2Message msgParam,
- byte [] inputBody,String tipoAttachment,boolean buildAsDataHandler,String contentTypeMessaggioOriginale, String ns) throws MessageException, MessageNotSupportedException{
-
- if(!MessageType.SOAP_11.equals(msgParam.getMessageType()) && !MessageType.SOAP_12.equals(msgParam.getMessageType())){
- throw MessageNotSupportedException.newMessageNotSupportedException(msgParam.getMessageType());
- }
- OpenSPCoop2SoapMessage msg = msgParam.castAsSoap();
- try{
-
- if(inputBody==null || inputBody.length<=0){
- throw new UtilsException("Contenuto da imbustare non presente");
- }
-
- SOAPBody soapBody = msg.getSOAPBody();
- QName name = null;
- if(HttpConstants.CONTENT_TYPE_OPENSPCOOP2_TUNNEL_SOAP.equals(tipoAttachment)){
- name = new QName(Costanti.SOAP_TUNNEL_NAMESPACE,
- Costanti.SOAP_TUNNEL_ATTACHMENT_ELEMENT_OPENSPCOOP2_TYPE,org.openspcoop2.utils.Costanti.OPENSPCOOP2);
- }else{
- name = new QName(Costanti.SOAP_TUNNEL_NAMESPACE,
- Costanti.SOAP_TUNNEL_ATTACHMENT_ELEMENT,org.openspcoop2.utils.Costanti.OPENSPCOOP2);
- }
- SOAPElement bodyElement = soapBody.addChildElement(name);
-
- if(HttpConstants.CONTENT_TYPE_OPENSPCOOP2_TUNNEL_SOAP.equals(tipoAttachment)){
- if(contentTypeMessaggioOriginale==null){
- throw new Exception("ContentType messaggio per cui applicare il tunnel non definito?");
- }else{
- bodyElement.setValue(contentTypeMessaggioOriginale);
- }
- }
- AttachmentPart ap = msg.createAttachmentPart();
-
- if(buildAsDataHandler){
- ap.setDataHandler(new DataHandler(new ByteArrayDataSource(inputBody,tipoAttachment)));
- TunnelSoapUtils.saveAttachmentOpenSPCoop(ap);
- }else{
- ap.setRawContentBytes(inputBody,0,inputBody.length,tipoAttachment);
- //ap.setContent(new ByteArrayInputStream(inputBody),tipoAttachment);
- }
- ap.setContentId(msg.createContentID(ns));
- msg.addAttachmentPart(ap);
- //System.out.println("debug - start");
- //msg.writeTo(System.out);
- //System.out.println(msg.getAsString(msg.getSOAPPart().getEnvelope()));
- //System.out.println("debug - stop");
- return msg;
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch (Exception e){
- throw new MessageException("Imbustamento msgConAttachment_inputStream non riuscito: "+e.getMessage(),e);
- }
- }
- private static void saveAttachmentOpenSPCoop(AttachmentPart ap) throws MessageException{
- try{
- // FIX: se non c'e' il dump abilitato serve il codice seguente per forzare il salvataggio, in caso si passi da DataHandler.
- javax.activation.DataHandler dh= ap.getDataHandler();
- java.io.InputStream inputDH = dh.getInputStream();
- java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
- byte [] readB = new byte[8192];
- int readByte = 0;
- while((readByte = inputDH.read(readB))!= -1)
- bout.write(readB,0,readByte);
- inputDH.close();
- bout.flush();
- bout.close();
- ap.setDataHandler(new DataHandler(bout.toByteArray(),ap.getContentType()));
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- /**
- * Ritorna un messaggio che contiene i byte in un attachment
- *
- * @param body byte del contenuto.
- * @return msg Messaggio Soap imbustato
- *
- */
- public static OpenSPCoop2Message imbustamentoMessaggioConAttachment(OpenSPCoop2MessageFactory messageFactory, MessageType messageType, MessageRole messageRole, byte [] body, String contentTypeMessaggioOriginale, String ns) throws MessageException, MessageNotSupportedException{
-
- if(!MessageType.SOAP_11.equals(messageType) && !MessageType.SOAP_12.equals(messageType)){
- throw MessageNotSupportedException.newMessageNotSupportedException(messageType);
- }
-
- OpenSPCoop2Message risposta = null;
- try{
- risposta = TunnelSoapUtils.imbustamentoMessaggioConAttachment(messageFactory, messageType, messageRole, body,HttpConstants.CONTENT_TYPE_PLAIN,false, contentTypeMessaggioOriginale, ns);
- return risposta;
- }
- catch (MessageException e){
- throw e;
- }
- catch (MessageNotSupportedException e){
- throw e;
- }
- catch (Exception e){
- throw new MessageException("Imbustamento msgConAttachment non riuscito: "+e.getMessage(),e);
- }
- }
-
-
- }