DumpRestMessageUtils.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.rest;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import javax.mail.BodyPart;
- import org.openspcoop2.message.OpenSPCoop2RestMessage;
- import org.openspcoop2.message.OpenSPCoop2RestMimeMultipartMessage;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.exception.MessageException;
- import org.openspcoop2.message.utils.DumpAttachment;
- import org.openspcoop2.message.utils.DumpMessaggio;
- import org.openspcoop2.message.utils.DumpMessaggioConfig;
- import org.openspcoop2.message.utils.DumpMessaggioMultipartInfo;
- import org.openspcoop2.utils.dch.MailcapActivationReader;
- import org.openspcoop2.utils.mime.MimeMultipart;
- import org.openspcoop2.utils.transport.http.HttpConstants;
- /**
- * DumpRestMessageUtils
- *
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class DumpRestMessageUtils {
- public static DumpMessaggio dumpMessage(OpenSPCoop2RestMessage<?> msg, boolean dumpAllBodyParts) throws MessageException{
- return dumpMessage(msg, new DumpMessaggioConfig(), dumpAllBodyParts);
- }
- @SuppressWarnings("incomplete-switch")
- public static DumpMessaggio dumpMessage(OpenSPCoop2RestMessage<?> msg,
- DumpMessaggioConfig config,
- boolean dumpAllBodyParts) throws MessageException{
- try{
- DumpMessaggio dumpMessaggio = new DumpMessaggio();
- dumpMessaggio.setMessageType(msg.getMessageType());
-
- Map<String, List<String>> pTrasporto = null;
- if(msg.getTransportRequestContext()!=null) {
- if(msg.getTransportRequestContext().getHeaders()!=null &&
- msg.getTransportRequestContext().getHeaders().size()>0){
- if(config.isDumpHeaders()) {
- pTrasporto = msg.getTransportRequestContext().getHeaders();
- }
- }
- }
- else if(msg.getTransportResponseContext()!=null) {
- if(msg.getTransportResponseContext().getHeaders()!=null &&
- msg.getTransportResponseContext().getHeaders().size()>0){
- if(config.isDumpHeaders()) {
- pTrasporto = msg.getTransportResponseContext().getHeaders();
- }
- }
- }
- if(config.isDumpHeaders() && pTrasporto!=null) {
- Iterator<String> keys = pTrasporto.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- if(key!=null){
- List<String> values = pTrasporto.get(key);
- dumpMessaggio.getHeadersValues().put(key, values);
- }
- }
- }
-
- boolean hasContent = msg.hasContent();
- if(hasContent){
-
- dumpMessaggio.setContentType(msg.getContentType());
-
- // La registrazione su log dello stream completo non e' una funzionalita' simmetrica rispetto al dump fatto su soap
- if(config.isDumpBody()) {
- if(!MessageType.MIME_MULTIPART.equals(msg.getMessageType())) {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- switch (msg.getMessageType()) {
- case XML:
- bout.write(msg.castAsRestXml().getContentAsByteArray());
- break;
- case JSON:
- bout.write(msg.castAsRestJson().getContentAsByteArray());
- break;
- case BINARY:
- bout.write(msg.castAsRestBinary().getContent().getContent());
- break;
- default:
- throw new MessageException("MessageType ["+msg.getMessageType()+"] unsupported");
- }
- bout.flush();
- bout.close();
- dumpMessaggio.setBody(bout);
- }
- }
- }
-
- if((config.isDumpBody() || config.isDumpAttachments()) && hasContent &&
- MessageType.MIME_MULTIPART.equals(msg.getMessageType())){
- OpenSPCoop2RestMimeMultipartMessage msgMime = msg.castAsRestMimeMultipart();
- MultipartContent mc = msgMime.getContent();
- MimeMultipart mimeMultipart = (mc!=null) ? mc.getMimeMultipart() : null;
- if(mimeMultipart!=null) {
- for (int i = 0; i < mimeMultipart.countBodyParts(); i++) {
- BodyPart bodyPart = mimeMultipart.getBodyPart(i);
-
- if(i>0) {
- if(!config.isDumpAttachments()) {
- break;
- }
- }
-
- DumpMessaggioMultipartInfo multipartInfoBody = null;
- DumpAttachment dumpAttach = null;
- if(i==0 && config.isDumpBody()) {
-
- multipartInfoBody = new DumpMessaggioMultipartInfo();
-
- multipartInfoBody.setContentId(mimeMultipart.getContentID(bodyPart));
- multipartInfoBody.setContentLocation(mimeMultipart.getContentDisposition(bodyPart)); // Uso Disposition in REST, più opportuna
- multipartInfoBody.setContentType(bodyPart.getContentType());
-
- }
- else {
-
- dumpAttach = new DumpAttachment();
-
- dumpAttach.setContentId(mimeMultipart.getContentID(bodyPart));
- dumpAttach.setContentLocation(mimeMultipart.getContentDisposition(bodyPart)); // Uso Disposition in REST, più opportuna
- dumpAttach.setContentType(bodyPart.getContentType());
- }
-
- if(config.isDumpMultipartHeaders()) {
- Enumeration<?> en = bodyPart.getAllHeaders();
- if(en!=null) {
- while(en.hasMoreElements()) {
- Object keyO = en.nextElement();
- if(keyO instanceof String) {
- String key = (String) keyO;
- String [] values = bodyPart.getHeader(key);
- List<String> lValues = new ArrayList<>();
- if(values!=null && values.length>0) {
- for (int j = 0; j < values.length; j++) {
- lValues.add(values[j]);
- }
- }
- if(!lValues.isEmpty()) {
- if(multipartInfoBody!=null) {
- multipartInfoBody.getHeadersValues().put(key, lValues);
- }
- else {
- dumpAttach.getHeadersValues().put(key, lValues);
- }
- }
- }
- else if(keyO instanceof javax.mail.Header) {
- javax.mail.Header hdr = (javax.mail.Header) keyO;
- if(hdr!=null && hdr.getName()!=null) {
- if(multipartInfoBody!=null) {
- List<String> lValues = null;
- if(multipartInfoBody.getHeadersValues().containsKey(hdr.getName())) {
- lValues = multipartInfoBody.getHeadersValues().get(hdr.getName());
- }
- else {
- lValues = new ArrayList<>();
- multipartInfoBody.getHeadersValues().put(hdr.getName(), lValues);
- }
- lValues.add(hdr.getValue());
- }
- else {
- List<String> lValues = null;
- if(dumpAttach.getHeadersValues().containsKey(hdr.getName())) {
- lValues = dumpAttach.getHeadersValues().get(hdr.getName());
- }
- else {
- lValues = new ArrayList<>();
- dumpAttach.getHeadersValues().put(hdr.getName(), lValues);
- }
- lValues.add(hdr.getValue());
- }
- }
- }
- }
- }
- }
-
- ByteArrayOutputStream boutAttach = null;
- if(dumpAllBodyParts){
- boutAttach = (ByteArrayOutputStream) DumpRestMessageUtils._dumpBodyPart(msg, bodyPart, true);
- }else{
- Object o = _dumpBodyPart(msg, bodyPart, false);
- if(o == null){
- dumpAttach.setErrorContentNotSerializable("Contenuto attachment non recuperato??");
- }
- else if(o instanceof String){
- boutAttach = new ByteArrayOutputStream();
- boutAttach.write(((String)o).getBytes());
- boutAttach.flush();
- boutAttach.close();
- }
- else if(o instanceof java.io.ByteArrayOutputStream){
- boutAttach = (java.io.ByteArrayOutputStream) o;
- }
- else{
- dumpAttach.setErrorContentNotSerializable("Contenuto attachment non è visualizzabile, tipo: "+o.getClass().getName());
- }
- }
- if(multipartInfoBody!=null) {
- dumpMessaggio.setBody(boutAttach);
-
- dumpMessaggio.setMultipartInfoBody(multipartInfoBody);
- }
- else {
- dumpAttach.setContent(boutAttach);
-
- if(dumpMessaggio.getAttachments()==null) {
- dumpMessaggio.setAttachments(new ArrayList<>());
- }
- dumpMessaggio.getAttachments().add(dumpAttach);
- }
- }
- }
- }
-
- return dumpMessaggio;
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- public static String dumpMessageAsString(DumpMessaggio msg, boolean dumpAllAttachments) throws MessageException{
- return dumpMessageAsString(msg, new DumpMessaggioConfig(), dumpAllAttachments);
- }
- public static String dumpMessageAsString(DumpMessaggio msg,
- DumpMessaggioConfig config, boolean dumpAllAttachments) throws MessageException{
- try{
- StringBuilder out = new StringBuilder(msg.toString(config,dumpAllAttachments));
- return out.toString();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- public static String dumpMessageAsString(OpenSPCoop2RestMessage<?> msg,
- boolean dumpAllBodyParts) throws MessageException{
- return dumpMessageAsString(msg, new DumpMessaggioConfig(), dumpAllBodyParts);
- }
- public static String dumpMessageAsString(OpenSPCoop2RestMessage<?> msg,
- DumpMessaggioConfig config,
- boolean dumpAllBodyParts) throws MessageException{
- try{
- StringBuilder out = new StringBuilder();
-
- Map<String,List<String>> pTrasporto = null;
- if(msg.getTransportRequestContext()!=null) {
- if(msg.getTransportRequestContext().getHeaders()!=null &&
- msg.getTransportRequestContext().getHeaders().size()>0){
- if(config.isDumpHeaders()) {
- pTrasporto = msg.getTransportRequestContext().getHeaders();
- }
- }
- }
- else if(msg.getTransportResponseContext()!=null) {
- if(msg.getTransportResponseContext().getHeaders()!=null &&
- msg.getTransportResponseContext().getHeaders().size()>0){
- if(config.isDumpHeaders()) {
- pTrasporto = msg.getTransportResponseContext().getHeaders();
- }
- }
- }
- if(config.isDumpHeaders()) {
- out.append("------ Header di trasporto ------\n");
- if(pTrasporto!=null && pTrasporto.size()>0) {
- Iterator<String> keys = pTrasporto.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- if(key!=null){
- List<String> values = pTrasporto.get(key);
- if(values!=null && !values.isEmpty()) {
- for (String value : values) {
- out.append("- "+key+": "+value+"\n");
- }
- }
- }
- }
- }
- else {
- out.append("Non presenti\n");
- }
- }
-
- boolean hasContent = msg.hasContent();
- String contentString = "Body";
- String contentType = "";
- if(!hasContent){
- contentString = "Empty Body";
- }
- if(hasContent) {
- if(msg.getContentType()!=null) {
- contentType = " (ContentType: "+msg.getContentType()+")";
- }
- }
- if(config.isDumpBody()) {
- out.append("------ "+contentString+contentType+" ("+msg.getMessageType()+") ------\n");
- // Nel caso di multipart non il body e gli attachments devono essere gestiti nell'iterazione successiva
- // Se si usa il metodo 'msg.getContentAsString()' si ottiene lo stream completo
- if(!MessageType.MIME_MULTIPART.equals(msg.getMessageType())) {
-
- out.append("\n");
-
- if(hasContent) {
- out.append(msg.getContentAsString());
- }
- }
- }
-
- if((config.isDumpBody() || config.isDumpAttachments()) && hasContent && MessageType.MIME_MULTIPART.equals(msg.getMessageType())){
- OpenSPCoop2RestMimeMultipartMessage msgMime = msg.castAsRestMimeMultipart();
- MultipartContent mc = msgMime.getContent();
- MimeMultipart mimeMultipart = mc!=null ? mc.getMimeMultipart() : null;
- if(mimeMultipart!=null) {
- for (int i = 0; i < mimeMultipart.countBodyParts(); i++) {
-
- if(i>0) {
- if(!config.isDumpAttachments()) {
- break;
- }
- }
-
- BodyPart bodyPart = mimeMultipart.getBodyPart(i);
-
- if(i>0 || !config.isDumpBody()) {
- out.append("\n------ BodyPart-"+(i+1)+" ------\n");
- }
-
- out.append("\n*** MimePart Header ***\n");
- String contentIdBodyPart = mimeMultipart.getContentID(bodyPart);
- if(contentIdBodyPart!=null) {
- out.append("- "+HttpConstants.CONTENT_ID+": "+contentIdBodyPart+"\n");
- }
- String contentLocationBodyPart = mimeMultipart.getContentDisposition(bodyPart); // Uso Disposition in REST, più opportuna
- if(contentLocationBodyPart!=null) {
- out.append("- "+HttpConstants.CONTENT_DISPOSITION+": "+contentLocationBodyPart+"\n");
- }
- if(bodyPart.getContentType()!=null) {
- out.append("- "+HttpConstants.CONTENT_TYPE+": "+bodyPart.getContentType()+"\n");
- }
- if(config.isDumpMultipartHeaders()) {
- Enumeration<?> en = bodyPart.getAllHeaders();
- if(en!=null) {
- while(en.hasMoreElements()) {
- Object keyO = en.nextElement();
- if(keyO instanceof String) {
- String key = (String) keyO;
- if(HttpConstants.CONTENT_ID.equalsIgnoreCase(key) ||
- HttpConstants.CONTENT_DISPOSITION.equalsIgnoreCase(key) ||
- HttpConstants.CONTENT_TYPE.equalsIgnoreCase(key)) {
- continue;
- }
- String [] values = bodyPart.getHeader(key);
- if(values!=null && values.length>0) {
- for (int j = 0; j < values.length; j++) {
- out.append("- "+key+": "+values[j]+"\n");
- }
- }
- }
- }
- }
- }
- out.append("\n");
-
- if(dumpAllBodyParts){
- out.append(DumpRestMessageUtils.dumpBodyPart(msg, bodyPart));
- }else{
- //Object o = ap.getContent(); NON FUNZIONA CON TOMCAT
- Object o = bodyPart.getDataHandler().getContent();
- //System.out.println("["+o.getClass().getName()+"])"+ap.getContentType()+"(");
- if(o instanceof String){
- out.append((String)o);
- }else{
- out.append("Contenuto attachments non è visualizzabile, tipo: "+o.getClass().getName());
- }
- }
- }
- }
- }
-
- return out.toString();
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
-
- public static String dumpBodyPart(OpenSPCoop2RestMessage<?> msg,BodyPart bodyPart) throws MessageException{
- Object o = _dumpBodyPart(msg, bodyPart, false);
- // Metodo sopra non torna mai null, segnalato da sonarqube
- /*if(o == null){
- throw new MessageException("Dump error (return null reference)");
- }*/
- if(o instanceof String){
- return (String) o;
- }
- else if(o instanceof java.io.ByteArrayOutputStream){
- java.io.ByteArrayOutputStream bout = null;
- try{
- bout = (java.io.ByteArrayOutputStream) o;
- return bout.toString();
- }finally{
- try{
- if(bout!=null){
- bout.close();
- }
- }catch(Exception eClose){
- // close
- }
- }
- }
- else{
- throw new MessageException("Dump error (return type "+o.getClass().getName()+" unknown)");
- }
- }
- public static byte[] dumpBodyPartAsByteArray(OpenSPCoop2RestMessage<?> msg,BodyPart bodyPart) throws MessageException{
- Object o = _dumpBodyPart(msg, bodyPart, false);
- // Metodo sopra non torna mai null, segnalato da sonarqube
- /*if(o == null){
- throw new MessageException("Dump error (return null reference)");
- }*/
- if(o instanceof String){
- return ((String) o).getBytes();
- }
- else if(o instanceof java.io.ByteArrayOutputStream){
- java.io.ByteArrayOutputStream bout = null;
- try{
- bout = (java.io.ByteArrayOutputStream) o;
- return bout.toByteArray();
- }finally{
- try{
- if(bout!=null){
- bout.close();
- }
- }catch(Exception eClose){
- // close
- }
- }
- }
- else{
- throw new MessageException("Dump error (return type "+o.getClass().getName()+" unknown)");
- }
- }
-
- private static boolean convert = false;
- public static void setConvert(boolean convert) {
- DumpRestMessageUtils.convert = convert;
- }
- private static Object _dumpBodyPart(OpenSPCoop2RestMessage<?> msg,BodyPart bodyPart, boolean forceReturnAsByteArrayOutputStream) throws MessageException{
- try{
- java.io.ByteArrayOutputStream bout = null;
- //Object o = ap.getContent(); NON FUNZIONA CON TOMCAT
- //java.io.InputStream inputDH = dh.getInputStream(); NON FUNZIONA CON JBOSS7 e JAVA7 e imbustamentoSOAP con GestioneManifest e rootElementMaggioreUno (tipo: application/octet-stream)
- Object o = bodyPart.getDataHandler().getContent();
- String s = null;
- if(o!=null){
- if(o instanceof byte[]){
- byte[] b = (byte[]) o;
- bout = new ByteArrayOutputStream();
- bout.write(b);
- bout.flush();
- bout.close();
- }
- else if(o instanceof InputStream){
- InputStream is = (InputStream) o;
- bout = new java.io.ByteArrayOutputStream();
- byte [] readB = new byte[8192];
- int readByte = 0;
- while((readByte = is.read(readB))!= -1)
- bout.write(readB,0,readByte);
- is.close();
- bout.flush();
- bout.close();
- }
- else if(o instanceof String){
- s = (String) o;
- bout = new ByteArrayOutputStream();
- bout.write(s.getBytes());
- bout.flush();
- bout.close();
- }
- else{
- // Provo con codiceOriginale ma in jboss non funziona sempre
- javax.activation.DataHandler dh= bodyPart.getDataHandler();
- java.io.InputStream inputDH = dh.getInputStream();
- 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();
- }
- }
- else{
- // Provo con codiceOriginale ma in jboss non funziona sempre
- javax.activation.DataHandler dh= bodyPart.getDataHandler();
- java.io.InputStream inputDH = dh.getInputStream();
- 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();
- }
- // Per non perdere quanto letto
- // in rest con le api utilizzate non sembra necessario ricostruirlo come si fa in soap.
- // anche il caso del tunnel soap non esiste.
- if(convert && MailcapActivationReader.existsDataContentHandler(bodyPart.getContentType())){
- if(bodyPart.getContentType()!=null && bodyPart.getContentType().startsWith(HttpConstants.CONTENT_TYPE_PLAIN)){
- processContentTypeTextPlain(s, bodyPart, bout);
- }
- else{
- //bodyPart.setDataHandler(new javax.activation.DataHandler(bout.toByteArray(),bodyPart.getContentType()));
- // Nel caso sia xml si ottiene il seguente errore:
- //Invalid Object type = class [B. XmlDCH can only convert DataSource or Source to XML.
- // Si potrebbe vederlo di gestire come e' stato fatto per il rebuild dell'attachment su SOAP.
- }
- }
- if(s!=null){
- if(forceReturnAsByteArrayOutputStream) {
- return bout;
- }
- else {
- return s;
- }
- }else{
- return bout;
- }
- }catch(Exception e){
- throw new MessageException(e.getMessage(),e);
- }
- }
- private static void processContentTypeTextPlain(String s, BodyPart bodyPart, java.io.ByteArrayOutputStream bout) throws Exception {
- // Se siamo in text plain non devo fare nulla. Comunque non l'ho perso.
- // Se uso il codice sotto, poi si perde il content-type, non viene serializzato
- /*
- if(s!=null){
- bodyPart.setDataHandler(new javax.activation.DataHandler(s,bodyPart.getContentType()));
- //bodyPart.setContent(s,bodyPart.getContentType());
- //bodyPart.setText(s);
- }
- else{
- //bodyPart.setDataHandler(new javax.activation.DataHandler(bout.toByteArray(),bodyPart.getContentType()));
- // devo comunque impostare una stringa nel caso di text/plain, senno ottengo un errore:
- // "text/plain" DataContentHandler requires String object, was given object of type class [B
- bodyPart.setDataHandler(new javax.activation.DataHandler(bout.toString(),bodyPart.getContentType()));
- //bodyPart.setContent(bout.toString(),bodyPart.getContentType());
- //bodyPart.setText(bout.toString());
- }*/
- }
-
- }