2014年11月25日 星期二

Java Call Splunk Restful Service with curl On Linux

之前文章已經實現了使用Java搭配Curl and openssl 來呼叫 Splunk Restful API
但那是透過 CMD 也就是 Windows平台,現在假設我們程式需要佈署在Linux平台上
則語法也會不同。首先在Linux平台上有個好處,那就是大多數已經內建了curl
但是使用Java呼叫curl時,我必須先知道 curl 需在哪執行,你可以在Linux 下執行which curl
一樣使用ProcessBuilder
程式範例如下:
import java.io.*;
import java.util.*;

public class ProcessBuilderTest {
  public static void main(String args[]) 
     throws InterruptedException,IOException 
  {
  final List<String> commands = new ArrayList<String>();                

commands.add("/usr/bin/curl"); 
 commands.add("-k"); 
 commands.add("-u"); 
 commands.add("admin:hello"); 
 commands.add("-s"); 
 commands.add("https://localhost:8089/services/search/jobs/"+sid+"/results/");

ProcessBuilder builder = new ProcessBuilder(commands);
File dir = new File("/home");
builder.directory(dir);

    final Process process = builder.start();
    
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    String line;
    while ((line = br.readLine()) != null) {
      System.out.println(line);
    }
    System.out.println("Program terminated!");
  }
}

如上面程式所示,只要能先得到Splunk Restful 回傳的 SID後加入程式,即可得到與Splunk Server上搜尋一樣的結果。
此外由於程式可能需要同時於Windows及Linux執行,所以可以使用下面程式來判別以決定command的組合模式
private static String OS = System.getProperty("os.name").toLowerCase();

private static boolean isWindows() {  
return (OS.indexOf("win") >= 0);
}
private static boolean isUnix() { 
return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );

當然Windows與Linux上指令上還有一些小差別,另外Linux可以使用空白,但Windows要使用%20或一些需要使用跳脫字元的用法,才可正確執行呼叫CURL,歡迎大家一起研究討論。

}

2014年7月7日 星期一

Java呼叫CMD的另一種方式使用ProcessBuilder(calling Splunk Restful API)

前幾天的文章已經可以順利的使用Java呼叫CMD
現在介紹另一種方式是使用ProcessBuilder呼叫,搭配前一篇Java處理字串中含有雙引號的字串
可以完整的呈現不使用批次檔,不用下 cd command to executing directory(可直接設定cmd執行目錄)

程式碼如下

import java.io.*;
import java.util.*;

public class ProcessBuilderTest {
  public static void main(String args[]) 
     throws InterruptedException,IOException 
  {
 final List<String> commands = new ArrayList<String>();                

 commands.add("cmd.exe");
 commands.add("/C");
 commands.add("curl -k -u admin:!QAZxsw2 -s https://localhost:8089/services/search/jobs/ -d\"search=| savedsearch selectFromDual\"");
 //在Java中若是字串中含有字串例如 " "name" " 應表示為 "\"name\" "
 //commands.add("curl -k -u admin:!QAZxsw2 -s https://localhost:8089/services/search/jobs/"+sid+"/results/");
 commands.add("start");

    //ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/C", "start");
ProcessBuilder builder = new ProcessBuilder(commands);
File dir = new File("C:\\Users\\Peter\\Desktop\\openssl-0.9.8h-1-bin\\bin");
builder.directory(dir);

    final Process process = builder.start();
    
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    String line;
    while ((line = br.readLine()) != null) {
      System.out.println(line);
    }
    System.out.println("Program terminated!");
  }
}

Java如何在字串中含有另一個雙引號的字串

最近遇到這樣的情形,使用cURL工具 search Splunk時 search的字串中含有另一個字串
想要以Java的方式呈現,都會出現錯誤!

今天終於找到方法了

如下程式碼

public class Test{  
  
    public static void main(String[] args){  
        String str1 = "\"Peter\"";//字串兩邊含有雙引號
        String str2 = "Peter \"is\" boy";//字串中間含有雙引號
        String str3 = "\\Peter";//使用\字符可以使字串包含其他字串  
          
        System.out.println("字串一:" + str1);  
        System.out.println("字串二:" + str2);  
        System.out.println("字串三:" + str3);  
    }  
}

執行結果

請注意看 字串一的寫法 在中間的字串雙引號前 先加一個 \  雙引號結尾前 再加一個 \

參考Java处理本身包含双引号的String

2014年7月3日 星期四

使用 Java 呼叫 cmd.exe 並下指令(下)-Splunk Java Solution

跟著上一篇文章,除了讓CMD幫我們做事情外,我還需要將資料直接可以在Java中取用
則更改前一篇文章,改使用以下程式碼,如圖就可以在Eclipse Console看到如CMD裡顯示的狀態啦!

import java.io.*;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
public class AppLauncher {
  public static void main(String[] args) throws Exception
  {
      /*
       *若需外部傳入可用下列語法,執行時ex:java AppLauncher "cmd.exe /c c:123.bat"
       */     
    //String cmd = args.length == 0? "java -version" : args[0];
    String[] cmd = new String[3];
    cmd[0] = "cmd.exe" ;
    cmd[1] = "/C" ;
    //填入執行程式路徑
    cmd[2] = "D:/SplunkSearchId.bat" ;
   
    //-s 為curl 不顯示download進度訊息
    //String cmd = "java -version";
    Process process = Runtime.getRuntime().exec(cmd);
    new Thread(new SubTask(process.getInputStream())).start();
    new Thread(new SubTask(process.getErrorStream())).start();
    process.waitFor();
    //多印一空白行
    System.out.println();
    System.out.println("====================Application terminated=======================");
  }
}
class SubTask implements Runnable {
  public SubTask(InputStream istream)
  {
    if (istream == null){
      iReader = new BufferedReader(new InputStreamReader(System.in));
    }
    else
      iReader = new BufferedReader(new InputStreamReader(istream));
  }
  public void run()
  {
    try {
      String input = iReader.readLine();
      while (input != null)
      {
        //若需執行結果可將input傳出
        System.out.println(input);
        
        /*String html = input;
Document doc = Jsoup.parse(html, "", Parser.xmlParser());
   //String testValue = "0";
for (Element e : doc.select("sid")) {
       //System.out.println(e);
    System.out.println("hi: " + e.text());
    //testValue = e.text();
   }*/
        
        input = iReader.readLine();
      }
    }
    catch (IOException ioe) {
    }
  }
  private BufferedReader iReader;
}


另外請注意一下 程式碼中有註解的地方 是 XML Parser的方式,這邊使用JSOUP jar
因為Splunk Restful API回傳的default格式是XML,其實這樣已經是一個完整的Splunk with JAVA Solution (Java+CMD+cURL+JSOUP)


使用 Java 呼叫 cmd.exe 並下指令(上)

如題,最近由於研究 Splunk Restful API
想透過 API 得到我所要的資料,但Splunk Default支援使用cURL工具來做查詢
由於我cURL安裝好了後,還是得使用cmd下指令,而將來也必須一併整合至
Java,所以以下範例程式為 撰寫一支Java程式呼叫cmd,並執行一個.bat檔案(splunk curl 指令)
目的是取回Splunk Job ID, 圖示為程式的執行結果~*


import java.io.*;

public class CMD {

public static void main(String args[]) {
    String path = "D:\\SplunkSearchId.bat";

   Runtime run = Runtime.getRuntime();   
   try {   
        
    /*cmd /c dir 是執行完dir命令後關閉命令窗口。
 cmd /k dir 是執行完dir命令後不關閉命令窗口。
              cmd /c start dir /b會打開一個新窗口後執行dir指令,原窗口會關閉。
               cmd /k start dir 會打開一個新窗口後執行dir指令,原窗口不會關閉。*/
       Process process = run.exec("cmd /k start " + path);
   
        
       InputStream in = process.getInputStream();
       
       
   } catch (Exception e) {            
       e.printStackTrace();   
   }   
}

}




使用WLS SNMP Monitor CMD

最近某個專案要利用SNMP來監測WLS的狀態
在現在新的版本都建議要使用WLS的SNMP Agent功能(請參考WLS設定Trap http://weblogic-wonders.com/weblogic/2010/12/19/weblogic-snmp-to-monitor-jdbc-connection-pool/)
但是 假設我們手邊沒有其它工具可以觀察是否設定成功
WLS本身有提供Command Line的方式來供使用者測試

首先打開命令提示字元後,必須將WEBLOGIC_PATH加入
意思是使用cmd會根據PATH尋找對應的class

由於我安裝的WLS並沒有事先把WEBLOGIC_PATH設定好
所以請參考下圖至%WLS_HOME/server/bin下使用setWLSEnv.cmd or setWLSEnv.sh(Linux)
再echo看看是否已設定成功,接著就可以使用 WLS提供的monitor cmd了
注意第三張圖 -p(port) 是 你在WLS Admin Console設定 Trap的 port喔!




2014年4月21日 星期一

Java Project 讀取 config.properties 設定檔的方式 Part 2

此法是採用 commons-configuration-1.x.jar (apache的OpenSource可以download)所提供的API
還需要commons-lang-2.x.jar

首先一樣把參數設定檔config.properties放在/src下
之後建立一個Class取名為 Constants,內容如下

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

public class Constants {

private final static String test_property;

static {
PropertiesConfiguration configuration = null;
try {
configuration = new PropertiesConfiguration("config.properties");
} catch(ConfigurationException e) {
e.printStackTrace();
System.out.println(e.getMessages());
}

test_property = configuration.getString("test_property");

}

public String getConfig(){
return test_property;
}

假設您的設定檔(.properties)內容為
test_property = this is a test

如果利用Constants Class來取得您要的設定檔內容呢!?如下

首先建立一個 ConfigTest.java

將剛才建立的Constants import進來(假設在同個package則不必)

接著

Contants cons = new Contants();

String test = cons.getConfig();

則此時 test 已經等於了 "this is a test"


此法的好處在於設定檔所有的內容都可經由Constants Class來取得
不需像上個方法一樣冗長的程式碼一一初始化


缺點是 修改參數後必須重新佈署程式,而且在 config.properties中

前面的 property key 不可含有 . 沒錯 就是點(上個範例可以)
而且等號後面的 key value不可有 , 沒錯就是逗號

以上面 test_property = this is a test 來說不可改為

test.property = this , is a test
這就2個錯誤都有了,其實第一個錯誤是 java String 類別不給使用
而第二個錯誤是 apache 會把逗號判斷成停止點,所以只能抓到 this 後面的字串就抓不到了