mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
ZEPPELIN-2443
This commit is contained in:
parent
6eecdecb5d
commit
4baa22e2b4
2 changed files with 136 additions and 24 deletions
|
|
@ -39,7 +39,8 @@ def r = HTTP.get(
|
|||
headers: [
|
||||
'Accept':'application/json',
|
||||
//'Authorization:' : g.getProperty('search_auth'),
|
||||
]
|
||||
],
|
||||
ssl : g.getProperty('search_ssl') // assume groovy interpreter property search_ssl = HTTP.getNaiveSSLContext()
|
||||
)
|
||||
//check response code
|
||||
if( r.response.code==200 ) {
|
||||
|
|
@ -76,41 +77,62 @@ g.table(
|
|||
|
||||
* `g.angular(String name)`
|
||||
|
||||
Returns angular object by name. Look up notebook scope first and then global scope.
|
||||
Returns angular object by name. Look up notebook scope first and then global scope.
|
||||
|
||||
|
||||
* `g.angularBind(String name, Object value)`
|
||||
|
||||
Assign a new `value` into angular object `name`
|
||||
|
||||
Assign a new `value` into angular object `name`
|
||||
|
||||
|
||||
* `java.util.Properties g.getProperties()`
|
||||
|
||||
returns all properties defined for this interpreter
|
||||
returns all properties defined for this interpreter
|
||||
|
||||
|
||||
* `String g.getProperty('PROPERTY_NAME')`
|
||||
```groovy
|
||||
g.PROPERTY_NAME
|
||||
g.'PROPERTY_NAME'
|
||||
g['PROPERTY_NAME']
|
||||
g.getProperties().getProperty('PROPERTY_NAME')
|
||||
```
|
||||
```groovy
|
||||
g.PROPERTY_NAME
|
||||
g.'PROPERTY_NAME'
|
||||
g['PROPERTY_NAME']
|
||||
g.getProperties().getProperty('PROPERTY_NAME')
|
||||
```
|
||||
|
||||
All above the accessor to named property defined in groovy interpreter.
|
||||
In this case with name `PROPERTY_NAME`
|
||||
All above the accessor to named property defined in groovy interpreter.
|
||||
In this case with name `PROPERTY_NAME`
|
||||
|
||||
|
||||
* `groovy.xml.MarkupBuilder g.html()`
|
||||
|
||||
Starts or continues rendering of `%angular` to output and returns [groovy.xml.MarkupBuilder](http://groovy-lang.org/processing-xml.html#_markupbuilder)
|
||||
MarkupBuilder is usefull to generate html (xml)
|
||||
Starts or continues rendering of `%angular` to output and returns [groovy.xml.MarkupBuilder](http://groovy-lang.org/processing-xml.html#_markupbuilder)
|
||||
MarkupBuilder is usefull to generate html (xml)
|
||||
|
||||
* `void g.table(obj)`
|
||||
|
||||
starts or continues rendering table rows.
|
||||
starts or continues rendering table rows.
|
||||
|
||||
obj: List(rows) of List(columns) where first line is a header
|
||||
obj: List(rows) of List(columns) where first line is a header
|
||||
|
||||
|
||||
* `g.input(name, value )`
|
||||
|
||||
Creates `text` input with value specified. The parameter `value` is optional.
|
||||
|
||||
* `g.select(name, default, Map<Object, String> options)`
|
||||
|
||||
Creates `select` input with defined options. The parameter `default` is optional.
|
||||
|
||||
```g.select('sex', 'm', ['m':'man', 'w':'woman'])```
|
||||
|
||||
* `g.checkbox(name, Collection checked, Map<Object, String> options)`
|
||||
|
||||
Creates `checkbox` input.
|
||||
|
||||
* `g.get(name, default)`
|
||||
|
||||
Returns interpreter-based variable. Visibility depends on interpreter scope. The parameter `default` is optional.
|
||||
|
||||
* `g.put(name, value)`
|
||||
|
||||
Stores new value into interpreter-based variable. Visibility depends on interpreter scope.
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,16 @@
|
|||
|
||||
import groovy.json.JsonOutput
|
||||
|
||||
import java.security.KeyStore;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.security.SecureRandom;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
/**
|
||||
* simple http rest client for groovy
|
||||
* by dlukyanov@ukr.net
|
||||
|
|
@ -44,6 +54,11 @@ public class HTTP{
|
|||
return send(ctx);
|
||||
}
|
||||
|
||||
public static Map<String,Object> head(Map<String,Object> ctx)throws IOException{
|
||||
ctx.put('method','HEAD');
|
||||
return send(ctx);
|
||||
}
|
||||
|
||||
public static Map<String,Object> post(Map<String,Object> ctx)throws IOException{
|
||||
ctx.put('method','POST');
|
||||
return send(ctx);
|
||||
|
|
@ -59,6 +74,16 @@ public class HTTP{
|
|||
return send(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param url string where to send request
|
||||
* @param query Map parameters to append to url
|
||||
* @param method http method to be used in request. standard methods: GET, POST, PUT, DELETE, HEAD
|
||||
* @param headers key-value map with headers that should be sent with request
|
||||
* @param body request body/data to send to url (InputStream, CharSequence, or Map for json and x-www-form-urlencoded context types)
|
||||
* @param encoding encoding name to use to send/receive data - default UTF-8
|
||||
* @param receiver Closure that will be called to receive data from server. Defaults: `HTTP.JSON_RECEIVER` for json content-type and `HTTP.TEXT_RECEIVER` otherwise. Available: `HTTP.FILE_RECEIVER(File)` - stores response to file.
|
||||
* @param ssl javax.net.ssl.SSLContext or String that evaluates the javax.net.ssl.SSLContext. example: send( url:..., ssl: "HTTP.getKeystoreSSLContext('./keystore.jks', 'testpass')" )
|
||||
*/
|
||||
public static Map<String,Object> send(Map<String,Object> ctx)throws IOException{
|
||||
String url = ctx.url;
|
||||
Map<String,String> headers = (Map<String,String>)ctx.headers;
|
||||
|
|
@ -67,6 +92,7 @@ public class HTTP{
|
|||
String encoding = ctx.encoding?:"UTF-8";
|
||||
Closure receiver = (Closure)ctx.receiver;
|
||||
Map<String,String> query = (Map<String,String>)ctx.query;
|
||||
Object sslCtxObj= ctx.ssl;
|
||||
|
||||
//copy context and set default values
|
||||
ctx = [:] + ctx;
|
||||
|
|
@ -78,14 +104,28 @@ public class HTTP{
|
|||
}
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
if(sslCtxObj!=null && connection instanceof HttpsURLConnection){
|
||||
SSLContext sslCtx = null;
|
||||
if(sslCtxObj instanceof SSLContext){
|
||||
sslCtx = (SSLContext)sslCtxObj;
|
||||
}else if(sslCtxObj instanceof CharSequence){
|
||||
//assume this is a groovy code to get ssl context
|
||||
sslCtx = evaluateSSLContext((CharSequence)sslCtxObj);
|
||||
}else{
|
||||
throw new IllegalArgumentException("Unsupported ssl parameter ${sslCtxObj.getClass()}")
|
||||
}
|
||||
((HttpsURLConnection)connection).setSSLSocketFactory(sslCtx.getSocketFactory());
|
||||
}
|
||||
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod(method);
|
||||
if ( headers!=null && !headers.isEmpty() ) {
|
||||
//add headers
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
connection.addRequestProperty(entry.getKey(), entry.getValue());
|
||||
if("content-type".equals(entry.getKey().toLowerCase()))contentType=entry.getValue();
|
||||
if(entry.getValue()){
|
||||
connection.addRequestProperty(entry.getKey(), entry.getValue());
|
||||
if("content-type".equals(entry.getKey().toLowerCase()))contentType=entry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,18 +137,20 @@ public class HTTP{
|
|||
}else if(body instanceof InputStream){
|
||||
out << (InputStream)body;
|
||||
}else if(body instanceof Map){
|
||||
if( contentType.matches("(?i)[^/]+/json") ){
|
||||
if( contentType =~ "(?i)[^/]+/json" ) {
|
||||
out.withWriter((String)ctx.encoding){
|
||||
it.append( JsonOutput.toJson((Map)body) );
|
||||
it.flush();
|
||||
}
|
||||
}else{
|
||||
throw new IOException("Map body type supported only for */json content-type");
|
||||
} else if( contentType =~ "(?i)[^/]+/x-www-form-urlencoded" ) {
|
||||
out.withWriter((String)ctx.encoding) {
|
||||
it.append( ((Map)body).collect{k,v-> ""+k+"="+URLEncoder.encode((String)v,'UTF-8') }.join('&') )
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Map body type supported only for */json of */x-www-form-urlencoded content-type");
|
||||
}
|
||||
}else if(body instanceof CharSequence){
|
||||
out.withWriter((String)ctx.encoding){
|
||||
it.append((CharSequence)body);
|
||||
it.flush();
|
||||
}
|
||||
}else{
|
||||
throw new IOException("Unsupported body type: "+body.getClass());
|
||||
|
|
@ -151,4 +193,52 @@ public class HTTP{
|
|||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@groovy.transform.Memoized
|
||||
public static SSLContext getKeystoreSSLContext(String keystorePath, String keystorePass, String keystoreType="JKS", String keyPass = null){
|
||||
if(keyPass == null) keyPass=keystorePass;
|
||||
KeyStore clientStore = KeyStore.getInstance(keystoreType);
|
||||
clientStore.load(new File( keystorePath ).newInputStream(), keystorePass.toCharArray());
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(clientStore, keyPass.toCharArray());
|
||||
KeyManager[] kms = kmf.getKeyManagers();
|
||||
//init TrustCerts
|
||||
TrustManager[] trustCerts = new TrustManager[1];
|
||||
trustCerts[0] = new X509TrustManager() {
|
||||
public void checkClientTrusted( final X509Certificate[] chain, final String authType ) { }
|
||||
public void checkServerTrusted( final X509Certificate[] chain, final String authType ) { }
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(kms, trustCerts, new SecureRandom());
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
@groovy.transform.Memoized
|
||||
public static SSLContext getNaiveSSLContext(){
|
||||
System.err.println("HTTP.getNaiveSSLContext() used. Must be disabled on prod!");
|
||||
KeyManager[] kms = new KeyManager[0];
|
||||
TrustManager[] trustCerts = new TrustManager[1];
|
||||
trustCerts[0] = new X509TrustManager() {
|
||||
public void checkClientTrusted( final X509Certificate[] chain, final String authType ) { }
|
||||
public void checkServerTrusted( final X509Certificate[] chain, final String authType ) { }
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, trustCerts, new SecureRandom());
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluates code that should return SSLContext
|
||||
*/
|
||||
@groovy.transform.Memoized
|
||||
public static SSLContext evaluateSSLContext(CharSequence code) {
|
||||
Object ssl = new GroovyShell( HTTP.class.getClassLoader() ).evaluate( code as String );
|
||||
return (SSLContext) ssl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue