From d754fb12961cab92b2985860e769b782584813f1 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Tue, 16 Nov 2010 12:44:13 -0500 Subject: [PATCH] INT-1614 first roud of refactoring for SFTP, removed SessionFactory configuration items from the namespace, added sesion-factory attribute to the inbound/outbound adapters --- ...SynchronizingMessageSourceFactoryBean.java | 97 ++++++++++--------- .../sftp/config/SftpNamespaceHandler.java | 6 +- .../SftpSendingMessageHandlerFactoryBean.java | 77 ++++++++------- .../sftp/session/QueuedSftpSessionPool.java | 8 +- .../integration/sftp/session/SftpSession.java | 6 +- ...ctoryBean.java => SftpSessionFactory.java} | 38 +++----- .../sftp/session/SftpSessionUtils.java | 54 ----------- .../config/spring-integration-sftp-2.0.xsd | 42 +++----- .../sftp/MessageHistory-context.xml | 34 +++---- .../sftp/SftpParserTests-inbound-all-fail.xml | 17 ++-- .../sftp/SftpParserTests-inbound-all.xml | 26 ++--- .../springframework/integration/sftp/sftpTest | 30 ++++++ 12 files changed, 203 insertions(+), 232 deletions(-) rename spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/{SftpSessionFactoryBean.java => SftpSessionFactory.java} (67%) delete mode 100644 spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionUtils.java create mode 100644 spring-integration-sftp/src/test/java/org/springframework/integration/sftp/sftpTest diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean.java index f4e5cfa639..186c666044 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean.java @@ -31,8 +31,7 @@ import org.springframework.integration.sftp.filters.SftpPatternMatchingFileListF import org.springframework.integration.sftp.inbound.SftpInboundRemoteFileSystemSynchronizer; import org.springframework.integration.sftp.inbound.SftpInboundRemoteFileSystemSynchronizingMessageSource; import org.springframework.integration.sftp.session.QueuedSftpSessionPool; -import org.springframework.integration.sftp.session.SftpSessionFactoryBean; -import org.springframework.integration.sftp.session.SftpSessionUtils; +import org.springframework.integration.sftp.session.SftpSessionFactory; import org.springframework.util.StringUtils; import com.jcraft.jsch.ChannelSftp; @@ -58,20 +57,28 @@ class SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean private volatile String filenamePattern; private volatile FileListFilter filter; + + private volatile SftpSessionFactory sftpSessionFactory; - private int port = 22; + - private String host; - - private String keyFile; - - private String keyFilePassword; + public void setSftpSessionFactory(SftpSessionFactory sftpSessionFactory) { + this.sftpSessionFactory = sftpSessionFactory; + } + // private int port = 22; +// +// private String host; +// +// private String keyFile; +// +// private String keyFilePassword; +// private String remoteDirectory; - - private String username; - - private String password; +// +// private String username; +// +// private String password; public void setLocalDirectoryResource(Resource localDirectoryResource) { @@ -98,21 +105,21 @@ class SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean this.filter = filter; } - public void setPort(int port) { - this.port = port; - } - - public void setHost(String host) { - this.host = host; - } - - public void setKeyFile(String keyFile) { - this.keyFile = keyFile; - } - - public void setKeyFilePassword(String keyFilePassword) { - this.keyFilePassword = keyFilePassword; - } +// public void setPort(int port) { +// this.port = port; +// } +// +// public void setHost(String host) { +// this.host = host; +// } +// +// public void setKeyFile(String keyFile) { +// this.keyFile = keyFile; +// } +// +// public void setKeyFilePassword(String keyFilePassword) { +// this.keyFilePassword = keyFilePassword; +// } /** * Set the remote directory to synchronize with @@ -120,21 +127,21 @@ class SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean public void setRemoteDirectory(String remoteDirectory) { this.remoteDirectory = remoteDirectory; } - - /** - * Set the user name to be used for authentication with the remote server - */ - public void setUsername(String username) { - this.username = username; - } - - /** - * Set the password to be used for authentication with the remote server - * @param password - */ - public void setPassword(String password) { - this.password = password; - } +// +// /** +// * Set the user name to be used for authentication with the remote server +// */ +// public void setUsername(String username) { +// this.username = username; +// } +// +// /** +// * Set the password to be used for authentication with the remote server +// * @param password +// */ +// public void setPassword(String password) { +// this.password = password; +// } /** * {@inheritDoc} @@ -183,8 +190,10 @@ class SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean this.filter = compositeFtpFileListFilter; // pools - SftpSessionFactoryBean sessionFactory = SftpSessionUtils.buildSftpSessionFactory(this.host, this.password, this.username, this.keyFile, this.keyFilePassword, this.port); - QueuedSftpSessionPool pool = new QueuedSftpSessionPool(15, sessionFactory); + + //SftpSession session = new Sf + //SftpSessionFactory sessionFactory = SftpSessionUtils.buildSftpSessionFactory(this.host, this.password, this.username, this.keyFile, this.keyFilePassword, this.port); + QueuedSftpSessionPool pool = new QueuedSftpSessionPool(15, sftpSessionFactory); pool.afterPropertiesSet(); SftpInboundRemoteFileSystemSynchronizer sftpSync = new SftpInboundRemoteFileSystemSynchronizer(); diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java index 5d2d2dab0c..389b00090d 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java @@ -53,9 +53,10 @@ public class SftpNamespaceHandler extends AbstractIntegrationNamespaceHandler { protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SftpInboundRemoteFileSystemSynchronizingMessageSourceFactoryBean.class.getName()); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "filter"); - for (String p : "filename-pattern,auto-create-directories,username,password,host,key-file,key-file-password,remote-directory,local-directory-path,auto-delete-remote-files-on-sync".split(",")) { + for (String p : "filename-pattern,auto-create-directories,remote-directory,local-directory-path,auto-delete-remote-files-on-sync".split(",")) { IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p); } + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "session-factory", "sftpSessionFactory"); return builder.getBeanDefinition(); } } @@ -69,11 +70,12 @@ public class SftpNamespaceHandler extends AbstractIntegrationNamespaceHandler { @Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SftpSendingMessageHandlerFactoryBean.class.getName()); - for (String p : "auto-create-directories,username,password,host,port,key-file,key-file-password,charset".split(",")) { + for (String p : "auto-create-directories,charset".split(",")) { IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p); } String remoteDirectory = element.getAttribute("remote-directory"); String remoteDirectoryExpression = element.getAttribute("remote-directory-expression"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "session-factory", "sftpSessionFactory"); boolean hasLiteralRemoteDirectory = StringUtils.hasText(remoteDirectory); boolean hasRemoteDirectoryExpression = StringUtils.hasText(remoteDirectoryExpression); if (hasLiteralRemoteDirectory ^ hasRemoteDirectoryExpression) { diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpSendingMessageHandlerFactoryBean.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpSendingMessageHandlerFactoryBean.java index 5eb9456bec..f819a73c13 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpSendingMessageHandlerFactoryBean.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpSendingMessageHandlerFactoryBean.java @@ -21,8 +21,7 @@ import org.springframework.expression.Expression; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.sftp.outbound.SftpSendingMessageHandler; import org.springframework.integration.sftp.session.QueuedSftpSessionPool; -import org.springframework.integration.sftp.session.SftpSessionFactoryBean; -import org.springframework.integration.sftp.session.SftpSessionUtils; +import org.springframework.integration.sftp.session.SftpSessionFactory; /** * Supports the construction of a MessagHandler that knows how to take inbound File objects @@ -32,19 +31,25 @@ import org.springframework.integration.sftp.session.SftpSessionUtils; */ class SftpSendingMessageHandlerFactoryBean implements FactoryBean { - private String host; - - private String keyFile; - - private String keyFilePassword; - - private String password; +// private String host; +// +// private String keyFile; +// +// private String keyFilePassword; +// +// private String password; private Expression remoteDirectoryExpression; - private String username; +// private String username; +// +// private int port; + + private volatile SftpSessionFactory sftpSessionFactory; - private int port; + public void setSftpSessionFactory(SftpSessionFactory sftpSessionFactory) { + this.sftpSessionFactory = sftpSessionFactory; + } private String charset; @@ -53,29 +58,29 @@ class SftpSendingMessageHandlerFactoryBean implements FactoryBean queue; - private final SftpSessionFactoryBean sftpSessionFactory; + private final SftpSessionFactory sftpSessionFactory; private final int maxPoolSize; - public QueuedSftpSessionPool(SftpSessionFactoryBean factory) { + public QueuedSftpSessionPool(SftpSessionFactory factory) { this(DEFAULT_POOL_SIZE, factory); } - public QueuedSftpSessionPool(int maxPoolSize, SftpSessionFactoryBean sessionFactory) { + public QueuedSftpSessionPool(int maxPoolSize, SftpSessionFactory sessionFactory) { this.sftpSessionFactory = sessionFactory; this.maxPoolSize = maxPoolSize; } @@ -61,7 +61,7 @@ public class QueuedSftpSessionPool implements SftpSessionPool, InitializingBean public SftpSession getSession() throws Exception { SftpSession session = this.queue.poll(); if (null == session) { - session = this.sftpSessionFactory.getObject(); + session = this.sftpSessionFactory.getSession(); if (this.queue.size() < this.maxPoolSize) { this.queue.add(session); } diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java index d006539ff4..509648e7fc 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java @@ -17,11 +17,15 @@ package org.springframework.integration.sftp.session; import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.Identity; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UserInfo; import org.apache.commons.lang.StringUtils; +import org.springframework.core.io.Resource; + +import java.io.File; import java.io.InputStream; /** @@ -86,7 +90,7 @@ public class SftpSession { jSch.setKnownHosts(knownHostsInputStream); } // private key - if (!StringUtils.isEmpty(this.privateKey)) { + if (privateKey != null) { if (!StringUtils.isEmpty(privateKeyPassphrase)) { jSch.addIdentity(this.privateKey, privateKeyPassphrase); } diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactoryBean.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactory.java similarity index 67% rename from spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactoryBean.java rename to spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactory.java index 308b0324a6..1987a2d727 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactoryBean.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionFactory.java @@ -16,7 +16,7 @@ package org.springframework.integration.sftp.session; -import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -27,9 +27,9 @@ import org.springframework.util.StringUtils; * @author Josh Long * @author Mario Gray */ -public class SftpSessionFactoryBean extends AbstractFactoryBean { +public class SftpSessionFactory { - private volatile String remoteHost; + private volatile String host; private volatile int port = 22; // the default @@ -39,13 +39,13 @@ public class SftpSessionFactoryBean extends AbstractFactoryBean { private volatile String knownHosts; - private volatile String privateKey; + private volatile Resource privateKey; private volatile String privateKeyPassphrase; - public void setRemoteHost(String remoteHost) { - this.remoteHost = remoteHost; + public void setHost(String host) { + this.host = host; } public void setPort(int port) { @@ -64,7 +64,7 @@ public class SftpSessionFactoryBean extends AbstractFactoryBean { this.knownHosts = knownHosts; } - public void setPrivateKey(String privateKey) { + public void setPrivateKey(Resource privateKey) { this.privateKey = privateKey; } @@ -72,25 +72,17 @@ public class SftpSessionFactoryBean extends AbstractFactoryBean { this.privateKeyPassphrase = privateKeyPassphrase; } - - @Override - public Class getObjectType() { - return SftpSession.class; - } - - @Override - public boolean isSingleton() { - return false; - } - - @Override - protected SftpSession createInstance() throws Exception { - Assert.hasText(this.remoteHost, "remoteHost must not be empty"); + protected SftpSession getSession() throws Exception { + Assert.hasText(this.host, "host must not be empty"); Assert.hasText(this.user, "user must not be empty"); Assert.isTrue(this.port >= 0, "port must be a positive number"); - Assert.isTrue(StringUtils.hasText(this.password) || StringUtils.hasText(this.privateKey) || StringUtils.hasText(this.privateKeyPassphrase), + Assert.isTrue(StringUtils.hasText(this.password) || privateKey != null || StringUtils.hasText(this.privateKeyPassphrase), "either a password or a private key and/or a private key passphrase is required"); - return new SftpSession(this.user, this.remoteHost, this.password, this.port, this.knownHosts, null, this.privateKey, this.privateKeyPassphrase); + String privateKeyToPass = null; + if (privateKey != null){ + privateKeyToPass = privateKey.getFile().getAbsolutePath(); + } + return new SftpSession(this.user, this.host, this.password, this.port, this.knownHosts, null, privateKeyToPass, this.privateKeyPassphrase); } } diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionUtils.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionUtils.java deleted file mode 100644 index 4dc2e3dfc6..0000000000 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSessionUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2010 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.sftp.session; - - -/** - * Utility methods for SFTP Session management. - * - * @author Josh Long - */ -public abstract class SftpSessionUtils { - - /** - * This method hides the minutae required to build an #SftpSessionFactory. - * - * @param host the host to connect to. - * @param usr this is required. It is the username of the credentials being authenticated. - * @param pw if password authentication is being used (as opposed to key-based authentication) then this is - * where you configure the password. - * @param pvKey the file that is the private key - * @param pvKeyPass the passphrase used to use the key file - * @param port the default (22) is used if the value here is N< 0. The value should be only be set if the port - * is non-standard (not 22) - * @return the SftpSessionFactory that's used to create connections and get us in the right state to start issue - * commands against a remote SFTP/SSH filesystem - * @throws Exception thrown in case of darned near anything - */ - public static SftpSessionFactoryBean buildSftpSessionFactory(String host, String pw, String usr, String pvKey, String pvKeyPass, int port) throws Exception { - SftpSessionFactoryBean sftpSessionFactory = new SftpSessionFactoryBean(); - sftpSessionFactory.setPassword(pw); - sftpSessionFactory.setPort(port); - sftpSessionFactory.setRemoteHost(host); - sftpSessionFactory.setUser(usr); - sftpSessionFactory.setPrivateKey(pvKey); - sftpSessionFactory.setPrivateKeyPassphrase(pvKeyPass); - sftpSessionFactory.afterPropertiesSet(); - return sftpSessionFactory; - } - -} diff --git a/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-2.0.xsd b/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-2.0.xsd index 755603e903..2278e4e55c 100644 --- a/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-2.0.xsd +++ b/spring-integration-sftp/src/main/resources/org/springframework/integration/sftp/config/spring-integration-sftp-2.0.xsd @@ -1,20 +1,4 @@ - - + @@ -47,14 +32,14 @@ - + - - - - - + + + + + @@ -78,6 +63,7 @@ + @@ -97,14 +83,14 @@ - + - - - - - + + + + + diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/MessageHistory-context.xml b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/MessageHistory-context.xml index e79c7d13c0..d638cd7f9c 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/MessageHistory-context.xml +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/MessageHistory-context.xml @@ -1,21 +1,4 @@ - - - + + + + + + + + + + + + auto-delete-remote-files-on-sync="true"> diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all-fail.xml b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all-fail.xml index 1c1d0a9c22..3f7aaebb16 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all-fail.xml +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all-fail.xml @@ -20,18 +20,23 @@ + + + + + + + + + + diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all.xml b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all.xml index f03a3d35a2..c704ee0b13 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all.xml +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/SftpParserTests-inbound-all.xml @@ -19,36 +19,36 @@ - + + + + + + + + + + + diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/sftpTest b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/sftpTest new file mode 100644 index 0000000000..75ab4085e4 --- /dev/null +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/sftpTest @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,FDDF18CD85159ADF + +LIfVRr6qLiHFWcRDBHFVce8dRT7CF/t9eEmIcj756QJGQXdHmuFLhDny6L5ZiNuV +0OyqpZHdpPEdpEiklJzNny7lt/dZxESKqJTWeCEi9s/FcdF0bwibAC8SvR/viNZ+ +kVkdFGF6HhB7K8RToihye6f/tVhIgE/aZ8cU71DjwLnmz1F21Moue1EfcQw4q7IZ +cjvcsXMvrGunC2hGProD+Dphqur5iE8nK7DI8tAiqyf6R/ArhA85kQ27Ly5mSq97 +0xQQKiicmQFIbSZQ+vlBvR+UPHFGc2hcKMWmcoKWfUjeiesqWk3zwR/hMWanCVsG +8nPa3y9/qrnuT4z+SfAuULm4QIU7TNmD/Z2KwClTd40ZFu9hFwDha3p17bbZxTzO +Xw/Cq/nx4lEj4mTcTDal+f56DkDpKDwrn8uLMGEjB5VUkPYQfY1OnAvH0KC8l5my +xnDC/J9OC0hJH3j6w2Z9Y27tU3Ut5ZmqRA3J4/9r5FBHHCplMAuPY7tCTzppqEex +7bckKswjByasYJKqwaJ1l1KB3sMJ1kUb1XF9/tb3hyku8zO8mBq9oRrUdQdGAxCp +XsxMDn/xD6C4gO9kX5j4YhJ22xqhSF0b/sw/4NugIq4oRQopNPtwXANihE0DfHMM +F1FBr1GOzlsa5MxJbCF350uMQK7AVqKi1vaEmQqC4mN46tSTnAT1Wj4d7I7OUQ8/ +OI7EQXDFvHymkscUghILDYTIpYsYL48ZZJeLfiTZ7AQ9Bz6agXlDiWBWBFYOmTQE +KQx3LLzl4Gc5krqq6rfkm8CPdS5KqDI03HUq5iCi+LRBvpWxh5W5IcZT1WP+cIEG +rgQkrlJw4nInNio00/07Qq2AnXIRwVjh0kVYNEdIUIvc/zCVCimRQp1Hlw3gAM8A ++HxdCfcNg4RYPRW1qkDun9dZB/uxEO43MhaiOyNaLuKgNbqWOi74bKz9m2fJLi2i +TzELkHjLRYxSGRROWJV3aHQMfiZDEYi/hdRPPL6hJWCPej6Fvo1sEqgowB6i2qzi +h+jsHMQnTbKO1t0n1Z3whgl9atgd9vanPx6D7yp+pb8rxBb2gUd4yyUUZUxHBai5 +Eun4K++BF1dM7QinHzrDb6/J5bA9MP7/Z4Vpn7V1Pv7eJaLthEK1Lu8av64yMqPK +Mvqj8gN/nJDclO6hIeB67yT8U/SgjQYwWSANuNufwq8PmpTI77nkx0KFCLTE8Nvr +uLK0QQdvmYHZuql1zobqjR78EtOEwY+RKrb5dM7cP7TR1ZBBIrgi/8L+WlnzlPO6 ++qU9Mw2hD1xOQsUQR4CwKdPbQop/wrYCiRasiMh3WXc3ukqGng5+tsUSHQzv7Vwm +SSBeYjlZBOuGEHcWGsNhHD9r1XoJVmJGUjJFua/epbcnNk3A8NOQbY4aOiRdX2EL +f+ebTbDyU/YX1pChgGuHhsVsdVsKmY2s9toK2YcyOM4edfGpv38DFHd+9DsXd6eo +bviIB0OfYnXwO2JTaQBh9lfrV4P8tZphGJsPkviru0lNJX4J5ipHgvIg5EvdPUTs +kKgfERLjzXh9gwJ5zoZRgM22VU9v9ILGGk/zhCjVqYA3Ea0uQt6w6w== +-----END RSA PRIVATE KEY-----