docker-hiveでHive JDBCを試す
Dockerを使ってHive JDBCを試したときのメモ。
準備
ソースコード
build.gradle
plugins { id 'java' id 'application' } group 'com.example' version '1.0-SNAPSHOT' sourceCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } dependencies { implementation 'org.apache.hive:hive-jdbc:2.3.6' } mainClassName = 'com.example.Main'
Main.java
package com.example; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class Main { public static void main(String[] args) throws Exception { Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000/default"); Statement stmt = con.createStatement(); try (con; stmt) { stmt.execute("CREATE TABLE IF NOT EXISTS table1 (id int, name string)"); stmt.executeUpdate("INSERT INTO table1 VALUES(1, 'user1')"); stmt.executeUpdate("INSERT INTO table1 VALUES(2, 'user2')"); stmt.executeUpdate("INSERT INTO table1 VALUES(3, 'user3')"); ResultSet res = stmt.executeQuery("SELECT * FROM table1"); while (res.next()) { System.out.println(res.getInt(1) + ", " + res.getString(2)); } } } }
docker-hive
今回はHive 2.3を試すため、2.3.2-postgresql-metastoreのブランチをダウンロードする。
% git clone https://github.com/big-data-europe/docker-hive -b 2.3.2-postgresql-metastore
https://github.com/big-data-europe/docker-hive
確認
HiveServer2を起動後、デモアプリを起動する。
% cd docker-hive
% docker-compose up -d
Docker ComposeでMongoDBのReplica Setを使う
Docker ComposeでMongoDBのReplica Setを試したときのメモ。
準備
docker-compose.yml
version: '3' services: mongo01: image: mongo:4.4 command: mongod --replSet rs1 --bind_ip_all ports: - "27017:27017" mongo02: image: mongo:4.4 command: mongod --replSet rs1 --bind_ip_all ports: - "27018:27017" mongo03: image: mongo:4.4 command: mongod --replSet rs1 --bind_ip_all ports: - "27019:27017"
手順
ホスト(Mac)の/etc/hosts
に以下を登録する。
127.0.0.1 mongo01 mongo02 mongo03
Docker ComposeでMongoDBを起動する。
% docker-compose up -d
Replica Setを設定する。
% mongo --port 27017 > rs.initiate({ _id: "rs1", members: [ {_id: 0, host: "mongo01:27017"}, {_id: 1, host: "mongo02:27017"}, {_id: 2, host: "mongo03:27017"} ] })
動作確認
% mongo --host rs1/127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019 MongoDB shell version v4.4.3 connecting to: mongodb://127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/?compressors=disabled&gssapiServiceName=mongodb&replicaSet=rs1
参考
Springfox SwaggerでCSRF tokenを送信する
Spring SecurityのCSRFを有効にしている状態で、SpringfoxのSwagger上でPOST等のメソッドを実行したいときのメモ。
そのままでは試せないが、以下のようなCSRF tokenがを返すエンドポイントを作れば、POST等のメソッドも実行できる。
ソースコード
plugins { id 'org.springframework.boot' version '2.4.5' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'io.springfox:springfox-boot-starter:3.0.0' ... }
@Profile("dev") @RestController public class CsrfController { @GetMapping("/csrf") public CsrfToken csrf(CsrfToken token) { return token; } }
springfox 3.0.0からはこの設定が必要。
@Bean public SecurityConfiguration securityConfiguration() { return SecurityConfigurationBuilder.builder() .enableCsrfSupport(true) .build(); }
参考
Spring Boot ActuatorのHTTP Client MetricsのURI tagが上限に達した
Spring Boot ActuatorとMicrometerを使っているときに、こんなwarnログが出たときのメモ。
WARN o.s.b.a.a.m.OnlyOnceLoggingDenyMeterFilter - Reached the maximum number of URI tags for 'http.client.requests'. Are you using 'uriVariables' on RestTemplate calls?
これは、RestTemplateのmetrics(http.client.requests
)のURIタグがmanagement.web.client.max-uri-tags
(defaultは100)に達したため。
warnログで指摘されている通り、RestTemplateのuriVariablesを使っていなかったので、クエリパラメータごとにURIタグが作られていた。
修正前
Spring Boot: 2.1.0
String uri = UriComponentsBuilder.fromHttpUrl("http://md5.jsontest.com") .queryParam("text", text) .toUriString(); restTemplate.getForObject(uri, Map.class);
Spring Boot ActuatorのPrometheusのエンドポイントを確認すると、URLクエリパラメータごとにURIタグが作られていた。
http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=aaa",} 1.0 http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=bbb",} 1.0 http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text=ccc",} 1.0
修正後
RestTemplateを呼び出すときに、uriVariablesを使うように変更。
String uri = UriComponentsBuilder.fromHttpUrl("http://md5.jsontest.com") .queryParam("text", "{text}") .build(false) .toUriString(); restTemplate.getForObject(uri, Map.class, text);
URIタグはtemplate形式になったので、一つになった。
http_client_requests_seconds_count{clientName="md5.jsontest.com",method="GET",status="200",uri="/http://md5.jsontest.com?text={text}",} 3.0
参考
Spring BootでCaffeineのcacheごとにexpireAfterAccessを指定する
Spring BootのcacheにCaffeineを使っている場合で、cacheごとにmaximumSizeやexpireAfterAccessを指定したいときのメモ。
プロパティのspring.cache.caffeine.spec
にはcacheごとにexpireAfterAccessなどを設定できないので、SimpleCacheManagerを使うしかなさそう。
@Bean public SimpleCacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); CaffeineCache cache1 = new CaffeineCache("cache1", Caffeine.newBuilder() .maximumSize(100) .expireAfterAccess(10, TimeUnit.MINUTES) .build()); CaffeineCache cache2 = new CaffeineCache("cache2", Caffeine.newBuilder() .maximumSize(200) .expireAfterAccess(20, TimeUnit.MINUTES) .build()); cacheManager.setCaches(List.of(cache1, cache2)); return cacheManager; }
参考
Spring DataとSpring Sessionで別々のRedisConnectionFactoryを使う
Spring Data RedisとSpring Session Data Redisで、RedisConnectionFactoryを分けたいときのメモ。
Spring Sessionで使うRedisConnectionFactoryに@SpringSessionRedisConnectionFactory
を付けると、Spring Sessionはこちらを使うようになる。
Spring Boot: 2.0.5
@Bean @Primary public LettuceConnectionFactory redisConnectionFactory() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); connectionFactory.setDatabase(0); return connectionFactory; } @Bean @SpringSessionRedisConnectionFactory public LettuceConnectionFactory springSessionRedisConnectionFactory() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(); connectionFactory.setDatabase(1); return connectionFactory; }