spring social connectivity with Facebook and accessing user data - java

I have started to work with spring social and following the tutorial from here. and pages that follow.
My java file looks like this.
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
//import org.springframework.boot.SpringApplication;
//import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactory;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.support.ConnectionFactoryRegistry;
import org.springframework.social.facebook.api.Comment;
import org.springframework.social.facebook.api.CommentOperations;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.api.impl.FacebookTemplate;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.oauth2.GrantType;
import org.springframework.social.oauth2.OAuth2Operations;
import org.springframework.social.oauth2.OAuth2Parameters;
//import org.springframework.social.UserIdSource;
//import org.springframework.social.connect.ConnectionFactoryLocator;
//import org.springframework.social.connect.ConnectionRepository;
//import org.springframework.social.connect.web.ConnectController;
#Configuration
#EnableAutoConfiguration
#Import(FacebookConfig.class)
#ComponentScan
public class App {
static private String accessToken = "accesstoken";
static private String secretKey = "secretkey";
static private String clientId = "clientid";
public static void main(String[] args) {
FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(clientId, secretKey);
OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
OAuth2Parameters params = new OAuth2Parameters();
params.setRedirectUri("http://facebook.com");
String authorizeUrl = oauthOperations.buildAuthorizeUrl(GrantType.IMPLICIT_GRANT, params);
AccessGrant accessGrant = new AccessGrant(accessToken);
System.out.println(accessGrant.getAccessToken());
System.out.println(accessGrant.getExpireTime());
System.out.println(accessGrant.getScope());
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(connectionFactory);
Facebook facebook = new FacebookTemplate(accessToken);
}
}
When i run this code i get the error as stated.
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2:exec (default-cli) on project mavenproject3: Command execution failed. Process exited with an error: 1(Exit value: 1) -> [Help 1]
To see the full stack trace of the errors, re-run Maven with the -e switch.
Re-run Maven using the -X switch to enable full debug logging.
For more information about the errors and possible solutions, please read the following articles:
[Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
When i comment out this line:
Facebook facebook = new FacebookTemplate(accessToken);
It works fine.
Can someone suggest me the requisite. I am a newbie so please bear with me.

The URL you mentioned isn't really a tutorial as much as it is a reference. Admittedly, it gets a bit detailed and isn't very helpful for the new user. Duly noted...expect a new tutorial to be written as soon as I get a moment to do so.
Where did you get the value of accessToken? If you didn't get it via an OAuth2 "dance" with Facebook, then it's not going to work.
First, I see you creating a FacebookConnectionFactory to obtain an OAuth2Operations, through which you set a redirect URI, etc, etc..and then build an authorization URL for IMPLICIT grant. There are several things out of sorts there:
Facebook doesn't support IMPLICIT grant. It only supports authorization code grant and client token grant. Even so, with implicit grant and authorization code grant your app must redirect to Facebook (in a web browser) to obtain permission from the user. Once that's granted, then it will redirect back to your app...speaking of which...
The redirect URI you set is http://facebook.com. That should be the URL of your application where Facebook will redirect back to after authorization.
After all of that, you never even use the authorizeUrl...it's just in a String. It wouldn't work even if you did use it, for the reasons already mentioned, but the first 5 or so lines are all for nothing.
You create a ConnectionFactoryRegistry and register the FacebookConnectionFactory with it...but then you do nothing with the ConnectionFactoryRegistry. That's okay...you almost never need to do anything with it anyway, because it primarily exists as a helper to ConnectController.
There's simply no good way of obtaining a user-oriented access token without the redirect "dance". It's important to get permission from the user you'll be accessing Facebook on behalf of. If it were any easier than that, it'd be way too easy to create an app that spams Facebook and essentially ruins the experience for everyone.
The work of obtaining an access token via that redirect "dance" is handled automatically by the framework using ConnectController. Sure, you can do it yourself if you'd rather, but ConnectController will handle all of that for you.
For lack of a proper tutorial at the moment, I recommend that you have a look at https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase. Also, there's a Spring Boot-oriented version of it at https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase-boot that simplifies the configuration more (albeit, it relies on changes that aren't in an official Spring Boot release yet).

Related

Cannot connect MongoDB Atlas from a newly created Spring Boot app with a connection string [duplicate]

I have deployed this Python app on Heroku and i want it to connect to a MongoDB Atlas cluster. I used my string to connect to the cluster, but for some reason i keep getting raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: bad auth Authentication failed. I checked twice and both the user and the password are correct. Any idea on why this is happening?
from pymongo import MongoClient
import time
import random
import time
import datetime
client = MongoClient('mongodb+srv://USER:<MYPASSWORD>#test-2liju.mongodb.net/test?retryWrites=true')
db = client.one
mycol = client["tst"]
while True:
test = int(random.randrange(-99999990,90000000,1))
dic = {"num": test}
result = db.tst.insert_one(dic)
print(test)
time.sleep(5)
Stupid error, i had to type MYPASSWORD instead of <MYPASSWORD>, without the <>
Don't use any special char in password, like '+' or '='.
I use OpenSSL to generate a password like u4wY9AOwnOLMY+h9EQ==. Came across bad auth Authentication failed.
After using MongoDB Compass it told me don't use special char, so I remove those and use like 'u4wY9AOwnOLMYh9EQ'.
Then it works.
check the compatibility of the version of the Python driver you choose from the Mongodb Atlas Connections. versions above 3.4 are not supported by mongoengine flask

Which region endpoint should AWS Java SDK v2 be using for Route 53?

On Windows 10 I'm using the AWS Java SDK v2 (software.amazon.awssdk:route53:2.8.3) and I'm trying to merely connect and list all my Route 53 hosted zones. I have us-west-1 specified in my user configuration (in my .aws/config file) as the default region.
I create a Route53Client using the following:
Route53Client route53Client = Route53Client.builder().build();
Note that I don't indicate a region, because in the online documentation it says:
When you submit requests using the AWS CLI or SDKs, either leave the Region and endpoint unspecified, or specify us-east-1 as the Region.
I then try to list hosted zones using something like this:
Set<HostedZone> hostedZones = client.listHostedZonesPaginator().stream()
.flatMap(response -> response.hostedZones().stream())
.collect(Collectors.toSet());
In the logs I see a debug message like this:
[DEBUG] Unable to load region from software.amazon.awssdk.regions.providers.SystemSettingsRegionProvider#...:Unable to load region from system settings. Region must be specified either via environment variable (AWS_REGION) or system property (aws.region).
Then it throws a java.net.UnknownHostException for route53.us-west-1.amazonaws.com.
Granted I am on a spotty Internet connection right now. Is that the correct endpoint? If it is, the why isn't that endpoint listed at https://docs.aws.amazon.com/general/latest/gr/rande.html ? If it isn't, why is it trying to connect to a us-west1 endpoint, if I'm following the online documentation (as I quoted above), which indicates that a region need not be indicated? Or is the problem simply my Internet connection and spotty DNS lookup at the moment?
The AWS SDK development team decided to require Route53 requests to explicitly indicate the Region.AWS_GLOBAL or requests would not work, as someone noted in Issue #456 for the SDK:
To access Route53 you would currently need to specify the AWS_GLOBAL region. This was done to prevent customers from using global services and not realizing that for this service your calls are likely not staying in region and could potentially be spanning the globe.
Unfortunately Amazon didn't bother documenting this in the SDK (that I could find), and didn't provide a helpful error message, instead assuming developers would somehow guess the problem when the SDK tried to access an endpoint that did not exist even though the SDK was being used according to the API and according to the online documentation.
In short the Route53 client must be created like this:
route53Client = Route53Client.builder().region(Region.AWS_GLOBAL).build();
Here is the AWS Route 53 V2 Code example that lists hosted zones:
package com.example.route;
//snippet-start:[route.java2.list_zones.import]
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.route53.Route53Client;
import software.amazon.awssdk.services.route53.model.HostedZone;
import software.amazon.awssdk.services.route53.model.Route53Exception;
import software.amazon.awssdk.services.route53.model.ListHostedZonesResponse;
import java.util.List;
//snippet-end:[route.java2.list_zones.import]
public class ListHostedZones {
public static void main(String[] args) {
Region region = Region.AWS_GLOBAL;
Route53Client route53Client = Route53Client.builder()
.region(region)
.build();
listZones(route53Client);
}
//snippet-start:[route.java2.list_zones.main]
public static void listZones(Route53Client route53Client) {
try {
ListHostedZonesResponse zonesResponse = route53Client.listHostedZones();
List<HostedZone> checklist = zonesResponse.hostedZones();
for (HostedZone check: checklist) {
System.out.println("The name is : "+check.name());
}
} catch (Route53Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
//snippet-end:[route.java2.list_zones.main]
}

Connection made to Google Cloud SQL drops intermittently

I am using a Google Cloud SQL using Java-SQL connector. The issue I am facing is that the connection to database drops unexpectedly. While Googling I came across this question and tried the solution suggested in the same question.
In your console click the project, on the left side click Storage > CloudSQL then click on your database name. You will see an 'Edit' button on top. Click that and scroll down to Activation Policy, change it to Always On and then click save.
But I'm still facing the same issue. Fortunately I have been keeping the logs on Google App Engine and I have attached the snapshot of the exception that occurred while connecting to database.
Gist of the code that I've posted below is used to establish connection to the database.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import com.google.appengine.api.utils.SystemProperty;
import static com.google.appengine.api.utils.SystemProperty.environment;
import static com.google.appengine.api.utils.SystemProperty.Environment.Value.Development;
import static com.google.appengine.api.utils.SystemProperty.Environment.Value.Production;
Connection con=null;
SystemProperty.Environment.Value env = environment.value();
if(env == Production)
{
System.out.println("Inside Production Phase");
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<my-project-id>:<cloud-sql-instance>/<database-name>?user=<user-name>&password=<database-password>&useUnicode=true&characterEncoding=UTF-8";
}//if
else if(env == Development)
{
System.out.println("Inside Development Phase");
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://127.0.0.1:3306/<database-name>?user=root";
}//else if
con = DriverManager.getConnection(url);
Is anyone facing the same problem, Please help.
Got a temporary fix, used following parameters while making connection to Google Cloud SQL
url = "jdbc:google:mysql://my-app:mysql2/project-name?user=root&password=password&autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
Reference URL: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html

Proper vertx versions for push notifications

I tried to run next code, but for 2.1.6 vertex library occurs io.vertx package not found problem.
Or if somebody have a small project with Java and JS code for this, give please a link.
Also I tried 3.x.x version, but it has no io.vertx method.
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpServer;
import org.vertx.java.core.sockjs.SockJSServer;
import org.vertx.java.core.sockjs.impl.DefaultSockJSServer;
//...
Vertx vertx = Vertx.newVertx();
EventBus eventBus = vertx.eventBus()
HttpServer server = vertx.createHttpServer();
JsonArray permitted = new JsonArray();
permitted.add(new JsonObject());
SockJSServer sockJSServer = new DefaultSockJSServer(vertx, server);
sockJSServer.bridge(new JsonObject().putString("prefix", "/pusher"), permitted, permitted);
server.listen(<some port>);
Vert.x versions 2.x used the org.vertx package, whereas the 3.x branch uses io.vertx, this is why you're running into problems.
For version 2 there are some examples regarding the event bus bridge:
https://github.com/vert-x/vertx-examples/tree/master/src/raw/java/eventbusbridge
And a lot of examples for Vert.x 3:
https://github.com/vert-x3/vertx-examples
So basically you should just stick to one of the versions and you should be fine.

What kinds Java APIs can I use to build a simple voice communications program?

I want to build a voice chat program for a group of friends, as several of them were hit by viruses that we believe to have been sent from an unknown user for Skype. Skype also has other security problems where users can gain access to a user on their friends lists's IP, allowing for DDoS's and other such things. To help stop this, I want to build a simple voice chat program that I can host on my computer (or from a separate server, if it ever comes to that). I've heard that Java's built in APIs work for this, but which APIs should I specifically use, and what are some good sources/tutorials/videos to learn these?
Twilio will most likely fit your requirement. You can get started here: Twilio Quick Start.
It allows you to initiate and receive calls, even SMS. You will need to learn a bit of TwiML, but it's relatively simple.
The site has good sample code on common use cases. Here's a sample Java program that sends SMS messages.
Here's one that initiates an outgoing call - excerpt from the Twilio site:
import java.util.Map;
import java.util.HashMap;
import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.TwilioRestException;
import com.twilio.sdk.resource.instance.Account;
import com.twilio.sdk.resource.instance.Call;
import com.twilio.sdk.resource.factory.CallFactory;
public class MakeCall {
public static final String ACCOUNT_SID = "AC123";
public static final String AUTH_TOKEN = "456bef";
public static void main(String[] args) throws TwilioRestException {
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
Account mainAccount = client.getAccount();
CallFactory callFactory = mainAccount.getCallFactory();
Map<String, String> callParams = new HashMap<String, String>();
callParams.put("To", "5105551212"); // Replace with your phone number
callParams.put("From", "(510) 555-1212"); // Replace with a Twilio number
callParams.put("Url", "http://demo.twilio.com/welcome/voice/");
// Make the call
Call call = callFactory.create(callParams);
// Print the call SID (a 32 digit hex like CA123..)
System.out.println(call.getSid());
}
}
Important Note: Twilio has a free trial, but it will eventually involve some cost.

Categories

Resources