tohokuaikiのチラシの裏

技術的ネタとか。

今更ですが、Composer.pharがinstallとupdateでcomposer.json/.lockを見て何をしているかを図解

基本的に、下記の事項を覚えておけば挙動は理解しやすい。

  • installは.lockを見てその通りに実行する
  • updateは、.jsonを見て依存性を解決する

composer.phar install を実行した場合にcomposer.lockの有無による挙動の違い

f:id:tohokuaiki:20161213171954p:plain

.lockがあれば待ち時間は少なくて済む。

composer.json を更新した際に、installとupdateでは何が違うのか?

ライブラリを追加したい場合にcomposer.jsonに記載したあと、それぞれのコマンドを打った場合。

install 実行

installは.lockファイルを見るだけなのでライブラリの追加は行われない。

f:id:tohokuaiki:20161213172108p:plain

update 実行

updateは.jsonを見て依存性を解決する。そのため追記したライブラリの依存性を解決しダウンロードが行われる。

f:id:tohokuaiki:20161213172150p:plain

LinuxのディストリビューションとデフォルトパッケージのPHPバージョンの一覧

ディストリビューション バージョン サポート終了 PHPのバージョン
CentOS 5 2017/3/31 5.1
CentOS 6 2020/11/30 5.3
CentOS 7 2024/6/30 5.4
Debian 7 2018/5/31 5.4
Debian 8 2020/4/30 ? 5.6
Ubuntu(LTS) 14 2019/4/30 5.5
Ubuntu(LTS) 16 2021/4/30 7

Laravel が必要とするPHPのバージョンの一覧

Release Notes - Laravel - The PHP Framework For Web Artisansから作成

Laravel PHPのバージョン
4.2 5.4
5.0 5.4
5.1 5.5.9
5.2 5.5.9
5.3 5.5.9

んー、でも現時点で https://laravel.com/docs/5.3#server-requirements を見ると 5.6.4が必要らしい。

開発環境でのConfluenceがクソ重いのでメモリを増やしてみた

Atlassian SDK使っているノートパソコンが古くなってきたのかな?と思ったくらいだったのでとりあえずメモリ増やす。

現状のメモリ使用量

管理画面の「システム情報」を見てみる。空きが14%しかない。

f:id:tohokuaiki:20161209123936p:plain

ということで、変更。

pom.xmlにて

    <build>
        <plugins>
            <plugin>
                <configuration>
                    <jvmArgs>-Xms512m -Xmx1g -XX:MaxPermSize=512m</jvmArgs>

これで、1Gのメモリを使ってくれるはず。

システムが8Gしかないのでちょっと心配なんだけど。。。 f:id:tohokuaiki:20161209124206p:plain

再起動してみる

f:id:tohokuaiki:20161209124359p:plain

これで少しでも快適になるかな・・・。

Windowsの方がやや厳しいかな・・・。f:id:tohokuaiki:20161209124914p:plain

ConfluenceのREST APIを作ってみる - POST編

GETメソッドの場合は引数を@QueryParamで受け取ればなんてことなかったのだけど、POSTの場合はちょっと違った。

なお、通信はXMLじゃなくてすべてJSONを使った場合。

AtlassianのDocumentでいうとこの辺りが参考になる。使わなかったけど。

Developing a REST Service Plugin - Atlassian Developers

あと、そもそもこの技術はJavaのjerseyを使っているので、とりあえずREST with Java (JAX-RS) using Jersey - Tutorialあたりを参考にしたりしました。

そもそもどういうRequestを作るべきなのか?

Labelを付けるREST APIを見ながら考察した。するつRequest Headerはこんな感じ。

Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:ja,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Content-Length:70
Content-Type:application/json
Cookie:JSESSIONID=xxxxxxxxxxxxxxxxxxxx

普通にjQueryで$.ajaxするとContent-Typeが「application/x-www-form-urlencoded」になるので、そこを変更しなければならない。

また、POSTデータを見てみると、Request Payloadになっていて、

[{"name":"ccc","id":1481094538830},{"name":"dddd","id":1481094538831}]

まんま、JSONの形。

ということで、これをjQueryで使うには

var data = {
    foo: 123,
    bar: 456
};
$.ajax({
    url: "{ConfluenceのBASE URL}/rest/restpath/1.0/restclasspath/{pageId}/restmethod.json",
    type: "post",
    contentType:'application/json',
    data: JSON.stringify(data)
}).success(function (data, status, xhr) {

という感じでContentTypeを指定し、送信データをJSON.stringifyしてやる。

受けるConfluence側

atlassian-plugin.xml

にてRESTの指定をする。決める重要な情報は、restのpathのみ。
先ほどのAjaxで受ける場合はrestpathの部分を以下のように指定する。

<rest key="foo-bar-rest" path="/restpath" version="1.0">
    <description>RESTの説明</description>
</rest>

JavaクラスとRESTのクラスパス

クラスの場所はどこでもいいので、@Pathアノテーションに持つクラスを作る。
これは結構不思議というか、じゃあ先ほどatlassian-plugin.xmlのpathで指定したものとの関連性は無いのか?という感じである。

とりあえず、先ほどのAjaxの場合は

@Path("/restclasspath")
public class Foobar {

という感じでClassを作る。

JavaメソッドとRESTのメソッド

先ほどのAjaxのパスの場合だと

    @POST
    @Path("{pageId}/restmethod")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response api(@PathParam("pageId") FoobarModel foobarModel) {

というメソッドを作る。メソッド名はapiとしているけどこれは特に意味は無い。わかりやすいのを付ければ何でもいいのではないかと思う。

メソッドの引数としては、メソッドの@Pathアノテーション内で定義したものを、@PathParamでアノテーションされた引数と、POSTされたJSONデータを受け取るModelクラスを指定する。

POST値を受け取るModelクラス
var data = {
    foo: 123,
    bar: 456
};

を受け取りたい場合はこんな感じ。

@XmlRootElement(name = "foobar")
@XmlAccessorType(XmlAccessType.FIELD)
public class foobarModel {

    @JsonIgnore
    @XmlElement(name = "foo")
    private String foo;

    @XmlElement(name = "bar")
    private String barString;

    public foobarModel() {
    }
}

@JsonIgnoreが付いていると、その要素は無くても大丈夫になる。各プロパティに逐一全部つけるのが面倒な場合はクラスにまとめて

@JsonIgnoreProperties(ignoreUnknown=true)
public class foobarModel {
@JsonIgnoreProperties({"foo","bar"})
public class foobarModel {

としてやる。

もし、JSONが下記のようであったら

var data = {
    foo: 123,
    bar: 456
};

プロパティにJsonアノテーションを付ける。

    @JsonProperty("barStr")
    @XmlElement(name = "bar")
    private String barString;

@JsonPropertyがなくても、@XmlElementのnameで指定していればそれを援用してくれる。

このようなオプションを通してもマッピングできない場合は、common.error.jersey.ThrowableExceptionMapper が投げられる。

レスポンスの設定

レスポンスには、OK/NGのステータスとOKの場合はJSONを付けられるので

return Response.ok(new foobarModel).build();

とすると、foobarModelオブジェクトをJSONにしたものを返却できる。

Confluenceのマクロモジュールを作成するときのi18nについて

マクロパラメータとかの名称をi18nにしたいなーって思ったときに今までやったことが無いことに気が付いた。

元資料

Including Information in your Macro for the Macro Browser - Atlassian Developers

の最後の方によると、自動的にi18nの定義を見てくれるらしい

i18nの定義 意味
{pluginKey}.{macroName}.label マクロ名
{pluginKey}.{macroName}.desc マクロの説明文
{pluginKey}.{macroName}.param.{paramName}.label パラメータの名前
{pluginKey}.{macroName}.param.{paramName}.desc パラメータの説明文
{pluginKey}.{macroName}.body.label Macro body label (defaults to 'Body Text' if not provided)
{pluginKey}.{macroName}.body.desc Macro body description