/* * Copyright 2013-2016 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.file.remote.session; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.file.remote.InputStreamCallback; import org.springframework.integration.file.remote.RemoteFileTemplate; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.support.GenericMessage; /** * @author Gary Russell * @since 3.0 * */ public class CachingSessionFactoryTests { @Test public void testCacheAndReset() { TestSessionFactory factory = new TestSessionFactory(); CachingSessionFactory<String> cache = new CachingSessionFactory<String>(factory); Session<String> sess1 = cache.getSession(); assertEquals("session:1", TestUtils.getPropertyValue(sess1, "targetSession.id")); Session<String> sess2 = cache.getSession(); assertEquals("session:2", TestUtils.getPropertyValue(sess2, "targetSession.id")); sess1.close(); // session back to pool; should be open and reused. assertTrue(sess1.isOpen()); sess1 = cache.getSession(); assertEquals("session:1", TestUtils.getPropertyValue(sess1, "targetSession.id")); sess1.close(); assertTrue(sess1.isOpen()); // reset the cache; should close idle (sess1); sess2 should closed later cache.resetCache(); assertFalse(sess1.isOpen()); sess1 = cache.getSession(); assertEquals("session:3", TestUtils.getPropertyValue(sess1, "targetSession.id")); sess1.close(); assertTrue(sess1.isOpen()); // session from previous epoch is closed on return sess2.close(); assertFalse(sess2.isOpen()); cache.resetCache(); assertFalse(sess1.isOpen()); } @Test public void testDirtySession() throws Exception { @SuppressWarnings("unchecked") SessionFactory<Object> factory = mock(SessionFactory.class); @SuppressWarnings("unchecked") Session<Object> session = mock(Session.class); when(factory.getSession()).thenReturn(session); when(session.readRaw("foo")).thenReturn(new ByteArrayInputStream("".getBytes())); when(session.finalizeRaw()).thenReturn(true); CachingSessionFactory<Object> ccf = new CachingSessionFactory<Object>(factory); RemoteFileTemplate<Object> template = new RemoteFileTemplate<Object>(ccf); template.setFileNameExpression(new LiteralExpression("foo")); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); try { template.get(new GenericMessage<String>("foo"), (InputStreamCallback) stream -> { throw new RuntimeException("bar"); }); fail("Expected exception"); } catch (Exception e) { assertThat(e.getCause(), instanceOf(RuntimeException.class)); assertThat(e.getCause().getMessage(), equalTo("bar")); } verify(session).close(); } private class TestSessionFactory implements SessionFactory<String> { private int n; @Override public Session<String> getSession() { return new TestSession("session:" + ++n); } } private class TestSession implements Session<String> { @SuppressWarnings("unused") private final String id; private volatile boolean open = true; private TestSession(String id) { this.id = id; } @Override public boolean remove(String path) throws IOException { return false; } @Override public String[] list(String path) throws IOException { return null; } @Override public void read(String source, OutputStream outputStream) throws IOException { } @Override public void write(InputStream inputStream, String destination) throws IOException { } @Override public void append(InputStream inputStream, String destination) throws IOException { } @Override public boolean mkdir(String directory) throws IOException { return false; } @Override public boolean rmdir(String directory) throws IOException { return false; } @Override public void rename(String pathFrom, String pathTo) throws IOException { } @Override public void close() { this.open = false; } @Override public boolean isOpen() { return this.open; } @Override public boolean exists(String path) throws IOException { return false; } @Override public String[] listNames(String path) throws IOException { return null; } @Override public InputStream readRaw(String source) throws IOException { return null; } @Override public boolean finalizeRaw() throws IOException { return false; } @Override public Object getClientInstance() { return null; } } }