CanActivateで取得したデータをResolveで返したい

次に遷移するコンポーネントの表示に必要なデータを、Resolveを使ってサーバーから取得するわけです。
しかし、サーバーでしかできない入力チェックとか、あるわけです。
なのでCanActivateでサーバーにアクセスするんですが、それならその時にデータも一緒に取ってきてResolveで返したいわけです。
ところが、こいつらの実行順はCanActivate→Resolveなわけです。
そしてcanActivate()の引数であるActivatedRouteSnapshotも、RouterStateSnapshotもResolveにデータを受け渡すような機能を持っていないのです。
CanActivateで適当なServiceにデータを保存して、Resolveでそれを返せばできますが・・・あまりスマートでない。


というわけで悩んだんですが、よく考えたら1個のクラスでCanActivateもResolveも実装してしまえばいいですね。単純。

@Injectable()
export class SomeComponentGuard implements CanActivate, Resolve<Data> {

  private data: Data;
  
  constructor(
    private service: ServerAccessService
  ) { }
  
  canActivate(
      next: ActivatedRouteSnapshot,
      state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.service.getData(next.queryParams).map(
      data => {
        this.data = data;
        return true;
      }
    ).catch(e => {
      return Observable.of(false);
    });
  }
  
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Data | Observable<Data> | Promise<Data> {
    return data;
  }

}

AngularでRouterのrunGuardsAndResolversが効かない

開発環境では効いていたrunGuardsAndResolversが、ビルドしてサーバーに上げたら効かなくなった。
AOTのせいかも……と思って下記個所を修正したらビンゴだった。
こういう書き方はだめらしい。

const ROUTES: Routes = [
  // たくさんのルーティング設定
];

ROUTES.forEach(route => {
  route.runGuardsAndResolvers = "always";  // ここがだめ 各ルーティング設定にひとつひとつ設定すべし
});

export const XXX_ROUTES = RouterModule.forChild(ROUTES);

java.lang.ClassCircularityError: java/util/logging/LogRecord

java.util.Loggerをslf4jにブリッジするために、下記設定をすることは色んなサイトに書いてある。

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
  <resetJUL>true</resetJUL>
</contextListener>

が、この設定をすると下記のエラーが発生してしまう。

java.lang.ClassCircularityError: java/util/logging/LogRecord
	at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:198)
	at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:293)
	at java.util.logging.Logger.log(Logger.java:738)
	at java.util.logging.Logger.doLog(Logger.java:765)
	at java.util.logging.Logger.logp(Logger.java:931)
	at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:180)
	at org.apache.juli.logging.DirectJDKLog.debug(DirectJDKLog.java:103)
	at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:355)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:161)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:630)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:351)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:485)

このエラーはlogback.xmlに下記設定を施すことで解決できた。

<logger name="org.apache" level="INFO">


参考:
https://stackoverflow.com/questions/2656565/classcircularityerror-when-running-tomcat-6-from-eclipse

wkhtmltopdfでChart.jsのチャートが出ない

wkhtmltopdf 0.12.3
Chart.js 2.7.0
Shark.PdfConvert 1.0.1
Windows7


色々調べた結果、new Chart()実行時にJavascriptでこけていることがわかった。
こけている原因は、Chart.jsが使用しているFunction.prototype.bindがundefinedであること。
だからFunction.prototype.bindを定義してあげれば直るはず。
だが実際にやってみると下記のエラーが発生する。

Unhandled Exception: System.IO.InvalidDataException: WkHTMLToPdf conversion of HTML data failed. Output: 
WkHTMLToPdf exited with code -1073741819.

色々試行錯誤して、wkhtmltopdfのバージョンを0.12.3.2に下げればFunction.prototype.bindを定義してもエラーにならないことがわかった。
だが理由はまったくわからない。
ちなみに0.13.0-alpha3もだめ。

.vimrcに設定を追加したら奇妙な動きをする

Windowsgvimを使っているのだが、.vimrcに下記の設定をしたところ奇妙な動きをするようになった。

"表示行通りに移動
noremap j gj
noremap k gk 

j → 表示行で2行ずつ移動
k → 動かない


わけがわからず設定をあれこれいじっているうちに、追加した分の設定の改行コードがCRLFになっていることに気づいた。
ぐぐって出たサイトからコピー&ペーストしたせいか。
そこで改行コードをLFに統一したところ、期待したとおりの動きになった。

LDAP認証が突然通らなくなる

Apache 2.4
mod_ldap
mod_authnz_ldap
mod_dav_svn
mod_authz_svn
OpenLDAP 2.4.40
docker


SVNサーバーを立て、LDAPで認証をしている。
普段は問題なく認証できているが、たまに突然認証が通らなくなることがある。
通らなくなったときは何回か認証を試すか、しばらく時間を置くか、SVNサーバーかLDAPサーバーを再起動すると認証が通るようになる。


認証が通らないときのApache側のログはこんな感じ。

[Tue Feb 14 05:22:26.513073 2017] [authz_core:debug] [pid 8] mod_authz_core.c(809): [client 172.18.0.7:36152] AH01626: authorization result of Require valid-user : denied (no authenticated user yet)
[Tue Feb 14 05:22:26.513113 2017] [authz_core:debug] [pid 8] mod_authz_core.c(809): [client 172.18.0.7:36152] AH01626: authorization result of : denied (no authenticated user yet)
[Tue Feb 14 05:22:26.513548 2017] [authz_core:debug] [pid 8] mod_authz_core.c(809): [client 172.18.0.7:36152] AH01626: authorization result of Require valid-user : denied (no authenticated user yet)
[Tue Feb 14 05:22:26.513566 2017] [authz_core:debug] [pid 8] mod_authz_core.c(809): [client 172.18.0.7:36152] AH01626: authorization result of : denied (no authenticated user yet)
[Tue Feb 14 05:22:26.513577 2017] [authnz_ldap:debug] [pid 8] mod_authnz_ldap.c(501): [client 172.18.0.7:36152] AH01691: auth_ldap authenticate: using URL ldap://ldap:389/ou=People,dc=example,dc=org?cn
[Tue Feb 14 05:22:26.514094 2017] [authnz_ldap:debug] [pid 8] mod_authnz_ldap.c(539): [client 172.18.0.7:36152] AH01694: auth_ldap authenticate: user xxxxxx authentication failed; URI /svn/XXXXXX/trunk [ldap_search_ext_s() for user failed][No such object] (not authoritative)
[Tue Feb 14 05:22:26.514113 2017] [auth_basic:error] [pid 8] [client 172.18.0.7:36152] AH01618: user xxxxxx not found: /svn/XXXXXX/trunk

OpenLDAP側はこんな感じ。

58a640c6 conn=1000 fd=17 ACCEPT from IP=172.18.0.5:40588 (IP=0.0.0.0:389)
58a640c6 conn=1000 op=0 BIND dn="cn=admin,dc=example,dc=org" method=128
58a640c6 conn=1000 op=0 BIND dn="cn=admin,dc=example,dc=org" mech=SIMPLE ssf=0
58a640c6 conn=1000 op=0 RESULT tag=97 err=0 text=
58a640c6 conn=1000 op=1 SRCH base="ou=People,dc=example,dc=org" scope=2 deref=3 filter="(&(objectClass=*)(cn=xxxxxx))"
58a640c6 conn=1000 op=1 SRCH attr=cn
58a640c6 <= bdb_equality_candidates: (cn) not indexed
58a640c6 conn=1000 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
58a640c6 conn=1000 op=2 BIND anonymous mech=implicit ssf=0
58a640c6 conn=1000 op=2 BIND dn="cn=xxxxxx,ou=People,dc=example,dc=org" method=128
58a640c6 conn=1000 op=2 BIND dn="cn=xxxxxx,ou=People,dc=example,dc=org" mech=SIMPLE ssf=0
58a640c6 conn=1000 op=2 RESULT tag=97 err=0 text=
58a640c6 conn=1000 op=3 SRCH base="ou=People,dc=example,dc=org" scope=2 deref=3 filter="(&(objectClass=*)(cn=xxxxxx))"
58a640c6 conn=1000 op=3 SRCH attr=cn
58a640c6 conn=1000 op=3 SEARCH RESULT tag=101 err=32 nentries=0 text=


1回目のアクセスがop=0〜op=2で、これは認証が成功する。
2回目のアクセスがop=3で、ここで認証が通らなくなる。
この間、コネクションが切られずに使いまわされている。
(この環境にはRedmineとかphpLDAPadminとかもいて、このLDAPサーバーを使うようにしているが、こいつらはコネクションを切る)
それになぜかop=2でバインドし直している。
mod_authnz_ldapの"The Authorization Phase"とかAuthLDAPInitialBindAsUserとかAuthLDAPCompareAsUserあたりの内容が関係ありそうだが、よくはわからない。
ともかく、dn="cn=xxxxxx,ou=People,dc=example,dc=org"はbase="ou=People,dc=example,dc=org"にアクセスする権限がなくてこうなってしまうのであろう。


こんなとっくの昔に枯れていそうな構成でバグが残っているのは不自然だから、自分の設定に何か問題があるのだろうけど、よくはわからない。


    DAV svn
    SVNParentPath /svn
    AuthType Basic
    AuthBasicProvider ldap
    AuthLDAPBindAuthoritative off
    AuthLDAPURL ldap://ldap:389/ou=People,dc=example,dc=org?cn
    AuthLDAPBindDN "cn=admin,dc=example,dc=org"
    AuthLDAPBindPassword "admin"
    AuthName "Auth for XXXXXX"
    Require valid-user


さしあたってはコネクションを切るようにすれば良いだろう。
の外側に下記を追加する。

LDAPConnectionPoolTTL 0

iOSを再起動させるとdidEnterRegionが呼ばれなくなる

iOS7.1からはビーコンのモニタリングはアプリを終了しても、iOSを再起動しても継続するはずなのだが、iOSを再起動させるとdidEnterRegionが呼ばれなくなった。
例によって色々調べてみると、iOS起動後しばらくはCoreLocationがまだおねむな状態らしい。
少なくとも2分は待ってね、と書いてあるので、待ってからリージョンに入るとdidEnterRegionが呼ばれるようになった。


ただ、ビーコンを近くに置いてON/OFFを切り替えるのでは、didEnterRegionもdidExitRegionも呼ばれない(呼ばれることもある?)ようなので、遠くからビーコンに近づいたり離れたりする正規の手順でやったほうが良いようだ。
(再起動後に限らないけど)


http://stackoverflow.com/questions/28028382/ibeacon-monitoring-ranging-after-device-restarts