Spring + JUnitでParameterized実行する
上記のQiita記事通りにやっても動かなかったので…
以下のような感じで、@ClassRuleと@Ruleを宣言してやれば無事動いた
package org.tmarcus import org.junit.ClassRule; import org.junit.Rule; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.junit4.rules.SpringClassRule; import org.springframework.test.context.junit4.rules.SpringMethodRule; @ActiveProfiles("test") @SPringApplicationConfiguration(ParameterizedTestBase.class) @EnableAutoConfiguration @ComponentScan(basePackages = { "org.tmarcus" }) @RunWith(Parameterized.class) public ParameterizedTestBase extends TestBase { @ClassRule public static final SpringClassRule SCR = new SpringClassRule(); @Rule public final SpringMethodRule springMethodRule = new SpringMethodRule(); }
package org.tmarcus import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runners.Parameterized; import org.tmarcus.service.MathmaticsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestContextManager; import java.util.Collection; import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @Slf4j public class SampleTest extends ParameterizedTestBase { private MathmaticsService service; @Autowired public void inject( MathmaticsService service) { this.service = service; } @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { { 0, 1 }, { 1, 1 }, { 2, 2 }, { 3, 6 }, { 4, 24 }, { 5, 120 } }); } @Parameterized.Parameter(0) // <- index=0のパラメータを代入する public int parameter; @Parameterized.Parameter(1) // <- index=1のパラメータを代入する public int factorialExpected; @Test public void test() { log.info("{} -> {}", parameter, expected); assertThat(service.factorial(parameter), is(factorialExpected)); } }
RabbitMQでHAを利用したときにClientで例外を吐いてしまう問題
RabbitMQでClusterを組み、ミラーリングを設定して、いざクライアントからデータを流そうとしたら、下記のようなエラーが出てキューを開けなかったので、その対応方法の覚書。
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-ha-policy'for queue 'queue_name01ha' in vhost '/': received none but current is the value 'all' of type 'longstr', class-id=50, method-id=10) at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:361) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:226) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118) ... 67 common frames omitted Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-ha-policy'for queue 'queue_name01ha' in vhost '/': received none but current is the value 'all' of type 'longstr', class-id=50, method-id=10) at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:484) at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:321) at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:144) at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:91) at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:560) ... 1 common frames omitted
Channelでキューを宣言するときに、このメソッドの第六引数で、以下の通りHAを使うという設定を入れてやればOK。
Connection connection = connectionFactory.getConnection(); Channel channel = connection.createChannel(); Map<String, Object> arguments = Maps.newHashMap(); arguments.put("x-ha-policy", "all"); channel.queueDeclare("queue_name01ha", true, true, false, false, arguments);
SpringMVCのMockMvcでurlVariablesを使う方法
SpringMVCのテストを書くときによく使うMockMvcで指定するgetやらpostやらでurlTemplate内でurlVarsをどう指定すればドキュメントが見当たらなかったので、ソースに潜った結果、どうすればいいかの覚書
第2引数をindex=0として{index}という形で書いてやれば置換される模様
例)
server.perform(get("/user/{0}/{1}/setting/categories", idType.getCode(), id) .header(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_APPLICATION_JSON)) .andExpect(status().isOk()) server.perform(post("/user/{0}/{1}/setting/category/{2}", idType.getCode(), id, CATEGORY1) .header(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_APPLICATION_JSON)) .andExpect(status().isOk())
Javaライブラリ覚書
Nexus Repository Managerにファイルを直接アップロードする
こんな感じで、個別にアップロードできるらしい。
$ curl -v \ -u ${NEXUS_USER}:${NEXUS_PASS} \ --upload-file hoge-api-server-sources.jar \ http://nexus.example.com/content/repositories/releases/com/example/hoge-api-server/1.10.0/hoge-api-server-1.10.0-sources.jar
maven-release-pluginでReceived fatal alert: bad_record_macが出た話
リリース作業中に問題発生したので、自戒録がてら書き連ねておく。
結果としては、Java7だったので、MAVEN_OPTS="-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2"
を環境変数にぶち込んで走らせれば解決しました。
(Java8は試してませんが、おそらく-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2
を指定すれば、行けるはずです)
事の起こりは、リリース作業中にpomのバージョンをイテレーションして、Sonatype Nexus Repository Manager(以下、Nexus)へ成果物のアップロードを行うJenkinsジョブを実行したところ…
_人人人人人人人人人人人人人人_
> 燦々と輝く「ジョブ失敗」 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
とりあえず、ログを眺めてみると…
$ mvn -Dresume=false release:prepare release:perform -B : : [INFO] --- maven-release-plugin:2.0:prepare (default-cli) @ hoge-api-server --- : : [INFO] --- maven-release-plugin:2.0:perform (default-cli) @ hoge-api-server --- : : [INFO] [INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ hoge-api-server --- [INFO] Uploading: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.jar [INFO] Uploading: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.pom [INFO] Uploaded: https://nexus.example.com/content/repositories/releases/com/example/api/hoge-api-server/1.59.0/hoge-api-server-1.59.0.pom (9 KB at 28.9 KB/sec) [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [INFO] BUILD FAILURE [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [INFO] Total time: 53.752s [INFO] [INFO] Finished at: Tue Feb 09 13:31:27 JST 2016 [INFO] [INFO] Final Memory: 57M/1313M [INFO] [INFO] ------------------------------------------------------------------------ [INFO] [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project hoge-api-server: Failed to deploy artifacts: Could not transfer artifact com.example:hoge-api-server:jar:1.10.0 from/to hoge-releases (https://nexus.hoge.org/content/repositories/releases/): Received fatal alert: bad_record_mac -> [Help 1] [INFO] [ERROR] [INFO] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [INFO] [ERROR] Re-run Maven using the -X switch to enable full debug logging. [INFO] [ERROR] [INFO] [ERROR] For more information about the errors and possible solutions, please read the following articles: [INFO] [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
何やら、Nexusへの登録がbad_record_mac
で失敗してるっぽい。
とりあえず、ググってみる。
検索結果から、SSL周りのエラーっぽい雰囲気が漂ってくる。
とりあえずjenkinsサーバに入って、Nexusと話をしてみる…
$ curl -vs https://nexus.example.com * Rebuilt URL to: https://nexus.example.com/ * Trying 12.34.56.78... * Connected to nexus.example.com (12.34.56.78) port 443 (#0) * TLS 1.2 connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 * Server certificate: *.example.com : : > GET / HTTP/1.1 > Host: nexus.example.com > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 8009 < Connection: keep-alive < X-Frame-Options: SAMEORIGIN < X-Content-Type-Options: nosniff < Last-Modified: Tue, 09 Feb 2016 10:47:55 GMT < Pragma: no-cache < Cache-Control: post-check=0, pre-check=0 < Expires: 0 < <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> : :
ちゃんとお話できてるっぽい。
SSLといえば、最近Poodleの関係で、SSLv3がサポート切られてたりしてたはず…ということで、SSLv3でお話してみると…
$ curl -vs --sslv3 https://nexus.example.com * Rebuilt URL to: https://nexus.example.com/ * Trying 12.34.56.78... * Connected to nexus.example.com (12.34.56.78) port 443 (#0) * SSL peer handshake failed, the server most likely requires a client certificate to connect * Closing connection 0 curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
ビンゴ!
ということで、Javaのオプションで、SSLv3をオフって解決
mvn -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Dresume=false release:prepare release:perform -B
詳しくはこちら