ある (jaxrs 準拠の) コンテナーにデプロイされたロギング・サービスがあるとします。
@Path("/logger")
public class LogService
{
@GET
@Path("/log")
public Response log(final String @QueryParam("msg") msg)
{
System.out.println(msg);
// ...
}
}
このサービスをホストしているコンテナーに対して次の要求を行うと、メッセージの出力がコンテナーの stdout ログに表示されるはずです。
GET <host>:<port>/logger/log?msg=foo
ここで、任意のクライアントによって指定された動作で、実行時にこのログ メッセージの実装を変更したいと思います。
たとえば、次のインターフェースがあるとします。
public interface LoggerApi
{
void logMessage(final String msg);
}
サービスは、このインターフェースの実装を使用するように再定義されました。
@Path("/logger")
public class LogService
{
public static LoggerApi LOGGER = new LoggerApi()
{
void logMessage(final String msg)
{
System.out.println(msg);
}
}
@GET
@Path("/log")
public Response log(final String @QueryParam("msg") msg)
{
LOGGER.logMessage(msg);
// ...
}
}
したがって、問題は、ロガーの実装を、サーバー外部のクライアントによって定義された新しい実装とホットスワップするにはどうすればよいかということになります。
私の最初の本能は、RMI および/または動的プロキシを使用すれば、自分が望む場所に到達できるということでしたが、セキュリティ ポリシーの狂気のせいで、あまり確信が持てませんでした。
基本的に私が欲しいのは、次のことを行う能力です。
@Path("/config")
public class ConfigService
{
@POST
@Path("/loggerApi")
public Response setLoggerApi(final LoggerApi clientSuppliedLogger)
{
LogService.LOGGER = clientSuppliedLogger;
// ...
}
}
考え?
(ああ、私はこれが深刻なセキュリティ リスクをもたらすことを知っており、そのようなパターンは本番環境では決して使用すべきではありません。私の関心は、モック サービスを呼び出す統合テストによってサービスの動作と副作用を定義できるモック サービスを設計することです)