/*
 * @(#)AssertionServiceWrapper.java
 *
 * Copyright 2006 Sony Corporation
 */
package info.dragonlady.cluster;

import info.dragonlady.sso.AssertionManager;
import info.dragonlady.sso.SSOConfig;
import info.dragonlady.sso.message.SSOMessageResource;

import java.rmi.ConnectException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.util.Map;

import org.apache.log4j.Logger;
import org.opensaml.SAMLAssertion;

/**
 * アサーション操作用サービスラッパークラス。
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.5 $ $Date: 2006/09/26 08:16:04 $
 */
public class AssertionServiceWrapper {

	/**
	 * コンストラクタ。
	 */
	public AssertionServiceWrapper() {
		super();
	}

	/**
	 * ローカルサーバ及びクラスタリングサーバのアサーション情報を設定。
	 * 
	 * @param assertion アサーション
	 * @throws AssertionServiceException
	 */
	public static final void put(SAMLAssertion assertion) throws AssertionServiceException {
		try {
			Friend[] friends = SSOConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバに情報設定
					String name = SSOConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					// ハンドル文字列取得
					String handleStr = (String)AssertionManager.getInstance().getHandleMap().get(assertion.getId());
					// SAMLAssertionはSerializeされていない為、Stringで送る
					service.put(handleStr, assertion.toString());
					Logger.getRootLogger().info(SSOMessageResource.getMessage("6113", args));
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6101", args), e);
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6102", args), e);
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6103", args), e);
				}
			}
		} catch (Exception e) {
			String message = SSOMessageResource.getMessage("6104");
			Logger.getRootLogger().error(message, e);
			throw new AssertionServiceException(message, e);
		}
	}

	/**
	 * ローカルサーバ及びクラスタリングサーバのアサーション情報から指定IDの情報を削除。
	 * 
	 * @param id アサーション管理ID
	 * @throws AssertionServiceException
	 */
	public static final void remove(String id) throws AssertionServiceException {
		try {
			Friend[] friends = SSOConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバから情報削除
					String name = SSOConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					service.remove(id);
					Logger.getRootLogger().info(SSOMessageResource.getMessage("6114", args));
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6105", args), e);
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6106", args), e);
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6107", args), e);
				}
			}
		} catch (Exception e) {
			String message = SSOMessageResource.getMessage("6108");
			Logger.getRootLogger().error(message, e);
			throw new AssertionServiceException(message, e);
		}
	}

	/**
	 * ローカルサーバのアサーション情報をクラスタリングサーバのアサーション情報と同期化。
	 * 
	 * @throws AssertionServiceException
	 */
	public static final void synchronize() throws AssertionServiceException {
		try {
			Friend[] friends = SSOConfig.getFriends();
			for(int i = 0; i < friends.length; i++) {
				String[] args = {friends[i].getHost(), friends[i].getPort()};
				try {
					// リモートサーバから情報取得
					String name = SSOConfig.getServiceName(args[0], args[1], AssertionService.SERVICE_NAME);
					AssertionService service = (AssertionService)Naming.lookup(name);
					Map<String, String> handleMap = service.getHandleMap();
					Map<String, String> assertionMap = service.getAssertionMap();
					if(handleMap != null && assertionMap != null) {
						// ローカルサーバに情報を設定
						AssertionManager.getInstance().setMap(assertionMap, handleMap);
						Logger.getRootLogger().info(SSOMessageResource.getMessage("6115", args));
						break;
					}
				} catch(ConnectException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6109", args), e);
				} catch(NotBoundException e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6110", args), e);
				} catch(Exception e) {
					// 失敗したホスト名とポート番号をログ出力
					Logger.getRootLogger().warn(SSOMessageResource.getMessage("6111", args), e);
				}
			}
		} catch (Exception e) {
			String message = SSOMessageResource.getMessage("6112");
			Logger.getRootLogger().error(message, e);
			throw new AssertionServiceException(message, e);
		}
	}

}
