Trying to run a local amazon dynamo db client with the following code which is basically just a sample i have gotten online, I have created the table with local stack so it should exist not really sure what the issue is.
public static void main(String[] args) {
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable("attestation-db");
// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);
//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");
//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();
List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough! Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);
List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product! Do not buy this.");
reviews.put("OneStar", oneStarReviews);
// Build the item
Item item = new Item()
.withPrimaryKey("Id", 123)
.withString("Title", "Bicycle 123")
.withString("Description", "123 description")
.withString("BicycleType", "Hybrid")
.withString("Brand", "Brand-Company C")
.withNumber("Price", 500)
.withStringSet("Color", new HashSet<String>(Arrays.asList("Red", "Black")))
.withString("ProductCategory", "Bicycle")
.withBoolean("InStock", true)
.withNull("QuantityOnHand")
.withList("RelatedItems", relatedItems)
.withMap("Pictures", pictures)
.withMap("Reviews", reviews);
// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
but i keep getting the following error when i run the main method.
Exception in thread "main" java.lang.NoSuchMethodError: com.amazonaws.util.StringUtils.trim(Ljava/lang/String;)Ljava/lang/String;
at com.amazonaws.auth.profile.internal.AwsProfileNameLoader.getEnvProfileName(AwsProfileNameLoader.java:72)
at com.amazonaws.auth.profile.internal.AwsProfileNameLoader.loadProfileName(AwsProfileNameLoader.java:54)
at com.amazonaws.regions.AwsProfileRegionProvider.<init>(AwsProfileRegionProvider.java:40)
at com.amazonaws.regions.DefaultAwsRegionProviderChain.<init>(DefaultAwsRegionProviderChain.java:23)
at com.amazonaws.client.builder.AwsClientBuilder.<clinit>(AwsClientBuilder.java:58)
at com.lmig.global.event.framework.sample.publisher.application.code.Attestation.main(Attestation.java:18)
It seems there are many versions of SDK present in classpath. can you try print the locations where classes are being loaded.
System.out.println(StringUtils.getClass().getProtectionDomain().getCodeSource());
System.out.println(AwsProfileNameLoader.getClass().getProtectionDomain().getCodeSource());
Related
I am using DynamoDBMapper to scan a a table, specifically a column named "title". I should be returned a list of blogs that contains a string passed into the scanExpression. This is code I wrote about a year and a half ago which I remember working. Maybe something has been updated since?
Thanks!
public List<BlogDetailsEntity> searchBlogs(String query) {
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
scanExpression.addFilterCondition("title", new Condition()
.withComparisonOperator(ComparisonOperator.CONTAINS)
.withAttributeValueList(new AttributeValue().withS(query.toLowerCase())));
return dynamoDBMapper.scan(BlogDetailsEntity.class, scanExpression);
}
Your code is not best practice anymore. Java V1 and this mapper should be replaced with AWS SDK for Java V2.
To get the latest code for AWS, always refer to the new AWS Code Library here.
Code examples for DynamoDB using AWS SDKs
To filter a column using the V2 enhanced client (a replacement for DynamoDBMapper), you can use DynamoDbEnhancedClient. For example, assume you want to scan a table to get all Closed items on a column named archive.
You can use code like this.
// Get Open items from the DynamoDB table.
public List<WorkItem> getOpenItems() {
// Create a DynamoDbEnhancedClient.
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(getClient())
.build();
try{
// Create a DynamoDbTable object.
DynamoDbTable<Work> table = enhancedClient.table("Work", TableSchema.fromBean(Work.class));
AttributeValue attr = AttributeValue.builder()
.s("Open")
.build();
Map<String, AttributeValue> myMap = new HashMap<>();
myMap.put(":val1",attr);
Map<String, String> myExMap = new HashMap<>();
myExMap.put("#archive", "archive");
// Set the Expression so only Closed items are queried from the Work table.
Expression expression = Expression.builder()
.expressionValues(myMap)
.expressionNames(myExMap)
.expression("#archive = :val1")
.build();
ScanEnhancedRequest enhancedRequest = ScanEnhancedRequest.builder()
.filterExpression(expression)
.limit(15)
.build();
// Scan items.
Iterator<Work> results = table.scan(enhancedRequest).items().iterator();
WorkItem workItem ;
ArrayList<WorkItem> itemList = new ArrayList<>();
while (results.hasNext()) {
workItem = new WorkItem();
Work work = results.next();
workItem.setName(work.getName());
workItem.setGuide(work.getGuide());
workItem.setDescription(work.getDescription());
workItem.setStatus(work.getStatus());
workItem.setDate(work.getDate());
workItem.setId(work.getId());
// Push the workItem to the list.
itemList.add(workItem);
}
return itemList;
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return null;
}
You can find a complete AWS end to end developer tutorial that teaches you how to use this code to display Amazon DynamoDB items in a React client app. For example, this illustration shows Closed items.
This complete doc can be found in the code lib here:
Create an Amazon Relational Database Service item tracker
I'm currently migrating my app from using the Stripe Charges API to use the Stripe PaymentIntents API, in order to comply with SCA regulations.
My subscription creation code roughly looks like this:
Map<String, Object> srchOpts = new HashMap<>();
srchOpts.put("email", userEmail);
List<Customer> matchingCustomers = Customer.list(srchOpts).getData();
Customer customer = null;
Subscription subscription = null;
if ( matchingCustomers.isEmpty() ){
Map<String, Object> params = new HashMap<String, Object>();
params.put("email", userEmail);
params.put("payment_token", stripeToken);
customer = Customer.create(params);
}
else if (matchingCustomers.size() == 1) {
customer = matchingCustomers.get(0);
Map<String, Object> params = new HashMap<String, Object>();
params.put("source", stripeToken);
PaymentSourceCollection paymentSources = customer.getSources();
paymentSources.create(params);
}
Map<String, Object> item = new HashMap<String, Object>();
item.put("plan", planId); // e.g. my-pro-plan (no trial days)
Map<String, Object> items = new HashMap<String, Object>();
items.put("0", item);
Map<String, Object> params = new HashMap<String, Object>();
params.put("items", items);
params.put("customer", customer.getId());
params.put("off_session", false);
subscription = Subscription.create(params);
I can see on the Stripe dashboard (in test mode) that the customer is created and has the card which I specified, but the Subscription.create call fails with:
com.stripe.exception.InvalidRequestException: This customer has no attached payment source; code: resource_missing
The customer has a card set (there is only 1 so it has to be the default card), the customer creation call happens before the subscription creation call and the customer ID is being passed to the sub creation call. Is there some other parameter I need to pass in?
I've tried setting Customer.invoice_settings.default_payment_method when the customer is being created, and that gets me past the subscription creation. Everything looks fine from the Stripe dashboard, except that I'm testing with an SCA test card, so the transaction is incomplete until the customer has authenticated further.
I need the client secret token from the response to continue, and I thought that I would get it from #Subscription.getLatestInvoiceObject().getPaymentIntentObject().getClientSecret() but the getLatestInvoiceObject() call is returning null.
I'm not setting collection_method on the Subscription object which defaults to charge_automatically. This is what I want because the customer is on-session and so the Invoice being null probably makes sense, but how do I get the client secret to pass back to the frontend? The SetupIntent object returned by the subscription response exposes a client secret, but that object is null too.
Subscription Invoices will use whichever of these three payment options are available (in order of preference):
The Subscription's default_payment_method (reference) or default_source (reference)
The Customer's invoice_settings.default_payment_method (reference)
The Customer's default_source (note: there is no concept of a default PaymentMethod on Customers)
Also worth noting is that PaymentMethods and Sources are two distinct resources. Cards (objects with ids prefixed with card_) can be used as either type.
I have dynamodb table structure as follows:
{
"id": "1",
"skills": {
"skill1": "html",
"skill2": "css"
}
}
I have task to filter by skills value, In order to complete my task wrote java logic as follows:
AmazonDynamoDB client = dynamoDBService.getClient();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable("dummy");
Map<String, String> attributeNames = new HashMap<String, String >();
attributeNames.put("#columnValue", "skills.skill1");
Map<String, AttributeValue> attributeValues = new HashMap<String, AttributeValue>();
attributeValues.put(":val1", new AttributeValue().withS("html"));
ScanSpec scanSpec = new ScanSpec().withProjectionExpression("skills.skill1")
.withFilterExpression("#columnValue = :val1 ").withNameMap(new NameMap().with("#columnValue", "skills.skill1"))
.withValueMap(new ValueMap().withString(":val1", "html"));
ItemCollection<ScanOutcome> items = table.scan(scanSpec);
Iterator<Item> iter = items.iterator();
while (iter.hasNext()) {
Item item = iter.next();
System.out.println("--------"+item.toString());
}
The mentioned code does not help me out. Any solution ?
You can use a ProjectionExpression to retrieve only specific attributes or elements, rather than an entire item. A ProjectionExpression can specify top-level or nested attributes, using document paths.
for example from AWS:
GetItemSpec spec = new GetItemSpec()
.withPrimaryKey("Id", 206)
.withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
.withConsistentRead(true);
Item item = table.getItem(spec);
System.out.println(item.toJSONPretty());
Simple solution to this problem is:
First fetch all the records from the table.
Then iterate over the list of that object.
Extract the skills from each object.
Wrote your logic to do filtering.
Repeat the loop till the last record.
I found solution,scanSpec should be as follows:
ScanSpec scanSpec = new ScanSpec()
.withFilterExpression("#category.#uid = :categoryuid").withNameMap(new NameMap().with("#category","skills").with("#uid",queryString))
.withValueMap(new ValueMap().withString(":categoryuid", queryString));
I created a table in Amazon dynamodb with primary key Issue(String) which has data stored in it.I want to read the values from my table. I'm using the following code..
#DynamoDBTable(tableName="Incident")
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient();
String tableName = "Incident";
Table table = dynamoDBClient.getTable("Incident");
Item getItem=dynamoDBClient.getItem();
I'm getting an error when calling the getTable method.... is it a predefined method just like createTable() or do we need to write our own..if so how?
And also what method should be used to read all items in the table..?
I used this link to write some of the code... http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/JavaDocumentAPIItemCRUD.html#JavaDocumentAPIGetItem
I'm new to Java please help..
Scan API can be used to get all the items from the table.
The scan should be done until LastEvaluatedKey is not null which is very important to get all the items. Otherwise, you will not get all the items if the table has many items i.e. the API will return 1 MB of data per scan.
A Scan operation performs eventually consistent reads by default, and
it can return up to 1 MB (one page) of data.
Scan API
Map<String, AttributeValue> lastKeyEvaluated = null;
do {
ScanRequest scanRequest = new ScanRequest()
.withTableName("ProductCatalog")
.withLimit(10)
.withExclusiveStartKey(lastKeyEvaluated);
ScanResult result = client.scan(scanRequest);
for (Map<String, AttributeValue> item : result.getItems()){
printItem(item);
}
lastKeyEvaluated = result.getLastEvaluatedKey();
} while (lastKeyEvaluated != null);
Here is example how to read data using Scan API :
#Override
protected ArrayList<String> doInBackground(String... params) {
String tableName = params[0];
ArrayList<String> tempList = new ArrayList<String>();
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient (
new BasicAWSCredentials(Constants.ACCESS_KEY_ID,
Constants.SECRET_KEY));
ScanRequest scanRequest = new ScanRequest()
.withTableName(tableName);
//.withAttributesToGet("name");
com.amazonaws.services.dynamodb.model.ScanResult result = dynamoDBClient.scan(scanRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
tempList.add(item.toString());
//analizeItem(tempList, item);
}
return tempList;
}
Reference from programcreeks
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withRegion(Regions.AP_SOUTH_1).build();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable("Student");
Item item = table.getItem("PK", "portion Key","SK","Sort Key");
System.out.println(item.toJSONPretty());
I have a JSON document stored in an attribute called doc that looks something like this:
{
doc:
{
"foo":
{
"bar": "baz"
}
}
}
I'd like to be able to do a table scan and filter/search on data.foo.bar == "baz". I'm using the Java SDK and have tried the following code but it doesn't seem to work for a sub-map of a document:
String filterExpression = "#d.#f.#b = :val";
Map<String, String> nameMap = new HashMap();
nameMap.put("#d", "doc");
nameMap.put("#f", "foo");
nameMap.put("#b", "bar");
Map valueMap = new HashMap();
valueMap.put(":val", "baz");
ItemCollection<ScanOutcome> items = table.scan(
new ScanSpec()
.withFilterExpression(filterExpression)
.withNameMap(nameMap)
.withValueMap(valueMap));
EDIT - I have found that this works:
String filterExpression = "#d.foo.bar = :val";
Where I only have a single ExpressionAttributeNames for the first attribute it works. Any thoughts why it doesn't work with 3 ExpressionAttributeNames? What if by some chance I needed 3, i.e. they were reserved words?
Any help or suggestions greatly appreciated. Thanks.