passing extra variables in Spark UDF JAVA - java

I have written a spark UDF in JAVA to encrypt particular columns in a dataframe. It is type 1 UDF and only accepts a string that needs to be encrypted or decrypted at a time. I want to pass corresponding password as well. I tried the currying approach but was not able to write the function properly. Can anyone suggest me any solution ?
public class EncryptString implements UDF1<String, String> {
#Override
public String call(String s) throws Exception {
return Aes256.encrypt(s);
//Aes.encrypt needs to have another variable password.
//So that while calling the UDF we can pass the required password.
}
}

You can pass the password - as well as any other parameters - as constructor parameter to the EncryptString class:
public static class EncryptString implements UDF1<String, String> {
private final String password;
public EncryptString(String password) {
this.password = password;
}
public String call(String s) throws Exception {
return Aes256.encrypt(s, password);
}
}
When instantiating the udf, you can pass the actual password:
spark.sqlContext().udf().register("EncryptUdf", new EncryptString("secret"), DataTypes.StringType);
[...]
spark.sql("select EncryptUdf(_c2) from df").show();

Related

Passing session to function in Gatling Java

I am trying to pass the session to a function in Gatling as shown in .body():
exec(http("ED/CTS/SGM")
.post(IDS_BASE_URL + edEndpoint)
.body(StringBody(createBodyStringForStudentAssignmentSetup(session)))
.headers(getHeaderMap)
.check(status().is(201),
jsonPath("$.assignments[0].refId").saveAs("assignmentRefId")));
The function being called is shown here:
public class CreateAssignmentDataSetup {
public static Body.WithString createBodyStringForStudentAssignmentSetup(Session session)
{
String title;
String assignmentName = "PerformanceTest_AssignmentApi_";
title = assignmentName.concat(LocalDate.now().toString());
String studentsList = session.getString("listOfStudents");
....
....
return StringBody(body);
}
Is it possible to pass "session" values like this to "createBodyStringForStudentAssignmetnSetup()" like this, since using an exec(session-> block (shown below) will not allow requests to be triggered for some reason:
exec(session -> {
});
Thanks
StringBody takes a Function<Session, String> so you want to write:
public static String createBodyStringForStudentAssignmentSetup(Session session)
{
String title;
String assignmentName = "PerformanceTest_AssignmentApi_";
title = assignmentName.concat(LocalDate.now().toString());
String studentsList = session.getString("listOfStudents");
....
....
return body;
}
.body(StringBody(CreateAssignmentDataSetup::createBodyStringForStudentAssignmentSetup))

char[] password getters and setters to a String

I have a typical char[] password variable with getters and setters. I have done this so that my password variable is never shown in plain text.
private String passwordAsString;
private char[] password;
public char[] getPassword() { return password; }
public void setPassword(char[] password) { this.password = password; }
I want to send my password to a database, but I believe it needs to be sent as a String type. So, I decided to create a new variable called PasswordAsString. Is there a better approach? This seems sloppy.
Secondly my getPasswordAsString is not returning the password as a String. What I have so far is:
public void setPasswordAsString(String passwordAsString) {
this.passwordAsString = passwordAsString;
}
public String getPasswordAsString() {
return password.toString();
}
The getter/setter for the password as a String could be implemented like this:
public void setPasswordAsString(String passwordAsString) {
this.password = passwordAsString.toCharArray();
}
public String getPasswordAsString() {
return new String(password);
}
These get and set the char[] password field directly – no need for a passwordAsString field. Convert from char[] to String with new String(char[]) and from String to char[] with String.toCharArray().
I'm pretty sure that passing around the password as a String like this defeats any security purpose for using a char array, though.
A char array's toString() method is not going to get you what you want. Instead, construct a new String:
public String getPasswordAsString() {
return new String(password);
}
Also, I would probably consider not including a setter for the passwordAsString field (or having a second field at all, for that matter), as this goes against what you are attempting to accomplish here.

The method Registration(String, String, String, String) is undefined for the type Client

if (type == "REGISTRATION"){
String name = json.getString("name");
String Location = json.getString("loc");
Client.Registration(username, password, name, Location); //error
DatabaseController.registerUser(Pobj, userObj);
}
Client.java
public static boolean Registration(String username, String password, String name, String loc){
clientUsername = username;
clientPassword = password;
clientname = name;
clientlocation = loc;
}
Registration function is defined here
it gives me error like:
method Registration(String, String, String, String) is undefined for the type Client
In java (and many other programming languages), your methods (or functions) have to have a return type. In your case, you declared the return type of your function to be boolean. This however means that this method must return a boolean. In your code, you have no return statement.
To solve the problem: you could either add a return statement, or change the return type to void, meaning it doesn't return anything.
Considering that you aren't returning anything in your function, I suggest using the second option, as follows:
public static void Registration(String username, String password, String name, String loc)
{ ... }
Also, as #Peadar Ó Duinnín mentioned, Java methods should be written in camel case, meaning the first word is not capitalized, but all the words after are, i.e. myFunctionThatDoesSomething(). This means your method should become registration(...)
Your Registration method (which should be registration. Method/Functions are camelCase in Java.) should be in your Client class as follows. You should also be returning a boolean or change the method signature to public static void registration(...
public class Client {
public static boolean registration(String username, String password, String name, String loc) {
clientUsername = username;
clientPassword = password;
clientName = name;
clientLocation = loc;
}
}

How to put current method's parameter into a list

I have two methods like
public void login(String userName, String password)
{
}
public void login(String userName, String password, Object loginOption)
{
}
and I hope to get all of them soloved in a certain method:
public boolean getThingsDone(Object...vargs)
{
//Do The Real Action
return true;
}
so I have to make different function call:
public void login(String userName, String password)
{
getThingsDone(userName,password);
}
public void login(String userName, String password, Object loginOption)
{
getThingsDone(userName,password,loginOption);
}
Is there any way that I can put different parameter into one List, so I can make the same call
getThingsDone(parameterList);
I have no idea but declare both method into login(String ...vargs), but that will confuse other people use this method.
Is there any one ever meet this problem? Any hint would be appreciated.
You can create a Login class with three attributes: - username, password, loginOption.
public class Login {
private String username;
private String password;
private Object loginOptions;
// Constructors
// public accessors.
}
And in your login method pass Login reference as parameter: -
public void login(Login login) {
}
So, if you want to pass loginOptions, call it like this: -
login(new Login(username, password, loginOptions));
else, just use a 2-parameterized constructor of Login class: -
login(new Login(username, password));
And from login method, call other method like this: -
getThingsDone(login);
Now in that method, check : - if (login.getLoginOptions() != null). If it is null, then do things related to username and password. And if it is not null, then do things related to all of them.
public void login(String userName, String password, Object loginOption)
This method should do the thing and should be able to handle the situation when loginOption is null.
Then you could invoke it as follows:
public void login(String userName, String password) {
login(userName, password, null);
You can pass an array list and use the length to do what ever you need. Why not use overloaded methods and modularize the rest of the code?

return multiple value from one method

I have a class UserFunction and it have two method getAudioFunction and getPromptFunction with returning String value, my problem is that i want to return both value in one method
how can i able to do that
UserFunction.java
public class UserFunction{
Map<String,PromptBean> promptObject=new HashMap<String,PromptBean>();
Map<String,AudioBean> audioObject = new HashMap<String,AudioBean>();
XmlReaderPrompt xrpObject=new XmlReaderPrompt();
public String getAudioFunction(String audioTag,String langMode )
{
Map<String, AudioBean> audioObject=xrpObject.load_audio(langMode);
AudioBean audioBean=(AudioBean)audioObject.get(audioTag);
String av=StringEscapeUtils.escapeXml(audioBean.getAudio());
return av;
}
public String getPromptFunction(String promptTag,String langMode )
{
Map<String, PromptBean> promptObject=xrpObject.load(langMode);
PromptBean promptBean= (PromptBean)promptObject.get(promptTag);
String pv=StringEscapeUtils.escapeXml(promptBean.getPrompt());
return pv;
}
}
You need to return an object which holds both values. You could create a class for this purpose. The class can have two getter methods for retrieving the values.
It is not possible to return more than one value from a method in java. You can set multiple value into Map or List or create a custom class and can return that object.
public Map<String,String> getAudioAndPromptFunction(String audioTag,String langMode )
{
Map<String,String> map =new HashMap();
...
map.put("audioBean",StringEscapeUtils.escapeXml(audioBean.getAudio()));
map.put("promptBean",StringEscapeUtils.escapeXml(promptBean.getPrompt());
return map;
}
or you can create a custom bean class like.
public class AudioPrompt{
private String audioBean;
private String promptBean;
...
}
public AudioPrompt getAudioAndPromptFunction(String audioTag,String langMode )
{
AudioPrompt audioPrompt =new AudioPrompt();
...
audioPrompt.set(StringEscapeUtils.escapeXml(audioBean.getAudio()));
audioPrompt.set(StringEscapeUtils.escapeXml(promptBean.getPrompt());
return audioPrompt ;
}
You'll need to return an object that includes both of the values. This could be an array with two elements, a Pair<A,B> class (which holds two generic values, typically from some pan-project utility library), or a method-specific class such as:
public class UserFunctionXmlPairing {
public final String audioBeanXml;
public final String promptBeanXml;
}
Create a new class that holds your two strings and return that.
class AudioPromptPair {
private String audio;
private String prompt;
public AudioPromptPair(String audio, String prompt) {
this.audio = audio;
this.prompt = prompt;
}
// add getters and setters
}
You can wrap all the values you wish into a single object and return that:
public class Prompts {
private Map<String, Object> prompts = new HashMap<String, Object>();
public void addPrompt(String name, Object prompt) {
this.prompts.put(name, prompt);
}
public Object getPrompt(String name) {
this.prompts.get(name);
}
}
It's even easier if your AudioBean and PromptBean have a common super class or interface.
My preference would be to lose the "Bean" in your class names. AudioPrompt and TextPrompt would be preferred.

Categories

Resources