/*
 * This software is distributed under following license based on modified BSD
 * style license.
 * ----------------------------------------------------------------------
 * 
 * Copyright 2009 The Nimbus2 Project. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE NIMBUS PROJECT ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE NIMBUS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Nimbus2 Project.
 */
package jp.ossc.nimbus.service.context;

import java.util.Set;

import jp.ossc.nimbus.core.ServiceBaseMBean;
import jp.ossc.nimbus.core.ServiceName;

/**
 * {@link DistributedSharedContextService}のMBeanインタフェース。<p>
 * 
 * @author M.Takata
 * @see DistributedSharedContextService
 */
public interface DistributedSharedContextServiceMBean<K> extends ServiceBaseMBean{
    
    /**
     * デフォルトのサブジェクト。<p>
     */
    public static final String DEFAULT_SUBJECT = "DistributedSharedContext";
    
    /**
     * クライアントモードのサブジェクト後置詞。<p>
     */
    public static final String CLIENT_SUBJECT_SUFFIX = ".Client";
    
    /**
     * データの分散数を設定する。<p>
     * デフォルトは、2。<br>
     *
     * @param size 分散数
     */
    public void setDistributedSize(int size) throws IllegalArgumentException;
    
    /**
     * データの分散数を取得する。<p>
     *
     * @return 分散数
     */
    public int getDistributedSize();
    
    /**
     * データの複製数を設定する。<p>
     * デフォルトは、2。<br>
     *
     * @param size 複製数
     */
    public void setReplicationSize(int size) throws IllegalArgumentException;
    
    /**
     * データの複製数を取得する。<p>
     *
     * @return 複製数
     */
    public int getReplicationSize();
    
    /**
     * {@link SharedContextKeyDistributor}サービスのサービス名を設定する。<p>
     * 指定しない場合は、{@link MD5HashSharedContextKeyDistributorService}が適用される。<br>
     * 
     * @param name SharedContextKeyDistributorサービスのサービス名
     */
    public void setSharedContextKeyDistributorServiceName(ServiceName name);
    
    /**
     * {@link SharedContextKeyDistributor}サービスのサービス名を取得する。<p>
     * 
     * @return SharedContextKeyDistributorサービスのサービス名
     */
    public ServiceName getSharedContextKeyDistributorServiceName();
    
    /**
     * {@link jp.ossc.nimbus.service.publish.RequestConnectionFactoryService RequestConnectionFactoryService}サービスのサービス名を設定する。<p>
     * 
     * @param name RequestConnectionFactoryServiceサービスのサービス名
     */
    public void setRequestConnectionFactoryServiceName(ServiceName name);
    
    /**
     * {@link jp.ossc.nimbus.service.publish.RequestConnectionFactoryService RequestConnectionFactoryService}サービスのサービス名を取得する。<p>
     * 
     * @return RequestConnectionFactoryServiceサービスのサービス名
     */
    public ServiceName getRequestConnectionFactoryServiceName();
    
    /**
     * {@link jp.ossc.nimbus.service.distribute.ClusterService ClusterService}サービスのサービス名を設定する。<p>
     * 
     * @param name ClusterServiceサービスのサービス名
     */
    public void setClusterServiceName(ServiceName name);
    
    /**
     * {@link jp.ossc.nimbus.service.distribute.ClusterService ClusterService}サービスのサービス名を取得する。<p>
     * 
     * @return ClusterServiceサービスのサービス名
     */
    public ServiceName getClusterServiceName();
    
    /**
     * クライアントモード時の{@link jp.ossc.nimbus.service.cache.CacheMap CacheMap}サービスのサービス名を設定する。<p>
     * コンテキスト情報をCacheMapに格納してデータのあふれ制御を行う場合、設定する。<br>
     * 
     * @param name CacheMapサービスのサービス名
     */
    public void setClientCacheMapServiceName(ServiceName name);
    
    /**
     * クライアントモード時の{@link jp.ossc.nimbus.service.cache.CacheMap CacheMap}サービスのサービス名を取得する。<p>
     * 
     * @return CacheMapサービスのサービス名
     */
    public ServiceName getClientCacheMapServiceName();
    
    /**
     * サーバモード時の{@link jp.ossc.nimbus.service.cache.CacheMap CacheMap}サービスのサービス名を設定する。<p>
     * コンテキスト情報をCacheMapに格納する場合、設定する。<br>
     * 
     * @param name CacheMapサービスのサービス名
     */
    public void setServerCacheMapServiceName(ServiceName name);
    
    /**
     * サーバモード時の{@link jp.ossc.nimbus.service.cache.CacheMap CacheMap}サービスのサービス名を取得する。<p>
     * 
     * @return CacheMapサービスのサービス名
     */
    public ServiceName getServerCacheMapServiceName();
    
    /**
     * {@link SharedContextStore}サービスのサービス名を設定する。<p>
     * 
     * @param name SharedContextStoreサービスのサービス名
     */
    public void setSharedContextStoreServiceName(ServiceName name);
    
    /**
     * {@link SharedContextStore}サービスのサービス名を取得する。<p>
     * 
     * @return SharedContextStoreサービスのサービス名
     */
    public ServiceName getSharedContextStoreServiceName();
    
    /**
     * サブジェクトを設定する。<p>
     * デフォルトは、{@link #DEFAULT_SUBJECT}。
     *
     * @param subject サブジェクト
     */
    public void setSubject(String subject);
    
    /**
     * サブジェクトを取得する。<p>
     *
     * @return サブジェクト
     */
    public String getSubject();
    
    /**
     * クライアント/サーバモードを設定する。<p>
     * デフォルトは、falseでサーバモード。<br>
     *
     * @param isClient クライアントモードの場合、true
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void setClient(boolean isClient) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * クライアント/サーバモードを判定する。<p>
     *
     * @return trueの場合、クライアントモード
     */
    public boolean isClient();
    
    /**
     * リハッシュが有効かどうかを設定する。<p>
     * デフォルトは、trueで有効。<br>
     *
     * @param isEnabled 有効にする場合、true
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void setRehashEnabled(boolean isEnabled) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * リハッシュが有効かどうかを判定する。<p>
     *
     * @return trueの場合、クライアントモード
     */
    public boolean isRehashEnabled();
    
    /**
     * 同期時のタイムアウト[ms]を設定する。<p>
     * デフォルトは、5000[ms]。<br>
     *
     * @param timeout タイムアウト[ms]
     */
    public void setSynchronizeTimeout(long timeout);
    
    /**
     * 同期時のタイムアウト[ms]を取得する。<p>
     *
     * @return タイムアウト[ms]
     */
    public long getSynchronizeTimeout();
    
    /**
     * コンテキスト分散の再配置時のタイムアウト[ms]を設定する。<p>
     * デフォルトは、10000[ms]。<br>
     *
     * @param timeout タイムアウト[ms]
     */
    public void setRehashTimeout(long timeout);
    
    /**
     * コンテキスト分散の再配置時のタイムアウト[ms]を取得する。<p>
     *
     * @return タイムアウト[ms]
     */
    public long getRehashTimeout();
    
    /**
     * タイムアウトを指定しないメソッドを呼び出した場合に適用されるタイムアウト[ms]を設定する。<p>
     * デフォルトは、1000[ms]。<br>
     *
     * @param timeout タイムアウト[ms]
     */
    public void setDefaultTimeout(long timeout);
    
    /**
     * タイムアウトを指定しないメソッドを呼び出した場合に適用されるタイムアウト[ms]を取得する。<p>
     *
     * @return タイムアウト[ms]
     */
    public long getDefaultTimeout();
    
    /**
     * データノードをサービスとして登録するかどうかを設定する。<p>
     * デフォルトは、falseで登録しない。<br>
     *
     * @param isManage 登録する場合は、true
     */
    public void setManagedDataNode(boolean isManage);
    
    /**
     * データノードをサービスとして登録するかどうかを判定する。<p>
     *
     * @return trueの場合、登録する
     */
    public boolean isManagedDataNode();
    
    /**
     * コンテキストの保存の前にストアをクリアするかどうかを設定する。<p>
     * デフォルトは、trueでクリアする。<br>
     *
     * @param isClear クリアする場合、true
     */
    public void setClearBeforeSave(boolean isClear);
    
    /**
     * コンテキストの保存の前にストアをクリアするかどうかを判定する。<p>
     *
     * @return trueの場合、クリアする
     */
    public boolean isClearBeforeSave();
    
    /**
     * {@link SharedContextUpdateListener}サービスのサービス名配列を設定する。<p>
     * 
     * @param names SharedContextUpdateListenerサービスのサービス名配列
     */
    public void setSharedContextUpdateListenerServiceNames(ServiceName[] names);
    
    /**
     * {@link SharedContextUpdateListener}サービスのサービス名配列を取得する。<p>
     * 
     * @return SharedContextUpdateListenerサービスのサービス名配列
     */
    public ServiceName[] getSharedContextUpdateListenerServiceNames();
    
    /**
     * コンテキスト分散の再配置を行う。<p>
     * 主ノードの場合は、全てのノードに再配置命令を出す。主ノードでない場合は、主ノードに再配置を促す。<br>
     *
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void rehash() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * コンテキスト分散の再配置を行う。<p>
     * 主ノードの場合は、全てのノードに再配置命令を出す。主ノードでない場合は、主ノードに再配置を促す。<br>
     *
     * @param timeout タイムアウト
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void rehash(long timeout) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * コンテキスト同期を行う。<p>
     * クライアントモードの場合は、ローカルのコンテキストをクリアする。また、サーバモードで主ノードの場合は、全てのノードに同期命令を出す。主ノードでない場合は、主ノードに同期を促す。<br>
     *
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void synchronize() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * コンテキスト同期を行う。<p>
     * クライアントモードの場合は、ローカルのコンテキストをクリアする。また、サーバモードで主ノードの場合は、全てのノードに同期命令を出す。<br>
     *
     * @param timeout タイムアウト
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void synchronize(long timeout) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 指定されたキーのロックを開放する。<p>
     *
     * @param key キー
     * @return ロック開放できた場合は、true
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     */
    public boolean unlock(K key) throws SharedContextSendException;
    
    /**
     * 指定されたキーのロックを開放する。<p>
     *
     * @param key キー
     * @param force 強制フラグ
     * @return ロック開放できた場合は、true
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     */
    public boolean unlock(K key, boolean force) throws SharedContextSendException;
    
    /**
     * キーの集合を取得する。<p>
     *
     * @return キーの集合
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public Set<K> keySet() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 登録されているキーの件数を取得する。<p>
     *
     * @return キーの件数
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public int size() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 全て削除する。<p>
     *
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void clear() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 全て削除する。<p>
     *
     * @param timeout タイムアウト[ms]
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public void clear(long timeout) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 非同期で全て削除する。<p>
     *
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     */
    public void clearAsynch() throws SharedContextSendException;
    
    /**
     * 指定されたキーがどのデータノードに格納されるかのインデックスを取得する。<p>
     *
     * @param key キー
     * @return データノードのインデックス
     */
    public int getDataNodeIndex(Object key);
    
    /**
     * 指定されたインデックスのデータノードに登録されているキーの数を取得する。<p>
     *
     * @param nodeIndex データノードのインデックス
     * @return キーの数
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public int size(int nodeIndex) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 指定されたインデックスのデータノードのキーの集合を取得する。<p>
     *
     * @param nodeIndex データノードのインデックス
     * @return キーの集合
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public Set<K> keySet(int nodeIndex) throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * 指定されたインデックスのデータノードがクライアントモードかどうかを判定する。<p>
     *
     * @param nodeIndex データノードのインデックス
     * @return trueの場合、クライアントモード
     */
    public boolean isClient(int nodeIndex);
    
    /**
     * 指定されたインデックスのデータノードが主ノードかどうかを判定する。<p>
     *
     * @param nodeIndex データノードのインデックス
     * @return trueの場合、主ノード
     */
    public boolean isMain(int nodeIndex);
    
    /**
     * 分散サーバのデータノードのクライアント/サーバモードの状態を表示する。<p>
     *
     * @return 分散サーバのデータノードのクライアント/サーバモードの状態を表す文字列
     * @exception SharedContextSendException 分散サーバへのメッセージ送信に失敗した場合
     * @exception SharedContextTimeoutException 分散サーバからの応答待ちでタイムアウトした場合
     */
    public String displayDistributeInfo() throws SharedContextSendException, SharedContextTimeoutException;
    
    /**
     * コンテキスト読み込みを行う。<p>
     * 主ノードでない場合、主ノードに読み込みを依頼する。<br>
     *
     * @param timeout 分散サーバへの通信タイムアウト[ms]
     * @exception Exception コンテキスト読み込みに失敗した場合
     */
    public void load(long timeout) throws Exception;
    
    /**
     * コンテキスト保存を行う。<p>
     * 主ノードでない場合、主ノードに保存を依頼する。<br>
     *
     * @param timeout 分散サーバへの通信タイムアウト[ms]
     * @exception Exception コンテキスト保存に失敗した場合
     */
    public void save(long timeout) throws Exception;
    
    /**
     * 主ノードかどうかを判定する。<p>
     *
     * @return 主ノードの場合true
     */
    public boolean isMain();
    
    /**
     * ノードIDを取得する。<p>
     *
     * @return ノードID
     */
    public Object getId();
    
    /**
     * 主ノードのノードIDを取得する。<p>
     *
     * @return ノードID
     */
    public Object getMainId();
}