[Confluence]不要トークンによるジョブエラー

なんとなく、過去対応したエラーを残しておく。
全部まとめて書こうと思ったのですが、多すぎるので、エラー毎に記載していく。
（atlassian製品の日本語記事を増やすために、草の根活動をしていく）

#Confluence
##不要トークンによるジョブエラー
検知/対処バージョン： Server 6.1.4
公式情報：[Service Provider Session Remover should remove token if the user does not exist](https://jira.atlassian.com/browse/JRASERVER-63106)

```:エラーログ
2016-07-27 09:02:38,879 Caesium-1-3 ERROR ServiceRunner     [c.a.scheduler.core.JobLauncher] Scheduled job with ID 'CompatibilityPluginScheduler.JobId.Service Provider Session Remover' failed
com.atlassian.oauth.serviceprovider.InvalidTokenException: Token 'トークン番号' is an access token, but has no user associated with it
	at com.atlassian.jira.oauth.serviceprovider.OfBizServiceProviderTokenStore.createTokenFromGV(OfBizServiceProviderTokenStore.java:322)
	at com.atlassian.jira.oauth.serviceprovider.OfBizServiceProviderTokenStore.removeExpiredTokens(OfBizServiceProviderTokenStore.java:250)
	at com.atlassian.jira.oauth.serviceprovider.OfBizServiceProviderTokenStore.removeExpiredTokensAndNotify(OfBizServiceProviderTokenStore.java:238)
	at com.atlassian.jira.oauth.serviceprovider.CachingServiceProviderTokenStore.removeExpiredTokensAndNotify(CachingServiceProviderTokenStore.java:106)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	... 2 filtered
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
	at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
	at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
	at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy1194.removeExpiredTokensAndNotify(Unknown Source)
	at com.atlassian.oauth.serviceprovider.internal.DelegatingTokenStoreImpl.removeExpiredTokensAndNotify(DelegatingTokenStoreImpl.java:48)
	at com.atlassian.oauth.serviceprovider.internal.ExpiredSessionRemover.execute(ExpiredSessionRemover.java:25)
	at com.atlassian.scheduler.compat.clustered.ClusteredJobRunner.runJob(ClusteredJobRunner.java:54)
	at com.atlassian.scheduler.core.JobLauncher.runJob(JobLauncher.java:153)
	at com.atlassian.scheduler.core.JobLauncher.launchAndBuildResponse(JobLauncher.java:118)
	at com.atlassian.scheduler.core.JobLauncher.launch(JobLauncher.java:97)
	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.launchJob(CaesiumSchedulerService.java:401)
	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeClusteredJob(CaesiumSchedulerService.java:396)
	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeQueuedJob(CaesiumSchedulerService.java:349)
	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:255)
	at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:252)
	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeJob(SchedulerQueueWorker.java:65)
	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeNextJob(SchedulerQueueWorker.java:59)
	at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.run(SchedulerQueueWorker.java:34)
	at java.lang.Thread.run(Thread.java:745)
```

検知起因：別件のユーザ問い合わせで、エラーログを確認していたら検知。
問題：不要トークンの残存により、ゴミを削除するジョブが異常終了。ゴミが削除されず、溜まり続けることになる。
対応：放置は危険そうなので、公式情報に則り、以下対応を実施。

**対象特定(方法1)**
以下のSQL実行すると犯人が出てくる。

```sql
select * from oauthsptoken where token_type = 'ACCESS' and username not in (select lower_user_name from cwd_user);
```

**対象特定(方法2)**
以下にアクセス！
https://ホスト名/secure/admin/SchedulerAdmin.jspa

「CompatibilityPluginScheduler.JobRunnerKey.Service Provider Session Remover」を開くと「error message」あたりにそれっぽいTokenがいるので、そいつが犯人。

**不要トークン削除**
以下コマンドを実行。(二行目は結果確認用のSQLです。)

```sql
delete from oauthsptoken where token='特定したTokenを書く';
select * from oauthsptoken where token_type = 'ACCESS' and username not in (select lower_user_name from cwd_user);
```

**結果確認**
このジョブは一定時間ごとに動くので、少し待つ必要がある。
以下のキャプチャは正常稼働したことを確認した時のもの。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/5e352f9b-7114-9d1e-23e2-2fad9d456468.png)

以上