Wicket で MountしているPage のURLが何なのかよくわからなくなるので、 Mount しているURL の一覧を取得するDropwizard の Task を作成してみました。


参考

How To: Create Dropwizard Tasks - flat


稼働環境の情報

Java Version 、Wicket の Version は以下の通りです。

  • OS

OS X El Capitan 
バージョン 10.11.6 

  • Java

java -version
------------------------------
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
------------------------------

  • Wicket

<dependency>
    <groupId>org.apache.wicket</groupId>
    <artifactId>wicket-core</artifactId>
    <version>7.5.0</version>
</dependency>

  • Dropwizard

assets はいらないかもしれません。

        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
            <version>1.0.5</version>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-assets</artifactId>
            <version>1.0.5</version>
        </dependency>


pom.xml に dependency を追加

dropwizard-servletspomに追加しました。
Taskの抽象クラスがこのjarに含まれてます。

        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-servlets</artifactId>
            <version>1.0.5</version>
        </dependency>


Task クラス

  • WicketShowUrlsTask.java

package xyz.monotalk.festivals4partypeople.web.tasks;

import com.google.common.collect.ImmutableMultimap;
import io.dropwizard.servlets.tasks.Task;
import org.apache.wicket.core.request.mapper.MountedMapper;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.IRequestMapper;
import xyz.monotalk.festivals4partypeople.web.inject.initialize.InjectorHolder;

import java.io.PrintWriter;
import java.util.Iterator;

/**
 * WicketShowUrlsTask
 */
public class WicketShowUrlsTask extends Task {

    public WicketShowUrlsTask() {
        super("show_urls");
    }

    protected WicketShowUrlsTask(String name) {
        super(name);
    }

    @Override
    public void execute(ImmutableMultimap<String, String> immutableMultimap, PrintWriter printWriter) throws Exception {
        WebApplication webApplication;
        if (!WebApplication.exists()) {
            webApplication = InjectorHolder._new(WebApplication.class);
        } else {
            webApplication = WebApplication.get();
        }

        printWriter.println("URLs------------------------------START");
        Iterator<IRequestMapper> iterator = webApplication.getRootRequestMapperAsCompound().iterator();
        while (iterator.hasNext()) {
            IRequestMapper mapper = iterator.next();
            if (mapper instanceof MountedMapper) {
                printWriter.println(mapper.toString());
            }
        }
        printWriter.println("------------------------------END");
        printWriter.flush();
    }
}

説明

  • if (!WebApplication.exists()) {存在確認する。
    Filter設定にも依るのでしょうが、
    Admin Port には、Filter設定していないので、
    WebApplication.get(); Application クラスを取得すると、
    WicketFilterを通していないので、
    以下の内容でエラーとなります。

 org.apache.wicket.WicketRuntimeException: There is no application attached to current thread 

Application は、GuiceでSingletonで登録しているので、存在しなければ、
Guice経由で取得するようにしています。
なので、

    webApplication = WebApplication.get();

は、事前に何らかの手段で設定しておかないと、実行されません。

  • webApplication.getRootRequestMapperAsCompound().iterator();結果
    戻り値のIterator<irequestmapper > iteratorですが、
    設定される要素がMountされたリソースになりますが、
    基本これらのURLパスにアクセスするメソッドが存在しないです。

MountedMapper だけいい感じのtoString()実装されているので、
if (mapper instanceof MountedMapper) { インスタンスを絞り込んで、
Output出力を行うようにしました。
MountPage で URL登録しているものについては出力できていますが、 それ以外の方法で登録しているリソースについては取得できません。1

[1] 別で全てのURLが取得できる方法があるのかもしれません。


Task登録

Applicationクラスに以下の記述を追加して、Taskを登録します。

    @Override
    public void run(WicketConfiguration t, Environment e) throws Exception {
        e.admin().addTask(new WicketShowUrlsTask());
    }


Application起動

Application 起動で、以下の通り、登録されたことが確認できました。

********************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode.              ***
***                               ^^^^^^^^^^^                    ***
*** Do NOT deploy to your live server(s) without changing this.  ***
*** See Application#getConfigurationType() for more information. ***
********************************************************************
INFO  [2016-11-30 23:03:45,271] org.eclipse.jetty.server.handler.ContextHandler: Started i.d.j.MutableServletContextHandler@196ae579{/,null,AVAILABLE}
INFO  [2016-11-30 23:03:45,278] io.dropwizard.setup.AdminEnvironment: tasks = 

    POST    /tasks/log-level (io.dropwizard.servlets.tasks.LogConfigurationTask)
    POST    /tasks/gc (io.dropwizard.servlets.tasks.GarbageCollectionTask)
    POST    /tasks/show_urls (xyz.monotalk.festivals4partypeople.web.tasks.WicketShowUrlsTask)


Task実行

curl コマンドの実行でTask実行ができます。

curl -X POST 'http://localhost:18081/tasks/show_urls'

outputは以下の通りです。

URLs------------------------------START
MountedMapper [mountSegments=404]
MountedMapper [mountSegments=admin/login]
MountedMapper [mountSegments=artists/${id}/similarities/c/${popCount}]
MountedMapper [mountSegments=artists/${id}/videos/c/${popCount}]
MountedMapper [mountSegments=artists/${id}/tracks/c/${popCount}]
MountedMapper [mountSegments=artists/${id}/blogs/c/${popCount}]
MountedMapper [mountSegments=artists/${id}/c/${popCount}]
MountedMapper [mountSegments=artists/${id}]
MountedMapper [mountSegments=festivals/${id}/c/${popCount}]
MountedMapper [mountSegments=festivals/${id}]
MountedMapper [mountSegments=festivals/c/${popCount}]
MountedMapper [mountSegments=festivals]
MountedMapper [mountSegments=]
------------------------------

Djangoのshow_urlのようないい感じに出力できればですが、そこまでは、できず。。
以上です。

コメント