2017-10-16 3 views
0

안녕하세요 전 SSH 연결이 필요한 서버에 데이터베이스가 있습니다.스프링 포트 응용 프로그램을 시작하기 전에 원격 데이터베이스에 대한 전달

나는이 지침을 따른다. post 터널 및 포트 포워딩을 생성한다.

나는 동일한 작업을 수행하지 않았다 그러나 나는 구현이 class (내가 모든 대화 상자없이 directely 만든 ..)

그리고 내 application.properties 내가이 줄이 :

spring.datasource.url = jdbc:mysql://localhost:3307/my_database?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 

을 하지만이 작업은 수동으로 첫 번째 수업을 시작한 후 스프링 부트 앱을 시작합니다.

이 클래스를 시작하는 응용 프로그램을 시작하기 전에 어떻게 자동으로 수행 할 수 있습니까?

package com.demo.demo; 

/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ 
/** 
* This program will demonstrate the port forwarding like option -L of 
* ssh command; the given port on the local host will be forwarded to 
* the given remote host and port on the remote side. 
* $ CLASSPATH=.:../build javac PortForwardingL.java 
* $ CLASSPATH=.:../build java PortForwardingL 
* You will be asked username, hostname, port:host:hostport and passwd. 
* If everything works fine, you will get the shell prompt. 
* Try the port on localhost. 
* 
*/ 
import com.jcraft.jsch.*; 
import java.awt.*; 
import javax.swing.*; 

public class PortForwardingLR{ 
    public static void main(String[] arg){ 

    int lport; 
    String rhost; 
    int rport; 

    try{ 
     JSch jsch=new JSch(); 

     String host=null; 
     if(arg.length>0){ 
     host=arg[0]; 
     } 
     else{ 
     host="[email protected]"; 
     } 
     String user=host.substring(0, host.indexOf('@')); 
     host=host.substring(host.indexOf('@')+1); 

     Session session=jsch.getSession(user, host, 22); 

     String foo="3307:8.8.8.8:3306"; 
     lport=Integer.parseInt(foo.substring(0, foo.indexOf(':'))); 
     foo=foo.substring(foo.indexOf(':')+1); 
     rhost=foo.substring(0, foo.indexOf(':')); 
     rport=Integer.parseInt(foo.substring(foo.indexOf(':')+1)); 

     // username and password will be given via UserInfo interface. 
     UserInfo ui=new MyUserInfo(); 
     session.setUserInfo(ui); 

     session.connect(); 

     //Channel channel=session.openChannel("shell"); 
     //channel.connect(); 

     int assinged_port=session.setPortForwardingL(lport, rhost, rport); 
     System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport); 
    } 
    catch(Exception e){ 
     System.out.println(e); 
    } 
    } 

    public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{ 
    public String getPassword(){ return passwd; } 
    public boolean promptYesNo(String str){ 
//  Object[] options={ "yes", "no" }; 
//  int foo=JOptionPane.showOptionDialog(null, 
//    str, 
//    "Warning", 
//    JOptionPane.DEFAULT_OPTION, 
//    JOptionPane.WARNING_MESSAGE, 
//    null, options, options[0]); 
//  return foo==0; 
     return true; 
    } 

    String passwd; 
// JTextField passwordField=(JTextField)new JPasswordField(20); 

    public String getPassphrase(){ return null; } 
    public boolean promptPassphrase(String message){ return true; } 
    public boolean promptPassword(String message){ 
//  Object[] ob={passwordField}; 
//  int result= 
// JOptionPane.showConfirmDialog(null, ob, message, 
//     JOptionPane.OK_CANCEL_OPTION); 
//  if(result==JOptionPane.OK_OPTION){ 
    passwd="ItsNotMyPwd"; 
    return true; 
//  } 
//  else{ return false; } 
    } 
    public void showMessage(String message){ 
     JOptionPane.showMessageDialog(null, message); 
    } 
    final GridBagConstraints gbc = 
     new GridBagConstraints(0,0,1,1,1,1, 
          GridBagConstraints.NORTHWEST, 
          GridBagConstraints.NONE, 
          new Insets(0,0,0,0),0,0); 
    private Container panel; 
    public String[] promptKeyboardInteractive(String destination, 
               String name, 
               String instruction, 
               String[] prompt, 
               boolean[] echo){ 
     panel = new JPanel(); 
     panel.setLayout(new GridBagLayout()); 

     gbc.weightx = 1.0; 
     gbc.gridwidth = GridBagConstraints.REMAINDER; 
     gbc.gridx = 0; 
     panel.add(new JLabel(instruction), gbc); 
     gbc.gridy++; 

     gbc.gridwidth = GridBagConstraints.RELATIVE; 

     JTextField[] texts=new JTextField[prompt.length]; 
     for(int i=0; i<prompt.length; i++){ 
     gbc.fill = GridBagConstraints.NONE; 
     gbc.gridx = 0; 
     gbc.weightx = 1; 
     panel.add(new JLabel(prompt[i]),gbc); 

     gbc.gridx = 1; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     gbc.weighty = 1; 
     if(echo[i]){ 
      texts[i]=new JTextField(20); 
     } 
     else{ 
      texts[i]=new JPasswordField(20); 
     } 
     panel.add(texts[i], gbc); 
     gbc.gridy++; 
     } 

     if(JOptionPane.showConfirmDialog(null, panel, 
             destination+": "+name, 
             JOptionPane.OK_CANCEL_OPTION, 
             JOptionPane.QUESTION_MESSAGE) 
     ==JOptionPane.OK_OPTION){ 
     String[] response=new String[prompt.length]; 
     for(int i=0; i<prompt.length; i++){ 
      response[i]=texts[i].getText(); 
     } 
    return response; 
     } 
     else{ 
     return null; // cancel 
     } 
    } 
    } 
} 

그리고 난 응용 프로그램처럼 실행되기 전에이 방법을 실행하는 것을 시도하고 작동하지 않는 S : :

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 


@SpringBootApplication 
public class SymspringdemoApplication { 

    public static void main(String[] args) { 
     someMethodThatDoesForwarding(); 
     SpringApplication.run(SymspringdemoApplication.class, args); 
    } 

    private static void someMethodThatDoesForwarding() { 

     PortForwardingLR.main(null);; 

    } 
} 

감사를 내 PortFrowarding 클래스는

.

답변

1

실제로 코드를 게시했는지 이해하는 것이 더 쉽지만 Spring이 자체 부트 스트래핑을 시작하기 전에 포트 전달을 설정하려는 경우 스프링이 bean을 작성하기 전에 코드를 실행하십시오 (궁극적으로 DB- 관련 콩).

예컨대 :

... 
    /* Execute your custom port-forwarding here */ 
    someMethodThatDoesForwarding(); 
    /* SpringBoot code continues.. */ 
    SpringApplication.run(DemoApplication.class, args); 
... 
+0

나는 또한 그것을 시도하고 작동하지 않습니다. 응용 프로그램이 발생하기 전에 포트 forwrd에 연결하려고합니다.그리고 모두 내가 sysout을 쓰고 o는 내 콘솔 thats에서이 방법을 실행하지 않는다는 것을 의미하지 않는다. – shmoolki

+0

스프링 부트 스트랩 전에 배치하면 메소드가 실행되어야한다. 잠시 동안 연결/청취자를 설정하고 그 이유는 실패합니다. 메소드가 실행되고 전달이 이루어질 때까지 약간의 차단을 시도 할 수 있습니까? – emirb

+0

하지만 sysout을 작성했는데 콘솔에 표시되지 않습니다. – shmoolki

1

당신은 몇 가지 옵션이 있습니다.

  • 메인 메서드에서 PortForwardingLR.main()을 명시 적으로 호출 할 수 있습니다.
  • 쉘 스크립트/배치 파일을 사용하여 프로그램 전에 PortForwardingLR에 전화 할 수 있습니다. OpenSSH를 사용하여 포트 포워딩을 수행 할 수도 있습니다.
  • PortForwardingLR.main()을 기본 방법으로 호출 할 수 있습니다.

PortForwardingLR의 코드를 연결을 여는 방법과 연결을 닫는 방법 두 가지로 다시 작성하는 것이 가장 좋습니다.

class MyDatabaseWorker { 
    public void run() { 
     // Do stuff here 
    } 

    public static void main(String[] args) { 
     PortForwardingLR forwarder = new PortForwardingLR(hostname, user, password); 
     forwarder.addPortForward(3306); 
     forwarder.connect(); 
     MyDatabaseWorker worker = new MyDatabaseWorker(); 
     worker.run(); 
     forwarder.disconnect(); 
    } 
} 

이 방법, 당신이 당신의 DB 클래스가 최소한으로 오염되어 다른 프로젝트에 대한 PortForwardingLR 클래스를 재사용 할 수 있습니다, 당신이 당신의 DB 클래스는 포트 포워딩없이 실행되지 않습니다 있는지 확인하십시오 목표는 이런 일을하는 것입니다.

포워딩중인 포트에서 수신 대기중인 다른 프로세스가있는 경우이 시나리오는 실패하므로주의하십시오.

관련 문제