Чтобы получить доступ к вашему локальному приложению на ваш сервер Mysql через SSH (например, с помощью MySql-Openshift), «единственная» дополнительная вещь, которую вам нужно будет сделать, - установить предыдущее соединение SSH, прежде чем ваш источник данных объект пытается получить соединение.
Как обычно, и, к счастью, есть несколько способов сделать это, но я попытаюсь объяснить простейший, который сработал для меня.
1) Добавить JCraft библиотеку на свой путь к классам (используется для работы с SSH соединений)
Если вы используете Maven добавить в свой pom.xml эти элементы:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
или просто скачать его от http://www.jcraft.com/jsch/
2) Создать класс для подключения к вашему SSH серверу (Здесь мы используем библиотеку импортируемого в предыдущем шаге)
Например:
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SSHConnection {
private final static String S_PATH_FILE_PRIVATE_KEY = "C:\\Users\\Val\\.ssh\\privatekeyputy.ppk"; \\windows absolut path of our ssh private key locally saved
private final static String S_PATH_FILE_KNOWN_HOSTS = "C:\\Users\\Val\\.ssh\\known_hosts";
private final static String S_PASS_PHRASE = "mypassphrase";
private final static int LOCAl_PORT = 3307;
private final static int REMOTE_PORT = 3306;
private final static int SSH_REMOTE_PORT = 22;
private final static String SSH_USER = "87a34c7f89f5cf407100093c";
private final static String SSH_REMOTE_SERVER = "myapp-mydomain.rhcloud.com";
private final static String MYSQL_REMOTE_SERVER = "127.6.159.102";
private Session sesion; //represents each ssh session
public void closeSSH()
{
sesion.disconnect();
}
public SSHConnection() throws Throwable
{
JSch jsch = null;
jsch = new JSch();
jsch.setKnownHosts(S_PATH_FILE_KNOWN_HOSTS);
jsch.addIdentity(S_PATH_FILE_PRIVATE_KEY, S_PASS_PHRASE.getBytes());
sesion = jsch.getSession(SSH_USER, SSH_REMOTE_SERVER, SSH_REMOTE_PORT);
sesion.connect(); //ssh connection established!
//by security policy, you must connect through a fowarded port
sesion.setPortForwardingL(LOCAl_PORT, MYSQL_REMOTE_SERVER, REMOTE_PORT);
}
}
Этот класс хранит всю необходимую информацию для установления соединения SSH. Обратите внимание, что мы определили только два метода: конструктор для создания экземпляра ssh-соединения, представленного единственным нестатическим полем класса, и другим, чтобы отключить/закрыть ssh-соединение.
3) Определить слушатель, который реализует интерфейс контекста сервлета (держа объект класса, определенный в пункте 2)
Обратите внимание, что мы пытаемся создать соединение SSH, когда наши старты приложения, закрывая его, когда наше приложение умирает.
@WebListener
public class MyContextListener implements ServletContextListener {
private SSHConnection conexionssh;
public MyContextListener()
{
super();
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent arg0)
{
System.out.println("Context initialized ... !");
try
{
conexionssh = new SSHConnection();
}
catch (Throwable e)
{
e.printStackTrace(); // error connecting SSH server
}
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0)
{
System.out.println("Context destroyed ... !");
conexionssh.closeSSH(); // disconnect
}
4) Используя Spring, установите объект DataSource в диспетчер-сервлет.XML как обычно, но указывающие на ваш fowarded порт
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3307/yourSchema" />
<property name="username" value="admin4ajCbcWM" />
<property name="password" value="dxvfwEfbyaPL-z" />
</bean>
И это все. Другой возможностью может быть создание вашего собственного DataSource, расширение предоставляемого Spring и добавление его функций ssh. Возможно, решение, подробно описанное здесь, лучше изолировано.