INTEXT-40 Add ZIP Transformer
* Add zip-transformer * Add unzip-transformer * Add UnZipResultSplitter * Add sample For reference see: https://jira.springsource.org/browse/INTEXT-40
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -22,3 +22,5 @@ target
|
||||
spring-integration-aws/src/test/resources/awscredentials.properties
|
||||
*.orig
|
||||
/spring-integration-java-dsl/hostkey.ser
|
||||
.springBeans
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ The Spring Integration Extensions project provides extension modules for [Spring
|
||||
* [Splunk][] Support
|
||||
* [Voldemort][] Support
|
||||
* [XQuery][] Support
|
||||
|
||||
* Zip Support (Compression and Uncompression)
|
||||
|
||||
## Samples
|
||||
|
||||
|
||||
56
samples/zip/README.md
Normal file
56
samples/zip/README.md
Normal file
@@ -0,0 +1,56 @@
|
||||
Spring Integration Zip Sample
|
||||
===================
|
||||
|
||||
This sample illustrates the usage of the Spring Integration Zip Extension. It uses the following components:
|
||||
|
||||
* zip-transformer
|
||||
* unzip-transformer
|
||||
|
||||
You can run the application by either
|
||||
|
||||
* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application)
|
||||
* or from the command line:
|
||||
- mvn package
|
||||
- mvn exec:java
|
||||
|
||||
You should see a screen as the following:
|
||||
|
||||
```
|
||||
=========================================================
|
||||
|
||||
Welcome to the Spring Integration Zip Sample
|
||||
|
||||
For more information please visit:
|
||||
http://www.springsource.org/spring-integration
|
||||
|
||||
=========================================================
|
||||
17:08:41.883 INFO [org.springframework.integration.samples.zip.Main.main()][org.springframework.integration.samples.zip.SpringIntegrationUtils]
|
||||
=========================================================
|
||||
|
||||
Intput directory is: '/dev/spring-integration-extensions/samples/zip/input-zip'
|
||||
Intput directory is: '/dev/spring-integration-extensions/samples/zip/input-uncompressed'
|
||||
Output directory is: 'target/output/decompressedFilesOut'
|
||||
Output directory is: 'target/output/zipFilesOut'
|
||||
|
||||
=========================================================
|
||||
17:08:41.887 INFO [org.springframework.integration.samples.zip.Main.main()][org.springframework.integration.samples.zip.Main]
|
||||
=========================================================
|
||||
|
||||
Please press 'q + Enter' to quit the application.
|
||||
|
||||
=========================================================
|
||||
```
|
||||
## Compressing Files
|
||||
|
||||
Drop an uncompressed file into the **input-uncompressed** directory. The file will be compressed and stored under **target/output/zipFilesOut**.
|
||||
|
||||
## Uncompressing Files
|
||||
|
||||
Drop a compressed file into the **input-zip** directory. The file will be decompressed and stored under **target/output/decompressedFilesOut**.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
For help please take a look at the Spring Integration documentation:
|
||||
|
||||
http://www.springsource.org/spring-integration
|
||||
|
||||
119
samples/zip/pom.xml
Normal file
119
samples/zip/pom.xml
Normal file
@@ -0,0 +1,119 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.integration.samples</groupId>
|
||||
<artifactId>zip-sample</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>zip-sample</name>
|
||||
<url>http://projects.spring.io/spring-integration/</url>
|
||||
|
||||
<prerequisites>
|
||||
<maven>2.2.1</maven>
|
||||
</prerequisites>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.integration.zip.version>1.0.0.BUILD-SNAPSHOT</spring.integration.zip.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<junit.version>4.11</junit.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repo.spring.io.milestone</id>
|
||||
<name>Spring Framework Maven Milestone Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<version>2.9</version>
|
||||
<configuration>
|
||||
<additionalProjectnatures>
|
||||
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
|
||||
</additionalProjectnatures>
|
||||
<additionalBuildcommands>
|
||||
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
|
||||
</additionalBuildcommands>
|
||||
<downloadSources>true</downloadSources>
|
||||
<downloadJavadocs>true</downloadJavadocs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<compilerArgument>-Xlint:all</compilerArgument>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<configuration>
|
||||
<mainClass>org.springframework.integration.samples.zip.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Testing -->
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Integration -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-zip</artifactId>
|
||||
<version>${spring.integration.zip.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Other -->
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jcl</artifactId>
|
||||
<version>1.7.12</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.samples.zip;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* Starts the Spring Context and will initialize the Spring Integration routes.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public final class Main {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(Main.class);
|
||||
|
||||
private Main() { }
|
||||
|
||||
/**
|
||||
* Load the Spring Integration Application Context
|
||||
*
|
||||
* @param args - command line arguments
|
||||
*/
|
||||
public static void main(final String... args) {
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("\n========================================================="
|
||||
+ "\n "
|
||||
+ "\n Welcome to the Spring Integration Zip Sample "
|
||||
+ "\n "
|
||||
+ "\n For more information please visit: "
|
||||
+ "\n http://www.springsource.org/spring-integration "
|
||||
+ "\n "
|
||||
+ "\n=========================================================" );
|
||||
}
|
||||
|
||||
final AbstractApplicationContext context =
|
||||
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
|
||||
|
||||
context.registerShutdownHook();
|
||||
|
||||
SpringIntegrationUtils.displayDirectories(context);
|
||||
|
||||
final Scanner scanner = new Scanner(System.in);
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("\n========================================================="
|
||||
+ "\n "
|
||||
+ "\n Please press 'q + Enter' to quit the application. "
|
||||
+ "\n "
|
||||
+ "\n=========================================================" );
|
||||
}
|
||||
|
||||
while (!scanner.hasNext("q")) {
|
||||
//Do nothing unless user presses 'q' to quit.
|
||||
}
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Exiting application...bye.");
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.file.FileReadingMessageSource;
|
||||
import org.springframework.integration.file.FileWritingMessageHandler;
|
||||
|
||||
/**
|
||||
* Displays the names of the input and output directories.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public final class SpringIntegrationUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringIntegrationUtils.class);
|
||||
|
||||
private SpringIntegrationUtils() { }
|
||||
|
||||
/**
|
||||
* Helper Method to dynamically determine and display input and output
|
||||
* directories as defined in the Spring Integration context.
|
||||
*
|
||||
* @param context Spring Application Context
|
||||
*/
|
||||
public static void displayDirectories(final ApplicationContext context) {
|
||||
|
||||
final Map<String, FileReadingMessageSource> fileReadingMessageSources = context.getBeansOfType(FileReadingMessageSource.class);
|
||||
|
||||
final List<String> inputDirectories = new ArrayList<String>();
|
||||
|
||||
for (FileReadingMessageSource source : fileReadingMessageSources.values()) {
|
||||
final File inDir = (File) new DirectFieldAccessor(source).getPropertyValue("directory");
|
||||
inputDirectories.add(inDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
final Map<String, FileWritingMessageHandler> fileWritingMessageHandlers = context.getBeansOfType(FileWritingMessageHandler.class);
|
||||
|
||||
final List<String> outputDirectories = new ArrayList<String>();
|
||||
|
||||
for (final FileWritingMessageHandler messageHandler : fileWritingMessageHandlers.values()) {
|
||||
final Expression outDir = (Expression) new DirectFieldAccessor(messageHandler).getPropertyValue("destinationDirectoryExpression");
|
||||
outputDirectories.add(outDir.getExpressionString());
|
||||
}
|
||||
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
stringBuilder.append("\n=========================================================");
|
||||
stringBuilder.append("\n");
|
||||
|
||||
for (final String inputDirectory : inputDirectories) {
|
||||
stringBuilder.append("\n Intput directory is: '" + inputDirectory + "'");
|
||||
}
|
||||
|
||||
for (final String outputDirectory : outputDirectories) {
|
||||
stringBuilder.append("\n Output directory is: '" + outputDirectory + "'");
|
||||
}
|
||||
|
||||
stringBuilder.append("\n\n=========================================================");
|
||||
|
||||
logger.info(stringBuilder.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.integration.annotation.Transformer;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* This Spring Integration transformation handler takes the input file, converts
|
||||
* the file into a string, converts the file contents into an upper-case string
|
||||
* and then sets a few Spring Integration message headers.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public class TransformationHandler {
|
||||
|
||||
/**
|
||||
* Actual Spring Integration transformation handler.
|
||||
*
|
||||
* @param inputMessage Spring Integration input message
|
||||
* @return New Spring Integration message with updated headers
|
||||
*/
|
||||
@Transformer
|
||||
public Message<String> handleFile(final Message<File> inputMessage) {
|
||||
|
||||
final File inputFile = inputMessage.getPayload();
|
||||
final String filename = inputFile.getName();
|
||||
final String fileExtension = FilenameUtils.getExtension(filename);
|
||||
|
||||
final String inputAsString;
|
||||
|
||||
try {
|
||||
inputAsString = FileUtils.readFileToString(inputFile);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
final Message<String> message = MessageBuilder.withPayload(inputAsString.toUpperCase(Locale.ENGLISH))
|
||||
.setHeader(FileHeaders.FILENAME, filename)
|
||||
.setHeader(FileHeaders.ORIGINAL_FILE, inputFile)
|
||||
.setHeader("file_size", inputFile.length())
|
||||
.setHeader("file_extension", fileExtension)
|
||||
.build();
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int-file:inbound-channel-adapter id="zipFilesIn"
|
||||
directory="file:input-zip">
|
||||
<int:poller id="poller" fixed-rate="5000" max-messages-per-poll="10" />
|
||||
</int-file:inbound-channel-adapter>
|
||||
|
||||
<int-file:inbound-channel-adapter id="uncompressedFilesIn" directory="file:input-uncompressed">
|
||||
<int:poller id="poller" fixed-rate="5000" max-messages-per-poll="10" />
|
||||
</int-file:inbound-channel-adapter>
|
||||
|
||||
<int-zip:zip-transformer id="zipFiles" input-channel="uncompressedFilesIn"
|
||||
output-channel="zipFilesOut" />
|
||||
|
||||
<int:chain id="unzipFiles" input-channel="zipFilesIn" output-channel="decompressedFilesOut">
|
||||
<int-zip:unzip-transformer result-type="BYTE_ARRAY"/>
|
||||
<int:splitter method="splitUnzippedMap">
|
||||
<bean class="org.springframework.integration.zip.transformer.splitter.UnZipResultSplitter"/>
|
||||
</int:splitter>
|
||||
</int:chain>
|
||||
|
||||
<int-file:outbound-channel-adapter
|
||||
id="decompressedFilesOut" directory="file:target/output/decompressedFilesOut"
|
||||
delete-source-files="true" />
|
||||
|
||||
<int-file:outbound-channel-adapter
|
||||
id="zipFilesOut" directory="file:target/output/zipFilesOut"
|
||||
delete-source-files="true" />
|
||||
|
||||
</beans>
|
||||
28
samples/zip/src/main/resources/log4j.xml
Normal file
28
samples/zip/src/main/resources/log4j.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<!-- Appenders -->
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Target" value="System.out" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Loggers -->
|
||||
<logger name="org.springframework.integration">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.samples.zip">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<!-- Root Logger -->
|
||||
<root>
|
||||
<priority value="warn" />
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.zip;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import org.springframework.integration.samples.zip.SpringIntegrationUtils;
|
||||
|
||||
/**
|
||||
* Verify that the Spring Integration Application Context starts successfully.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class SpringIntegrationProjectStartupTest {
|
||||
|
||||
@Test
|
||||
public void testStartupOfSpringInegrationContext() throws Exception{
|
||||
final ApplicationContext context
|
||||
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
|
||||
SpringIntegrationProjectStartupTest.class);
|
||||
SpringIntegrationUtils.displayDirectories(context);
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.kafka.support;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import kafka.consumer.ConsumerIterator;
|
||||
import kafka.consumer.KafkaStream;
|
||||
import kafka.javaapi.consumer.ConsumerConnector;
|
||||
import kafka.message.MessageAndMetadata;
|
||||
import kafka.serializer.Decoder;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
/**
|
||||
* @author Soby Chacko
|
||||
* @author Rajasekar Elango
|
||||
* @since 0.5
|
||||
*/
|
||||
public class ConsumerConfigurationTests<K,V> {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageForSingleTopicFromSingleStream() {
|
||||
final ConsumerMetadata<K,V> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<K,V> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
Map<String, Integer> topicStreamMap = new HashMap<String, Integer>();
|
||||
topicStreamMap.put("topic1", 1);
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicStreamMap);
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<K,V> consumerConfiguration = new ConsumerConfiguration<K,V>(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(1);
|
||||
|
||||
final KafkaStream<K,V> stream = mock(KafkaStream.class);
|
||||
final List<KafkaStream<K,V>> streams = new ArrayList<KafkaStream<K,V>>();
|
||||
streams.add(stream);
|
||||
final Map<String, List<KafkaStream<K,V>>> messageStreams = new HashMap<String, List<KafkaStream<K,V>>>();
|
||||
messageStreams.put("topic", streams);
|
||||
|
||||
when(consumerConfiguration.createMessageStreamsForTopic()).thenReturn(messageStreams);
|
||||
final ConsumerIterator<K,V> iterator = mock(ConsumerIterator.class);
|
||||
when(stream.iterator()).thenReturn(iterator);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata = mock(MessageAndMetadata.class);
|
||||
when(iterator.next()).thenReturn(messageAndMetadata);
|
||||
when(messageAndMetadata.message()).thenReturn((V) "got message");
|
||||
when(messageAndMetadata.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata.partition()).thenReturn(1);
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
Assert.assertEquals(1, messages.size());
|
||||
Assert.assertEquals(1, messages.get("topic").size());
|
||||
Assert.assertEquals("got message", messages.get("topic").get(1).get(0));
|
||||
|
||||
verify(stream, times(1)).iterator();
|
||||
verify(iterator, times(1)).next();
|
||||
verify(messageAndMetadata, times(1)).message();
|
||||
verify(messageAndMetadata, times(1)).topic();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageForSingleTopicFromMultipleStreams() {
|
||||
<<<<<<< HEAD
|
||||
final ConsumerMetadata<K,V> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
=======
|
||||
final ConsumerMetadata<?,?> consumerMetadata = Mockito.mock(ConsumerMetadata.class);
|
||||
>>>>>>> INTEXT-40 - Add ZIP Transformer
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<K,V> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
|
||||
Map<String, Integer> topicStreamMap = new HashMap<String, Integer>();
|
||||
topicStreamMap.put("topic1", 1);
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicStreamMap);
|
||||
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<K,V> consumerConfiguration = new ConsumerConfiguration<K,V>(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(3);
|
||||
|
||||
final KafkaStream<K,V> stream1 = mock(KafkaStream.class);
|
||||
final KafkaStream<K,V> stream2 = mock(KafkaStream.class);
|
||||
final KafkaStream<K,V> stream3 = mock(KafkaStream.class);
|
||||
final List<KafkaStream<K,V>> streams = new ArrayList<KafkaStream<K,V>>();
|
||||
streams.add(stream1);
|
||||
streams.add(stream2);
|
||||
streams.add(stream3);
|
||||
final Map<String, List<KafkaStream<K,V>>> messageStreams = new HashMap<String, List<KafkaStream<K,V>>>();
|
||||
messageStreams.put("topic", streams);
|
||||
|
||||
when(consumerConfiguration.createMessageStreamsForTopic()).thenReturn(messageStreams);
|
||||
final ConsumerIterator<K,V> iterator1 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<K,V> iterator2 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<K,V> iterator3 = mock(ConsumerIterator.class);
|
||||
|
||||
when(stream1.iterator()).thenReturn(iterator1);
|
||||
when(stream2.iterator()).thenReturn(iterator2);
|
||||
when(stream3.iterator()).thenReturn(iterator3);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata1 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata2 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata3 = mock(MessageAndMetadata.class);
|
||||
|
||||
when(iterator1.next()).thenReturn(messageAndMetadata1);
|
||||
when(iterator2.next()).thenReturn(messageAndMetadata2);
|
||||
when(iterator3.next()).thenReturn(messageAndMetadata3);
|
||||
|
||||
when(messageAndMetadata1.message()).thenReturn((V)"got message");
|
||||
when(messageAndMetadata1.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata1.partition()).thenReturn(1);
|
||||
|
||||
when(messageAndMetadata2.message()).thenReturn((V)"got message");
|
||||
when(messageAndMetadata2.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata2.partition()).thenReturn(2);
|
||||
|
||||
when(messageAndMetadata3.message()).thenReturn((V)"got message");
|
||||
when(messageAndMetadata3.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata3.partition()).thenReturn(3);
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
Assert.assertEquals(messages.size(), 1);
|
||||
int sum = 0;
|
||||
|
||||
final Map<Integer, List<Object>> values = messages.get("topic");
|
||||
|
||||
for (final List<Object> l : values.values()) {
|
||||
sum += l.size();
|
||||
}
|
||||
|
||||
Assert.assertEquals(3, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageForMultipleTopicsFromMultipleStreams() {
|
||||
<<<<<<< HEAD
|
||||
final ConsumerMetadata<K,V> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
=======
|
||||
final ConsumerMetadata<?,?> consumerMetadata = Mockito.mock(ConsumerMetadata.class);
|
||||
>>>>>>> INTEXT-40 - Add ZIP Transformer
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<K, V> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
|
||||
Map<String, Integer> topicStreamMap = new HashMap<String, Integer>();
|
||||
topicStreamMap.put("topic1", 1);
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicStreamMap);
|
||||
|
||||
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<K,V> consumerConfiguration = new ConsumerConfiguration<K,V>(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(9);
|
||||
|
||||
final KafkaStream<K,V> stream1 = mock(KafkaStream.class);
|
||||
final KafkaStream<K,V> stream2 = mock(KafkaStream.class);
|
||||
final KafkaStream<K,V> stream3 = mock(KafkaStream.class);
|
||||
final List<KafkaStream<K,V>> streams = new ArrayList<KafkaStream<K,V>>();
|
||||
streams.add(stream1);
|
||||
streams.add(stream2);
|
||||
streams.add(stream3);
|
||||
final Map<String, List<KafkaStream<K,V>>> messageStreams = new HashMap<String, List<KafkaStream<K,V>>>();
|
||||
messageStreams.put("topic1", streams);
|
||||
messageStreams.put("topic2", streams);
|
||||
messageStreams.put("topic3", streams);
|
||||
|
||||
when(consumerConfiguration.createMessageStreamsForTopic()).thenReturn(messageStreams);
|
||||
final ConsumerIterator<K,V> iterator1 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<K,V> iterator2 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<K,V> iterator3 = mock(ConsumerIterator.class);
|
||||
|
||||
when(stream1.iterator()).thenReturn(iterator1);
|
||||
when(stream2.iterator()).thenReturn(iterator2);
|
||||
when(stream3.iterator()).thenReturn(iterator3);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata1 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata2 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<K,V> messageAndMetadata3 = mock(MessageAndMetadata.class);
|
||||
|
||||
when(iterator1.next()).thenReturn(messageAndMetadata1);
|
||||
when(iterator2.next()).thenReturn(messageAndMetadata2);
|
||||
when(iterator3.next()).thenReturn(messageAndMetadata3);
|
||||
|
||||
when(messageAndMetadata1.message()).thenReturn((V)"got message1");
|
||||
when(messageAndMetadata1.topic()).thenReturn("topic1");
|
||||
when(messageAndMetadata1.partition()).thenAnswer(getAnswer());
|
||||
|
||||
when(messageAndMetadata2.message()).thenReturn((V)"got message2");
|
||||
when(messageAndMetadata2.topic()).thenReturn("topic2");
|
||||
when(messageAndMetadata1.partition()).thenAnswer(getAnswer());
|
||||
|
||||
when(messageAndMetadata3.message()).thenReturn((V)"got message3");
|
||||
when(messageAndMetadata3.topic()).thenReturn("topic3");
|
||||
when(messageAndMetadata1.partition()).thenAnswer(getAnswer());
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
|
||||
int sum = 0;
|
||||
|
||||
final Collection<Map<Integer, List<Object>>> values = messages.values();
|
||||
|
||||
for (final Map<Integer, List<Object>> m : values) {
|
||||
for (final List<Object> l : m.values()) {
|
||||
sum += l.size();
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(9, sum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Answer<Object> getAnswer() {
|
||||
return new Answer<Object>() {
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public Object answer(final InvocationOnMock invocation) throws Throwable {
|
||||
if (count++ == 1) {
|
||||
return 1;
|
||||
} else if (count++ == 2) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageAndVerifyMessageLeftoverFromPreviousPollAreTakenFirst() {
|
||||
<<<<<<< HEAD
|
||||
final ConsumerMetadata<K,V> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
=======
|
||||
final ConsumerMetadata<?,?> consumerMetadata = Mockito.mock(ConsumerMetadata.class);
|
||||
>>>>>>> INTEXT-40 - Add ZIP Transformer
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<K,V> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
Map<String, Integer> topicStreamMap = new HashMap<String, Integer>();
|
||||
topicStreamMap.put("topic1", 1);
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicStreamMap);
|
||||
when(messageLeftOverTracker.getCurrentCount()).thenReturn(3);
|
||||
|
||||
final MessageAndMetadata<String, String> m1 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<String, String> m2 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<String, String> m3 = mock(MessageAndMetadata.class);
|
||||
|
||||
when(m1.key()).thenReturn("key1");
|
||||
when(m1.message()).thenReturn("value1");
|
||||
when(m1.topic()).thenReturn("topic1");
|
||||
when(m1.partition()).thenReturn(1);
|
||||
|
||||
when(m2.key()).thenReturn("key2");
|
||||
when(m2.message()).thenReturn("value2");
|
||||
when(m2.topic()).thenReturn("topic2");
|
||||
when(m2.partition()).thenReturn(1);
|
||||
|
||||
when(m3.key()).thenReturn("key1");
|
||||
when(m3.message()).thenReturn("value3");
|
||||
when(m3.topic()).thenReturn("topic3");
|
||||
when(m3.partition()).thenReturn(1);
|
||||
|
||||
final List<MessageAndMetadata<String, String>> mList = new ArrayList<MessageAndMetadata<String, String>>();
|
||||
mList.add(m1);
|
||||
mList.add(m2);
|
||||
mList.add(m3);
|
||||
|
||||
when((List<MessageAndMetadata<String, String>>) (Object) messageLeftOverTracker.getMessageLeftOverFromPreviousPoll()).thenReturn(mList);
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<K,V> consumerConfiguration = new ConsumerConfiguration<K,V>(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(5);
|
||||
|
||||
final KafkaStream<K,V> stream = mock(KafkaStream.class);
|
||||
final List<KafkaStream<K,V>> streams = new ArrayList<KafkaStream<K,V>>();
|
||||
streams.add(stream);
|
||||
final Map<String, List<KafkaStream<K,V>>> messageStreams = new HashMap<String, List<KafkaStream<K,V>>>();
|
||||
messageStreams.put("topic1", streams);
|
||||
when(consumerConfiguration.createMessageStreamsForTopic()).thenReturn(messageStreams);
|
||||
final ConsumerIterator<K, V> iterator = mock(ConsumerIterator.class);
|
||||
when(stream.iterator()).thenReturn(iterator);
|
||||
final MessageAndMetadata<K, V> messageAndMetadata = mock(MessageAndMetadata.class);
|
||||
when(iterator.next()).thenReturn(messageAndMetadata);
|
||||
when(messageAndMetadata.message()).thenReturn((V) "got message");
|
||||
when(messageAndMetadata.topic()).thenReturn("topic1");
|
||||
when(messageAndMetadata.partition()).thenReturn(1);
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
int sum = 0;
|
||||
|
||||
final Collection<Map<Integer, List<Object>>> values = messages.values();
|
||||
|
||||
for (final Map<Integer, List<Object>> m : values) {
|
||||
for (final List<Object> l : m.values()) {
|
||||
sum += l.size();
|
||||
}
|
||||
|
||||
}
|
||||
Assert.assertEquals(5, sum);
|
||||
|
||||
Assert.assertTrue(messages.containsKey("topic1"));
|
||||
Assert.assertTrue(messages.containsKey("topic2"));
|
||||
Assert.assertTrue(messages.containsKey("topic3"));
|
||||
|
||||
Assert.assertTrue(valueFound(messages.get("topic1").get(1), "value1"));
|
||||
Assert.assertTrue(valueFound(messages.get("topic2").get(1), "value2"));
|
||||
Assert.assertTrue(valueFound(messages.get("topic3").get(1), "value3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
<<<<<<< HEAD
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetConsumerMapWithMessageStreamsWithNullDecoders() {
|
||||
|
||||
final ConsumerMetadata<K,V> mockedConsumerMetadata = mock(ConsumerMetadata.class);
|
||||
|
||||
assertNull(mockedConsumerMetadata.getKeyDecoder());
|
||||
assertNull(mockedConsumerMetadata.getValueDecoder());
|
||||
|
||||
final Map<String, Integer> topicsStreamMap = new HashMap<String, Integer>();
|
||||
when(mockedConsumerMetadata.getTopicStreamMap()).thenReturn(topicsStreamMap);
|
||||
|
||||
final ConsumerConnectionProvider mockedConsumerConnectionProvider = mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<K,V> mockedMessageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector mockedConsumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(mockedConsumerConnectionProvider.getConsumerConnector()).thenReturn(mockedConsumerConnector);
|
||||
|
||||
final Map<String, List<KafkaStream<K,V>>> messageStreams = new HashMap<String, List<KafkaStream<K,V>>>();
|
||||
when((Map<String, List<KafkaStream<K,V>>>)
|
||||
(Object) mockedConsumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
|
||||
final ConsumerConfiguration<K,V> consumerConfiguration = new ConsumerConfiguration<K,V>(mockedConsumerMetadata,
|
||||
mockedConsumerConnectionProvider, mockedMessageLeftOverTracker);
|
||||
|
||||
consumerConfiguration.createMessageStreamsForTopic();
|
||||
|
||||
verify(mockedConsumerMetadata, atLeast(1)).getTopicStreamMap();
|
||||
verify(mockedConsumerConnector, atLeast(1)).createMessageStreams(topicsStreamMap, null, null);
|
||||
//verify(mockedConsumerConnector, atMost(0)).createMessageStreams(topicsStreamMap, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetConsumerMapWithMessageStreamsWithDecoders() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final ConsumerMetadata<String, String> mockedConsumerMetadata = mock(ConsumerMetadata.class);
|
||||
|
||||
final Map<String, Integer> topicsStreamMap = new HashMap<String, Integer>();
|
||||
when(mockedConsumerMetadata.getTopicStreamMap()).thenReturn(topicsStreamMap);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Decoder<String> mockedKeyDecoder = mock(Decoder.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Decoder<String> mockedValueDecoder = mock(Decoder.class);
|
||||
|
||||
when(mockedConsumerMetadata.getKeyDecoder()).thenReturn(mockedKeyDecoder);
|
||||
when(mockedConsumerMetadata.getValueDecoder()).thenReturn(mockedValueDecoder);
|
||||
|
||||
final ConsumerConnectionProvider mockedConsumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<String, String> mockedMessageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector mockedConsumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(mockedConsumerConnectionProvider.getConsumerConnector()).thenReturn(mockedConsumerConnector);
|
||||
|
||||
final Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = new HashMap<String, List<KafkaStream<byte[],byte[]>>>();
|
||||
when(mockedConsumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
|
||||
final ConsumerConfiguration<String, String> consumerConfiguration =
|
||||
new ConsumerConfiguration<String, String>(mockedConsumerMetadata, mockedConsumerConnectionProvider,
|
||||
mockedMessageLeftOverTracker);
|
||||
|
||||
consumerConfiguration.createMessageStreamsForTopic();
|
||||
|
||||
verify(mockedConsumerMetadata, atLeast(1)).getTopicStreamMap();
|
||||
verify(mockedConsumerConnector, atMost(0)).createMessageStreams(topicsStreamMap);
|
||||
verify(mockedConsumerConnector, atLeast(1))
|
||||
.createMessageStreams(topicsStreamMap, mockedKeyDecoder, mockedValueDecoder);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageForTopicFilterFromSingleStream() {
|
||||
final ConsumerMetadata<byte[], String> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<byte[], String> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(consumerMetadata.getTopicFilterConfiguration()).thenReturn(new TopicFilterConfiguration(".*", 1, false));
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<byte[], String> consumerConfiguration =
|
||||
new ConsumerConfiguration<byte[], String>(consumerMetadata, consumerConnectionProvider,
|
||||
messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(1);
|
||||
|
||||
final KafkaStream<byte[],String> stream = mock(KafkaStream.class);
|
||||
final List<KafkaStream<byte[], String>> streams = new ArrayList<KafkaStream<byte[], String>>();
|
||||
streams.add(stream);
|
||||
|
||||
when(consumerConfiguration.createMessageStreamsForTopicFilter()).thenReturn(streams);
|
||||
final ConsumerIterator<byte[], String> iterator = mock(ConsumerIterator.class);
|
||||
when(stream.iterator()).thenReturn(iterator);
|
||||
final MessageAndMetadata<byte[], String> messageAndMetadata = mock(MessageAndMetadata.class);
|
||||
when(iterator.next()).thenReturn(messageAndMetadata);
|
||||
when(messageAndMetadata.message()).thenReturn("got message");
|
||||
when(messageAndMetadata.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata.partition()).thenReturn(1);
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
Assert.assertEquals(1, messages.size());
|
||||
Assert.assertEquals(1, messages.get("topic").size());
|
||||
Assert.assertEquals("got message", messages.get("topic").get(1).get(0));
|
||||
|
||||
verify(stream, times(1)).iterator();
|
||||
verify(iterator, times(1)).next();
|
||||
verify(messageAndMetadata, times(1)).message();
|
||||
verify(messageAndMetadata, times(1)).topic();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReceiveMessageForTopicFilterFromMultipleStreams() {
|
||||
final ConsumerMetadata<byte[], byte[]> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker<byte[], byte[]> messageLeftOverTracker = mock(MessageLeftOverTracker.class);
|
||||
|
||||
when(consumerMetadata.getTopicFilterConfiguration()).thenReturn(new TopicFilterConfiguration(".*", 1, false));
|
||||
|
||||
final ConsumerConnector consumerConnector = mock(ConsumerConnector.class);
|
||||
|
||||
when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final ConsumerConfiguration<byte[], byte[]> consumerConfiguration =
|
||||
new ConsumerConfiguration<byte[], byte[]>(consumerMetadata, consumerConnectionProvider,
|
||||
messageLeftOverTracker);
|
||||
consumerConfiguration.setMaxMessages(3);
|
||||
|
||||
final KafkaStream<byte[], byte[]> stream1 = mock(KafkaStream.class);
|
||||
final KafkaStream<byte[], byte[]> stream2 = mock(KafkaStream.class);
|
||||
final KafkaStream<byte[], byte[]> stream3 = mock(KafkaStream.class);
|
||||
final List<KafkaStream<byte[], byte[]>> streams = new ArrayList<KafkaStream<byte[], byte[]>>();
|
||||
streams.add(stream1);
|
||||
streams.add(stream2);
|
||||
streams.add(stream3);
|
||||
|
||||
when(consumerConfiguration.createMessageStreamsForTopicFilter()).thenReturn(streams);
|
||||
final ConsumerIterator<byte[], byte[]> iterator1 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<byte[], byte[]> iterator2 = mock(ConsumerIterator.class);
|
||||
final ConsumerIterator<byte[], byte[]> iterator3 = mock(ConsumerIterator.class);
|
||||
|
||||
when(stream1.iterator()).thenReturn(iterator1);
|
||||
when(stream2.iterator()).thenReturn(iterator2);
|
||||
when(stream3.iterator()).thenReturn(iterator3);
|
||||
final MessageAndMetadata<byte[], byte[]> messageAndMetadata1 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<byte[], byte[]> messageAndMetadata2 = mock(MessageAndMetadata.class);
|
||||
final MessageAndMetadata<byte[], byte[]> messageAndMetadata3 = mock(MessageAndMetadata.class);
|
||||
|
||||
when(iterator1.next()).thenReturn(messageAndMetadata1);
|
||||
when(iterator2.next()).thenReturn(messageAndMetadata2);
|
||||
when(iterator3.next()).thenReturn(messageAndMetadata3);
|
||||
|
||||
when(messageAndMetadata1.message()).thenReturn("got message".getBytes());
|
||||
when(messageAndMetadata1.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata1.partition()).thenReturn(1);
|
||||
|
||||
when(messageAndMetadata2.message()).thenReturn("got message".getBytes());
|
||||
when(messageAndMetadata2.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata2.partition()).thenReturn(2);
|
||||
|
||||
when(messageAndMetadata3.message()).thenReturn("got message".getBytes());
|
||||
when(messageAndMetadata3.topic()).thenReturn("topic");
|
||||
when(messageAndMetadata3.partition()).thenReturn(3);
|
||||
|
||||
final Map<String, Map<Integer, List<Object>>> messages = consumerConfiguration.receive();
|
||||
Assert.assertEquals(1, messages.size());
|
||||
int sum = 0;
|
||||
|
||||
final Map<Integer, List<Object>> values = messages.get("topic");
|
||||
|
||||
for (final List<Object> l : values.values()) {
|
||||
sum += l.size();
|
||||
}
|
||||
|
||||
Assert.assertEquals(3, sum);
|
||||
=======
|
||||
public void testGetConsumerMapWithMessageStreamsWithNullDecoders() {
|
||||
|
||||
final ConsumerMetadata<?,?> consumerMetadata = Mockito.mock(ConsumerMetadata.class);
|
||||
|
||||
final Map<String, Integer> topicsStreamMap = new HashMap<String, Integer>();
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicsStreamMap);
|
||||
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
Mockito.mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker messageLeftOverTracker = Mockito.mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector consumerConnector = Mockito.mock(ConsumerConnector.class);
|
||||
|
||||
Mockito.when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = new HashMap<String, List<KafkaStream<byte[],byte[]>>>();
|
||||
Mockito.when(consumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
Mockito.when(consumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
|
||||
final ConsumerConfiguration consumerConfiguration = new ConsumerConfiguration(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
|
||||
consumerConfiguration.getConsumerMapWithMessageStreams();
|
||||
|
||||
verify(consumerMetadata, atLeast(1)).getTopicStreamMap();
|
||||
verify(consumerConnector, atLeast(1)).createMessageStreams(topicsStreamMap);
|
||||
verify(consumerConnector, atMost(0)).createMessageStreams(topicsStreamMap, null, null);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConsumerMapWithMessageStreamsWithDecoders() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final ConsumerMetadata<String, String> consumerMetadata = mock(ConsumerMetadata.class);
|
||||
|
||||
final Map<String, Integer> topicsStreamMap = new HashMap<String, Integer>();
|
||||
when(consumerMetadata.getTopicStreamMap()).thenReturn(topicsStreamMap);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Decoder<String> mockedKeyDecoder = (Decoder<String>) mock(Decoder.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Decoder<String> mockedValueDecoder = (Decoder<String>) mock(Decoder.class);
|
||||
|
||||
when(consumerMetadata.getKeyDecoder()).thenReturn(mockedKeyDecoder);
|
||||
when(consumerMetadata.getValueDecoder()).thenReturn(mockedValueDecoder);
|
||||
|
||||
final ConsumerConnectionProvider consumerConnectionProvider =
|
||||
Mockito.mock(ConsumerConnectionProvider.class);
|
||||
final MessageLeftOverTracker messageLeftOverTracker = Mockito.mock(MessageLeftOverTracker.class);
|
||||
final ConsumerConnector consumerConnector = Mockito.mock(ConsumerConnector.class);
|
||||
|
||||
Mockito.when(consumerConnectionProvider.getConsumerConnector()).thenReturn(consumerConnector);
|
||||
|
||||
final Map<String, List<KafkaStream<byte[], byte[]>>> messageStreams = new HashMap<String, List<KafkaStream<byte[],byte[]>>>();
|
||||
Mockito.when(consumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
Mockito.when(consumerConnector.createMessageStreams(topicsStreamMap)).thenReturn(messageStreams);
|
||||
|
||||
final ConsumerConfiguration consumerConfiguration = new ConsumerConfiguration(consumerMetadata,
|
||||
consumerConnectionProvider, messageLeftOverTracker);
|
||||
|
||||
consumerConfiguration.getConsumerMapWithMessageStreams();
|
||||
|
||||
verify(consumerMetadata, atLeast(1)).getTopicStreamMap();
|
||||
verify(consumerConnector, atMost(0)).createMessageStreams(topicsStreamMap);
|
||||
verify(consumerConnector, atLeast(1)).createMessageStreams(topicsStreamMap, mockedKeyDecoder, mockedValueDecoder);
|
||||
|
||||
>>>>>>> INTEXT-40 - Add ZIP Transformer
|
||||
}
|
||||
|
||||
private boolean valueFound(final List<Object> l, final String value){
|
||||
for (final Object o : l){
|
||||
if (value.equals(o)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
171
spring-integration-zip/README.md
Normal file
171
spring-integration-zip/README.md
Normal file
@@ -0,0 +1,171 @@
|
||||
Spring Integration Zip Support
|
||||
==============================
|
||||
|
||||
| | Build Status |
|
||||
| ------------- | :-------------: |
|
||||
| Linux | [](https://build.spring.io/browse/INTEXT-ZIP) |
|
||||
| Windows | [](https://build.spring.io/browse/INTEXT-ZIPWIN) |
|
||||
|
||||
## Introduction
|
||||
|
||||
This *Spring Integration Extension* provides [Zip][] (un-) compression support. The following components are provided:
|
||||
|
||||
* Zip transformer
|
||||
* Unzip transformer
|
||||
* UnZipResultSplitter
|
||||
|
||||
**Important!** This module is currently under active development and not all functionality is provided or stable, yet.
|
||||
|
||||
## ZIP Compression Support
|
||||
|
||||
The following input data types can be **compressed**:
|
||||
|
||||
* File
|
||||
* String
|
||||
* byte[]
|
||||
* Iterable
|
||||
|
||||
In input data types can be mixed as part of an Iterable. E.g. you should be
|
||||
easily be able to compress a collection containing Strings, byte arrays and Files.
|
||||
It is important to note that nested Iterables are *NOT SUPPORTED* at present time.
|
||||
|
||||
The zip transformer can be customized by setting several properties:
|
||||
|
||||
### compressionLevel
|
||||
|
||||
Sets the compression level. Default is `Deflater#DEFAULT_COMPRESSION`
|
||||
|
||||
### useFileAttributes
|
||||
|
||||
Specifies whether the name of the file shall be used for the zip entry.
|
||||
|
||||
## ZIP Un-compression Support
|
||||
|
||||
The following input data types can be **decompressed**:
|
||||
|
||||
* File
|
||||
* InputStream
|
||||
* byte[]
|
||||
|
||||
When unzipping data, you can also specify a property **expectSingleResult**. If set
|
||||
to *true* and more than *1* zip entry were detected, a **MessagingException** will be raised.
|
||||
This property also influences the return type of the payload. If set to *false* (the *default*),
|
||||
then the payload will be of type *SortedMap*, if *true*, however, the actual zip
|
||||
entry will be returned.
|
||||
|
||||
Othe properties that can be set on the UnZipTransformer:
|
||||
|
||||
### deleteFiles
|
||||
|
||||
If the payload is an instance of `File`, this property specifies whether to delete the File after transformation. Default is *false*.
|
||||
|
||||
### workDirectory
|
||||
|
||||
Set the work-directory. The work directory is used when the ZipResultType is set to ZipResultType.FILE. By default this property is set to the System temporary directory containing a sub-directory "ziptransformer".
|
||||
|
||||
### ZipResultType
|
||||
|
||||
Defines the format of the data returned after transformation. Available options are:
|
||||
|
||||
* File
|
||||
* byte[]
|
||||
|
||||
## UnZipResultSplitter
|
||||
|
||||
The `UnZipResultSplitter` is useful in cases where Zip files contain more than *1*
|
||||
zip entry.
|
||||
|
||||
## Zipping and Unzipping Large Files
|
||||
|
||||
TBD
|
||||
|
||||
## Java Package Structure
|
||||
|
||||
### Base package
|
||||
|
||||
The base package `org.springframework.integration.zip` contains the *ZipHeaders* class which defines the *Spring Integration* message headers that are specific to the Zip module.
|
||||
|
||||
### config.xml
|
||||
|
||||
This package contains the parser classes for the XML Namespace support.
|
||||
|
||||
### transformer
|
||||
|
||||
Contain the classes responsible for the actual (un-) zip operation:
|
||||
|
||||
* ZipTransformer
|
||||
* UnZipTransformer
|
||||
|
||||
## Namespace Support
|
||||
|
||||
Full XML namespace support is provided.
|
||||
|
||||
## Building the Project
|
||||
|
||||
To build and install jars into your local Maven cache, please execute:
|
||||
|
||||
./gradlew install
|
||||
|
||||
If you encounter out of memory errors during the build, increase available heap and permgen for Gradle:
|
||||
|
||||
GRADLE_OPTS='-XX:MaxPermSize=1024m -Xmx1024m'
|
||||
|
||||
To build api Javadoc (results will be in `build/api`):
|
||||
|
||||
./gradlew api
|
||||
|
||||
To build complete distribution including `-dist` and `-schema` zip files (results will be in `build/distributions`)
|
||||
|
||||
./gradlew dist
|
||||
|
||||
# IDE Support
|
||||
|
||||
While your custom Spring Integration Adapter is initially created with SpringSource Tool Suite, you in fact end up with a Gradle-based project. As such, the created project can be imported into other IDEs as well.
|
||||
|
||||
## Using Spring Tool Suite
|
||||
|
||||
Gradle projects can be directly imported into STS. But please make sure that you have the Gradle support installed.
|
||||
|
||||
## Using Plain Eclipse
|
||||
|
||||
To generate Eclipse metadata (*.classpath* and *.project* files), do the following:
|
||||
|
||||
./gradlew eclipse
|
||||
|
||||
Once complete, you may then import the project into Eclipse as usual:
|
||||
|
||||
*File -> Import -> Existing projects into workspace*
|
||||
|
||||
Browse to the root directory of the project and it should import free of errors.
|
||||
|
||||
## Using IntelliJ IDEA
|
||||
|
||||
To generate IDEA metadata (.iml and .ipr files), do the following:
|
||||
|
||||
./gradlew idea
|
||||
|
||||
# Further Resources
|
||||
|
||||
## Getting support
|
||||
|
||||
Check out the [spring-integration][spring-integration tag] tag on [Stack Overflow][].
|
||||
|
||||
## Related GitHub projects
|
||||
|
||||
* [Spring Integration][]
|
||||
* [Spring Integration Samples][]
|
||||
* [Spring Integration Templates][]
|
||||
* [Spring Integration Dsl Groovy][]
|
||||
* [Spring Integration Dsl Scala][]
|
||||
|
||||
For more information, please also don't forget to visit the [Spring Integration][] website.
|
||||
|
||||
[Spring Integration]: https://github.com/SpringSource/spring-integration
|
||||
[spring-integration tag]: http://stackoverflow.com/questions/tagged/spring-integration
|
||||
[Spring Integration Samples]: https://github.com/SpringSource/spring-integration-samples
|
||||
[Spring Integration Templates]: https://github.com/SpringSource/spring-integration-templates/tree/master/si-sts-templates
|
||||
[Spring Integration Dsl Groovy]: https://github.com/SpringSource/spring-integration-dsl-groovy
|
||||
[Spring Integration Dsl Scala]: https://github.com/SpringSource/spring-integration-dsl-scala
|
||||
[Stack Overflow]: http://stackoverflow.com/faq
|
||||
|
||||
[Zip]: http://en.wikipedia.org/wiki/Zip_%28file_format%29
|
||||
243
spring-integration-zip/build.gradle
Normal file
243
spring-integration-zip/build.gradle
Normal file
@@ -0,0 +1,243 @@
|
||||
description = 'Spring Integration Zip Adapter'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url 'https://repo.springsource.org/plugins-snapshot' }
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply from: "${rootProject.projectDir}/publish-maven.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
|
||||
group = 'org.springframework.integration'
|
||||
|
||||
repositories {
|
||||
maven { url 'http://repo.springsource.org/libs-milestone' }
|
||||
maven { url 'http://repo.springsource.org/plugins-release' }
|
||||
}
|
||||
|
||||
sourceCompatibility=1.6
|
||||
targetCompatibility=1.6
|
||||
|
||||
ext {
|
||||
|
||||
linkHomepage = 'https://github.com/spring-projects/spring-integration-extensions'
|
||||
linkCi = 'https://build.spring.io/browse/INTEXT-ZIP'
|
||||
linkIssue = 'https://jira.spring.io/browse/INTEXT'
|
||||
linkScmUrl = 'https://github.com/spring-projects/spring-integration-extensions'
|
||||
linkScmConnection = 'https://github.com/spring-projects/spring-integration-extensions.git'
|
||||
linkScmDevConnection = 'git@github.com:spring-projects/spring-integration-extensions.git'
|
||||
|
||||
junitVersion = '4.11'
|
||||
log4jVersion = '1.2.17'
|
||||
mockitoVersion = '1.9.5'
|
||||
springVersion = '4.0.7.RELEASE'
|
||||
springIntegrationVersion = '4.2.0.M1'
|
||||
ztZipVersion = '1.8'
|
||||
|
||||
idPrefix = 'zip'
|
||||
}
|
||||
|
||||
eclipse {
|
||||
project {
|
||||
natures += 'org.springframework.ide.eclipse.core.springnature'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
resources {
|
||||
srcDirs = ['src/test/resources', 'src/test/java']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:configurations
|
||||
// and http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html
|
||||
configurations {
|
||||
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.springframework.integration:spring-integration-core:$springIntegrationVersion"
|
||||
compile "org.springframework.integration:spring-integration-file:$springIntegrationVersion"
|
||||
compile "org.zeroturnaround:zt-zip:$ztZipVersion"
|
||||
testCompile "org.springframework.integration:spring-integration-test:$springIntegrationVersion"
|
||||
testCompile "junit:junit:$junitVersion"
|
||||
testCompile "log4j:log4j:$log4jVersion"
|
||||
testCompile "org.mockito:mockito-all:$mockitoVersion"
|
||||
testCompile "org.springframework:spring-test:$springVersion"
|
||||
jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.7.4.201502262128", classifier: "runtime"
|
||||
}
|
||||
|
||||
|
||||
// enable all compiler warnings; individual projects may customize further
|
||||
ext.xLintArg = '-Xlint:all'
|
||||
[compileJava, compileTestJava]*.options*.compilerArgs = [xLintArg]
|
||||
|
||||
test {
|
||||
// suppress all console output during testing unless running `gradle -i`
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=*"
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allJava
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
archives javadocJar
|
||||
}
|
||||
|
||||
apply plugin: 'sonar-runner'
|
||||
|
||||
sonarRunner {
|
||||
sonarProperties {
|
||||
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
|
||||
property "sonar.links.homepage", linkHomepage
|
||||
property "sonar.links.ci", linkCi
|
||||
property "sonar.links.issue", linkIssue
|
||||
property "sonar.links.scm", linkScmUrl
|
||||
property "sonar.links.scm_dev", linkScmDevConnection
|
||||
property "sonar.java.coveragePlugin", "jacoco"
|
||||
}
|
||||
}
|
||||
|
||||
task api(type: Javadoc) {
|
||||
group = 'Documentation'
|
||||
description = 'Generates the Javadoc API documentation.'
|
||||
title = "${rootProject.description} ${version} API"
|
||||
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
|
||||
options.author = true
|
||||
options.header = rootProject.description
|
||||
options.overview = 'src/api/overview.html'
|
||||
|
||||
source = sourceSets.main.allJava
|
||||
classpath = project.sourceSets.main.compileClasspath
|
||||
destinationDir = new File(buildDir, "api")
|
||||
}
|
||||
|
||||
task schemaZip(type: Zip) {
|
||||
group = 'Distribution'
|
||||
classifier = 'schema'
|
||||
description = "Builds -${classifier} archive containing all " +
|
||||
"XSDs for deployment at static.springframework.org/schema."
|
||||
|
||||
def Properties schemas = new Properties();
|
||||
def shortName = idPrefix.replaceFirst("${idPrefix}-", '')
|
||||
|
||||
project.sourceSets.main.resources.find {
|
||||
it.path.endsWith('META-INF/spring.schemas')
|
||||
}?.withInputStream { schemas.load(it) }
|
||||
|
||||
for (def key : schemas.keySet()) {
|
||||
File xsdFile = project.sourceSets.main.resources.find {
|
||||
it.path.endsWith(schemas.get(key))
|
||||
}
|
||||
assert xsdFile != null
|
||||
into ("integration/${shortName}") {
|
||||
from xsdFile.path
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task docsZip(type: Zip) {
|
||||
group = 'Distribution'
|
||||
classifier = 'docs'
|
||||
description = "Builds -${classifier} archive containing api docs " +
|
||||
"for deployment at static.springframework.org/spring-integration/docs."
|
||||
|
||||
from('src/dist') {
|
||||
include 'changelog.txt'
|
||||
}
|
||||
|
||||
from (api) {
|
||||
into 'api'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
|
||||
group = 'Distribution'
|
||||
classifier = 'dist'
|
||||
description = "Builds -${classifier} archive, containing all jars and docs, " +
|
||||
"suitable for community download page."
|
||||
|
||||
ext.baseDir = "${project.name}-${project.version}";
|
||||
|
||||
from('src/dist') {
|
||||
include 'readme.txt'
|
||||
include 'license.txt'
|
||||
include 'notice.txt'
|
||||
into "${baseDir}"
|
||||
}
|
||||
|
||||
from(zipTree(docsZip.archivePath)) {
|
||||
into "${baseDir}/docs"
|
||||
}
|
||||
|
||||
from(zipTree(schemaZip.archivePath)) {
|
||||
into "${baseDir}/schema"
|
||||
}
|
||||
|
||||
into ("${baseDir}/libs") {
|
||||
from project.jar
|
||||
from project.sourcesJar
|
||||
from project.javadocJar
|
||||
}
|
||||
}
|
||||
|
||||
// Create an optional "with dependencies" distribution.
|
||||
// Not published by default; only for use when building from source.
|
||||
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
|
||||
group = 'Distribution'
|
||||
classifier = 'dist-with-deps'
|
||||
description = "Builds -${classifier} archive, containing everything " +
|
||||
"in the -${distZip.classifier} archive plus all dependencies."
|
||||
|
||||
from zipTree(distZip.archivePath)
|
||||
|
||||
gradle.taskGraph.whenReady { taskGraph ->
|
||||
if (taskGraph.hasTask(":${zipTask.name}")) {
|
||||
def projectName = rootProject.name
|
||||
def artifacts = new HashSet()
|
||||
|
||||
rootProject.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
|
||||
def dependency = artifact.moduleVersion.id
|
||||
if (!projectName.equals(dependency.name)) {
|
||||
artifacts << artifact.file
|
||||
}
|
||||
}
|
||||
|
||||
zipTask.from(artifacts) {
|
||||
into "${distZip.baseDir}/deps"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives distZip
|
||||
archives docsZip
|
||||
archives schemaZip
|
||||
}
|
||||
|
||||
task dist(dependsOn: assemble) {
|
||||
group = 'Distribution'
|
||||
description = 'Builds -dist, -docs and -schema distribution archives.'
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = 'Generates gradlew[.bat] scripts'
|
||||
gradleVersion = '2.4'
|
||||
}
|
||||
1
spring-integration-zip/gradle.properties
Normal file
1
spring-integration-zip/gradle.properties
Normal file
@@ -0,0 +1 @@
|
||||
version=1.0.0.BUILD-SNAPSHOT
|
||||
BIN
spring-integration-zip/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
spring-integration-zip/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
spring-integration-zip/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
spring-integration-zip/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Tue May 12 22:21:08 EDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
|
||||
164
spring-integration-zip/gradlew
vendored
Executable file
164
spring-integration-zip/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
spring-integration-zip/gradlew.bat
vendored
Normal file
90
spring-integration-zip/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
61
spring-integration-zip/publish-maven.gradle
Normal file
61
spring-integration-zip/publish-maven.gradle
Normal file
@@ -0,0 +1,61 @@
|
||||
apply plugin: 'maven'
|
||||
|
||||
ext.optionalDeps = []
|
||||
ext.providedDeps = []
|
||||
|
||||
ext.optional = { optionalDeps << it }
|
||||
ext.provided = { providedDeps << it }
|
||||
|
||||
install {
|
||||
repositories.mavenInstaller {
|
||||
customizePom(pom, project)
|
||||
}
|
||||
}
|
||||
|
||||
def customizePom(pom, gradleProject) {
|
||||
pom.whenConfigured { generatedPom ->
|
||||
// respect 'optional' and 'provided' dependencies
|
||||
gradleProject.optionalDeps.each { dep ->
|
||||
generatedPom.dependencies.find { it.artifactId == dep.name }?.optional = true
|
||||
}
|
||||
gradleProject.providedDeps.each { dep ->
|
||||
generatedPom.dependencies.find { it.artifactId == dep.name }?.scope = 'provided'
|
||||
}
|
||||
|
||||
// eliminate test-scoped dependencies (no need in maven central poms)
|
||||
generatedPom.dependencies.removeAll { dep ->
|
||||
dep.scope == 'test'
|
||||
}
|
||||
|
||||
// add all items necessary for maven central publication
|
||||
generatedPom.project {
|
||||
name = gradleProject.description
|
||||
description = gradleProject.description
|
||||
url = 'https://github.com/SpringSource/spring-integration-extensions'
|
||||
organization {
|
||||
name = 'SpringSource'
|
||||
url = 'http://springsource.org'
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name 'The Apache Software License, Version 2.0'
|
||||
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||
distribution 'repo'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = 'https://github.com/SpringSource/spring-integration-extensions'
|
||||
connection = 'scm:git:git://github.com/SpringSource/spring-integration-extensions'
|
||||
developerConnection = 'scm:git:git://github.com/SpringSource/spring-integration-extensions'
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id = 'not specified'
|
||||
name = 'Gunnar Hillert'
|
||||
email = 'not specified'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
spring-integration-zip/src/api/overview.html
Normal file
22
spring-integration-zip/src/api/overview.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<body>
|
||||
This document is the API specification for Spring Integration
|
||||
<hr/>
|
||||
<div id="overviewBody">
|
||||
<p>
|
||||
For further API reference and developer documentation, see the
|
||||
<a href="http://static.springsource.org/spring-integration/reference" target="_top">Spring
|
||||
Integration reference documentation</a>.
|
||||
That documentation contains more detailed, developer-targeted
|
||||
descriptions, with conceptual overviews, definitions of terms,
|
||||
workarounds, and working code examples.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are interested in commercial training, consultancy, and
|
||||
support for Spring Integration, please visit <a href="http://www.springsource.com" target="_top">
|
||||
http://www.springsource.com</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
15
spring-integration-zip/src/dist/changelog.txt
vendored
Normal file
15
spring-integration-zip/src/dist/changelog.txt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Spring Integration Zip Adapter CHANGELOG
|
||||
=========================================
|
||||
|
||||
For the full detailed changelog, see:
|
||||
https://....
|
||||
|
||||
|
||||
Changes in version 1.0 GA (insert date here)
|
||||
https://....
|
||||
|
||||
|
||||
*** GENERAL ***
|
||||
|
||||
Upgraded Spring Framework dependency to ...
|
||||
...
|
||||
201
spring-integration-zip/src/dist/license.txt
vendored
Normal file
201
spring-integration-zip/src/dist/license.txt
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
21
spring-integration-zip/src/dist/notice.txt
vendored
Normal file
21
spring-integration-zip/src/dist/notice.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
========================================================================
|
||||
== NOTICE file corresponding to section 4 d of the Apache License, ==
|
||||
== Version 2.0, in this case for the Spring Integration distribution. ==
|
||||
========================================================================
|
||||
|
||||
This product includes software developed by
|
||||
the Apache Software Foundation (http://www.apache.org).
|
||||
|
||||
The end-user documentation included with a redistribution, if any,
|
||||
must include the following acknowledgement:
|
||||
|
||||
"This product includes software developed by the Spring Framework
|
||||
Project (http://www.springframework.org)."
|
||||
|
||||
Alternatively, this acknowledgement may appear in the software itself,
|
||||
if and wherever such third-party acknowledgements normally appear.
|
||||
|
||||
The names "Spring", "Spring Framework", and "Spring Integration" must
|
||||
not be used to endorse or promote products derived from this software
|
||||
without prior written permission. For written permission, please contact
|
||||
enquiries@springsource.com.
|
||||
13
spring-integration-zip/src/dist/readme.txt
vendored
Normal file
13
spring-integration-zip/src/dist/readme.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Spring Integration Zip Adapter
|
||||
-----------------------------------
|
||||
|
||||
To find out what has changed since any earlier releases, see 'changelog.txt'.
|
||||
|
||||
Please consult the documentation located within the 'docs/reference' directory
|
||||
of this release and also visit the official Spring Integration home at
|
||||
http://www.springsource.org/spring-integration
|
||||
|
||||
There you will find links to the forum, issue tracker, and several other resources.
|
||||
|
||||
See https://github.com/SpringSource/spring-integration#readme for additional
|
||||
information including instructions on building from source.
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.zip;
|
||||
|
||||
/**
|
||||
* Zip adapter specific message headers.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class ZipHeaders {
|
||||
|
||||
private static final String PREFIX = "zip_";
|
||||
|
||||
public static final String ZIP_ENTRY_FILE_NAME = PREFIX + "entryFilename";
|
||||
public static final String ZIP_ENTRY_PATH = PREFIX + "entryPath";
|
||||
public static final String ZIP_ENTRY_LAST_MODIFIED_DATE = PREFIX + "entryLastModifiedDate";
|
||||
|
||||
/** Noninstantiable utility class */
|
||||
private ZipHeaders() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractTransformerParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for Zip transformer parsers.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class AbstractZipTransformerParser extends AbstractTransformerParser {
|
||||
|
||||
/**
|
||||
* @param element The XML Element to process
|
||||
* @param parserContext The Spring ParserContext
|
||||
* @param builder BeanDefinitionBuilder for constructing Bean Definitions
|
||||
*/
|
||||
@Override
|
||||
protected final void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String deleteFiles = element.getAttribute("delete-files");
|
||||
if (StringUtils.hasText(deleteFiles)) {
|
||||
builder.addPropertyValue("deleteFiles", deleteFiles);
|
||||
}
|
||||
this.postProcessTransformer(element, parserContext, builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide additional configuration.
|
||||
*
|
||||
* @param element The XML Element to process
|
||||
* @param parserContext The Spring ParserContext
|
||||
* @param builder BeanDefinitionBuilder for constructing Bean Definitions
|
||||
*/
|
||||
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.zip.transformer.UnZipTransformer;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for the 'unzip-transformer' element.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public class UnZipTransformerParser extends AbstractZipTransformerParser {
|
||||
|
||||
@Override
|
||||
protected String getTransformerClassName() {
|
||||
return UnZipTransformer.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
|
||||
|
||||
final String resultType = element.getAttribute("result-type");
|
||||
|
||||
if (StringUtils.hasText(resultType)) {
|
||||
|
||||
final ZipResultType zipResultType = ZipResultType.convertToZipResultType(resultType);
|
||||
|
||||
if (zipResultType != null) {
|
||||
builder.addPropertyValue("zipResultType", zipResultType);
|
||||
}
|
||||
else {
|
||||
parserContext.getReaderContext().error(
|
||||
String.format("Unable to convert the provided result-type '%s' " +
|
||||
"to the respective ZipResultType enum.", resultType), source);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
|
||||
|
||||
/**
|
||||
* The namespace handler for the Zip namespace
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
this.registerBeanDefinitionParser("zip-transformer", new ZipTransformerParser());
|
||||
this.registerBeanDefinitionParser("unzip-transformer", new UnZipTransformerParser());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.integration.zip.transformer.ZipTransformer;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for the 'zip-transformer' element.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public class ZipTransformerParser extends AbstractZipTransformerParser {
|
||||
|
||||
@Override
|
||||
protected String getTransformerClassName() {
|
||||
return ZipTransformer.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "compression-level");
|
||||
|
||||
final String resultType = element.getAttribute("result-type");
|
||||
|
||||
if (StringUtils.hasText(resultType)) {
|
||||
|
||||
final ZipResultType zipResultType = ZipResultType.convertToZipResultType(resultType);
|
||||
|
||||
if (zipResultType != null) {
|
||||
builder.addPropertyValue("zipResultType", zipResultType);
|
||||
}
|
||||
else {
|
||||
parserContext.getReaderContext().error(
|
||||
String.format("Unable to convert the provided result-type '%s' " +
|
||||
"to the respective ZipResultType enum.", resultType), source);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Provides parser classes to provide Xml namespace support for the Zip components.
|
||||
*/
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Root package of the Zip Module.
|
||||
*/
|
||||
package org.springframework.integration.zip;
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.transformer.AbstractTransformer;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for transformers that provide Zip compression.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class AbstractZipTransformer extends AbstractTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ZipTransformer.class);
|
||||
|
||||
protected volatile Charset charset = Charset.defaultCharset();
|
||||
|
||||
protected volatile FileNameGenerator fileNameGenerator;
|
||||
|
||||
protected volatile ZipResultType zipResultType = ZipResultType.FILE;
|
||||
|
||||
protected volatile File workDirectory = new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer");
|
||||
|
||||
protected volatile boolean deleteFiles;
|
||||
|
||||
/**
|
||||
* If the payload is an instance of {@link File}, this property specifies
|
||||
* whether to delete the {@link File} after transformation.
|
||||
* Default is <em>false</em>.
|
||||
*
|
||||
* @param deleteFiles Defaults to <em>false</em> if not set
|
||||
*/
|
||||
public void setDeleteFiles(boolean deleteFiles) {
|
||||
this.deleteFiles = deleteFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the work-directory. The work directory is used when the {@link ZipResultType}
|
||||
* is set to {@link ZipResultType#FILE}. By default this property is set to
|
||||
* the System temporary directory containing a sub-directory "ziptransformer".
|
||||
*
|
||||
* @param workDirectory Must not be null and must not represent a file.
|
||||
*/
|
||||
public void setWorkDirectory(File workDirectory) {
|
||||
Assert.notNull(workDirectory, "workDirectory must not be null.");
|
||||
Assert.isTrue(!workDirectory.isFile(), "The workDirectory specified must not point to a file");
|
||||
this.workDirectory = workDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the format of the data returned after transformation. Available
|
||||
* options are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>File</li>
|
||||
* <li>Byte Array</li>
|
||||
* </ul>
|
||||
*
|
||||
* Defaults to {@link ZipResultType#FILE}.
|
||||
*
|
||||
* @param zipResultType Must not be null
|
||||
*/
|
||||
public void setZipResultType(ZipResultType zipResultType) {
|
||||
Assert.notNull(zipResultType, "The zipResultType must not be empty.");
|
||||
this.zipResultType = zipResultType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() throws Exception {
|
||||
super.onInit();
|
||||
|
||||
if (!workDirectory.exists()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Creating work directory '%s'.", this.workDirectory));
|
||||
}
|
||||
workDirectory.mkdirs();
|
||||
}
|
||||
final DefaultFileNameGenerator defaultFileNameGenerator = new DefaultFileNameGenerator();
|
||||
defaultFileNameGenerator.setBeanFactory(getBeanFactory());
|
||||
defaultFileNameGenerator.setConversionService(getConversionService());
|
||||
this.fileNameGenerator = defaultFileNameGenerator;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message the message and its payload must not be null.
|
||||
*/
|
||||
@Override
|
||||
protected Object doTransform(Message<?> message) throws Exception {
|
||||
Assert.notNull(message, "message must not be null");
|
||||
final Object payload = message.getPayload();
|
||||
Assert.notNull(payload, "payload must not be null");
|
||||
|
||||
return doZipTransform(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to provide the Zip transformation
|
||||
* logic.
|
||||
*
|
||||
* @param message The message will never be null.
|
||||
* @return The result of the Zip transformation.
|
||||
* @throws Exception Any exception.
|
||||
*/
|
||||
protected abstract Object doZipTransform(Message<?> message) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.zeroturnaround.zip.ZipEntrySource;
|
||||
import org.zeroturnaround.zip.ZipException;
|
||||
|
||||
/**
|
||||
* Once the Spring Integration Zip support matures, we need to contribute the
|
||||
* methods in this utility class back to the ZT Zip project.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class SpringZipUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringZipUtils.class);
|
||||
|
||||
public static byte[] pack(Collection<ZipEntrySource> entries, int compressionLevel) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Creating byte array from '%s'.",
|
||||
entries));
|
||||
}
|
||||
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
pack(entries, outputStream, compressionLevel);
|
||||
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
public static void pack(Collection<ZipEntrySource> entries, File zip,
|
||||
int compressionLevel) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating '" + zip + "' from "
|
||||
+ entries + ".");
|
||||
}
|
||||
|
||||
final FileOutputStream outputStream;
|
||||
try {
|
||||
outputStream = new FileOutputStream(zip);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalStateException(String.format("File '%s' not found.", zip.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
pack(entries, outputStream, compressionLevel);
|
||||
|
||||
}
|
||||
|
||||
private static void pack(Collection<ZipEntrySource> entries, OutputStream outputStream, int compressionLevel) {
|
||||
|
||||
ZipOutputStream out = null;
|
||||
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
|
||||
|
||||
try {
|
||||
out = new ZipOutputStream(bufferedOutputStream);
|
||||
out.setLevel(compressionLevel);
|
||||
for (ZipEntrySource entry : entries) {
|
||||
addEntry(entry, out);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw rethrow(e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void addEntry(ZipEntrySource entry, ZipOutputStream out)
|
||||
throws IOException {
|
||||
out.putNextEntry(entry.getEntry());
|
||||
InputStream in = entry.getInputStream();
|
||||
if (in != null) {
|
||||
try {
|
||||
IOUtils.copy(in, out);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
out.closeEntry();
|
||||
}
|
||||
|
||||
private static ZipException rethrow(IOException e) {
|
||||
throw new ZipException(e);
|
||||
}
|
||||
|
||||
public static void copy(InputStream in, File file) throws IOException {
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
|
||||
try {
|
||||
IOUtils.copy(in, out);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] copy(InputStream in) throws IOException {
|
||||
return IOUtils.toByteArray(in);
|
||||
}
|
||||
|
||||
static boolean isValid(final File file) {
|
||||
ZipFile zipfile = null;
|
||||
try {
|
||||
zipfile = new ZipFile(file);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (zipfile != null) {
|
||||
zipfile.close();
|
||||
zipfile = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.zeroturnaround.zip.ZipEntryCallback;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
/**
|
||||
* Transformer implementation that applies an UnZip transformation to the message
|
||||
* payload.
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipTransformer extends AbstractZipTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UnZipTransformer.class);
|
||||
|
||||
private volatile boolean expectSingleResult = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* This parameter indicates that only one result object shall be returned as
|
||||
* a result from the executed Unzip operation. If set to <code>true</code> and
|
||||
* more than 1 element is returned, then that
|
||||
* 1 element is extracted and returned as payload.
|
||||
*
|
||||
* If the result map contains more than 1 element and
|
||||
* {@link #expectSingleResult} is <code>true</code>, then a
|
||||
* {@link MessagingException} is thrown.
|
||||
*
|
||||
* If set to <code>false</code>, the complete result list is returned as the
|
||||
* payload. This is the {@code default}.
|
||||
*
|
||||
* @param expectSingleResult If not set explicitly, will default to false
|
||||
*
|
||||
*/
|
||||
public void setExpectSingleResult(boolean expectSingleResult) {
|
||||
this.expectSingleResult = expectSingleResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doZipTransform(final Message<?> message) throws Exception {
|
||||
|
||||
try {
|
||||
final Object payload = message.getPayload();
|
||||
final Object unzippedData;
|
||||
|
||||
InputStream inputStream = null;
|
||||
|
||||
try {
|
||||
if (payload instanceof File) {
|
||||
final File filePayload = (File) payload;
|
||||
|
||||
if (filePayload.isDirectory()) {
|
||||
throw new UnsupportedOperationException(String.format("Cannot unzip a directory: '%s'", filePayload.getAbsolutePath()));
|
||||
}
|
||||
|
||||
if (!SpringZipUtils.isValid(filePayload)) {
|
||||
throw new IllegalStateException(String.format("Not a zip file: '%s'.", filePayload.getAbsolutePath()));
|
||||
}
|
||||
|
||||
inputStream = new FileInputStream(filePayload);
|
||||
}
|
||||
else if (payload instanceof InputStream) {
|
||||
inputStream = (InputStream) payload;
|
||||
}
|
||||
else if (payload instanceof byte[]) {
|
||||
inputStream = new ByteArrayInputStream((byte[]) payload);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(String.format("Unsupported payload type '%s'. The only supported payload types are " +
|
||||
"java.io.File, byte[] and java.io.InputStream", payload.getClass().getSimpleName()));
|
||||
}
|
||||
|
||||
final SortedMap<String, Object> uncompressedData = new TreeMap<String, Object>();
|
||||
|
||||
ZipUtil.iterate(inputStream, new ZipEntryCallback() {
|
||||
|
||||
@Override
|
||||
public void process(InputStream zipEntryInputStream, ZipEntry zipEntry) throws IOException {
|
||||
|
||||
final String zipEntryName = zipEntry.getName();
|
||||
final long zipEntryTime = zipEntry.getTime();
|
||||
final long zipEntryCompressedSize = zipEntry.getCompressedSize();
|
||||
final String type = zipEntry.isDirectory() ? "directory" : "file";
|
||||
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(String.format("Unpacking Zip Entry - Name: '%s',Time: '%s', Compressed Size: '%s', Type: '%s'",
|
||||
zipEntryName, zipEntryTime, zipEntryCompressedSize, type));
|
||||
}
|
||||
|
||||
if (ZipResultType.FILE.equals(zipResultType)) {
|
||||
final File tempDir = new File(workDirectory, message.getHeaders().getId().toString());
|
||||
tempDir.mkdirs();
|
||||
final File destinationFile = new File(tempDir, zipEntryName);
|
||||
|
||||
if (zipEntry.isDirectory()) {
|
||||
destinationFile.mkdirs();
|
||||
}
|
||||
else {
|
||||
SpringZipUtils.copy(zipEntryInputStream, destinationFile);
|
||||
uncompressedData.put(zipEntryName, destinationFile);
|
||||
}
|
||||
}
|
||||
else if (ZipResultType.BYTE_ARRAY.equals(zipResultType)) {
|
||||
if (!zipEntry.isDirectory()) {
|
||||
byte[] data = IOUtils.toByteArray(zipEntryInputStream);
|
||||
uncompressedData.put(zipEntryName, data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unsupported zipResultType " + zipResultType);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (uncompressedData.isEmpty()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("No data unzipped from payload with message Id " + message.getHeaders().getId());
|
||||
}
|
||||
unzippedData = null;
|
||||
}
|
||||
else {
|
||||
|
||||
if (this.expectSingleResult) {
|
||||
if (uncompressedData.size() == 1) {
|
||||
unzippedData = uncompressedData.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new MessagingException(message,
|
||||
String.format("The UnZip operation extracted %s "
|
||||
+ "result objects but expectSingleResult was 'true'.", uncompressedData.size()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
unzippedData = uncompressedData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (payload instanceof File && this.deleteFiles) {
|
||||
final File filePayload = (File) payload;
|
||||
if (!filePayload.delete() && logger.isWarnEnabled()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("failed to delete File '" + filePayload + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
return unzippedData;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*/
|
||||
public enum ZipResultType {
|
||||
|
||||
FILE("FILE"),
|
||||
BYTE_ARRAY("BYTE_ARRAY");
|
||||
|
||||
private String id;
|
||||
|
||||
private ZipResultType(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the matching enum constant for a provided String representation
|
||||
* of the {@link ZipResultType}. The provided name must match exactly the identifier as
|
||||
* used to declare the enum constant.
|
||||
*
|
||||
* @param zipResultTypeAsString Name of the enum to convert. Must be not null and not empty.
|
||||
* @return The enumeration that matches. Returns Null of no match was found.
|
||||
*
|
||||
*/
|
||||
public static ZipResultType convertToZipResultType(String zipResultTypeAsString) {
|
||||
|
||||
Assert.hasText(zipResultTypeAsString, "Parameter zipResultTypeAsString must not be null or empty");
|
||||
|
||||
for (ZipResultType zipResultType : ZipResultType.values()) {
|
||||
if (zipResultType.name().equalsIgnoreCase(zipResultTypeAsString)) {
|
||||
return zipResultType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.transformer.Transformer;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.zeroturnaround.zip.ByteSource;
|
||||
import org.zeroturnaround.zip.FileSource;
|
||||
import org.zeroturnaround.zip.ZipEntrySource;
|
||||
|
||||
/**
|
||||
* {@link Transformer} implementation that applies a Zip transformation to the
|
||||
* message payload. Keep in mind that Zip entry timestamps are recorded only to
|
||||
* two 2 second precision:
|
||||
*
|
||||
* See also: http://mindprod.com/jgloss/zip.html
|
||||
*
|
||||
* If you want to generate Zip files larger than {@code 4GB}, you must use Java 7:
|
||||
*
|
||||
* See also: https://blogs.oracle.com/xuemingshen/entry/zip64_support_for_4g_zipfile
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformer extends AbstractZipTransformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ZipTransformer.class);
|
||||
|
||||
private static final String ZIP_EXTENSION = ".zip";
|
||||
|
||||
private volatile int compressionLevel = Deflater.DEFAULT_COMPRESSION;
|
||||
|
||||
private volatile boolean useFileAttributes = true;
|
||||
|
||||
@Autowired Environment env;
|
||||
|
||||
/**
|
||||
* Sets the compression level. Default is {@link Deflater#DEFAULT_COMPRESSION}.
|
||||
*
|
||||
* @param compressionLevel Must be an integer value from 0-9.
|
||||
*/
|
||||
public void setCompressionLevel(int compressionLevel) {
|
||||
Assert.isTrue(compressionLevel >= 0 && compressionLevel <= 9, "Acceptable levels are 0-9");
|
||||
this.compressionLevel = compressionLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the name of the file shall be used for the
|
||||
* zip entry.
|
||||
*
|
||||
* @param useFileAttributes Defaults to true if not set explicitly
|
||||
*/
|
||||
public void setUseFileAttributes(boolean useFileAttributes) {
|
||||
this.useFileAttributes = useFileAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The payload may encompass the following types:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link File}
|
||||
*...<li>{@link String}
|
||||
*...<li>byte[]
|
||||
*...<li>{@link Iterable}
|
||||
* </ul>
|
||||
*
|
||||
* When providing an {@link Iterable}, nested Iterables are not supported. However,
|
||||
* payloads can be of of any of the other supported types.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected Object doZipTransform(Message<?> message) throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
final Object payload = message.getPayload();
|
||||
final Object zippedData;
|
||||
final String baseFileName = this.fileNameGenerator.generateFileName(message);
|
||||
|
||||
final String zipEntryName;
|
||||
final String zipFileName;
|
||||
|
||||
if (message.getHeaders().containsKey(ZipHeaders.ZIP_ENTRY_FILE_NAME)) {
|
||||
zipEntryName = (String) message.getHeaders().get(ZipHeaders.ZIP_ENTRY_FILE_NAME);
|
||||
}
|
||||
else {
|
||||
zipEntryName = baseFileName;
|
||||
}
|
||||
|
||||
if (message.getHeaders().containsKey(FileHeaders.FILENAME)) {
|
||||
zipFileName = baseFileName;
|
||||
}
|
||||
else {
|
||||
zipFileName = baseFileName + ZIP_EXTENSION;
|
||||
}
|
||||
|
||||
final Date lastModifiedDate;
|
||||
|
||||
if (message.getHeaders().containsKey(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE)) {
|
||||
lastModifiedDate = (Date) message.getHeaders().get(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE);
|
||||
}
|
||||
else {
|
||||
lastModifiedDate = new Date();
|
||||
}
|
||||
|
||||
java.util.List<ZipEntrySource> entries = new ArrayList<ZipEntrySource>();
|
||||
|
||||
if (payload instanceof Iterable<?>) {
|
||||
int counter = 1;
|
||||
|
||||
String baseName = FilenameUtils.getBaseName(zipEntryName);
|
||||
String fileExtension = FilenameUtils.getExtension(zipEntryName);
|
||||
|
||||
if (StringUtils.hasText(fileExtension)) {
|
||||
fileExtension = FilenameUtils.EXTENSION_SEPARATOR_STR + fileExtension;
|
||||
}
|
||||
|
||||
for (Object item : (Iterable<?>) payload) {
|
||||
|
||||
final ZipEntrySource zipEntrySource = createZipEntrySource(item, lastModifiedDate, baseName + "_" + counter + fileExtension, useFileAttributes);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ZipEntrySource path: '" + zipEntrySource.getPath() + "'");
|
||||
}
|
||||
entries.add(zipEntrySource);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final ZipEntrySource zipEntrySource = createZipEntrySource(payload, lastModifiedDate, zipEntryName, useFileAttributes);
|
||||
entries.add(zipEntrySource);
|
||||
}
|
||||
|
||||
final byte[] zippedBytes = SpringZipUtils.pack(entries, this.compressionLevel);
|
||||
|
||||
if (ZipResultType.FILE.equals(zipResultType)) {
|
||||
final File zippedFile = new File(this.workDirectory, zipFileName);
|
||||
FileCopyUtils.copy(zippedBytes, zippedFile);
|
||||
zippedData = zippedFile;
|
||||
}
|
||||
else if (ZipResultType.BYTE_ARRAY.equals(zipResultType)) {
|
||||
zippedData = zippedBytes;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unsupported zipResultType " + zipResultType);
|
||||
}
|
||||
|
||||
return this.getMessageBuilderFactory()
|
||||
.withPayload(zippedData).copyHeaders(message.getHeaders()).setHeader(FileHeaders.FILENAME, zipFileName).build();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessageHandlingException(message, "Failed to apply Zip transformation.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ZipEntrySource createZipEntrySource(Object item,
|
||||
Date lastModifiedDate, String zipEntryName, boolean useFileAttributes) {
|
||||
|
||||
if (item instanceof File) {
|
||||
final File filePayload = (File) item;
|
||||
|
||||
final String fileName = useFileAttributes ? filePayload.getName() : zipEntryName;
|
||||
|
||||
if (((File) item).isDirectory()) {
|
||||
throw new UnsupportedOperationException("Zipping of directories is not supported.");
|
||||
}
|
||||
|
||||
final FileSource fileSource = new FileSource(fileName, filePayload);
|
||||
|
||||
if (this.deleteFiles) {
|
||||
if (!filePayload.delete() && logger.isWarnEnabled()) {
|
||||
logger.warn("failed to delete File '" + filePayload + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return fileSource;
|
||||
|
||||
}
|
||||
else if (item instanceof byte[] || item instanceof String) {
|
||||
|
||||
byte[] bytesToCompress = null;
|
||||
|
||||
if (item instanceof String) {
|
||||
bytesToCompress = ((String) item).getBytes(this.charset);
|
||||
}
|
||||
else {
|
||||
bytesToCompress = (byte[]) item;
|
||||
}
|
||||
|
||||
final ZipEntrySource zipEntrySource = new ByteSource(zipEntryName, bytesToCompress, lastModifiedDate.getTime());
|
||||
|
||||
return zipEntrySource;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
|
||||
"java.io.File, java.lang.String, and byte[]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer.splitter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipResultSplitter {
|
||||
|
||||
public List<Message<Object>> splitUnzippedMap(Map<String, Object> unzippedEntries) {
|
||||
|
||||
final List<Message<Object>> messages = new ArrayList<Message<Object>>(unzippedEntries.size());
|
||||
|
||||
for (Map.Entry<String, Object> entry : unzippedEntries.entrySet()) {
|
||||
final String path = FilenameUtils.getPath(entry.getKey());
|
||||
final String filename = FilenameUtils.getName(entry.getKey());
|
||||
final Message<Object> splitMessage = MessageBuilder.withPayload(entry.getValue())
|
||||
.setHeader(FileHeaders.FILENAME, filename)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_PATH, path).build();
|
||||
messages.add(splitMessage);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.springframework.org/schema/integration/zip=org.springframework.integration.zip.config.xml.ZipNamespaceHandler
|
||||
@@ -0,0 +1,2 @@
|
||||
http\://www.springframework.org/schema/integration/zip/spring-integration-zip-1.0.xsd=org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd
|
||||
http\://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd=org/springframework/integration/config/xml/spring-integration-zip-1.0.xsd
|
||||
@@ -0,0 +1,4 @@
|
||||
# Tooling related information for the integration Zip namespace
|
||||
http\://www.springframework.org/schema/integration/zip@name=integration Zip Namespace
|
||||
http\://www.springframework.org/schema/integration/zip@prefix=int-zip
|
||||
http\://www.springframework.org/schema/integration/zip@icon=org/springframework/integration/config/xml/spring-integration-zip.gif
|
||||
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
targetNamespace="http://www.springframework.org/schema/integration/zip"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration"
|
||||
schemaLocation="http://www.springframework.org/schema/integration/spring-integration.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Integration
|
||||
Zip Adapter.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="zip-transformer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Creates a Transformer that compresses message
|
||||
payloads using Zip compressions. The following payload types are
|
||||
supported:
|
||||
|
||||
- java.io.File
|
||||
- byte[]
|
||||
- String
|
||||
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="transformerType">
|
||||
<xsd:attribute name="compression-level" type="xsd:integer"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Sets the compression level. Default is
|
||||
java.util.zip.Deflater.DEFAULT_COMPRESSION
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="unzip-transformer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Creates a Transformer that uncompresses message
|
||||
payloads using Zip compressions. The following payload types are
|
||||
supported:
|
||||
|
||||
- java.io.File
|
||||
- byte[]
|
||||
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="transformerType">
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="transformerType">
|
||||
<xsd:attribute name="id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Identifies the underlying Spring bean definition (EventDrivenConsumer)]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="input-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[The input channel of the transformer.]]>
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="output-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[The channel to which the transformer will send the transformed message.
|
||||
Optional, because incoming messages can specify a reply channel using the 'replyChannel'
|
||||
message header value themselves.]]>
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="delete-files" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[If the payload is an instance of {@link File}, this
|
||||
attribute specifies whether to delete the {@link File} after
|
||||
transformation. The default is 'false'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expect-single-result" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[If set to 'true', this property indicates
|
||||
that only one result object shall be returned as a result
|
||||
from the executed Unzip operation. Defaults to 'false'.]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="result-type" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Defines the format of the data returned after
|
||||
transformation. Available options are:
|
||||
- File
|
||||
- Byte Array
|
||||
|
||||
Depending on the used input format, not all
|
||||
options may be applicable.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="resultType xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="resultType">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="BYTE_ARRAY" />
|
||||
<xsd:enumeration value="FILE" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 539 B |
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
|
||||
<int:chain input-channel="input" output-channel="out">
|
||||
<int-zip:unzip-transformer result-type="BYTE_ARRAY"/>
|
||||
<int:splitter method="splitUnzippedMap">
|
||||
<bean class="org.springframework.integration.zip.transformer.splitter.UnZipResultSplitter"/>
|
||||
</int:splitter>
|
||||
</int:chain>
|
||||
|
||||
<int:channel id="out">
|
||||
<int:interceptors>
|
||||
<int:wire-tap channel="logger"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:logging-channel-adapter id="logger" log-full-message="true" level="WARN"/>
|
||||
|
||||
<int-file:outbound-channel-adapter id="write-file" channel="out" directory-expression="'${workDir}/' + headers.zip_entryPath" auto-create-directory="true"/>
|
||||
|
||||
<context:property-placeholder properties-ref="properties"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZip2FileTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private ResourceLoader resourceLoader;
|
||||
private MessageChannel input;
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
properties.put("workDir", workDir);
|
||||
System.out.print(this.workDir.getAbsolutePath());
|
||||
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
context.register(ContextConfiguration.class);
|
||||
context.refresh();
|
||||
input = context.getBean("input", MessageChannel.class);
|
||||
resourceLoader = context;
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void unZipWithOneEntry() throws Exception {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
byte[] zipdata = IOUtils.toByteArray(is);
|
||||
|
||||
final Message<byte[]> message = MessageBuilder.withPayload(zipdata).build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
|
||||
File fileInWorkDir = this.workDir.listFiles()[0];
|
||||
|
||||
Assert.assertTrue(fileInWorkDir.isFile());
|
||||
Assert.assertEquals("single.txt", fileInWorkDir.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unZipWithMultipleEntries() throws Exception {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
byte[] zipdata = IOUtils.toByteArray(is);
|
||||
|
||||
final Message<byte[]> message = MessageBuilder.withPayload(zipdata).build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 4);
|
||||
|
||||
File[] files = this.workDir.listFiles();
|
||||
|
||||
boolean continents = false;
|
||||
boolean de = false;
|
||||
boolean fr = false;
|
||||
boolean pl = false;
|
||||
|
||||
for (File file : files) {
|
||||
if (file.getName().equals("continents")) {
|
||||
continents = true;
|
||||
Assert.assertTrue(file.isDirectory());
|
||||
Assert.assertTrue(file.list().length == 2);
|
||||
}
|
||||
if (file.getName().equals("de.txt")) {
|
||||
de = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
if (file.getName().equals("fr.txt")) {
|
||||
fr = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
if (file.getName().equals("pl.txt")) {
|
||||
pl = true;
|
||||
Assert.assertTrue(file.isFile());
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue(continents);
|
||||
Assert.assertTrue(de);
|
||||
Assert.assertTrue(fr);
|
||||
Assert.assertTrue(pl);
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:org/springframework/integration/zip/UnZip2FileTests-context.xml")
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
Properties properties() throws IOException {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<int:channel id="input">
|
||||
</int:channel>
|
||||
|
||||
<int-zip:zip-transformer input-channel="input" output-channel="write-file" result-type="BYTE_ARRAY"/>
|
||||
<int-file:outbound-channel-adapter id="write-file" directory="${workDir}" auto-create-directory="true"/>
|
||||
|
||||
<context:property-placeholder properties-ref="properties"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class Zip2FileTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private MessageChannel input;
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
properties.put("workDir", workDir);
|
||||
System.out.print(this.workDir.getAbsolutePath());
|
||||
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
context.register(ContextConfiguration.class);
|
||||
context.refresh();
|
||||
input = context.getBean("input", MessageChannel.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringWithDefaultFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final Message<String> message = MessageBuilder.withPayload("Zip me up.").build();
|
||||
|
||||
input.send(message);
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
|
||||
File fileInWorkDir = this.workDir.listFiles()[0];
|
||||
|
||||
Assert.assertTrue(fileInWorkDir.isFile());
|
||||
Assert.assertTrue(fileInWorkDir.getName().contains(message.getHeaders().getId().toString()));
|
||||
Assert.assertTrue("The created file should have a 'zip' file extension.", fileInWorkDir.getName().endsWith(".zip"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringWithExplicitFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
input.send(MessageBuilder.withPayload("Zip me up.").setHeader(FileHeaders.FILENAME, "zipString.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipString.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipBytesWithExplicitFileName() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
input.send(MessageBuilder.withPayload("Zip me up.".getBytes()).setHeader(FileHeaders.FILENAME, "zipString.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipString.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipFile() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final File fileToCompress = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToCompress, "hello world");
|
||||
|
||||
input.send(MessageBuilder.withPayload(fileToCompress).build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals(fileToCompress.getName() + ".zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipIterableWithMultipleStrings() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
String stringToCompress1 = "String1";
|
||||
String stringToCompress2 = "String2";
|
||||
String stringToCompress3 = "String3";
|
||||
String stringToCompress4 = "String4";
|
||||
|
||||
final List<String> stringsToCompress = new ArrayList<String>(4);
|
||||
|
||||
stringsToCompress.add(stringToCompress1);
|
||||
stringsToCompress.add(stringToCompress2);
|
||||
stringsToCompress.add(stringToCompress3);
|
||||
stringsToCompress.add(stringToCompress4);
|
||||
|
||||
input.send(MessageBuilder.withPayload(stringsToCompress).setHeader(FileHeaders.FILENAME, "zipWith4Strings.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("zipWith4Strings.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipIterableWithDifferentTypes() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
String stringToCompress = "String1";
|
||||
byte[] bytesToCompress = "String2".getBytes();
|
||||
final File fileToCompress = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToCompress, "hello world");
|
||||
|
||||
final List<Object> objectsToCompress = new ArrayList<Object>(3);
|
||||
|
||||
objectsToCompress.add(stringToCompress);
|
||||
objectsToCompress.add(bytesToCompress);
|
||||
objectsToCompress.add(fileToCompress);
|
||||
|
||||
input.send(MessageBuilder.withPayload(objectsToCompress).setHeader(FileHeaders.FILENAME, "objects-to-compress.zip").build());
|
||||
|
||||
Assert.assertTrue(this.workDir.list().length == 1);
|
||||
Assert.assertEquals("objects-to-compress.zip", this.workDir.listFiles()[0].getName());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:org/springframework/integration/zip/Zip2FileTests-context.xml")
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
Properties properties() throws IOException {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.transformer.MessageTransformingHandler;
|
||||
import org.springframework.integration.zip.transformer.UnZipTransformer;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class UnZipTransformerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testUnZiptransformerParserWithDefaults() {
|
||||
|
||||
setUp("UnZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("unzipTransformerWithDefaults", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final UnZipTransformer unZipTransformer = TestUtils.getPropertyValue(handler, "transformer", UnZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(unZipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(unZipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(unZipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(unZipTransformer, "workDirectory", File.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(unZipTransformer, "deleteFiles", Boolean.class);
|
||||
final Boolean expectSingleResult = TestUtils.getPropertyValue(unZipTransformer, "expectSingleResult", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(deleteFiles);
|
||||
assertNotNull(expectSingleResult);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertFalse("By default the 'deleteFiles' property should be false.", deleteFiles);
|
||||
assertFalse("The 'expectSingleResult' property should be false.", expectSingleResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnZiptransformerParserWithExplicitSettings() {
|
||||
|
||||
setUp("UnZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("unzipTransformer", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final UnZipTransformer unZipTransformer = TestUtils.getPropertyValue(handler, "transformer", UnZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(unZipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(unZipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(unZipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(unZipTransformer, "workDirectory", File.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(unZipTransformer, "deleteFiles", Boolean.class);
|
||||
final Boolean expectSingleResult = TestUtils.getPropertyValue(unZipTransformer, "expectSingleResult", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(deleteFiles);
|
||||
assertNotNull(expectSingleResult);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertTrue("The 'deleteFiles' property should be true.", deleteFiles);
|
||||
assertTrue("The 'expectSingleResult' property should be true.", expectSingleResult);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown(){
|
||||
if(context != null){
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUp(String name, Class<?> cls){
|
||||
context = new ClassPathXmlApplicationContext(name, cls);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:unzip-transformer id="unzipTransformer"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="FILE" expect-single-result="true"/>
|
||||
|
||||
<int-zip:unzip-transformer id="unzipTransformerWithDefaults"
|
||||
input-channel="input" output-channel="output" />
|
||||
</beans>
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.zip.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.transformer.MessageTransformingHandler;
|
||||
import org.springframework.integration.zip.transformer.ZipResultType;
|
||||
import org.springframework.integration.zip.transformer.ZipTransformer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformerParserTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithDefaults() {
|
||||
|
||||
setUp("ZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("zipTransformerWithDefaults", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final ZipTransformer zipTransformer = TestUtils.getPropertyValue(handler, "transformer", ZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(zipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(zipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(zipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(zipTransformer, "workDirectory", File.class);
|
||||
final Integer compressionLevel = TestUtils.getPropertyValue(zipTransformer, "compressionLevel", Integer.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(zipTransformer, "deleteFiles", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(compressionLevel);
|
||||
assertNotNull(deleteFiles);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.FILE, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertEquals(Integer.valueOf(Deflater.DEFAULT_COMPRESSION), Integer.valueOf(compressionLevel));
|
||||
assertFalse("By default the 'deleteFiles' property should be false.", deleteFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithExplicitSettings() {
|
||||
|
||||
setUp("ZipTransformerParserTests.xml", getClass());
|
||||
|
||||
EventDrivenConsumer consumer = this.context.getBean("zipTransformer", EventDrivenConsumer.class);
|
||||
|
||||
final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("input", inputChannel.getComponentName());
|
||||
|
||||
final MessageTransformingHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageTransformingHandler.class);
|
||||
|
||||
final AbstractMessageChannel outputChannel = TestUtils.getPropertyValue(handler, "outputChannel", AbstractMessageChannel.class);
|
||||
assertEquals("output", outputChannel.getComponentName());
|
||||
|
||||
final ZipTransformer zipTransformer = TestUtils.getPropertyValue(handler, "transformer", ZipTransformer.class);
|
||||
|
||||
final Charset charset = TestUtils.getPropertyValue(zipTransformer, "charset", Charset.class);
|
||||
final FileNameGenerator fileNameGenerator = TestUtils.getPropertyValue(zipTransformer, "fileNameGenerator", FileNameGenerator.class);
|
||||
final ZipResultType zipResultType = TestUtils.getPropertyValue(zipTransformer, "zipResultType", ZipResultType.class);
|
||||
final File workDirectory = TestUtils.getPropertyValue(zipTransformer, "workDirectory", File.class);
|
||||
final Integer compressionLevel = TestUtils.getPropertyValue(zipTransformer, "compressionLevel", Integer.class);
|
||||
final Boolean deleteFiles = TestUtils.getPropertyValue(zipTransformer, "deleteFiles", Boolean.class);
|
||||
|
||||
assertNotNull(charset);
|
||||
assertNotNull(fileNameGenerator);
|
||||
assertNotNull(zipResultType);
|
||||
assertNotNull(workDirectory);
|
||||
assertNotNull(compressionLevel);
|
||||
assertNotNull(deleteFiles);
|
||||
|
||||
assertEquals(Charset.defaultCharset(), charset);
|
||||
Assert.isInstanceOf(DefaultFileNameGenerator.class, fileNameGenerator);
|
||||
assertEquals(ZipResultType.BYTE_ARRAY, zipResultType);
|
||||
assertEquals(new File(System.getProperty("java.io.tmpdir") + File.separator + "ziptransformer"), workDirectory);
|
||||
assertTrue("WorkDirectory should exist.", workDirectory.exists());
|
||||
assertTrue("WorkDirectory should be a directory.", workDirectory.isDirectory());
|
||||
assertEquals(Integer.valueOf(2), Integer.valueOf(compressionLevel));
|
||||
assertTrue("The 'deleteFiles' property should be true.", deleteFiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZiptransformerParserWithIncorrectResultType() {
|
||||
|
||||
try {
|
||||
setUp("ZipTransformerParserTestsWithIncorrectResultType.xml", getClass());
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
String expectedErrorMessage = "Unable to convert the provided result-type 'INCORRECT' " +
|
||||
"to the respective ZipResultType enum.";
|
||||
assertTrue(String.format("Expected exception message to contain '%s' but got '%s'", expectedErrorMessage, e.getMessage()),
|
||||
e.getMessage().contains(expectedErrorMessage));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
@After
|
||||
public void tearDown(){
|
||||
if(context != null){
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUp(String name, Class<?> cls){
|
||||
context = new ClassPathXmlApplicationContext(name, cls);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformer" compression-level="2"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="BYTE_ARRAY"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformerWithDefaults"
|
||||
input-channel="input" output-channel="output" />
|
||||
</beans>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
<int:channel id="input"/>
|
||||
<int:channel id="output"/>
|
||||
|
||||
<int-zip:zip-transformer id="zipTransformer" compression-level="2"
|
||||
delete-files="true" input-channel="input" output-channel="output"
|
||||
result-type="INCORRECT"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"classpath:org/springframework/integration/zip/transformer/UnZipTransformerTests.xml"})
|
||||
public class UnZipTransformerTests {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private File workDir;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
this.workDir = testFolder.newFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing a single file only. The result will be
|
||||
* a byte array.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileAsInputstreamToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final File inputFile = new File(this.workDir, "unzipSingleFileToByteArray");
|
||||
|
||||
IOUtils.copy(is, new FileOutputStream(inputFile));
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(inputFile).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertTrue(inputFile.exists());
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipSingleFileToByteArrayWithDeleteFilesTrue() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/single.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final File inputFile = new File(this.workDir, "unzipSingleFileToByteArray");
|
||||
|
||||
IOUtils.copy(is, new FileOutputStream(inputFile));
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(inputFile).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setDeleteFiles(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 1);
|
||||
Assert.assertFalse(inputFile.exists());
|
||||
Assert.assertEquals("Spring Integration Rocks!", new String(unzippedData.values().iterator().next()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing multiple files. The result will be
|
||||
* a collection of files.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipMultipleFilesAsInputstreamToByteArray() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<?> resultMessage = unZipTransformer.transform(message);
|
||||
|
||||
Assert.assertNotNull(resultMessage);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, byte[]> unzippedData = (Map<String, byte[]>) resultMessage.getPayload();
|
||||
|
||||
Assert.assertNotNull(unzippedData);
|
||||
Assert.assertTrue(unzippedData.size() == 5);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* UnCompress a ZIP archive containing multiple files. The result will be
|
||||
* a collection of files.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void unzipMultipleFilesAsInputstreamWithExpectSingleResultTrue() throws IOException {
|
||||
|
||||
final Resource resource = resourceLoader.getResource("classpath:testzipdata/countries.zip");
|
||||
final InputStream is = resource.getInputStream();
|
||||
|
||||
final Message<InputStream> message = MessageBuilder.withPayload(is).build();
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setExpectSingleResult(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
unZipTransformer.transform(message);
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
Assert.assertTrue(e.getMessage().contains("The UnZip operation extracted "
|
||||
+ "5 result objects but expectSingleResult was 'true'."));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.fail("Expected a MessagingException to be thrown.");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unzipInvalidZipFile() throws FileNotFoundException, IOException, InterruptedException {
|
||||
|
||||
final File fileToUnzip = testFolder.newFile();
|
||||
FileUtils.writeStringToFile(fileToUnzip, "hello world");
|
||||
|
||||
final UnZipTransformer unZipTransformer = new UnZipTransformer();
|
||||
unZipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
unZipTransformer.setExpectSingleResult(true);
|
||||
unZipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(fileToUnzip).build();
|
||||
|
||||
try {
|
||||
unZipTransformer.transform(message);
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
Assert.assertTrue(e.getMessage().contains(String.format("Not a zip file: '%s'.", fileToUnzip.getAbsolutePath())));
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.fail("Expected a MessagingException to be thrown.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/zip http://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.zip.transformer;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.zip.ZipHeaders;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
public class ZipTransformerTests {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder testFolder = new TemporaryFolder();
|
||||
|
||||
/**
|
||||
* Compress a simple String. The result will be a byte array.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void zipString() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String stringToCompress = "Hello World";
|
||||
|
||||
final Date fileDate = new Date();
|
||||
|
||||
final Message<String> message = MessageBuilder.withPayload(stringToCompress)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, "test.txt")
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE, fileDate)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Object resultPayload = result.getPayload();
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of byte but was "
|
||||
+ resultPayload.getClass().getName(), resultPayload instanceof byte[]);
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
ZipUtil.unpack(new ByteArrayInputStream((byte[]) resultPayload), temporaryTestDirectory);
|
||||
|
||||
final File unzippedEntry = new File(temporaryTestDirectory, "test.txt");
|
||||
Assert.assertTrue(unzippedEntry.exists());
|
||||
Assert.assertTrue(unzippedEntry.isFile());
|
||||
|
||||
//See http://stackoverflow.com/questions/3725662/what-is-the-earliest-timestamp-value-that-is-supported-in-zip-file-format
|
||||
Assert.assertTrue((fileDate.getTime() - 3000) < unzippedEntry.lastModified());
|
||||
Assert.assertTrue((fileDate.getTime() + 3000) > unzippedEntry.lastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringCollection() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.BYTE_ARRAY);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String string1ToCompress = "Cartman";
|
||||
final String string2ToCompress = "Kenny";
|
||||
final String string3ToCompress = "Butters";
|
||||
|
||||
final List<String> strings = new ArrayList<String>(3);
|
||||
|
||||
strings.add(string1ToCompress);
|
||||
strings.add(string2ToCompress);
|
||||
strings.add(string3ToCompress);
|
||||
|
||||
final Date fileDate = new Date();
|
||||
|
||||
final Message<List<String>> message = MessageBuilder.withPayload(strings)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, "test.txt")
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE, fileDate)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Object resultPayload = result.getPayload();
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of byte but was "
|
||||
+ resultPayload.getClass().getName(), resultPayload instanceof byte[]);
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
ZipUtil.unpack(new ByteArrayInputStream((byte[]) resultPayload), temporaryTestDirectory);
|
||||
|
||||
File[] files = temporaryTestDirectory.listFiles();
|
||||
|
||||
Assert.assertTrue(files.length >= 3);
|
||||
|
||||
final Set<String> expectedFileNames = new HashSet<String>();
|
||||
|
||||
expectedFileNames.add("test_1.txt");
|
||||
expectedFileNames.add("test_2.txt");
|
||||
expectedFileNames.add("test_3.txt");
|
||||
|
||||
for (File file : files) {
|
||||
|
||||
if (file.getName().startsWith("test")) {
|
||||
Assert.assertTrue(file.exists());
|
||||
Assert.assertTrue(file.isFile());
|
||||
|
||||
//See http://stackoverflow.com/questions/3725662/what-is-the-earliest-timestamp-value-that-is-supported-in-zip-file-format
|
||||
Assert.assertTrue(String.format("%s : %s", fileDate.getTime() - 4000, file.lastModified()), (fileDate.getTime() - 4000) < file.lastModified());
|
||||
Assert.assertTrue((fileDate.getTime() + 4000) > file.lastModified());
|
||||
|
||||
Assert.assertTrue(
|
||||
String.format("File '%s' did not end with '.txt'.", file.getName()),
|
||||
file.getName().endsWith(".txt"));
|
||||
|
||||
Assert.assertTrue(expectedFileNames.contains(file.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipStringToFile() throws FileNotFoundException, IOException {
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.setZipResultType(ZipResultType.FILE);
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final String stringToCompress = "Hello World";
|
||||
|
||||
final String zipEntryFileName = "test.txt";
|
||||
final Message<String> message = MessageBuilder.withPayload(stringToCompress)
|
||||
.setHeader(ZipHeaders.ZIP_ENTRY_FILE_NAME, zipEntryFileName)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue("Expected payload to be an instance of file but was "
|
||||
+ result.getPayload().getClass().getName(), result.getPayload() instanceof File);
|
||||
|
||||
final File payload = (File) result.getPayload();
|
||||
|
||||
System.out.println(payload.getAbsolutePath());
|
||||
|
||||
Assert.assertEquals(message.getHeaders().getId().toString() + ".msg.zip", payload.getName());
|
||||
Assert.assertTrue(SpringZipUtils.isValid(payload));
|
||||
|
||||
final byte[] zipEntryData = ZipUtil.unpackEntry(payload, "test.txt");
|
||||
|
||||
Assert.assertNotNull("Entry '" + zipEntryFileName + "' was not found.", zipEntryData);
|
||||
Assert.assertTrue("Hello World".equals(new String(zipEntryData)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipFile() throws IOException {
|
||||
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final File testFile = createTestFile(10);
|
||||
|
||||
Assert.assertTrue(testFile.exists());
|
||||
|
||||
final Message<File> message = MessageBuilder.withPayload(testFile).build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue(result.getPayload() instanceof File);
|
||||
|
||||
final File payload = (File) result.getPayload();
|
||||
|
||||
Assert.assertEquals(testFile.getName() + ".zip", payload.getName());
|
||||
Assert.assertTrue(SpringZipUtils.isValid(payload));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zipCollection() throws IOException {
|
||||
|
||||
final File testFile1 = createTestFile(1);
|
||||
final File testFile2 = createTestFile(2);
|
||||
final File testFile3 = createTestFile(3);
|
||||
final File testFile4 = createTestFile(4);
|
||||
|
||||
Assert.assertTrue(testFile1.exists());
|
||||
Assert.assertTrue(testFile2.exists());
|
||||
Assert.assertTrue(testFile3.exists());
|
||||
Assert.assertTrue(testFile4.exists());
|
||||
|
||||
final Collection<File> files = new ArrayList<File>();
|
||||
|
||||
files.add(testFile1);
|
||||
files.add(testFile2);
|
||||
files.add(testFile3);
|
||||
files.add(testFile4);
|
||||
|
||||
final ZipTransformer zipTransformer = new ZipTransformer();
|
||||
zipTransformer.setBeanFactory(mock(BeanFactory.class));
|
||||
zipTransformer.afterPropertiesSet();
|
||||
|
||||
final Message<Collection<File>> message = MessageBuilder.withPayload(files)
|
||||
.build();
|
||||
|
||||
final Message<?> result = zipTransformer.transform(message);
|
||||
|
||||
Assert.assertTrue(result.getPayload() instanceof File);
|
||||
|
||||
final File outputZipFile = (File) result.getPayload();
|
||||
|
||||
Assert.assertTrue(outputZipFile.exists());
|
||||
Assert.assertTrue(outputZipFile.isFile());
|
||||
Assert.assertTrue(outputZipFile.getName().endsWith("zip"));
|
||||
Assert.assertTrue(SpringZipUtils.isValid(outputZipFile));
|
||||
|
||||
}
|
||||
|
||||
private File createTestFile(int size) throws IOException {
|
||||
|
||||
final File temporaryTestDirectory = testFolder.newFolder();
|
||||
|
||||
final File testFile = new File(temporaryTestDirectory, "testdata" + UUID.randomUUID().toString() + ".data");
|
||||
|
||||
RandomAccessFile f = null;
|
||||
try {
|
||||
f = new RandomAccessFile(testFile, "rw");
|
||||
f.setLength(size * 1024 * 1024);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (f != null) {
|
||||
f.close();
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
return testFile;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n
|
||||
|
||||
log4j.category.org.springframework.integration=INFO
|
||||
log4j.category.org.springframework.integration.zip=INFO
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Asia
|
||||
@@ -0,0 +1 @@
|
||||
Europe
|
||||
@@ -0,0 +1 @@
|
||||
Germany
|
||||
@@ -0,0 +1 @@
|
||||
France
|
||||
@@ -0,0 +1 @@
|
||||
Poland
|
||||
BIN
spring-integration-zip/src/test/resources/testzipdata/single.zip
Normal file
BIN
spring-integration-zip/src/test/resources/testzipdata/single.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user