Can someone help with getting starting using the AWS Java SDK for Personalize? I used to the console to build a Campaign. Now I want to query for recommendations using Java.
Amazon has many examples in Python, but I need Java. Starting with the client builder is especially useful.
Thanks.
To query for recommendations by using Java V2, you use the PersonalizeRuntimeClient object.
Here is an example that uses Java V2. We will have the full examples posted in Java V2 Github very soon.
**
package com.example.personalize;
//snippet-start:[personalize.java2.get_recommendations.import]
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.personalizeruntime.PersonalizeRuntimeClient;
import software.amazon.awssdk.services.personalizeruntime.model.GetRecommendationsRequest;
import software.amazon.awssdk.services.personalizeruntime.model.GetRecommendationsResponse;
import software.amazon.awssdk.services.personalizeruntime.model.PredictedItem;
import java.util.List;
//snippet-end:[personalize.java2.get_recommendations.import]
public class GetRecommendations {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" GetRecommendations <campaignArn> <userId>\n\n" +
"Where:\n" +
" campaignArn - The ARN of the campaign.\n\n" +
" userId - The user ID to provide recommendations for\n\n";
if (args.length < 2) {
System.out.println(USAGE);
System.exit(1);
}
/* Read the name from command args */
String campaignArn = args[0];
String userId = args[1];
Region region = Region.US_EAST_1;
PersonalizeRuntimeClient personalizeRuntimeClient = PersonalizeRuntimeClient.builder()
.region(region)
.build();
getRecs(personalizeRuntimeClient, campaignArn, userId);
}
//snippet-start:[personalize.java2.get_recommendations.main]
public static void getRecs(PersonalizeRuntimeClient personalizeRuntimeClient, String campaignArn, String userId){
try {
GetRecommendationsRequest recommendationsRequest = GetRecommendationsRequest.builder()
.campaignArn(campaignArn)
.numResults(20)
.userId(userId)
.build();
GetRecommendationsResponse recommendationsResponse = personalizeRuntimeClient.getRecommendations(recommendationsRequest);
List<PredictedItem> items = recommendationsResponse.itemList();
for (PredictedItem item: items) {
System.out.println("Item Id is : "+item.itemId());
System.out.println("Item score is : "+item.score());
}
} catch (AwsServiceException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
}
//snippet-end:[personalize.java2.get_recommendations.main]
}
**
Related
I'm following the AWS documentation about how to connect to redshift [generating user credentials][1]
But the get-cluster-credentials API requires a cluster id parameter, which i don't have for a serverless endpoint. What id should I use?
EDIT:
[![enter image description here][2]][2]
This is the screen of a serverless endpoint dashboard. There is no cluster ID.
[1]: https://docs.aws.amazon.com/redshift/latest/mgmt/generating-user-credentials.html
[2]: https://i.stack.imgur.com/VzvIs.png
Look at this Guide (a newer one) that talks about Connecting to Amazon Redshift Serverless. https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-connecting.html
See this information that answers your question:
Connecting to the serverless endpoint with the Data API
You can also use the Amazon Redshift Data API to connect to serverless endpoint. Leave off the cluster-identifier parameter in your AWS CLI calls to route your query to serverless endpoint.
UPDATE
I wanted to test this to make sure that a successful connection can be made. I followed this doc to setup a Serverless instance.
Get started with Amazon Redshift Serverless
I loaded sample data and now have this.
Now I attemped to connect to it using software.amazon.awssdk.services.redshiftdata.RedshiftDataClient.
The Java V2 code:
try {
ExecuteStatementRequest statementRequest = ExecuteStatementRequest.builder()
.database(database)
.sql(sqlStatement)
.build();
ExecuteStatementResponse response = redshiftDataClient.executeStatement(statementRequest);
return response.id();
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
Notice there is no cluster id or user. Only a database name (sample_data_dev). The call worked perfectly.
HEre is the full code example that successfully queries data from a serverless instance using the AWS SDK for Java V2.
package com.example.redshiftdata;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.redshiftdata.model.*;
import software.amazon.awssdk.services.redshiftdata.RedshiftDataClient;
import software.amazon.awssdk.services.redshiftdata.model.DescribeStatementRequest;
import java.util.List;
/**
* To run this Java V2 code example, ensure that you have setup your development environment, including your credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class RetrieveDataServerless {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" RetrieveData <database> <sqlStatement> \n\n" +
"Where:\n" +
" database - the name of the database (for example, sample_data_dev). \n" +
" sqlStatement - the sql statement to use. \n" ;
String database = "sample_data_dev" ;
String sqlStatement = "Select * from tickit.sales" ;
Region region = Region.US_WEST_2;
RedshiftDataClient redshiftDataClient = RedshiftDataClient.builder()
.region(region)
.build();
String id = performSQLStatement(redshiftDataClient, database, sqlStatement);
System.out.println("The identifier of the statement is "+id);
checkStatement(redshiftDataClient,id );
getResults(redshiftDataClient, id);
redshiftDataClient.close();
}
public static void checkStatement(RedshiftDataClient redshiftDataClient,String sqlId ) {
try {
DescribeStatementRequest statementRequest = DescribeStatementRequest.builder()
.id(sqlId)
.build() ;
// Wait until the sql statement processing is finished.
boolean finished = false;
String status = "";
while (!finished) {
DescribeStatementResponse response = redshiftDataClient.describeStatement(statementRequest);
status = response.statusAsString();
System.out.println("..."+status);
if (status.compareTo("FINISHED") == 0) {
break;
}
Thread.sleep(1000);
}
System.out.println("The statement is finished!");
} catch (RedshiftDataException | InterruptedException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
public static String performSQLStatement(RedshiftDataClient redshiftDataClient,
String database,
String sqlStatement) {
try {
ExecuteStatementRequest statementRequest = ExecuteStatementRequest.builder()
.database(database)
.sql(sqlStatement)
.build();
ExecuteStatementResponse response = redshiftDataClient.executeStatement(statementRequest);
return response.id();
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
public static void getResults(RedshiftDataClient redshiftDataClient, String statementId) {
try {
GetStatementResultRequest resultRequest = GetStatementResultRequest.builder()
.id(statementId)
.build();
GetStatementResultResponse response = redshiftDataClient.getStatementResult(resultRequest);
// Iterate through the List element where each element is a List object.
List<List<Field>> dataList = response.records();
// Print out the records.
for (List list: dataList) {
for (Object myField:list) {
Field field = (Field) myField;
String value = field.stringValue();
if (value != null)
System.out.println("The value of the field is " + value);
}
}
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}
I want to receive the role information for a role name. For example getting the exact ARN identifier.
Somehow this code below is not working. Sadly there is no error message in cloudwatch
import software.amazon.awssdk.services.iam.*;
import com.amazonaws.services.identitymanagement.model._
import com.amazonaws.services.identitymanagement.{AmazonIdentityManagementClient, AmazonIdentityManagement, AmazonIdentityManagementClientBuilder}
// ....
val iamClient = AmazonIdentityManagementClient
.builder()
.withRegion("eu-central-1")
.build()
val roleRequest = new GetRoleRequest();
roleRequest.setRoleName("InfrastructureStack-StandardRoleD-HBLE12VPTWQ")
val result = iamClient.getRole(roleRequest) // <-- Nothing happens after this line
println("wont execute this println statement")
Other services like CognitoIdentityProvider are working perfectly fine.
I also tried the builder pattern for the GetRoleRequest and IamClient.
I got this IAM V2 code working fine. As stated in my comment, setup your dev environment to use AWS SDK for Java V2.
package com.example.iam;
import software.amazon.awssdk.services.iam.model.*;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
public class GetRole {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" <policyArn> \n\n" +
"Where:\n" +
" policyArn - a policy ARN that you can obtain from the AWS Management Console. \n\n" ;
// if (args.length != 1) {
// System.out.println(USAGE);
//// System.exit(1);
// }
String roleName = "DynamoDBAutoscaleRole" ; //args[0];
Region region = Region.AWS_GLOBAL;
IamClient iam = IamClient.builder()
.region(region)
.build();
getRoleInformation(iam, roleName);
System.out.println("Done");
iam.close();
}
public static void getRoleInformation(IamClient iam, String roleName) {
try {
GetRoleRequest roleRequest = GetRoleRequest.builder()
.roleName(roleName)
.build();
GetRoleResponse response = iam.getRole(roleRequest) ;
System.out.println("The ARN of the role is " +response.role().arn());
} catch (IamException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
}
}
Output:
In my project there is a need for creating share link for external users without aws user from my researching found out a couple ways for doing so
Bucket policy based on tag
Lambda that creates sign url every time some user request the file
The question is what is the best practice for doing so
I need the download to be available until the user sharing the file stopes it
Thank guys for any answers
Using the AWS SDK, you can use Amazon S3 Pre-sign functionality. You can perform this task in any of the supported programming languages (Java, JS, Python, etc).
The following code shows how to sign an object via the Amazon S3 Java V2 API.
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.time.Duration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.utils.IoUtils;
// snippet-end:[presigned.java2.getobjectpresigned.import]
/**
* To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class GetObjectPresignedUrl {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" GetObjectPresignedUrl <bucketName> <keyName> \n\n" +
"Where:\n" +
" bucketName - the Amazon S3 bucket name. \n\n"+
" keyName - a key name that represents a text file. \n\n";
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String bucketName = args[0];
String keyName = args[1];
Region region = Region.US_WEST_2;
S3Presigner presigner = S3Presigner.builder()
.region(region)
.build();
getPresignedUrl(presigner, bucketName, keyName);
presigner.close();
}
// snippet-start:[presigned.java2.getobjectpresigned.main]
public static void getPresignedUrl(S3Presigner presigner, String bucketName, String keyName ) {
try {
GetObjectRequest getObjectRequest =
GetObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(10))
.getObjectRequest(getObjectRequest)
.build();
// Generate the presigned request
PresignedGetObjectRequest presignedGetObjectRequest =
presigner.presignGetObject(getObjectPresignRequest);
// Log the presigned URL
System.out.println("Presigned URL: " + presignedGetObjectRequest.url());
HttpURLConnection connection = (HttpURLConnection) presignedGetObjectRequest.url().openConnection();
presignedGetObjectRequest.httpRequest().headers().forEach((header, values) -> {
values.forEach(value -> {
connection.addRequestProperty(header, value);
});
});
// Send any request payload that the service needs (not needed when isBrowserExecutable is true)
if (presignedGetObjectRequest.signedPayload().isPresent()) {
connection.setDoOutput(true);
try (InputStream signedPayload = presignedGetObjectRequest.signedPayload().get().asInputStream();
OutputStream httpOutputStream = connection.getOutputStream()) {
IoUtils.copy(signedPayload, httpOutputStream);
}
}
// Download the result of executing the request
try (InputStream content = connection.getInputStream()) {
System.out.println("Service returned response: ");
IoUtils.copy(content, System.out);
}
} catch (S3Exception e) {
e.getStackTrace();
} catch (IOException e) {
e.getStackTrace();
}
// snippet-end:[presigned.java2.getobjectpresigned.main]
}
}
I have built a Q&A-chatbot using Amazon Lex with all intents and its utterances being in English. Now of course when an user asks some question in English, Amazon Lex processes the question and gives an answer in English.
Now I also want to make it possible for example using Amazon Translate to have a possibility for other language interactions. That means: e.g. French user asks a question in French, Amazon Translate translates it into English and automatically forwards it to Amazon Lex, where the procedure just continues as before. The answers, which are triggered by the lambda function, are in English so when answering Amazon Translate should take the English answer text, translate it back into French and return it to the user.
Is there a proper tutorial on that as the Tutorials by Amazon seem to be just general information. Or is there a simple button I can click on and Amazon Translate is already ready to go ;)
Thanks for your answers in advance!
Using the AWS SDK, you can build this functionality. You can use Amazon Comprehend to determine the language. If it's french (or other supported language), pass the string to the AWS Translate service to get English.
This is a multi service use case that requires code. I programmed an example web app by using the AWS SDK For Java that performs this use case perfectly.
This Java code uses Amazon LEX, Comprehend, and the AWS Translation to solve this use case. As you can see, this handles French and other languages.
This example handles other languages too such as Italian:
Here is the Java V2 code that solves this. Note that the text is posted from the HTML client to the controller and the controller calls the getText method and passes the text.
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lexruntime.LexRuntimeClient;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.services.lexruntime.model.LexRuntimeException;
import software.amazon.awssdk.services.lexruntime.model.PostTextRequest;
import software.amazon.awssdk.services.comprehend.ComprehendClient;
import software.amazon.awssdk.services.comprehend.model.ComprehendException;
import software.amazon.awssdk.services.comprehend.model.DetectDominantLanguageRequest;
import software.amazon.awssdk.services.comprehend.model.DetectDominantLanguageResponse;
import software.amazon.awssdk.services.comprehend.model.DominantLanguage;
import software.amazon.awssdk.services.translate.TranslateClient;
import software.amazon.awssdk.services.translate.model.TranslateTextRequest;
import software.amazon.awssdk.services.translate.model.TranslateTextResponse;
import software.amazon.awssdk.services.translate.model.TranslateException;
import java.util.*;
import java.text.SimpleDateFormat;
import software.amazon.awssdk.services.lexruntime.model.PostTextResponse;
#Component
public class LexService {
public String getText(String text) {
Region region = Region.US_EAST_1;
LexRuntimeClient lexRuntimeClient = LexRuntimeClient.builder()
.region(region)
.build();
String engMessage ="";
try {
// Need to determine the language.
String lanCode = DetectLanguage(text);
// If the lanCode is NOT Eng - then we need to translate the message to English to pass to Amazon Lex.
if (lanCode.compareTo("en") !=0)
engMessage = textTranslateToEn(lanCode, text);
else
engMessage=text;
String userId = "chatbot-demo" ;
Map<String,String> sessionAttributes = new HashMap<>();
PostTextRequest textRequest = PostTextRequest.builder()
.botName("BookTrip")
.botAlias("scott")
.inputText(engMessage)
.userId(userId)
.sessionAttributes(sessionAttributes)
.build();
PostTextResponse textResponse = lexRuntimeClient.postText(textRequest);
String message = textResponse.message();
// If not EN, we need to translate the text back
String outputText ="";
if (lanCode.compareTo("en") !=0)
outputText = textTranslateFromEn(lanCode, message);
else
outputText = message;
return outputText ;
} catch (LexRuntimeException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
private String DetectLanguage(String text) {
Region region = Region.US_EAST_1;
ComprehendClient comClient = ComprehendClient.builder()
.region(region)
.build();
try {
String lanCode = "";
DetectDominantLanguageRequest request = DetectDominantLanguageRequest.builder()
.text(text)
.build();
DetectDominantLanguageResponse resp = comClient.detectDominantLanguage(request);
List<DominantLanguage> allLanList = resp.languages();
Iterator<DominantLanguage> lanIterator = allLanList.iterator();
while (lanIterator.hasNext()) {
DominantLanguage lang = lanIterator.next();
lanCode = lang.languageCode();
}
return lanCode;
} catch (ComprehendException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
return "";
}
public String textTranslateToEn(String lanCode, String text) {
Region region = Region.US_EAST_1;
TranslateClient translateClient = TranslateClient.builder()
.credentialsProvider(EnvironmentVariableCredentialsProvider.create())
.region(region)
.build();
try {
TranslateTextRequest textRequest = TranslateTextRequest.builder()
.sourceLanguageCode(lanCode)
.targetLanguageCode("en")
.text(text)
.build();
TranslateTextResponse textResponse = translateClient.translateText(textRequest);
return textResponse.translatedText();
} catch (TranslateException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
public String textTranslateFromEn(String lanCode, String text) {
Region region = Region.US_EAST_1;
TranslateClient translateClient = TranslateClient.builder()
.credentialsProvider(EnvironmentVariableCredentialsProvider.create())
.region(region)
.build();
try {
TranslateTextRequest textRequest = TranslateTextRequest.builder()
.sourceLanguageCode("en")
.targetLanguageCode(lanCode)
.text(text)
.build();
TranslateTextResponse textResponse = translateClient.translateText(textRequest);
return textResponse.translatedText();
} catch (TranslateException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
}
I want to fetch all the failed executions and need to re-trigger them dynamically.
PS: In stepfunction definition I had proper retry mechanism, now I want to rerun the failed executions dynamically.
I need to implement it in java. Please help me with the approach.
Thanks in advance.
You can use the AWS Step Functions API to get a list of excutions:
https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/SfnClient.html#listExecutions-
Then you can get a list of ExecutionListItem by calling the executions() method that belongs to the ListExecutionsResponse object (returned by the listExecutions method)
https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionListItem.html
Using this object - you can do two things:
1 - check status - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionStatus.html
2 - get state machine ARN value - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionListItem.html#stateMachineArn--
Using the state machine ARN value, you can execute a state machine with the AWS Step Functions Java API V2:
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sfn.SfnClient;
import software.amazon.awssdk.services.sfn.model.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.UUID;
// snippet-end:[stepfunctions.java2.start_execute.import]
public class StartExecution {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" StartExecution <stateMachineArn> <jsonFile>\n\n" +
"Where:\n" +
" stateMachineArn - the ARN of the state machine.\n\n" +
" jsonFile - A JSON file that contains the values to pass to the worflow.\n" ;
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String stateMachineArn = args[0];
String jsonFile = args[1];
Region region = Region.US_EAST_1;
SfnClient sfnClient = SfnClient.builder()
.region(region)
.build();
String exeArn = startWorkflow(sfnClient,stateMachineArn, jsonFile);
System.out.println("The execution ARN is" +exeArn);
sfnClient.close();
}
// snippet-start:[stepfunctions.java2.start_execute.main]
public static String startWorkflow(SfnClient sfnClient, String stateMachineArn, String jsonFile) {
String json = getJSONString(jsonFile);
// Specify the name of the execution by using a GUID value.
UUID uuid = UUID.randomUUID();
String uuidValue = uuid.toString();
try {
StartExecutionRequest executionRequest = StartExecutionRequest.builder()
.input(json)
.stateMachineArn(stateMachineArn)
.name(uuidValue)
.build();
StartExecutionResponse response = sfnClient.startExecution(executionRequest);
return response.executionArn();
} catch (SfnException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
return "";
}
private static String getJSONString(String path) {
try {
JSONParser parser = new JSONParser();
JSONObject data = (JSONObject) parser.parse(new FileReader(path));//path to the JSON file.
String json = data.toJSONString();
return json;
} catch (IOException | org.json.simple.parser.ParseException e) {
e.printStackTrace();
}
return "";
}
// snippet-end:[stepfunctions.java2.start_execute.main]
}