package com.bao.lc.site.s3; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.apache.commons.chain.Chain; import org.apache.commons.chain.Context; import org.apache.commons.chain.impl.ChainBase; import org.apache.commons.chain.impl.ContextBase; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.params.ClientPNames; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import com.bao.lc.AppConfig; import com.bao.lc.ResMgr; import com.bao.lc.client.BrowserClient; import com.bao.lc.client.utils.HttpClientUtils; import com.bao.lc.httpcommand.CommandCompleteListener; import com.bao.lc.httpcommand.impl.DefaultHttpCommandDirector; import com.bao.lc.httpcommand.params.HttpCommandPNames; import com.bao.lc.site.s3.bean.PassengerInfo; import com.bao.lc.site.s3.bean.TicketFilterCondition; import com.bao.lc.site.s3.commands.BookTicket; import com.bao.lc.site.s3.commands.DoLogout; import com.bao.lc.site.s3.commands.GetTicketBookInitPage; import com.bao.lc.site.s3.commands.Login; import com.bao.lc.site.s3.commands.WelComePage; import com.bao.lc.site.s3.params.InputParameter; import com.bao.lc.site.s3.params.TdPNames; import com.bao.lc.site.s3.params.TdParams; import com.bao.lc.util.MiscUtils; public class TdClient { private static Log log = LogFactory.getLog(TdClient.class); private BrowserClient session = null; private Context clientContext = null; /** * Default constructor */ public TdClient() { if(!initHttpClient()) { throw new IllegalArgumentException("Failed to init http client"); } clientContext = new ContextBase(); } /** * Init HttpClient * @return true if init successfully */ private boolean initHttpClient() { SSLContext sslContext = null; //1. Create SSLContext instance try { sslContext = SSLContext.getInstance("TLS"); } catch(NoSuchAlgorithmException e) { log.error("SSLContext getInstance failed.", e); return false; } //2. Init try { TrustManager[] trustMgrs = new TrustManager[] { new TrustAllManager() }; sslContext.init((KeyManager[]) null, trustMgrs, (SecureRandom) null); } catch(KeyManagementException e) { log.error("SSLContext init failed.", e); return false; } //3. Create HTTPS scheme SSLSocketFactory ssf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme sch = new Scheme("https", 443, ssf); //4. Register with Connection Manager ThreadSafeClientConnManager tcm = new ThreadSafeClientConnManager(); tcm.getSchemeRegistry().register(sch); //5. Create client BasicHttpParams params = new BasicHttpParams(); params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, Boolean.TRUE); session = new BrowserClient(tcm, params); return true; } private void updateParameter(Context context, InputParameter parameter, boolean includeUserInfo) { if(includeUserInfo) { context.put(TdPNames.PARAM_USER, parameter.user); context.put(TdPNames.PARAM_PASSWORD, parameter.pwd); } context.put(TdPNames.PARAM_FROM_STATION, parameter.fromStation); context.put(TdPNames.PARAM_TO_STATION, parameter.toStation); context.put(TdPNames.PARAM_TICKET_DATE, parameter.ticketDate); context.put(TdPNames.PARAM_PASSENGER_COUNT, parameter.passengers.size()); context.put(TdPNames.PARAM_PASSENGER_LIST, parameter.passengers); context.put(TdPNames.PARAM_FILTER_CONDITION, parameter.filterCond); context.put(TdPNames.PARAM_TICKET_TIME_RANGE, parameter.ticketTimeRange); } private Context createContext(InputParameter parameter, Log uiLog) { HttpContext httpContext = new BasicHttpContext(); Context context = new ContextBase(); context.put(HttpCommandPNames.HTTP_CLIENT, session); context.put(HttpCommandPNames.HTTP_CONTEXT, httpContext); // Input Parameters context.put(HttpCommandPNames.RESPONSE_DEFAULT_CHARSET, "UTF-8"); if(uiLog == null) { uiLog = LogFactory.getLog("TdClient.UI"); } context.put(TdPNames._USER_INTERFACE, uiLog); updateParameter(context, parameter, true); // Internal parameters //Welcome page String welComeURL = AppConfig.getInstance().getPropInternal("td.welcome.url"); String welComeReferer = AppConfig.getInstance().getPropInternal("td.welcome.referer"); context.put(TdPNames.PARAM_WELCOME_URL, welComeURL); context.put(TdPNames.PARAM_WELCOME_REFERER, welComeReferer); //Login page String loginURL = AppConfig.getInstance().getPropInternal("td.login.url"); String loginReferer = AppConfig.getInstance().getPropInternal("td.login.referer"); context.put(TdPNames.PARAM_LOGIN_URL, loginURL); context.put(TdPNames.PARAM_LOGIN_REFERER, loginReferer); //Init page String ticketBookInitURL = AppConfig.getInstance().getPropInternal("td.ticket_booking.init.url"); String ticketBookInitReferer = AppConfig.getInstance().getPropInternal("td.ticket_booking.init.referer"); context.put(TdPNames.PARAM_TICKET_BOOK_INIT_URL, ticketBookInitURL); context.put(TdPNames.PARAM_TICKET_BOOK_INIT_REFERER, ticketBookInitReferer); //queryLeftTicket page String queryLeftTicketBaseURL = AppConfig.getInstance().getPropInternal("td.queryLeftTicket.url"); String queryLeftTicketReferer = AppConfig.getInstance().getPropInternal("td.queryLeftTicket.referer"); context.put(TdPNames.PARAM_QUERY_LEFT_TICKET_BASE_URL, queryLeftTicketBaseURL); context.put(TdPNames.PARAM_QUERY_LEFT_TICKET_REFERER, queryLeftTicketReferer); //submit order page String submitOrderURL = AppConfig.getInstance().getPropInternal("td.submitOrder.url"); String submitOrderReferer = AppConfig.getInstance().getPropInternal("td.submitOrder.referer"); context.put(TdPNames.PARAM_SUBMIT_ORDER_URL, submitOrderURL); context.put(TdPNames.PARAM_SUBMIT_ORDER_REFERER, submitOrderReferer); //confirm passenger init page String confirmPassengerURL = AppConfig.getInstance().getPropInternal("td.confirmPassenger.init.url"); String confirmPassengerReferer = AppConfig.getInstance().getPropInternal("td.confirmPassenger.init.referer"); context.put(TdPNames.PARAM_CONFIRM_PASSENGER_INIT_URL, confirmPassengerURL); context.put(TdPNames.PARAM_CONFIRM_PASSENGER_INIT_REFERER, confirmPassengerReferer); return context; } private boolean isContextInitialed() { if(clientContext != null) { Log uiLog = (Log)clientContext.get(TdPNames._USER_INTERFACE); return uiLog != null; } return false; } public boolean isLogin() { return TdParams.isLogin(clientContext); } public void initContext(InputParameter parameter, Log uiLog) { if(isContextInitialed()) { if(isLogin()) { log.error("Assert Failure: make sure the user has logout"); logout(); } clientContext.clear(); } clientContext = createContext(parameter, uiLog); } public void updateParameter(InputParameter parameter, boolean includeUserInfo) { if(!isContextInitialed()) { throw new IllegalArgumentException("Context doesn't init yet"); } updateParameter(clientContext, parameter, includeUserInfo); } public boolean login() { Chain chain = new ChainBase(); chain.addCommand(new WelComePage()); chain.addCommand(new Login()); // 3. Execute TdParams.getUI(clientContext).info(ResMgr.getString("td.msg.start.login")); CommandCompleteListener listener = new TdWorkCompleteListener(TdParams.getUI(clientContext), log); DefaultHttpCommandDirector director = new DefaultHttpCommandDirector(); try { director.execute(chain, clientContext, listener); } catch(Exception e) { TdParams.getUI(clientContext).error(e.getMessage(), e); } boolean isLogin = TdParams.isLogin(clientContext); return isLogin; } public void bookTicket() { // retry with newly input verification code clientContext.remove(TdPNames._CONFIRM_PASSENGER_VOCDE); Chain chain = new ChainBase(); chain.addCommand(new GetTicketBookInitPage()); chain.addCommand(new BookTicket()); // 3. Execute TdParams.getUI(clientContext).info(ResMgr.getString("td.msg.start.book")); CommandCompleteListener listener = new TdWorkCompleteListener(TdParams.getUI(clientContext), log); DefaultHttpCommandDirector director = new DefaultHttpCommandDirector(); try { director.execute(chain, clientContext, listener); } catch(Exception e) { TdParams.getUI(clientContext).error(e.getMessage(), e); } } public void logout() { // 3. Execute TdParams.getUI(clientContext).info(ResMgr.getString("td.msg.start.logout")); CommandCompleteListener listener = new TdWorkCompleteListener(TdParams.getUI(clientContext), log); DefaultHttpCommandDirector director = new DefaultHttpCommandDirector(); try { director.execute(new DoLogout(), clientContext, listener); } catch(Exception e) { TdParams.getUI(clientContext).error(e.getMessage(), e); } } public void shutdown() { // shutdown connections session.getConnectionManager().shutdown(); clientContext.clear(); clientContext = null; } public String getCookie() { if(session == null) { return null; } return HttpClientUtils.formatCookie(session.getCookieStore().getCookies()); } private static List<PassengerInfo> getPassengerList(int passengerCount) { List<PassengerInfo> passengerList = new ArrayList<PassengerInfo>(passengerCount); for(int i = 0; i < passengerCount; i++) { String content = AppConfig.getInstance().getPropInput("td.passenger" + (i + 1)); String[] fields = content.split(","); if(fields.length < 6) { log.fatal("passenger info is incomplete. content=" + content); System.exit(-2); } PassengerInfo passenger = new PassengerInfo(); passenger.name = fields[0]; passenger.cardType = TdUtils.getCardTypeValue(fields[1]); passenger.cardNo = fields[2]; passenger.tiketType = TdUtils.getTicketTypeValue(fields[3]); passenger.phone = fields[4]; passenger.isSave = fields[5]; passengerList.add(passenger); } return passengerList; } private static TicketFilterCondition getFilterCond() { TicketFilterCondition cond = new TicketFilterCondition(); String conditions = AppConfig.getInstance().getPropInput("td.ticket.sort.conditions"); String[] args = conditions.split(","); for(String category : args) { String propName = "td.ticket.sort.cond." + category; String value = AppConfig.getInstance().getPropInput(propName); //Seat Class if("4".equalsIgnoreCase(category)) { cond.seatClassList = Arrays.asList(value.split(",")); } //Train Class else if("2".equalsIgnoreCase(category)) { cond.trainClassList = Arrays.asList(value.split(",")); } } return cond; } /** * @param args */ public static void main(String[] args) { String user = AppConfig.getInstance().getPropInput("td.user"); String pwd = AppConfig.getInstance().getPropInput("td.password"); String fromStation = AppConfig.getInstance().getPropInput("td.from_station"); String toStation = AppConfig.getInstance().getPropInput("td.to_station"); String ticketDate = AppConfig.getInstance().getPropInput("td.ticket.date"); String ticketTimeRange = AppConfig.getInstance().getPropInput("td.ticket.time_range"); Integer passengerCount = MiscUtils.toInt(AppConfig.getInstance().getPropInput("td.user.count")); InputParameter param = new InputParameter(); param.user = user; param.pwd = pwd; param.fromStation = fromStation; param.toStation = toStation; param.ticketDate = ticketDate; param.passengers = getPassengerList(passengerCount); param.ticketTimeRange = ticketTimeRange; param.filterCond = getFilterCond(); TdClient client = new TdClient(); try { client.initContext(param, null); client.login(); client.bookTicket(); } finally { if(client.isLogin()) { client.logout(); } client.shutdown(); } System.exit(0); } }