DynamoDB Query expression on partitionKey - amazon-dynamodb

i have one AmazonDynamoDB whose hashKey is: "userId" and rangeKey is: "timestamp".
I am writing one query for fetching up all records related to particular userId.
String keyConditionExpression = "userId = :userId";
HashMap<String, AttributeValue> attributeValuesMap = new HashMap<>();
attributeValuesMap.put(":userId", new AttributeValue().withS("someId"));
DynamoDBQueryExpression<MyTableItem> queryExpression =
new DynamoDBQueryExpression<MyTableItem>()
.withKeyConditionExpression(keyConditionExpression)
.withExpressionAttributeValues(attributeValuesMap)
.withConsistentRead(false);
dynamoDBMapper.queryPage(MyTableItem.class, queryExpression);
this query operation is failing, but not able to see, why it's failing.
As given here, this should come under query criteria.
Any help would be really appreciated. Thanks.

I have tested the code and it runs as expected, returning the correct results. Is userId your tables Partition Key?
Can you share which error you are getting, that will help to recommend a solution.
DynamoDBMapper mapper = new DynamoDBMapper(client);
String keyConditionExpression = "userId = :userId";
HashMap<String, AttributeValue> attributeValuesMap = new HashMap<>();
attributeValuesMap.put(":userId", new AttributeValue().withS("leeroy"));
DynamoDBQueryExpression<BillingDashboardRecord> queryExpression =
new DynamoDBQueryExpression<BillingDashboardRecord>()
.withKeyConditionExpression(keyConditionExpression)
.withExpressionAttributeValues(attributeValuesMap)
.withConsistentRead(false);
try{
mapper.queryPage(BillingDashboardRecord.class, queryExpression);
}catch (Exception e){
System.out.println(e.getMessage());
}

Related

What is a BindAsync method with two params in the IBinding interface

In the Azure WebJobs SDK, we have the IBinding interface. This interface has a method BindAsync with two params, but I can't understand what is the first param object value and when this overload method will be called.
The same question related ITriggerBinding interface.
I have tried to find the answer in the SDK code source. I know that BindingSource contains a dictionary of parameters where the key is an argument name and value is an argument value that will be provided to the BindAsync method, but I cannot understand what these arguments are and where they come from?
UPDATE
IBinding.BindAsync Method Returns Task<IValueProvider>.
The usage of IBinding.BindAsync.
Microsoft.Azure.WebJobs.Host.Bindings.IBinding.BindAsync(Microsoft.Azure.WebJobs.Host.Bindings.BindingContext)
Sample Code
public async Task BindAsync_String()
{
ParameterInfo parameterInfo = GetType().GetMethod("TestStringFunction").GetParameters()[0];
HttpTriggerAttributeBindingProvider.HttpTriggerBinding binding = new HttpTriggerAttributeBindingProvider.HttpTriggerBinding(new HttpTriggerAttribute(), parameterInfo, false);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://functions/myfunc?code=abc123");
request.Content = new StringContent("This is a test");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/text");
FunctionBindingContext functionContext = new FunctionBindingContext(Guid.NewGuid(), CancellationToken.None, new TestTraceWriter(TraceLevel.Verbose));
ValueBindingContext context = new ValueBindingContext(functionContext, CancellationToken.None);
ITriggerData triggerData = await binding.BindAsync(request, context);
Assert.Equal(0, triggerData.BindingData.Count);
string result = (string)triggerData.ValueProvider.GetValue();
Assert.Equal("This is a test", result);
}
From sample code(HttpTrigger), you will find request, context. They are two params in BindAsync. You will know the usage of BindAsync.

Get value from dictionary based on key throws error - syncfusion schedule

In my ASP.NET (c#) application using syncfusion schedule, I am trying to get a value from a dictionary based on the key.
When I try to do that I get this error message:
System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the dictionary.
This line of code (where I try to get the value of key 'Subject' and assign it to variable sSubject) throws the error:
string sSubject = list["Subject"].ToString();
Code:
public Dictionary<string, object> Arguments { get; set; }
protected void Schedule1_ServerAppointmentEdited(object sender, Syncfusion.JavaScript.Web.ScheduleEventArgs e)
{
Arguments = e.Arguments["appointment"] as Dictionary<string, object>;
dynamic list = Arguments as Dictionary<string, object>;
string sSubject = list["Subject"].ToString();
}
If I debug my code to look what's in my dictionary, I do see that key 'Subject' is present:
What am I doing wrong? How can I get value 'test subject' from key 'subject'?
Project: http://www.syncfusion.com/downloads/support/forum/119417/ze/ScheduleCRUDWithWebServices-728709208
Documentation: https://www.syncfusion.com/kb/5182/how-to-perform-the-crud-operation-in-the-schedule-control-with-webservices-datasource
Thank you
Your dictionary is inside a list, namely the 2nd element. You should access it as follows:
string sSubject = list[1]["Subject"].ToString();
This is how I finally retrieved the value of key 'subject':
Arguments = e.Arguments["appointment"] as Dictionary<string, object>;
//dynamic list = Arguments as Dictionary<string, object>;
System.Collections.ArrayList list2 = (System.Collections.ArrayList)Arguments["changed"];
Dictionary<string, object> dic = (Dictionary<string,object>)list2[0];
string sSubject2 = dic["Subject"].ToString();
Usually the server-side arguments will receive only the appointment details while performing the edit action. Can you share the details on which particular scenario, you are getting the arguments with “added” and “changed” options as depicted in your screenshot.
Regards,
Dharani

2sxc - Get EntityId or EntityGuid of newly created object inside custom api controller

For adding new entity inside my custom API I use code like this:
var tagGroup = new Dictionary<string, object>();
tagGroup.Add("Title", "Some new tagGroup name");
App.Data.Create("TagGroup", tagGroup, "WebApiUser");
This work fine if I just need to add new entity, but If I need to do more operations and in this opetarions I need to use Id or Guid of this newly created entity I don't know how to get it.
One way is to get this new entity by its title back, but If this title is not unique I don't know how?
I try with this code:
dynamic obj1 = App.Data.Create("TagGroup", tagGroup, "Web Api User");
// or
var obj2 = App.Data.Create("TagGroup", tagGroup, "Web Api User");
But get error becouse function don't return any value.. Is there any other way how to make this work?
Is posible to define guid of new entity in advance like for IsPublished?
====================
Solution 1:
var tGuid = System.Guid.NewGuid().ToString();
tagGroup.Add("EntityGuid", tGuid);
and work OK
I am OK with solution to set EntityGuid in custom api controller to get new EntityId
var tGuid = System.Guid.NewGuid();
var tagGroup = new Dictionary<string, object>();
tagGroup.Add("Title", "Some new tagGroup name");
tagGroup.Add("EntityGuid", tGuid);
App.Data.Create("TagGroup", tagGroup, "WebApiUser");
var tNewObj =AsDynamic(App.Data["TagGroup"]).Where(x=>x.EntityGuid==tGuid).First();
var tNewEntityId = tNewObj.EntityId;
// do whatewer you want with this entity..
This is my final code...
Update: 2sxc now has this functionality. .Create() now returns the newly created Entity...
In 2sxc, after an App.Data.Create(), is there a way to get the new EntityId (or Guid) or a Pointer to the new Entity?

ExecuteStoredProcedureAsync running it across partition keys

I need to have one stored procedure which I need to run on different partition keys. My collection is partitioned on one key entityname and I want to execute the stored procecure on each entity in the partition.
sproc = await client.CreateStoredProcedureAsync(collectionLink, sproc,
new RequestOptions { PartitionKey = new PartitionKey(partitionkey) });
StoredProcedureResponse<int> scriptResult = await client.ExecuteStoredProcedureAsync<int>(
sproc.SelfLink,
new RequestOptions { PartitionKey = new PartitionKey(partitionkey) },
args);
I get the following exception:
Requests originating from scripts cannot reference partition keys other than the one for which client request was submitted
Is it necessary to create a stored procedure in each partition based on key?
Is it possible to have one stored procedure which can execute for all keys?
When stored procedure is executed from client, RequestOptions specify the partition key, stored procedure will run in context of this partition and cannot operate (e.g. create) on docs that have different partition key value.
What you can do is to execute the sproc from client for each partition key. For instance, if sproc is to bulk-create documents, you can group the docs by partition key and send each group (can be done in parallel) to the sproc providing partition key value in RequestOptions. Would that be helpful?
You don't have to create sproc for each partition key, just create once without providing partition key.
I have developed the above in Java.
There are differences in how we implement while using Java SDK and stored procedure.
Please note the use of 'string' and the need to separate records based on partition key.
Bulk Import Store Procedure used: https://learn.microsoft.com/en-us/azure/documentdb/documentdb-programming
Below is the client calling the store procedure
public void CallStoredProcedure(Map <String, List<String>> finalMap)
{
for ( String key : finalMap.keySet() ) {
try
{
ExecuteStoredProcedure(finalMap.get(key),key);
}
catch(Exception ex)
{
LOG.info(ex.getMessage());
}
}
}
public void ExecuteStoredProcedure(List<String> documents, String partitionKey)
{
try {
if (documentClient == null) {
documentClient = new DocumentClient(documentDBHostUrl, documentDBAccessKey, null, ConsistencyLevel.Session);
}
options = new RequestOptions();
options.setPartitionKey(new PartitionKey(partitionKey));
Object[] sprocsParams = new Object[2] ;
sprocsParams[0] = documents;
sprocsParams[1] = null;
StoredProcedureResponse rs = documentClient.executeStoredProcedure(selflink, options, sprocsParams);
} catch (Exception ex) {
}
}

passing parameters to json web service using HttpWebRequest

I am having a problem in passing parameters to webservice which except POST data in JSON. I am using HttpWebRequest for this, following is the code i have tried so far, but everytime server returns any of these two errors:
Error 1:
{"command":null,"handle":null,"code":2003,"msg":"Required parameter missing","error":["Parameter 'login_handle' missing.","Parameter 'login_pass' missing."],"params":{"0":{"Key":"login_handle","Value":"test"},"1":{"Key":"login_pass","Value":"test"},"handle":"example.com"},"svTRID":null,"response":[]}
Error 2:
{"command":null,"handle":null,"code":2400,"msg":"Command failed","error":["Internal Server Error. resulted in the following error: array_key_exists() [<a href='function.array-key-exists'>function.array-key-exists<\/a>]: The second argument should be either an array or an object"],"params":[],"svTRID":null,"response":[],"children":[{"command":"Internal Server Error.","handle":null,"code":2400,"msg":"Command failed","error":["array_key_exists() [<a href='function.array-key-exists'>function.array-key-exists<\/a>]: The second argument should be either an array or an object"],"params":{"errno":2,"errstr":"array_key_exists() [<a href='function.array-key-exists'>function.array-key-exists<\/a>]: The second argument should be either an array or an object","errfile":"\/home\/ote\/httpapi\/v1\/index.php","errline":54},"svTRID":null,"response":[]}]}
Here is the code:
try
{
ASCIIEncoding encoding = new ASCIIEncoding();
Dictionary<string, string> data = new Dictionary<string, string>();
data["login_handle"] = "test";
data["login_pass"] = "test";
System.Net.WebRequest webReq = System.Net.WebRequest.Create(url);
webReq.Method = "POST";
webReq.ContentType = "application/json; charset=utf-8";
DataContractJsonSerializer ser = new DataContractJsonSerializer(data.GetType());
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, data);
String json = Encoding.UTF8.GetString(ms.ToArray());
StreamWriter writer = new StreamWriter(webReq.GetRequestStream());
writer.Write(json);
writer.Close();
System.Net.WebResponse webResp = webReq.GetResponse();
System.IO.StreamReader sr = new System.IO.StreamReader(webResp.GetResponseStream());
string s = sr.ReadToEnd().Trim();
}
catch (Exception ex)
{
string e = ex.Message;
}
If i use string data = "[login_handle:'username',login_pass:'password']"; instead of Dictionary<string, string> , i receive error number 2.
Never mind, i solved it myself, instead of using Dictionary type i used anonymous type like this var data = new { login_handle = "test", login_pass = "test" }; and it solved my problem.
What you should have done is create a DataContract class (we'll call JsonData) which has two DataMembers named login_handle and login_pass.
Then, in the DataContractJsonSerializer, pass typeof(JsonData) to the constructor.
This solution is the best because you cannot create complex types using an anonymous type. Also, by parenting your DataContracts you can easily create complex JSON.

Resources