can not mapping entity when using AWS DynamoDB - amazon-web-services

I am begin with dynamoDB. I using annotion mapping enity follow :
#DynamoDBTable(tableName = "ProductCatalogz")
public static class Book {
private int id;+
private String title;+
private String ISBN;+
private Set<String> bookAuthors;+
// private DimensionType dimensionType;
#DynamoDBHashKey(attributeName = "Id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#DynamoDBAttribute(attributeName = "Title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#DynamoDBAttribute(attributeName = "ISBN")
public String getISBN() {
return ISBN;
}
public void setISBN(String ISBN) {
this.ISBN = ISBN;
}
}
and
public static void main(String[] args) throws IOException {
AWSCredentials credentials = new PropertiesCredentials(
Tester2.class.getResourceAsStream("/AwsCredentials.properties"));
client = new AmazonDynamoDBClient(credentials);
Region usWest2 = Region.getRegion(Regions.US_EAST_1);
client.setRegion(usWest2);
Book book = new Book();
book.setId(1);
book.setTitle("Book 502");
book.setISBN("5555555555555");
book.setBookAuthors(new HashSet<String>(Arrays.asList("Author1",
"Author2")));
// book.setDimensions(dimType);
DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(book);
}
But when I run this error :
Exception in thread "main" ResourceNotFoundException: Status Code: 400, AWS Service: AmazonDynamoDBv2, AWS Request ID: NSG3K0BQOBCPNQONE8, AWS Error Code: ResourceNotFoundException, AWS Error Message: Requested resource not found
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:644)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:338)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:190)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:1245)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:1026)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:636)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:483)
at test.Tester2.main(Tester2.java:47)
please help me

The message Requested resource not found means that Dynamo DB table is not found. You should create it first through AWS console, API, or CLI.

Ensure that you have set the endpoint on the client
BasicAWSCredentials b = new BasicAWSCredentials("Access Key ID","Secret Access Key");
AmazonDynamoDBClient client = new AmazonDynamoDBClient(b);
client.setEndpoint("dynamodb.ap-northeast-1.amazonaws.com");
Refer http://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region for the complete list of End Points for DynamoDB

Related

Lambda Error: #DynamoDBIndexHashKey must specify one of HASH GSI name/names

I have the following class:
#DynamoDBTable(tableName = "PodcastReviewService-Episodes")
public class Episode {
private String podcast;
private int episodeNr;
private String name;
private int avgRating;
private String episodeId;
private List<Review> reviews;
public Episode() {}
#DynamoDBIndexHashKey(attributeName = "podcast")
public String getPodcast() {return podcast;}
#DynamoDBRangeKey(attributeName = "episodeNr")
public int getEpisodeNr() {return episodeNr;}
#DynamoDBAttribute(attributeName = "name")
public String getName() {
return name;
}
#DynamoDBIndexHashKey(attributeName = "avgRating", globalSecondaryIndexName = "avgRating")
public int getAvgRating() {
return avgRating;
}
#DynamoDBIndexRangeKey(attributeName = "episodeId", globalSecondaryIndexName = "episodeId")
public String getEpisodeId() {
return episodeId;
}
#DynamoDBAttribute(attributeName = "reviews")
public List<Review> getReviews() {
return reviews;
}
The class that attempts to add an object Episode to my DynamoDB table is :
public class EpisodeDao {
private final DynamoDBMapper dynamoDBMapper;
public EpisodeDao() {
this.dynamoDBMapper = new DynamoDBMapper(AmazonDynamoDBClientBuilder.standard().withCredentials(DefaultAWSCredentialsProviderChain.getInstance()).withRegion(Regions.US_WEST_2).build());
}
public Episode getEpisode(String podcast, int episodeNr) {
Episode episode = this.dynamoDBMapper.load(Episode.class, podcast, episodeNr);
if (episode == null) {
throw new EpisodeNotFoundException("Could not find episode of " + podcast + " nr." + episodeNr);
}
return episode;
}
public Episode saveEpisode(String podcast, String name, int episodeNr) {
Episode episode = new Episode();
//Check if episode already exists, if so return an DuplicateEpisodeException
//We initialize average rating at 0 since no reviews have been submitted
if (getEpisode(podcast, episodeNr) == null) {
episode.setPodcast(podcast);
episode.setName(name);
episode.setEpisodeNr(episodeNr);
episode.setEpisodeId(podcast.charAt(0) + name.charAt(0) + PodcastReviewsUtils.generateRandomID());
episode.setAvgRating(0);
episode.setReviews(new ArrayList<>());
} else throw new DuplicateEpisodeException("The episode that you are trying to add seems to already exist.");
return episode;
}
This is the output I get on Lambda:
"errorMessage": "#DynamoDBIndexHashKey must specify one of HASH GSI name/names",
"errorType": "com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException",
"stackTrace": [
"com.amazonaws.services.dynamodbv2.datamodeling.StandardAnnotationMaps$FieldMap.globalSecondaryIndexNames(StandardAnnotationMaps.java:345)",
"com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel$Properties$Immutable.<init>(DynamoDBMapperFieldModel.java:459)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$Bean.<init>(StandardBeanProperties.java:92)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$Bean.<init>(StandardBeanProperties.java:86)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$BeanMap.putOrFlatten(StandardBeanProperties.java:217)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$BeanMap.putAll(StandardBeanProperties.java:207)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$BeanMap.<init>(StandardBeanProperties.java:198)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$CachedBeans.getBeans(StandardBeanProperties.java:55)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$CachedBeans.access$100(StandardBeanProperties.java:48)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties.of(StandardBeanProperties.java:42)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:132)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:116)",
"com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$StandardTableFactory.getTable(StandardModelFactories.java:107)",
"com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:409)",
"com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.load(DynamoDBMapper.java:447)",
"com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.load(AbstractDynamoDBMapper.java:85)",
"com.podcast_reviews_service.dynamodb.EpisodeDao.getEpisode(EpisodeDao.java:35)",
"com.podcast_reviews_service.dynamodb.EpisodeDao.saveEpisode(EpisodeDao.java:50)",
"com.podcast_reviews_service.activity.AddEpisodeActivity.handleRequest(AddEpisodeActivity.java:35)",
"java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
"java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)",
"java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)",
"java.base/java.lang.reflect.Method.invoke(Unknown Source)"
]
I haven't yet implemented the class that utilizes the GSI. I tried without the secondary index annotation but since my table has them I get the same error.
The error makes me think that I either annotated the Episode class wrong or I'm sending a null value as HASH key for the GSI, which I'm pretty sure I'm not.
You must define the name of your index for the indexhashkey.
#DynamoDBIndexHashKey(attributeName = "podcast",globalSecondaryIndexNames={ "my-index-name"})
public String getPodcast() {return podcast;}

How to Solve Argument 2: cannot convert from 'Amazon.DynamoDBv2.DataModel.DynamoDBOperationConfig' to 'Amazon.DynamoDBv2.AmazonDynamoDBCallback'

I am working in DyanmoDB.In My project i have to dynamically set the database name and i have to load the database dynamically. This is my code
using UnityEngine;
using System.Collections;
using Amazon.DynamoDBv2.DataModel;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
using Amazon.DynamoDBv2;
using UnityEngine.UI;
using Amazon;
namespace AWSSDK.Examples
{
public class HighLevel3 : DynamoDbBaseExample
{
private IAmazonDynamoDB _client;
private DynamoDBContext _context;
public Text resultText;
public Button back;
public Button createOperation;
public Button updateOperation;
public Button deleteOperation;
public string S_tablefieldset;
string bookID;
int bookID1 = 9;
public string Email;
private DynamoDBContext Context
{
get
{
if (_context == null)
_context = new DynamoDBContext(_client);
return _context;
}
}
void Awake()
{
back.onClick.AddListener(BackListener);
createOperation.onClick.AddListener(PerformCreateOperation);
_client = Client;
S_tablefieldset = "Orders";
HighLevelTableExample.GetDynamoDbOperationConfig(S_tablefieldset);
}
void Start()
{
bookID = SystemInfo.deviceUniqueIdentifier;
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "Orders");
PerformCreateOperation();
}
public static DynamoDBOperationConfig GetDynamoDbOperationConfig(string dynamoDbTable)
{
Debug.Log("The Table name is " + dynamoDbTable);
var tableName = System.Environment.GetEnvironmentVariable("MONO_REFLECTION_SERIALIZER");
Debug.Log("The Table name is" + tableName);
DynamoDBOperationConfig config = new DynamoDBOperationConfig()
{
// OverrideTableName =
OverrideTableName = tableName
};
return config;
}
public void PerformCreateOperation()
{
Debug.Log(" I am in Perform Create Operation is working fine and good");
Book12 myBook = new Book12
{
OrderID = bookID,
OrderItem = 50,
};
// Save the book.
var tableName = System.Environment.GetEnvironmentVariable("TABLE_NAME");
Context.SaveAsync(myBook, new DynamoDBOperationConfig {
OverrideTableName = tableName });
}
}
public class Book12
{
[DynamoDBHashKey] // Hash key.
public string OrderID { get; set; }
[DynamoDBProperty]
public string UserName { get; set; }
[DynamoDBProperty]
}
}
While doing the above i received the error in
error CS1503: Argument 2: cannot convert from
'Amazon.DynamoDBv2.DataModel.DynamoDBOperationConfig' to
Amazon.DynamoDBv2.AmazonDynamoDBCallback'
How to solve the error.

Amazon Elasticsearch service 403-forbidden error

I am having trouble fetching result from my amazon elastic search cluster using the amazon java SDK and an IAm user credential. Now the issue is that when the PATH string is equal to "/" then I am able to fetch the result correctly but when I try with a different path for e.g "/private-search" then I get a 403 forbidden error. Even when for the path that has public access I am getting a 403 forbidden error for this IAm user but it works if I remove "signer.sign(requestToSign, credentials);" line in performSigningSteps method(for public resource only).
My policy in AWS gives this IAM user access to everything in my elastic search service. And also what can I do to avoid hard-coding the access key and secret key in source code?
private static final String SERVICE_NAME = "es";
private static final String REGION = "region-name";
private static final String HOST = "host-name";
private static final String ENDPOINT_ROOT = "http://" + HOST;
private static final String PATH = "/private-search";
private static final String ENDPOINT = ENDPOINT_ROOT + PATH;
private static String accessKey = "IAmUserAccesskey"
private static String secretKey = "IAmUserSecretkey"
public static void main(String[] args) {
// Generate the request
Request<?> request = generateRequest();
// Perform Signature Version 4 signing
performSigningSteps(request);
// Send the request to the server
sendRequest(request);
}
private static Request<?> generateRequest() {
Request<?> request = new DefaultRequest<Void>(SERVICE_NAME);
request.setContent(new ByteArrayInputStream("".getBytes()));
request.setEndpoint(URI.create(ENDPOINT));
request.setHttpMethod(HttpMethodName.GET);
return request;
}
private static void performSigningSteps(Request<?> requestToSign) {
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(requestToSign.getServiceName());
signer.setRegionName(REGION);
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
signer.sign(requestToSign, credentials);
}
private static void sendRequest(Request<?> request) {
ExecutionContext context = new ExecutionContext();
ClientConfiguration clientConfiguration = new ClientConfiguration();
AmazonHttpClient client = new AmazonHttpClient(clientConfiguration);
MyHttpResponseHandler<Void> responseHandler = new MyHttpResponseHandler<Void>();
MyErrorHandler errorHandler = new MyErrorHandler();
Void response = client.execute(request, responseHandler, errorHandler, context);
}
public static class MyHttpResponseHandler<T> implements HttpResponseHandler<AmazonWebServiceResponse<T>> {
#Override
public AmazonWebServiceResponse<T> handle(com.amazonaws.http.HttpResponse response) throws Exception {
InputStream responseStream = response.getContent();
String responseString = convertStreamToString(responseStream);
System.out.println(responseString);
AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>();
return awsResponse;
}
#Override
public boolean needsConnectionLeftOpen() {
return false;
}
}
public static class MyErrorHandler implements HttpResponseHandler<AmazonServiceException> {
#Override
public AmazonServiceException handle(com.amazonaws.http.HttpResponse response) throws Exception {
System.out.println("In exception handler!");
AmazonServiceException ase = new AmazonServiceException("exception.");
ase.setStatusCode(response.getStatusCode());
ase.setErrorCode(response.getStatusText());
return ase;
}
#Override
public boolean needsConnectionLeftOpen() {
return false;
}
}
public static String convertStreamToString(InputStream is) throws IOException {
// To convert the InputStream to String we use the
// Reader.read(char[] buffer) method. We iterate until the
// Reader return -1 which means there's no more data to
// read. We use the StringWriter class to produce the string.
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
}
finally {
is.close();
}
return writer.toString();
}
return "";
}

Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value:

Hi here is Bussinss object class where pwdId and userId are notnull in db
#Entity
#Table(name="CLOUD_SVR_PASSWORDS_HISTORY")
#NamedQuery(name="CloudSvrPasswordsHistory.findAll", query="SELECT c FROM CloudSvrPasswordsHistory c")
public class CloudSvrPasswordsHistory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name="PWD_ID",nullable=false)
private long pwdId;
#Column(name="OLD_PASSWORD")
private String oldPassword;
#Column(name="CURRENT_PASSWORD")
private String currentPassword;
#Column(name="PWD_CHANGE_TYPE")
private String pwdChangeType;
#Column(name="CREATED_DATE")
private Timestamp createdDate;
#ManyToOne
#JoinColumn(name="USER_ID",nullable=false)
private CloudSvrUser user;
public long getPwdId() {
return pwdId;
}
public void setPwdId(long pwdId) {
this.pwdId = pwdId;
}
public String getOldPassword() {
return oldPassword;
}
public void setOldPassword(String oldPassword) {
this.oldPassword = oldPassword;
}
public String getCurrentPassword() {
return currentPassword;
}
public void setCurrentPassword(String currentPassword) {
this.currentPassword = currentPassword;
}
public String getPwdChangeType() {
return pwdChangeType;
}
public void setPwdChangeType(String pwdChangeType) {
this.pwdChangeType = pwdChangeType;
}
public Timestamp getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Timestamp createdDate) {
this.createdDate = createdDate;
}
public CloudSvrUser getUser() {
return user;
}
public void setUser(CloudSvrUser user) {
this.user = user;
}
here is my service implementation class only one method I am specifyng
#Transactional
public void changePassword(CloudSvrPasswordsHistory pwdInfo)throws BusinessException
{
//String password=null;
try{
System.out.println("servcimpl----------");
CloudSvrUser dbUser =getUser(pwdInfo);
if(dbUser != null){
List<CloudSvrPasswordsHistory> newPwdList = new ArrayList<CloudSvrPasswordsHistory>();
CloudSvrPasswordsHistory changedPwd = new CloudSvrPasswordsHistory();
changedPwd.setOldPassword(pwdInfo.getOldPassword());
changedPwd.setCurrentPassword(pwdInfo.getCurrentPassword());
newPwdList.add(changedPwd);
dbUser.setPassCode(changedPwd.getCurrentPassword());
//set childs to parent
pwdInfo.setUser(dbUser);
dbUser.setUserPwdList(newPwdList);
//password=
changedPwd(dbUser);
System.out.println("serviceimplend---------");
}
}
catch(DaoException daoexception)
{
throw new BusinessException(daoexception.getMessage());
}
//return password;
}
here is my DAOImpl class
#Repository("passwordDao")
public class PasswordDaoImpl extends BaseDaoImpl implements PasswordDao
{
PasswordDaoImpl()
{}
public void ChangedPwd(CloudSvrUser user)
{
//String password=null;
List<CloudSvrPasswordsHistory> pwdinfo = user.getUserPwdList();
for(CloudSvrPasswordsHistory changedPwd:pwdinfo)
{
//changedPwd.setPwdId((new Long(1)));
changedPwd.setCreatedDate(new Timestamp(System.currentTimeMillis()));
changedPwd.setPwdChangeType("ByUser");
}
try{
super.getHibernateTemplate().update(user);
//this.userDao.updateUser(dbUser);
}
catch(DataAccessException accessException){
throw new DaoException("Internal DB error occured.");
}
//return password ;
}
when giving request getting exception in console
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.omnypay.dao.bo.CloudSvrPasswordsHistory.user
please help me
The error says the user property of CloudSvrPasswordsHistory entity is null, where as hibernate is expecting it to be not-null, this is because you told hibernate that nullable=false for user property using this mapping:
#ManyToOne
#JoinColumn(name="USER_ID",nullable=false)
private CloudSvrUser user;
So to fix the issue you have to set the user property for your CloudSvrPasswordsHistory entity as:
changedPwd.setUser(dbUser);

how can i resolve this "Etat HTTP 500 - java.lang.NullPointerException"?

i'm developping a restful web service that extract data (messages) from my database and return all messages!
every single message is a MsgBean ( with an id, contenu, from, numexp,... )
the web service couldn't return a table so i created a new object that contain a table (msgTable) of MsgBean !
while running my web service on the rest console, i got this error :
Etat HTTP 500 - java.lang.NullPointerException
type Rapport d''exception
message java.lang.NullPointerException
description Le serveur a rencontré une erreur interne qui l''a empêché de satisfaire la requête.
Click to see the rest of error
my MsgBean is :
#XmlRootElement
public class MsgBean implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String frommm;
private String contenu;
private String DateEnvoi;
private String NumExp;
private int idu;
public MsgBean(){};
#XmlElement
public int getIdu() {
return idu;
}
public void setIdu(int idu) {
this.idu = idu;
}
#XmlElement
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement
public String getFrommm() {
return frommm;
}
public void setFrommm(String frommm) {
this.frommm = frommm;
}
#XmlElement
public String getContenu() {
return contenu;
}
public void setContenu(String contenu) {
this.contenu = contenu;
}
#XmlElement
public String getDateEnvoi() {
return DateEnvoi;
}
public void setDateEnvoi(String DateEnvoi) {
this.DateEnvoi = DateEnvoi;
}
#XmlElement
public String getNumExp() {
return NumExp;
}
public void setNumExp(String NameExp) {
this.NumExp = NameExp;
}
}
my msgTabl is :
#XmlRootElement
public class msgTabl implements Serializable {
String test;
MsgBean[] m = new MsgBean[100];
public msgTabl(){};
#XmlElement
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
#XmlElement
public MsgBean getM(int i) {
return m[i];
}
public void setM(int i, MsgBean mb) {
this.m[i].setId(mb.getId());
this.m[i].setIdu(mb.getIdu());
this.m[i].setFrommm(mb.getFrommm());
this.m[i].setNumExp(mb.getNumExp());
this.m[i].setDateEnvoi(mb.getDateEnvoi());
this.m[i].setContenu(mb.getContenu());
}
}
and here is the web service that i did test with :
#GET
#Path("/historiquemethod")
#Produces("application/json")
//#Produces("text/plain")
public msgTabl historique(
#QueryParam("pseudo") String pseudo,
#QueryParam("motDePasse") String motDePasse
) {
msgTabl tab = new msgTabl();
MsgBean ms = new MsgBean();
// set information into our msg to test
ms.setContenu("contenu");
ms.setFrommm("8080");
ms.setNumExp("2584126");
ms.setId(1);
ms.setIdu(2);
ms.setDateEnvoi("date");
// set the message into the first table case
tab.setM(0, ms);
tab.setTest("ok");
return tab;
}
In setM method do this in first line :
this.m[i] = new MsgBean();
Problem is that you have instantiated your array but the objects are null inside that array. So you need to first instantiate the object at required index and then use it.
UPDATE FOR COMMENT
Make a getter method for your m like this getM() and annotate it with XmlElement(Remove the annotation from your current overloaded getM(int i) method). The method getM(int i) cannot be used by JAXB, since jaxb needs simple getter and setter for your properties.