Skip to content

Commit 71f0878

Browse files
author
Evan Wong
committed
Merge pull request #1 from evanwong/develop
Merging develop to master
2 parents 1f3e6d6 + 0ef43e1 commit 71f0878

21 files changed

Lines changed: 802 additions & 2 deletions

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: java
2+
3+
jdk:
4+
- oraclejdk8
5+
6+
branches:
7+
only:
8+
- master
9+
- develop

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
[![Build Status](https://snap-ci.com/evanwong/hipchat-java/branch/develop/build_image)](https://snap-ci.com/evanwong/hipchat-java/branch/develop)
2+
13
hipchat-java
24
============

build.gradle

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
apply plugin: 'java'
1+
apply plugin: 'groovy'
22

33
repositories {
4-
mavenCentral()
4+
mavenCentral()
5+
maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
6+
}
7+
8+
sourceCompatibility = 1.8
9+
10+
dependencies {
11+
compile 'org.apache.httpcomponents:httpclient:4.3.5'
12+
compile 'org.slf4j:slf4j-api:1.7.7'
13+
runtime 'org.slf4j:slf4j-simple:1.7.7'
14+
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.2'
15+
compile "org.codehaus.groovy:groovy-all:2.3.7"
16+
testCompile "org.spockframework:spock-core:1.0-groovy-2.3-SNAPSHOT"
517
}
618

719
task wrapper(type: Wrapper) {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package io.evanwong.hipchat.v2;
2+
3+
import io.evanwong.hipchat.v2.rooms.GetAllRoomsRequestBuilder;
4+
import io.evanwong.hipchat.v2.rooms.SendRoomNotificationRequestBuilder;
5+
import org.apache.http.impl.client.CloseableHttpClient;
6+
import org.apache.http.impl.client.HttpClients;
7+
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.io.IOException;
12+
import java.util.concurrent.ExecutorService;
13+
import java.util.concurrent.Executors;
14+
15+
public class HipChatClient {
16+
17+
private static final Logger log = LoggerFactory.getLogger(HipChatClient.class);
18+
19+
private CloseableHttpClient httpClient;
20+
private ExecutorService executorService;
21+
private String defaultAccessToken;
22+
//TODO move this out
23+
private int maxConnections = 20;
24+
//TODO move this out
25+
private int maxConnectionsPerRoute = 4;
26+
27+
28+
public HipChatClient() {
29+
init();
30+
}
31+
32+
public HipChatClient(String defaultAccessToken) {
33+
this.defaultAccessToken = defaultAccessToken;
34+
init();
35+
}
36+
37+
private void init() {
38+
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
39+
cm.setMaxTotal(maxConnections);
40+
log.debug("Max pool size: {}", maxConnections);
41+
cm.setDefaultMaxPerRoute(maxConnectionsPerRoute);
42+
log.debug("Max per route: {}", maxConnectionsPerRoute);
43+
44+
httpClient = HttpClients.custom().setConnectionManager(cm).build();
45+
//setting the thread pool size equal to the max connections size
46+
executorService = Executors.newFixedThreadPool(maxConnections);
47+
}
48+
49+
public void setDefaultAccessToken(String defaultAccessToken) {
50+
this.defaultAccessToken = defaultAccessToken;
51+
}
52+
53+
public GetAllRoomsRequestBuilder prepareGetAllRoomsRequestBuilder(String accessToken) {
54+
return new GetAllRoomsRequestBuilder(accessToken, httpClient, executorService);
55+
}
56+
57+
public GetAllRoomsRequestBuilder prepareGetAllRoomsRequestBuilder() {
58+
return prepareGetAllRoomsRequestBuilder(defaultAccessToken);
59+
}
60+
61+
public SendRoomNotificationRequestBuilder prepareSendRoomNotificationRequestBuilder(String idOrName, String message, String accessToken) {
62+
return new SendRoomNotificationRequestBuilder(idOrName, message, accessToken, httpClient, executorService);
63+
}
64+
65+
public SendRoomNotificationRequestBuilder prepareSendRoomNotificationRequestBuilder(String idOrName, String message) {
66+
return prepareSendRoomNotificationRequestBuilder(idOrName, message, defaultAccessToken);
67+
}
68+
69+
public void close() {
70+
log.info("Shutting down...");
71+
try {
72+
httpClient.close();
73+
} catch (IOException e) {
74+
log.error("Failed to close the HttpClient.", e);
75+
}
76+
executorService.shutdown();
77+
}
78+
79+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
import org.apache.http.client.HttpClient;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.concurrent.ExecutorService;
8+
9+
public abstract class ExpandableRequestBuilder<T> extends RequestBuilder {
10+
11+
protected final List<String> expansions;
12+
13+
public ExpandableRequestBuilder(String accessToken, HttpClient httpClient, ExecutorService executorService) {
14+
super(accessToken, httpClient, executorService);
15+
expansions = new ArrayList<>();
16+
}
17+
18+
public T addExpansion(String title) {
19+
expansions.add(title);
20+
return (T)this;
21+
}
22+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
import org.apache.http.HttpResponse;
4+
import org.apache.http.client.methods.HttpGet;
5+
import org.apache.http.client.protocol.HttpClientContext;
6+
import org.apache.http.message.BasicHeader;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.stream.Collectors;
15+
16+
public abstract class GetRequest<T> extends Request {
17+
18+
private static final Logger log = LoggerFactory.getLogger(GetRequest.class);
19+
protected List<String> expansions = new ArrayList<>();
20+
21+
@Override
22+
protected HttpResponse request() throws IOException {
23+
Map<String, Object> params = toQueryMap();
24+
if (!expansions.isEmpty()) {
25+
params.put("expand", expansions.stream().collect(Collectors.joining(",")));
26+
}
27+
log.info("GET - path: {}, params: {}", getPath(), params);
28+
String query = params != null && params.size() > 0 ? "?" : "";
29+
for (String key : params.keySet()) {
30+
query += key + "=" + params.get(key) + "&";
31+
}
32+
33+
HttpGet httpGet = new HttpGet(BASE_URL + getPath() + query);
34+
httpGet.addHeader(new BasicHeader("Authorization", "Bearer " + accessToken));
35+
return httpClient.execute(httpGet, HttpClientContext.create());
36+
}
37+
38+
public boolean addExpansion(String title) {
39+
return expansions.add(title);
40+
}
41+
42+
public List<String> getExpansions() {
43+
return new ArrayList<>(expansions);
44+
}
45+
}
46+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
public class NoContent {
4+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
public class PagingLinks {
4+
private String self;
5+
private String prev;
6+
private String next;
7+
8+
public PagingLinks() {
9+
}
10+
11+
public String getSelf() {
12+
return self;
13+
}
14+
15+
public void setSelf(String self) {
16+
this.self = self;
17+
}
18+
19+
public String getPrev() {
20+
return prev;
21+
}
22+
23+
public void setPrev(String prev) {
24+
this.prev = prev;
25+
}
26+
27+
public String getNext() {
28+
return next;
29+
}
30+
31+
public void setNext(String next) {
32+
this.next = next;
33+
}
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
import org.apache.http.HttpResponse;
4+
import org.apache.http.client.methods.HttpPost;
5+
import org.apache.http.client.protocol.HttpClientContext;
6+
import org.apache.http.entity.StringEntity;
7+
import org.apache.http.message.BasicHeader;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.io.IOException;
12+
import java.util.Map;
13+
14+
public abstract class PostRequest<T> extends Request {
15+
16+
private static final Logger log = LoggerFactory.getLogger(PostRequest.class);
17+
18+
@Override
19+
protected HttpResponse request() throws IOException {
20+
Map<String, Object> params = toQueryMap();
21+
log.info("POST - path: {}, params: {}", getPath(), params);
22+
23+
HttpPost httpPost = new HttpPost(BASE_URL + getPath());
24+
httpPost.addHeader(new BasicHeader("Authorization", "Bearer " + accessToken));
25+
httpPost.addHeader(new BasicHeader("Content-Type", "application/json"));
26+
httpPost.setEntity(new StringEntity(objectWriter.writeValueAsString(params)));
27+
return httpClient.execute(httpPost, HttpClientContext.create());
28+
}
29+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.evanwong.hipchat.v2.commons;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.fasterxml.jackson.databind.ObjectReader;
5+
import com.fasterxml.jackson.databind.ObjectWriter;
6+
import org.apache.http.HttpEntity;
7+
import org.apache.http.HttpResponse;
8+
import org.apache.http.client.HttpClient;
9+
import org.apache.http.util.EntityUtils;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
13+
import java.io.IOException;
14+
import java.lang.reflect.ParameterizedType;
15+
import java.util.Map;
16+
import java.util.concurrent.ExecutorService;
17+
import java.util.concurrent.Future;
18+
19+
public abstract class Request<T> {
20+
21+
private static final Logger log = LoggerFactory.getLogger(PostRequest.class);
22+
23+
protected static final String BASE_URL = "https://api.hipchat.com/v2";
24+
protected ExecutorService executorService;
25+
protected String accessToken;
26+
protected HttpClient httpClient;
27+
private final ObjectMapper objectMapper = new ObjectMapper();
28+
protected final ObjectWriter objectWriter = objectMapper.writer();
29+
protected final ObjectReader objectReader = objectMapper.reader(getParameterClass());
30+
protected abstract Map<String, Object> toQueryMap();
31+
protected abstract HttpResponse request() throws IOException;
32+
protected abstract String getPath();
33+
34+
public Future<T> execute() {
35+
36+
Future<T> future = executorService.submit(() -> {
37+
HttpResponse response = request();
38+
int status = response.getStatusLine().getStatusCode();
39+
HttpEntity entity = response.getEntity();
40+
String content = entity != null ? EntityUtils.toString(entity) : null;
41+
if (status >= 200 && status < 300) {
42+
if (content == null) {
43+
//should be NoContent
44+
return getParameterClass().newInstance();
45+
}
46+
return objectReader.readValue(content);
47+
} else {
48+
log.error("Invalid response status: {}, content: {}", status, content);
49+
return null;
50+
}
51+
});
52+
return future;
53+
}
54+
55+
protected Class<T> getParameterClass() {
56+
return (Class<T>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
57+
}
58+
}

0 commit comments

Comments
 (0)