diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/README.md b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/README.md new file mode 100644 index 00000000..8aa58d60 --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/README.md @@ -0,0 +1,64 @@ +# Building this example in Linux + +## Prepare dependencies jar into work dir + +bash ./prepare.sh +## Building jars + +bash ./build.sh + +# Running this sample + +The App.java has hardcoded values in it mentioned in the sections below. Those should be pointed to the right values. + +Before running this application, the kinit which somes with the JRE needs to be run to get a kerberos token. + +`\bin\kinit.exe @` + +e.g. + +`\bin\kinit.exe admin@ARIS.LOCAL` + +In Linux, you can directly using kinit in system. + +e.g. + + kinit admin@ARIS.LOCAL + +# Sample login.conf. There is an existing login.conf that is being checked in as well. + +For more details about login.conf refer https://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/tutorials/LoginConfigFile.html + +``` +com.sun.security.jgss.login { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true; + }; + + com.sun.security.jgss.initiate { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true; + }; + + com.sun.security.jgss.accept { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true; + }; + + ``` + + In App.java the following properties need to be configured or parameterized using command line. + + ``` + private static String GW_ENDPOINT = "https://knox.tdeupgrade.aris.local:30443/gateway/default/webhdfs/v1"; + + private static String KDC = "ARIS-WIN2016-DC.aris.local"; + + private static String DOMAIN_REALM = "ARIS.LOCAL"; + + private static String LOGIN_CONF_PATH = "login.conf"; + + +``` +# Upload file example + +``` +java -cp "./running_work_dir/*" com.microsoft.mssql.App ./source /tmp/destination +``` diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/build.sh b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/build.sh new file mode 100755 index 00000000..76c04f6a --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/build.sh @@ -0,0 +1,4 @@ +mvn compile +mvn package +cp target/webhdfsclientsample-1.0-SNAPSHOT.jar running_work_dir/ +cd runnint_work_dir diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/login.conf b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/login.conf new file mode 100644 index 00000000..72f9ce7b --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/login.conf @@ -0,0 +1,11 @@ +com.sun.security.jgss.login { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true principal="admin"; + }; + + com.sun.security.jgss.initiate { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true principal="admin"; + }; + + com.sun.security.jgss.accept { + com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true debug=true principal="admin"; + }; \ No newline at end of file diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/pom.xml b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/pom.xml new file mode 100644 index 00000000..a109289e --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/pom.xml @@ -0,0 +1,123 @@ + + + + 4.0.0 + + com.microsoft.mssql + webhdfsclientsample + 1.0-SNAPSHOT + + webhdfsclientsample + + http://www.example.com + + + UTF-8 + 1.7 + 1.7 + + + + + junit + junit + 4.11 + test + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + org.apache.httpcomponents + httpmime + 4.5.13 + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + copy-resources + validate + + copy-resources + + + ${basedir}/target/Crunchify + + + resources + true + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/Crunchify/lib + false + false + true + + + + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/prepare.sh b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/prepare.sh new file mode 100755 index 00000000..976abc59 --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/prepare.sh @@ -0,0 +1,2 @@ +# Prepare dependencies jars into a work dir +mvn dependency:copy-dependencies -DoutputDirectory=running_work_dir -Dhttps.protocols=TLSv1.2 diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/main/java/com/microsoft/mssql/App.java b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/main/java/com/microsoft/mssql/App.java new file mode 100644 index 00000000..3af5b735 --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/main/java/com/microsoft/mssql/App.java @@ -0,0 +1,118 @@ +package com.microsoft.mssql; + +import java.security.Principal; +import java.io.File; + +import org.apache.http.HttpEntity; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +/** + * Sample app for Encryption Zone interactions with WebHdfs. + */ +public class App { + + // Properties to be configured before running the application. + private static String GW_ENDPOINT = "https://knox.test.azdata.local:30443/gateway/default/webhdfs/v1"; + + private static String KDC = "winad.azdata.local"; + + private static String DOMAIN_REALM = "AZDATA.LOCAL"; + + // The existing login.conf along with this project can be modified instead of providing a new path. + private static String LOGIN_CONF_PATH = "login.conf"; + // End of properties to be configured. + + static Credentials emptyCredentials = new Credentials() { + public String getPassword() { + return null; + } + public Principal getUserPrincipal() { + return null; + } + }; + + static CredentialsProvider provider = new CredentialsProvider() { + @Override + public void setCredentials(AuthScope authscope, Credentials credentials) { + // No op + } + + @Override + public Credentials getCredentials(AuthScope authscope) { + //TODO: this can be enhanced to pass controller use name and password in case the AuthScope authscheme is basic. + return emptyCredentials; + } + + @Override + public void clear() { + // No op. Nothing to clean up. + } + }; + private static void uploadResource(String inputFilePath, String outputFilePath){ + System.out.println("Entering create resource"); + // Construct Knox endpoint + String createOperationEndpoint = GW_ENDPOINT + outputFilePath + "?op=CREATE&overwrite=true"; + try (CloseableHttpClient client2 = HttpClients.custom().setDefaultCredentialsProvider(provider).build()) { + HttpUriRequest request = new HttpPut(createOperationEndpoint); + // First request to get the location in data nodes + try (CloseableHttpResponse response = client2.execute(request)) { + System.out.println("==============="); + String newlocation = response.getFirstHeader("Location").getValue(); + HttpEntity entity = response.getEntity(); + System.out.println("----------------------------------------"); + System.out.println(response.getStatusLine()); + System.out.println("----------------------------------------"); + if (entity != null) { + System.out.println(EntityUtils.toString(entity)); + } + System.out.println("----------------------------------------"); + EntityUtils.consume(entity); + // Second request to put the content to that location + File testUploadFile = new File(inputFilePath); + HttpEntity putData = MultipartEntityBuilder.create().addBinaryBody("upfile", testUploadFile).build(); + HttpUriRequest putRequest = RequestBuilder.put(newlocation).setEntity(putData).build();//setEntity(postData).build(); + System.out.println("Executing request " + putRequest.getRequestLine()); + CloseableHttpResponse response2 = client2.execute(putRequest); + HttpEntity entity2 = response2.getEntity(); + System.out.println("----------------------------------------"); + System.out.println(response2.getStatusLine()); + System.out.println("----------------------------------------"); + if (entity2 != null) { + System.out.println(EntityUtils.toString(entity2)); + } + System.out.println("----------------------------------------"); + + } + } catch (Exception e) { + System.out.println(e); + } + + } + + public static void main(String[] args) throws Exception { + // These properties can be specified using command line as well by using + // -Djava.security.auth.login.conf=login.conf -Djava.security.krb5.realm=MYDOMAIN.LOCAL + // In case command line is used to pass these arguments, then code below setting system properties should not be used.. + System.setProperty("java.security.auth.login.config", LOGIN_CONF_PATH); // The login conf for Java GSS to use. See readme for a sample. + System.setProperty("java.security.krb5.realm", DOMAIN_REALM); // The domain name. + System.setProperty("java.security.krb5.kdc", KDC); // Provide the KDC name here + System.setProperty("sun.security.krb5.debug", "true"); // This can be set to true to print debug information about Kerberos login. + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + for(int i = 0; i < args.length; i++) { + System.out.println(args[i]); + } + uploadResource(args[0], args[1]); + } +} diff --git a/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/test/java/com/microsoft/mssql/AppTest.java b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/test/java/com/microsoft/mssql/AppTest.java new file mode 100644 index 00000000..79b300ff --- /dev/null +++ b/samples/features/sql-big-data-cluster/connectivity/webhdfs-java-client/src/test/java/com/microsoft/mssql/AppTest.java @@ -0,0 +1,20 @@ +package com.microsoft.mssql; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +}