2016-06-09 3 views
1

Я знаю, что Mule имеет отличную поддержку сжатия данных gzip с помощью элемента. Однако теперь клиент хочет сжатие почтового индекса, так как файл должен быть помещен на FTP как почтовый сжатый файл :(Mule Zip File и отправить zip-файл на FTP-сервер

Я сталкиваюсь с трудностями в муле следующего сценарий:

Я создал Spring бин, где приходит файл . Я хочу, чтобы в сжать этот файл, используя класс ZipOutputStream и передать его к нашему FTP

Это моя конфигурация потока:.

<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> 

Это код моего 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(); 
    } 
} 

Я написал блок-тест, и компрессия отлично работает. Файл действительно переносится на FTP с правильным именем, но zip-файл недействителен и, открыв его в NotePad ++, содержит только исходное имя файла.

Я думаю, что я делаю что-то неправильно с передачей zip-файла обратно в поток мула, но я застрял в данный момент, поэтому любая помощь будет принята с благодарностью!

+1

Я побежал копию потока и zipCompressor. Я также получаю файл, но файл никогда не сжимается. Он находится в исходном состоянии. – tbriscoe

ответ

2

Я реализовал трансформатор для этого

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; 
     } 
    } 


} 

Используется как

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

В настоящее время устанавливает имя файла в качестве test.txt. вы можете изменить, используя любое свойство или переменную.

Надеюсь, это поможет.

+0

То, что мне нужно. Я попытаюсь преобразовать его, чтобы использовать аннотацию @Transform. Благодаря! –

1

Простейший способ сделать это - использовать gzip-трансформатор в mule для сжатия файла. Обратите внимание, что вы должны сделать это через xml.

<gzip-compress-transformer/> 
+0

Я знаю, у меня сначала было сжатие gzip, но требования - сжатие ZIP, как указано в первой строке моего сообщения. –

0

В конструкторе ZipTransformer устаревшее.

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

Используйте вместо этого:

registerSourceType(DataTypeFactory.create(InputStream.class)); 
registerSourceType(DataTypeFactory.create(byte[].class)); 
Смежные вопросы