AWS crc32 mismatch dynamo - android

I am trying to request some entries from AWS DynamoDB from an App in Android Studio. I am getting a CRC32 mismatch for a scanResult. Does anyone know why this is happening. attaching snippet and stack trace below.
credentials = new CognitoCachingCredentialsProvider(
MapValidate.getContext(), // Context
“FILLED_MY_ID_HERE", // Identity Pool ID
Regions.US_EAST_1 // Region
);
AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient(credentials);
Region usEast1 = Region.getRegion(Regions.US_EAST_1);
dynamoDB.setRegion(usEast1);
HashMap<String,Condition> scanFilter = new HashMap<String,Condition>();
Condition condition1lat = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS(user_lat));
scanFilter.put("DegLat", condition1lat);
ScanRequest scanRequest = new ScanRequest()
.withTableName("MY_TABLE_NAME")
.withAttributesToGet("DegLat","DegLong","Latitude")
.withScanFilter(scanFilter);
ScanResult result = dynamoDB.scan(scanRequest);
I am getting the following exception as below:
04-28 19:34:03.729 4744-4793/com.google.sample I/AmazonHttpClient﹕
Unable to execute HTTP request:
Client calculated crc32 checksum didn't match that calculated by server side

CRC checksum errors may be caused by requesting compression in the request header.
If you have not already done this, please try the following with ClientConfiguration:
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.withGzip(ClientConfiguration.DEFAULT_USE_GZIP /*false*/);

Update: I just resolved the issue. It is a problem with the sdk-2.2.0 . Upgraded to the latest version of 2.2.1 released a few days ago resolved the issue.

The Android SDK actually does not support ClientConfiguration.DEFAULT_USE_GIP... It does try to take this into consideration thought if you look at the HttpRequestFactory class https://github.com/aws/aws-sdk-android/blob/4de3a3146d66d9ab5684eb5e71d5a2cef9f4dec9/aws-android-sdk-core/src/main/java/com/amazonaws/http/HttpRequestFactory.java If you have not explicitly set an Accept-Encoding, then the sdk will turn off compression by default. If however you DID explicitly set it, you could be running in to compression problems.
Let me know if this does not solve your problem.
Thanks,
Weston

Related

PJSUA2: Error creating SDP answer: SRTP crypto attribute required

I'm trying to use the latest version of pjsip for android
https://github.com/VoiSmart/pjsip-android.
And got an error for incoming call:
Error creating SDP answer: SRTP crypto attribute required (PJMEDIA_SRTP_ESDPREQCRYPTO) [status=220228]
inv0x78653290a8 .Sending Response msg 406/INVITE/cseq=47488686 (tdta0x78bfbcf0a8)
Account configuration for use srtp
SrtpOpt opt = new SrtpOpt();
IntVector optVector = new IntVector();
optVector.add(pjmedia_srtp_keying_method.PJMEDIA_SRTP_KEYING_DTLS_SRTP);
optVector.add(pjmedia_srtp_keying_method.PJMEDIA_SRTP_KEYING_SDES);
opt.setKeyings(optVector);
accCfg.getMediaConfig().setSrtpOpt(opt);
accCfg.getMediaConfig().setSrtpUse(pjmedia_srtp_use.PJMEDIA_SRTP_OPTIONAL);
accCfg.getMediaConfig().setRtcpMuxEnabled(true);
accCfg.getMediaConfig().setSrtpSecureSignaling(0);
Looks like that missed a=crypto: attribute in sdp, but I don't understand how to include it.
However, old version that we used before - works and I don't understand the reason.
And I think if error in creating SDP answer then maybe problem is in incoming sdp.
Is it client or server problem?
Please, help me resolve it.
It was a server problem.
Works well after upgrade server and add a=crypto attribute into SDP.

gRPC Android Client losing connection "too many pings"

Android grpc client is receiving GOAWAY from server with "too many pings" error. Now I realise that this is probably a server side issue, but I think the issue is that the client channel settings do not match that of the servers.
I have a C# gRPC server with the following settings:
List<ChannelOption> channelOptions = new List<ChannelOption>();
channelOptions.Add(new
ChannelOption("GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS",
1000));
channelOptions.Add(new
ChannelOption("GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA", 0));
channelOptions.Add(new
ChannelOption("GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS", 1));
this.server = new Server(channelOptions) {
Services = { TerminalService.BindService(this) },
Ports = {new ServerPort("0.0.0.0", 5000,
ServerCredentials.Insecure)}
};
On Android I have the following channel setup:
private val channel = ManagedChannelBuilder.forAddress(name, port)
.usePlaintext()
.keepAliveTime(10, TimeUnit.SECONDS)
.keepAliveWithoutCalls(true)
.build()
After a few min (however seems to be a random time). I get the goaway error. I noticed that if I stream data on the call then the error never happens. It is only when there is no data on the stream. This leads me to believe the issue is that the GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA needs to be set on the Android client aswell. Problem is for the life of me I cannot find where to set these channel settings on gRPC java. Can someone point out to me where I can set these channel settings? There are no examples where these have been set.
The channel options being specified are using the wrong names. Names like GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA are the C-defines for things like "grpc.http2.max_pings_without_data".
You can map from the C name to the key string by looking at grpc_types.h. You should prefer using one of the C# constants in ChannelOptions when it is available, but that doesn't seem to be an option in this case.
These options are not visible in the Java ManagedChannelBuilder API because they are server-specific settings. So instead they are visible on the ServerBuilder. See A8 client-side keepalive for reference to the Java keepalive API.

AWS DynamoDB Scan failing on iOS but works on Android

I am using DynamoDB as back-end database for my mobile app, and the schema etc are identical across Android & iOS. For a particular use-case, I have to perform a Scan, based on two attributes which are not indexed. For iOS Objective C, I am using the following code:
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
scanExpression.limit = [NSNumber numberWithInt:maxCount];
scanExpression.filterExpression = #"#l = :location AND event = :event";
scanExpression.expressionAttributeNames = #{#"#l":#"location"};
scanExpression.expressionAttributeValues = #{#":location":location,
#":event":EVENT_TASTING};
Both location and event are Strings. EVENT_TASTING is a String constant. This scan keeps returning zero results, even though I have validated that for the provided entries I should be receiving the results. I use the following code in Android Java:
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
scanExpression.setLimit(maxCount);
scanExpression.addFilterCondition("location",
new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withS(location)));
scanExpression.addFilterCondition("event",
new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withS(Constants.EVENT_TASTING)));
The scan works as expected in Android. What needs to change in iOS to make it work there too? I updated iOS SDK to 2.3.6 but it has not made a difference. This is the only scan operation I am doing in my code.
Is there an error in my scanExpression for iOS? Is there a way I can use the Android-style syntax to make this work on iOS?
Update
I tried the following changes:
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
AWSDynamoDBAttributeValue *locationVal = [AWSDynamoDBAttributeValue new];
locationVal.S = location;
AWSDynamoDBAttributeValue *eventVal = [AWSDynamoDBAttributeValue new];
eventVal.S = EVENT_TASTING;
scanExpression.limit = [NSNumber numberWithInt:maxCount];
scanExpression.filterExpression = #"#l = :location AND event = :event";
scanExpression.expressionAttributeNames = #{#"#l":#"location"};
scanExpression.expressionAttributeValues = #{#":location":locationVal,
#":event":eventVal};
But now I am getting an error:
The request failed. Error: [Error Domain=com.amazonaws.AWSDynamoDBErrorDomain Code=0 "(null)" UserInfo={message=ExpressionAttributeValues contains invalid value: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes for key :location, __type=com.amazon.coral.validate#ValidationException}]
Thanks to the hint from #YosukeMatsuda, I was able to fix this by calling Scan repeatedly until LastEvaluatedKey is empty. I am posting this as answer because unfortunately Mike's answer is not pointing out the correct issue and is misleading.
Here's how I changed the code in iOS:
// In a different method (for first call):
AWSDynamoDBScanExpression *scanExpression = // See code in original question
// In a new method that can be called recursively:
// DynamoDBObjectMapper scan:class-for-model expression:scanExpression
// continueWithBlock -> if (task.result):
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
if (paginatedOutput.items.count != 0)
// Append the paginatedOutput.items to the cumulative array
else
// Replace the cumulative array with paginatedOutput.items
if (paginatedOutput.lastEvaluatedKey.count == 0) {
// Scan is complete - handle results
} else {
// Check if you have sufficient results
// In my case I had asked for 25 results but was getting 39
// So it doesn't seem to obey the scanExpression.limit value
// If more results are needed, continue the scan
[scanExpression setExclusiveStartKey:paginatedOutput.lastEvaluatedKey];
// Call this method recursively
}
If there is a more elegant solution I'd love to hear it. But at least it works now.
There are several differences between the Android code you're using and the ObjectiveC version.
in the Android Version you're using the older Filter Condition API while in the ObjectiveC you're using the more modern Filter Expression API; this doesn't necessarily make the newer one fail but it's just something to point out
in the case of ExpressionAttributeValues, the values for location and event that you're passing in should be of type AWSDynamoDBAttributeValue *, not strings; if you make this change your query will most likely start working.
I hope this answers your question but can't be certain because you only say "this works as expected in Android - how can I make it work in iOS" but you're not telling us what's broken.

How to set android backend minSdk

im working on an android app with some server-side business logic. Im using android studio and im creating that kind of app for a first time.
I am trying to use server-side application to login to a different system and return me a cookie, so my android application can tell, whether the set credentials are correct.
Here's my endpoint provided method.
/** Returns user with cookie set either to null or actual cookie from AIS */
#ApiMethod(name = "login")
public User login(#Named("loginName") String name, #Named("password") String password) {
AISCommunicator aisCommunicator = new AISCommunicator();
String cookieVal = aisCommunicator.login(password,name);
User user = new User();
user.setCookie(cookieVal);
//user.setCookie("asdasdasd");
return user;
}
AISCommunicator is a serverside bean. At the moment it's part of a code
CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
is marked as incorrect by Android studio, which tells me, that to use it, i need to declare minSdk level 9, while currently i have 1. How can i do that? I have set minSdk in my client's app, but it seems like it does not influence the serverside bean.
Anyway, the code is still runnable for some reason and the endpoint Bean returns 404 not found error at the moment.
Ignore Android Studio's error. This is one of its known and unfixed bugs.

Google Spreadsheet API - Java - com.google.gdata.util.ParseException: Unrecognized content type:application/binary

I am using Google Spreadsheet API in my simple Android application. This is the piece of code:
URL spreadSheetUrl = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
SpreadsheetQuery query = new SpreadsheetQuery(spreadSheetUrl);
query.setTitleQuery("xyz");
query.setTitleExact(true);
SpreadsheetFeed spreadSheetFeed = service.getFeed(query, SpreadsheetFeed.class);
This piece of code is called from my application's sync adapter.
I am getting this error:
com.google.gdata.util.ParseException: Unrecognized content type:application/binary
com.google.gdata.client.Service.parseResponseData(Service.java:2136)
com.google.gdata.client.Service.parseResponseData(Service.java:2098)
com.google.gdata.client.Service.getFeed(Service.java:1136)
com.google.gdata.client.Service.getFeed(Service.java:1077)
com.google.gdata.client.GoogleService.getFeed(GoogleService.java:676)
com.google.gdata.client.Service.getFeed(Service.java:1034)
Can someone suggest how I can solve this issue?
It turns out that I did not set the user credentials before executing this piece of code.
service.setUserCredentials(user, password);
Adding this line helped solve this issue. Weird.

Categories

Resources