2016-06-09 10 views
1

Ich weiß, dass Mule große Unterstützung für Gzip-Komprimierung von Daten mit dem Element hat. Doch jetzt der Client ZIP-Komprimierung will, da hat die Datei auf einem FTP als ZIP-komprimierte Datei platziert werden :(Mule Zip-Datei und senden gezippte Datei in Richtung FTP-Server

ich auf Schwierigkeiten stoßen in mule mit folgendem Szenario aus:

ich eine Spring-Bean erstellt, wo eine Datei kommt . ich möchte in diese Datei mit der ZipOutputStream Klasse komprimieren und zu unserem ftp passieren

Dies ist mein Flow-Konfiguration:.

<flow name="testFlow" initialState="stopped"> 
    <file:inbound-endpoint path="${home.dir}/out" moveToDirectory="${hip.dir}/out/hist" fileAge="10000" responseTimeout="10000" connector-ref="input"/> 
    <component> 
     <spring-object bean="zipCompressor"/> 
    </component> 
    <set-variable value="#[message.inboundProperties.originalFilename]" variableName="originalFilename" /> 
    <ftp:outbound-endpoint host="${ftp.host}" port="${ftp.port}" user="${ftp.username}" password="${ftp.password}" path="${ftp.root.out}" outputPattern="#[flowVars['originalFilename']].zip" /> 
</flow> 

Dies ist der Code meiner zipCompressor:

@Component 
public class ZipCompressor implements Callable { 

    private static final Logger LOG = LogManager.getLogger(ZipCompressor.class.getName()); 

    @Override 
    @Transactional 
    public Object onCall(MuleEventContext eventContext) throws Exception { 

     if (eventContext.getMessage().getPayload() instanceof File) { 
      final File srcFile = (File) eventContext.getMessage().getPayload(); 
      final String fileName = srcFile.getName(); 
      final File zipFile = new File(fileName + ".zip"); 

      try { 

       // create byte buffer 
       byte[] buffer = new byte[1024]; 
       FileOutputStream fos = new FileOutputStream(zipFile); 
       ZipOutputStream zos = new ZipOutputStream(fos); 
       FileInputStream fis = new FileInputStream(srcFile); 
       // begin writing a new ZIP entry, positions the stream to the start of the entry data 
       zos.putNextEntry(new ZipEntry(srcFile.getName())); 
       int length; 
       while ((length = fis.read(buffer)) > 0) { 
        zos.write(buffer, 0, length); 
       } 
       zos.closeEntry(); 
       // close the InputStream 
       fis.close(); 
       // close the ZipOutputStream 
       zos.close(); 
      } 
      catch (IOException ioe) { 
       LOG.error("Error creating zip file" + ioe); 
      } 
      eventContext.getMessage().setPayload(zipFile); 
     } 
     return eventContext.getMessage(); 
    } 
} 

Ich schrieb einen Komponententest und die Kompression funktioniert gut. Eine Datei wird zwar mit dem richtigen Namen an den FTP-Server übertragen, aber die ZIP-Datei ist ungültig, und wenn sie in NotePad ++ geöffnet wird, enthält sie nur den ursprünglichen Dateinamen.

Ich denke, ich mache etwas falsch damit, die Zip-Datei zurück in den Mule-Flow zu geben, aber ich stecke im Moment fest, also würde jede Hilfe sehr geschätzt!

+1

lief ich eine Kopie des Strömungs- und zipCompressor. Ich bekomme auch eine Datei, aber die Datei wird nie komprimiert. Es ist in seinem ursprünglichen Zustand. – tbriscoe

Antwort

2

Ich habe den Transformator für dieses

benutzte es als

<custom-transformer class="com.test.transformer.ZipTransformer" doc:name="file zip transformer"/> 

package com.test.transformer; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipOutputStream; 

import org.apache.commons.io.IOUtils; 
import org.apache.commons.io.output.ByteArrayOutputStream; 
import org.mule.api.MuleMessage; 
import org.mule.api.transformer.TransformerException; 
import org.mule.transformer.AbstractMessageTransformer; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class ZipTransformer 
    extends AbstractMessageTransformer 
{ 
    private static final Logger log = LoggerFactory.getLogger(ZipTransformer.class); 
    public static final int DEFAULT_BUFFER_SIZE = 32768; 
    public static byte[] MAGIC = { 'P', 'K', 0x3, 0x4 }; 

    public ZipTransformer() 
    { 
    registerSourceType(InputStream.class); 
    registerSourceType(byte[].class); 
    } 

    public Object transformMessage(MuleMessage message, String outputEncoding) 
    throws TransformerException 
    { 
    Object payload = message.getPayload(); 
    try{ 
     byte[] data; 
     if (payload instanceof byte[]) 
     { 
      data = (byte[]) payload; 
     } 
     else if (payload instanceof InputStream) { 
      data = IOUtils.toByteArray((InputStream)payload); 
     } 
     else if (payload instanceof String) 
     { 
      data = ((String) payload).getBytes(outputEncoding); 
     } 
     else 
     { 
      data = muleContext.getObjectSerializer().serialize(payload); 
     } 
     return compressByteArray(data); 
    }catch (Exception ioex) 
    { 
     throw new TransformerException(this, ioex); 
    } 
    } 

    public Object compressByteArray(byte[] bytes) throws IOException 
    { 
     if (bytes == null || isCompressed(bytes)) 
     { 
      if (logger.isDebugEnabled()) 
      { 
       logger.debug("Data already compressed; doing nothing"); 
      } 
      return bytes; 
     } 

     if (logger.isDebugEnabled()) 
     { 
      logger.debug("Compressing message of size: " + bytes.length); 
     } 

     ByteArrayOutputStream baos = null; 
     ZipOutputStream zos = null; 

     try 
     { 
      baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE); 
      zos = new ZipOutputStream(baos); 
      zos.putNextEntry(new ZipEntry("test.txt")); 
      zos.write(bytes, 0, bytes.length); 
      zos.finish(); 
      zos.close(); 

      byte[] compressedByteArray = baos.toByteArray(); 

      baos.close(); 
      if (logger.isDebugEnabled()) 
      { 
       logger.debug("Compressed message to size: " + compressedByteArray.length); 
      } 

      return compressedByteArray; 
     } 
     catch (IOException ioex) 
     { 
      throw ioex; 
     } 
     finally 
     { 
      IOUtils.closeQuietly(zos); 
      IOUtils.closeQuietly(baos); 
     } 
    } 

    public boolean isCompressed(byte[] bytes) throws IOException 
    { 
     if ((bytes == null) || (bytes.length < 4)) 
     { 
      return false; 
     } 
     else 
     { 
      for (int i = 0; i < MAGIC.length; i++) { 
       if (bytes[i] != MAGIC[i]) { 
       return false; 
       } 
      } 
      return true; 
     } 
    } 


} 

implementiert Wie nun der Dateiname als test.txt setzt. Sie können eine beliebige Eigenschaft oder Variable ändern.

Hoffe, das hilft.

+0

Genau was ich brauchte. Ich werde versuchen, es zu konvertieren, um die Annotation @Transform zu verwenden. Vielen Dank! –

1

Eine einfachere Möglichkeit besteht darin, den gzip-Transformer in mule zu verwenden, um die Datei zu komprimieren. Beachten Sie, dass Sie dies über das XML tun müssen.

<gzip-compress-transformer/> 
+0

Ich weiß, ich hatte zuerst gzip-Komprimierung, aber die Anforderungen sind Zip-Komprimierung wie in der ersten Zeile meines Posts angegeben. –

0

Im ZipTransformer-Konstruktor ist Folgendes veraltet.

registerSourceType(InputStream.class); 
registerSourceType(byte[].class); 

Verwenden Sie stattdessen:

registerSourceType(DataTypeFactory.create(InputStream.class)); 
registerSourceType(DataTypeFactory.create(byte[].class));