Skip to content

Web socket support. #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions examples/src/main/java/io/kubernetes/client/examples/Example.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.examples;

import io.kubernetes.client.ApiClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.examples;

import io.kubernetes.client.ApiClient;
import io.kubernetes.client.ApiException;
import io.kubernetes.client.util.Config;
import io.kubernetes.client.util.WebSockets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

public class WebSocketsExample {
public static void main(String... args) throws ApiException, IOException {
final ApiClient client = Config.defaultClient();
WebSockets.stream(args[0], "GET", client, new WebSockets.SocketListener() {
public void open() {}
public void close() {
// Trigger shutdown of the dispatcher's executor so this process can exit cleanly.
client.getHttpClient().getDispatcher().getExecutorService().shutdown();
}
public void bytesMessage(InputStream is) {}
public void textMessage(Reader in) {
try {
BufferedReader reader = new BufferedReader(in);
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(line);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}
5 changes: 3 additions & 2 deletions kubernetes/.swagger-codegen-ignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.gitignore
git_push.sh
# Remove this once swagger-codegen 2.2.3 is released and we update.
# We want https://github.com/swagger-api/swagger-codegen/pull/5629
# in the release.
# Verify the following PRs are in the release:
# * https://github.com/swagger-api/swagger-codegen/pull/5629
# * https://github.com/swagger-api/swagger-codegen/pull/5648
src/main/java/io/kubernetes/client/ApiClient.java

9 changes: 7 additions & 2 deletions kubernetes/src/main/java/io/kubernetes/client/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,12 @@ public <T> T handleResponse(Response response, Type returnType) throws ApiExcept
* @throws ApiException If fail to serialize the request body object
*/
public Call buildCall(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
Request request = buildRequest(path, method, queryParams, body, headerParams, formParams, authNames, progressRequestListener);

return httpClient.newCall(request);
}

public Request buildRequest(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);

final String url = buildUrl(path, queryParams);
Expand Down Expand Up @@ -1108,8 +1114,7 @@ public Call buildCall(String path, String method, List<Pair> queryParams, Object
} else {
request = reqBuilder.method(method, reqBody).build();
}

return httpClient.newCall(request);
return request;
}

/**
Expand Down
48 changes: 31 additions & 17 deletions util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,23 @@
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp-ws</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.stefanbirkner/system-rules -->
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
Expand All @@ -49,22 +58,27 @@
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<systemProperties>
<property>
<name>loggerPath</name>
<value>conf/log4j.properties</value>
</property>
</systemProperties>
<argLine>-Xms512m -Xmx1500m</argLine>
<parallel>methods</parallel>
<forkMode>pertest</forkMode>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<systemProperties>
<property>
<name>loggerPath</name>
<value>conf/log4j.properties</value>
</property>
</systemProperties>
<argLine>-Xms512m -Xmx1500m</argLine>
<parallel>methods</parallel>
<forkMode>pertest</forkMode>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.7</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
</project>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line at the end of the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

14 changes: 13 additions & 1 deletion util/src/main/java/io/kubernetes/client/util/Config.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.util;

import io.kubernetes.client.ApiClient;
Expand Down Expand Up @@ -163,4 +175,4 @@ public static ApiClient defaultClient() throws IOException {
client.setBasePath(DEFAULT_FALLBACK_HOST);
return client;
}
}
}
12 changes: 12 additions & 0 deletions util/src/main/java/io/kubernetes/client/util/KubeConfig.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.util;

import java.io.File;
Expand Down
128 changes: 128 additions & 0 deletions util/src/main/java/io/kubernetes/client/util/WebSockets.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.util;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No license header?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please add license header to all files. we need a check for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


import io.kubernetes.client.ApiClient;
import io.kubernetes.client.ApiException;
import io.kubernetes.client.Pair;

import com.google.common.net.HttpHeaders;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import com.squareup.okhttp.ws.WebSocket;
import com.squareup.okhttp.ws.WebSocketCall;
import com.squareup.okhttp.ws.WebSocketListener;
import okio.Buffer;

import static com.squareup.okhttp.ws.WebSocket.BINARY;
import static com.squareup.okhttp.ws.WebSocket.TEXT;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;

public class WebSockets {
public static final String V4_STREAM_PROTOCOL = "v4.channel.k8s.io";
public static final String V3_STREAM_PROTOCOL = "v3.channel.k8s.io";
public static final String V2_STREAM_PROTOCOL = "v2.channel.k8s.io";
public static final String V1_STREAM_PROTOCOL = "channel.k8s.io";
public static final String STREAM_PROTOCOL_HEADER = "X-Stream-Protocol-Version";
public static final String SPDY_3_1 = "SPDY/3.1";

/**
* A simple interface for a listener on a web socket
*/
public interface SocketListener {
/**
* Called when the socket is opened
*/
public void open();

/**
* Callled when a binary media type message is received
* @param in The input stream containing the binary data
*/
public void bytesMessage(InputStream in);

/**
* Called when a text media type message is received
* @param in The character stream containing the message
*/
public void textMessage(Reader in);

/**
* Called when the stream is closed.
*/
public void close();
}

/**
* Create a new WebSocket stream
* @param path The HTTP Path to request from the API
* @param method The HTTP method to use for the call
* @param client The ApiClient for communicating with the API
* @param listener The socket listener to handle socket events
*/
public static void stream(String path, String method, ApiClient client, SocketListener listener) throws ApiException, IOException {
HashMap<String, String> headers = new HashMap<String, String>();
String allProtocols = String.format("%s,%s,%s,%s", V4_STREAM_PROTOCOL, V3_STREAM_PROTOCOL, V2_STREAM_PROTOCOL, V1_STREAM_PROTOCOL);
headers.put(STREAM_PROTOCOL_HEADER, allProtocols);
headers.put(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE);
headers.put(HttpHeaders.UPGRADE, SPDY_3_1);

Request request = client.buildRequest(path, method, new ArrayList<Pair>(), null, headers, new HashMap<String, Object>(), new String[0], null);
WebSocketCall.create(client.getHttpClient(), request).enqueue(new Listener(listener));
}

private static class Listener implements WebSocketListener {
private SocketListener listener;

public Listener(SocketListener listener) {
this.listener = listener;
}

@Override
public void onOpen(WebSocket webSocket, Response response) {
listener.open();
}

@Override
public void onMessage(ResponseBody body) throws IOException {
if (body.contentType() == TEXT) {
listener.bytesMessage(body.byteStream());
} else if (body.contentType() == BINARY) {
listener.textMessage(body.charStream());
}
body.close();
}

@Override
public void onPong(Buffer payload) {
}

@Override
public void onClose(int code, String reason) {
listener.close();
}

@Override
public void onFailure(IOException e, Response res) {
e.printStackTrace();
listener.close();
}
}
}
12 changes: 12 additions & 0 deletions util/src/test/java/io/kuberentes/client/util/ConfigTest.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.kubernetes.client.util;

import io.kubernetes.client.ApiClient;
Expand Down