AWS Java SDK Error - withPermissionsBoundary for IAM user - java

Using AWS SDK for JAVA, i want to limit access to a single Bucket folder.
When i try to run this code to assign permissions to a new IAM user:
final AmazonIdentityManagement client = AmazonIdentityManagementClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_2)
.build();
try {
String permissionsBoundary =
"{" +
"\"Version\": \"2012-10-17\"," +
" \"Statement\": [" +
" {" +
" \"Effect\": \"Allow\"," +
" \"Action\": "+
" [" +
" \"s3:PutObject\"," +
" \"s3:GetObject\"," +
" \"s3:DeleteObject\"" +
" ]," +
" \"Resource\": \"arn:aws:s3:::mybucket/*\"" +
" }" +
" ]" +
"}";
CreateUserRequest request = new CreateUserRequest()
.withUserName(usernameIAM)
.withPermissionsBoundary(permissionsBoundary);
CreateUserResult response = client.createUser(request);
i get this error:
ARN {"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:ListAllMyBuckets","Resource":"arn:aws:s3:::*"}]} is not valid. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: InvalidInput; Request ID: ...xxxxxxxxxxxx...)[Ljava.lang.StackTraceElement;#2f3a60a1
i followed this
Amazon IAM Policy
what is the correct use of the method withPermissionsBoundary and how is the rule correctly defined?

The error message says the following:
ARN
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
}
]
}
is not valid.
This is clearly not a valid ARN, because it isn't an ARN at all, it is a policy. Where is this used in your code? Wherever it is used, you need to replace it with the correct ARN.

Related

AWS Lambda Java Function is successful but times out

I created a basic AWS Lambda java function to convert an xml message to json. The function is triggered off of an S3 event (message is converted and dropped in different S3 bucket). It appears to be successful, I can see the steps in cloudwatch and the converted message is in the S3 destination bucket. However, I see the timeout warning in the cloud watch logs (set timeout to 15 seconds). I must be missing something, definitely a newby when it comes to Lambda. Do I need to provide the context with a done or success? Any suggestions or tips would be greatly appreciated.
Code Snippet:
public void msgConvertToJson(S3Event s3event, Context context) {
final String key = s3event.getRecords().get(0).getS3().getObject().getKey();
final String bucketName = s3event.getRecords().get(0).getS3().getBucket().getName();
log.info("key: " + key + " bucketName:" + bucketName);
String action = "";
try {
//Attempt to retrieve the message from S3 on notification
log.info("attempting to get message");
action = "get";
final String message = s3Client.getObjectAsString(bucketName, key);
//Attempt to parse and convert the message to JSON
log.info("attempting to parse message");
String msgJson = new MessageParser(message).getMessageJson();
//Attempt to write the converted message to a new S3 bucket
final String parsedBucket = "parsed-" + bucketName;
final String newKey = key.replace(".xml",".json");
log.info("newKey: " + newKey + " parsedBucketName:" + parsedBucket);
log.info("attempting to put message");
action = "put";
s3Client.putObject(parsedBucket, newKey, msgJson );
} catch (AmazonServiceException ase) {
log.error("Caught an AmazonServiceException trying to " + action + " file " + key + ", which " +
"means your request made it " +
"to Amazon S3, but was rejected with an error response" +
" for some reason.");
log.error("Error Message: " + ase.getMessage());
log.error("HTTP Status Code: " + ase.getStatusCode());
log.error("AWS Error Code: " + ase.getErrorCode());
log.error("Error Type: " + ase.getErrorType());
log.error("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
log.error("Caught an AmazonClientException while trying to " + action + " file " + key + ", which " +
"means the client encountered " +
"an internal error while trying to " +
"communicate with S3, " +
"such as not being able to access the network.");
log.error("Error Message: " + ace.getMessage());
}
}
It actually turned out that it was just the timeout was too short. The cold start for the JVM, must be taking longer than I would have thought. I was just assuming I had another issue in my code. Bumped memory to 192 and timeout to 45 seconds. Hope this helps someone else.
Really unfortunate I was marked down by someone that was pointing me at the wrong information (NodeJS) instead of Java.

What is the syntax of Firebase notification

I want to write the firebase notification as a String like JSON format .. I already sent the notification for one device but when trying to send to multiple devices i got bad request ..
params = new StringEntity("{\n" +
" \"to\" : \"ds1YTh...UUZOos\",\n" +
" \"notification\" : {\n" +
" \"body\" : \""+jobTitle+"\",\n" +
" \"title\" : \"New Job!\",\n" +
" \"icon\" : \"hire\"\n" +
" \"sound\" : \"default\"\n"+
" \"time_to_live\" : "+3600+
" }\n" +
" \"data\": {"+
" }"+
" }");
how could i do that .. and if I can't do it this way what is the best way to implement this .. I'm using HttpClient and HttpPost and primefaces 5.3
First a few relevant links:
Sending notifications to multiple devices not subscribed to a certain topic
the Firebase documentation on sending downstream messages
the Firebase documentation on sending to multiple devices (which covers using topics and device groups)
FCM (Firebase Cloud Messaging) Send to multiple devices
But if you want to stick closest to your current code, you should be able to specify the device tokens in a registration_ids property:
params = new StringEntity("{\n" +
" \"registration_ids\" : [\"ds1YTh...UUZOos\", \"et2ZUi...VVUPpt\"],\n" +
" \"notification\" : {\n" +
" \"body\" : \""+jobTitle+"\",\n" +
" \"title\" : \"New Job!\",\n" +
" \"icon\" : \"hire\"\n" +
" \"sound\" : \"default\"\n"+
" \"time_to_live\" : "+3600+
" }\n" +
" \"data\": {"+
" }"+
" }");
I have done it in Asp.net I hope it will help in some way...
for (int i = 0; i < dt.Rows.Count (No. of Rows or Device); i++)
{
tRequest.ContentType = "application/json";
var data1 = new
{
to="" + DeviceID + "",
priority="high",
notification = new
{
body = Message,
is_background = true,
title = Heading,
appicon = "http://webbestsites.com/images/1_icon.png",
sound = "default"
},
}

cordova push plugin server side php

Specs
phonegap-plugin-push 1.8.1 "PushPlugin" in a cordova application
Issue
I can't seem to figure out the server side JSON to send to GCM so that I can get a bigpicture notification on the phone.
Only the message and title are appearing at the moment
postData = "{ \"registration_ids\": [ \"" + RegKeyIDs + "\" ], \"data\": {\"additionalData\":\"" +
"additionalData" + "\", \"title\":\"" + "title" + "\", \"message\": \"" + "message" + "\", \"image\": \"" +
"https://google.com/randomimage.jpg" + "\", \"subtitle\":\"" + "subtitle" + "\", \"tickerText\": \"" +
"1" + "\", \"smallIcon\": \"" +
"https://google.com/randomimage.jpg" + "\", \"largeIcon\": \"" +
"https://google.com/randomimage.jpg" + "\", \"bigpicture\": \"" +
"http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg" + "\"}}";
Is there any documentation for server side GCM handling for big picture notifications
Looks like you need to set a style field to picture and an image field to the location of your image http://path_to_image.

`rtserver-id` turns to `rtserver - id` in java string

I have this code:
public void foo (){
String script =
"var aLocation = {};" +
"var aOffer = {};" +
"var aAdData = " +
"{ " +
"location: aLocation, " +
"offer: aOffer " +
" };" +
"var aClientEnv = " +
" { " +
" sessionid: \"\", " +
" cookie: \"\", " +
" rtserver-id: 1, " +
" lon: 34.847, " +
" lat: 32.123, " +
" venue: \"\", " +
" venue_context: \"\", " +
" source: \"\"," + // One of the following (string) values: ADS_PIN_INFO,
// ADS_0SPEED_INFO, ADS_LINE_SEARCH_INFO,
// ADS_ARROW_NEARBY_INFO, ADS_CATEGORY_AUTOCOMPLETE_INFO,
// ADS_HISTORY_LIST_INFO
// (this field is also called "channel")
" locale: \"\"" + // ISO639-1 language code (2-5 characters), supported formats:
" };" +
"W.setOffer(aAdData, aClientEnv);";
javascriptExecutor.executeScript(script);
}
I have two q:
when I debug and copy script value I see a member rtserver - id instead of rtserver-id
how can it be? the code throws an exception because of this.
Even if i remove this rtserver-id member (and there is not exception thrown)
I evaluate aLocation in this browser console and get "variable not defined". How can this be?
rtserver-id isn't a valid identifier - so if you want it as a field/property name, you need to quote it. You can see this in a Chrome Javascript console, with no need for any Java involved:
> var aClientEnv = { sessionId: "", rtserver-id: 1 };
Uncaught SyntaxError: Unexpected token -
> var aClientEnv = { sessionId: "", "rtserver-id": 1 };
undefined
> aClientEnv
Object {sessionId: "", rtserver-id: 1}
Basically I don't think anything's adding spaces - you've just got an invalid script. You can easily add the quotes in your Java code:
" \"rtserver-id\": 1, " +

Java vs. Net HTTP Client Performance

We call a webservice from our C# app which takes about 300ms using WCF (BasicHttpBinding). We noticed that the same SOAP call does only take about 30ms when sending it from SOAP UI.
Now we also implemented a test accessing the webservice via a basic WebClient in order to make sure that the DeSer-part of the WCf is not the reason for this additional delay. When using the WebClient class the call takes about 300ms as well.
Any ideas on why Java compared to C# is about 10x faster in this regard? Is there some kind of tweaking possible on the .NET side of things?
private void Button_Click(object sender, RoutedEventArgs e)
{
executeTest(() =>
{
var resultObj = client.getNextSeqNr(new WcfClient()
{
domain = "?",
hostname = "?",
ipaddress = "?",
loginVersion = "?",
processId = "?",
program = "?",
userId = "?",
userIdPw = "?",
userName = "?"
}, "?", "?");
});
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
WebClient webClient = new WebClient();
executeTest(()=>
{
webClient.Proxy = null;
webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
webClient.Headers.Add("Content-Type", "application/xml");
webClient.Encoding = Encoding.UTF8;
var data = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"SomeNamespace\">" +
" <soapenv:Header/>" +
" <soapenv:Body>" +
" <ser:getNextSeqNr>" +
" <!--Optional:-->" +
" <clientInfo>" +
" <!--Optional:-->" +
" <domain>?</domain>" +
" <!--Optional:-->" +
" <hostname>?</hostname>" +
" <!--Optional:-->" +
" <ipaddress>?</ipaddress>" +
" <!--Optional:-->" +
" <loginVersion>?</loginVersion>" +
" <!--Optional:-->" +
" <processId>?</processId>" +
" <!--Optional:-->" +
" <program>?</program>" +
" <!--Optional:-->" +
" <userId>*</userId>" +
" <!--Optional:-->" +
" <userIdPw>?</userIdPw>" +
" <!--Optional:-->" +
" <userName>?</userName>" +
" </clientInfo>" +
" <!--Optional:-->" +
" <name>?</name>" +
" <!--Optional:-->" +
" <schema>?</schema>" +
" </ser:getNextSeqNr>" +
" </soapenv:Body>" +
"</soapenv:Envelope>";
string result = webClient.UploadString("http://server:8080/service", "POST", data);
});
}
Am I missing something here? Any idea would be helpful... ;-)
Kind regards,
Sebastian
I just found the reason for this.
It's the 100-Expect Continue HTTP Header and the corresponding implementation in .NET. The .NET client wait 350ms as default on the server. This causes the delays. Java seems to have other default values here...
Just add the following line of code very early in your code:
System.Net.ServicePointManager.Expect100Continue = false;
Cheers!

Categories

Resources