Category Archives: Uncategorised

Oracle’s MOOC on Lambdas and streams

At the end of November I saw a post on Reddit about Oracle having a MOOC (Massive Open Online Course) on lambdas and streams in December 2016. I signed up and was enrolled. It was divided into three lessons starting in December, one lesson a week. At the end of each lesson there was a test.

Instructor Simon Ritter was very good at covering the subjects. The first lesson introduces lambda expressions, why it was added to Java 8, what problems it intends to solve. Then the syntax is described and basic usage.

One example is a list converted to uppercase:

List<String> myList = ...
myList.replaceAll(s -> s.toUppercase);

So instead of manually creating a loop to iterate over the list and convert each element it is now told what to do. This small example is of course a bit contrived but shows the essence of lambda expressions.

Lesson two introduces the streams api and functional programming concepts. It “allows functions to be treated as values” and is the reason “Lambda expressions were required in JDK 8” (page 9).

One or more stream operations can be chained together. The last operation is a terminal operation.

List<String> l = Arrays.asList("a", "b", "c");

List<String> r = l.stream().limit(1).collect(Collectors.toList());

Lesson three covers streams in more detail. Streams can be serial or parallel. If an element in the source input is computational intensive it can be beneficial to parallelize the stream but it also incurs some overhead. This lesson have some tips on how and when to convert a streams to either serial or parallel.

This course by Oracle is recommended when a person like me knows “something” about lambdas and streams and have begun to explore them but still would like to know more when and where it can be put to work in an efficient manner.

Add unit test to Spring Boot

As a project grows testing becomes more vital. It’s easy to perform these test manually when you have just begun (I’m looking at myself) and repeat and enhance these as the code evolves.

But sooner or later unit test will add structure to your tests, save time and maybe uncover some bugs or other errors. I found one that is not an error as such but a result of how Spring Boot parses the last part of a rest-endpoint and it did lead to imprecise results. The reason is that when Spring Boot encounters a dot (.) it considers this a file-extension. Thanks to the good folks at Stackoverflow this thread have some solutions. I decided to implement the solution Dave Syer suggested.

I’m passing latitude and longitude in the rest-api as a decimal number and Spring Boot would initially interpret longitude with a value 6.3968833 as 6 because it discarded anything after the decimal point. And this move westward is not desired.

This post is a continuation of my rest-api post where I show how to query a database for cities/locations within a radius. The source code for this project can be found here.

Back to unit test. Spring Boot integrates nicely with JUnit, and JUnit integrates nicely with the Eclipse IDE so testing the code is easy.

Add a class to the project, I’ll call mine WorldcitiesApplicationTests, and put it in the src/test/java-folder. The first test will test for a non-existing endpoint.

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class WorldcitiesApplicationTests {

 @Autowired
 private MockMvc mvc;
 @Test
 public void getUnknowPath() throws Exception {
 mvc.perform(MockMvcRequestBuilders.get("/greetingtest").accept(MediaType.APPLICATION_JSON))
 .andExpect(status().isNotFound());
 }
}

To run the unit test mark the class and click on the green play button with the white triangle on the top of the IDE. At the bottom click at the JUnit tab to see result of the tests. Here I have all nine test passing.

springboot15

This first test is a nice start. But it doesn’t really test anything except it verifies that an endpoint does not exist. A useful test will return an array with zero or more items in it. Counting items in a json-response is described here and my first real test looks like this.

 @Test
 public void getEmptyCity() throws Exception {
 mvc.perform(MockMvcRequestBuilders.get("/city/a").accept(MediaType.APPLICATION_JSON))
 .andExpect(status().isOk())
 .andExpect(jsonPath("$.*", org.hamcrest.Matchers.hasSize(0)));
 }

hasSize() accepts an integer and here I want an empty array. Lets test for the nearest town called Sandane. In my case there is only one Sandane in the database, a city like Barcelona or Berlin will have more items in the array.

 @Test
 public void getOneCity() throws Exception {
 mvc.perform(MockMvcRequestBuilders.get("/city/Sandane").accept(MediaType.APPLICATION_JSON))
 .andExpect(status().isOk())
 .andExpect(jsonPath("$.*", org.hamcrest.Matchers.hasSize(1)));
 }

I define latitude and longitude with a default value and then parse them in a try-catch.

 Float lat = (float) 61.7428745;
 
 try {
 lat = Float.parseFloat(latitude);
 } catch (NumberFormatException e) { }

If latitude and longitude isn’t parsed into a float it retains the default value, which is where I live. So /citites/a/b will query locations within a radius of 20 km from my home. This test looks like this and will return 29 items in the array.

 @Test
 public void getCitiesNearBreimWithMalformedLatitudeAndLongitude() throws Exception {
 mvc.perform(MockMvcRequestBuilders.get("/cities/a/b").accept(MediaType.APPLICATION_JSON))
 .andExpect(status().isOk())
 .andExpect(jsonPath("$.*", org.hamcrest.Matchers.hasSize(29)));
 }

Next I wanted to test for the real location. Copied, pasted and modified the test and expected 29 items.

 @Test
 public void getCitiesNearBreimWithDefaultRadius() throws Exception {
 mvc.perform(MockMvcRequestBuilders.get("/cities/61.7428745/6.3968833").accept(MediaType.APPLICATION_JSON))
 .andExpect(status().isOk())
 .andExpect(jsonPath("$.*", org.hamcrest.Matchers.hasSize(29)));
 }

But this time I received 37 items and the test failed. Hmm, what is going on? I added a println() and saw longitude was changed from 6.3968833 to 6. As it turns out Spring Boot cuts of the decimal part as explained above. Adding this class to the projects modifies the parsing so I get to keep the decimal part.

@Configuration
public class AllResources extends WebMvcConfigurerAdapter {

 @Override
 public void configurePathMatch(PathMatchConfigurer matcher) {
 matcher.setUseRegisteredSuffixPatternMatch(true);
 }
}

After this I received 29 items and the test passed. If unit testing is added early in the process it quickly becomes a part of the coding routine. And it can uncover bugs or parsing peculiarities like this before it hits production.

 

Create a rest-api with the Spring Boot Java framework, part two

Hi. In the previous post I showed one way to get a Spring Boot project up and running. Then added a single endpoint to display some text.

The source code for this project is available from github.

Now we’ll connect to a postgresql-server. I chose postgresql because I am familiar with it but mysql would work just as well. I use JPA and Hibernate to abstract the database.
Configuring Spring Boot to use postgresql it very easy. This guide was helpful.

Add the following code to pom.xml for postgresql. And to prepare Spring Boot for the rest-protocol. I forgot to select this during the initial configuration of the program.

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-rest</artifactIdd>
</dependency>

Spring Boot should download any dependencies automatically. Then add the following lines to the file application.properties. If you don’t use a password you can omit the third line.


spring.datasource.url= jdbc:postgresql://localhost:5432/worldcities
spring.datasource.username=worldcities
spring.datasource.password=postgres@123

Just make sure postgresql have been installed and configured. I use macports on os x, others use homebrew.

Then we’re ready to add our first class called City. This is not the complete class, constructors and getters are not included for brevity. Other than that it includes the @Entity and @Table annotation to tell Spring Boot what the table in the database looks like.

I have an old habit of using lowercase names for table names. And class names start, as an convention, with an uppercase letter and would look for a table called City if I didn’t override it in @Table.


@Entity
@Table(name = "city")
public class City implements Serializable {
    
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", columnDefinition = "serial")
    private final Integer id;
    private final String countrycode;
    private final String name_lowercase;
    private final String name;
    private final String region;
    private Integer population;
    private Float latitude;
    private Float longitude;
}

You define the endpoints for the rest-api in CityController. Lets define an endpoint to get a cityname.

@Autowired
private CityRepository cityInterface;

@RequestMapping(value = "/city/{name}", method = RequestMethod.GET)
public List<City> cityByName(@PathVariable("name") String name) {
 return cityInterface.findByName(name);
}

The database-calls are handled via the interface defined in CityRepository.

public interface CityRepository extends CrudRepository<City, Long> {
 List<City> findByName(String name);
}

So pretty easy to follow it turns out. Extract the cityname  from the path with @PathVariable and assign it to the string variable name. The call to findByName() returns zero or more City objects in a ArrayList.

I had an issue with a null-pointer exception when I called findByName() without @Autowired prepended to the CityRepository interface. I’m not sure why since it was not mentioned in the examples I looked at on the Spring Boot site. After some digging a Stackoverflow thread helped.

To get cities/locations within a radius I add the endpoint /cities/latitude/longitude/radius.

@RequestMapping(value = "/cities/{latitude}/{longitude}/{radius}", method = RequestMethod.GET)
public List<City> cityByLatitudeLongitudeRadius(
 @PathVariable("latitude") String latitude,
 @PathVariable("longitude") String longitude,
 @PathVariable("radius") String string_radius)
{}

First I define a variable with a default value for latitude, longitude and radius. And try to parse the string. Then call get_locations() that returns a List<City>.

Float lat = (float) 61.7428745;

try {
 lat = Float.parseFloat(latitude);
} catch (NumberFormatException e) { }

return get_locations(lat, lng, radius);

In get_locations() I use SimpleLatLng to calculate the latitude west and east and longitude south and north of the center. Then select all locations with this square. And lastly iterate through this list and remove locations outside the radius and return the remaining items.

List<City> cities = cityInterface.findByLatitudeBetweenAndLongitudeBetween(lat_west, lat_east, lng_south, lng_north); 

for (Iterator<City> iterator = cities.iterator(); iterator.hasNext();) {
 City city = iterator.next(); 
 LatLng p = new LatLng(city.getLatitude(), city.getLongitude());
 double d = LatLngTool.distance(center, p, LengthUnit.KILOMETER);
 if (d > radius) {
 iterator.remove();
 }
}

return cities;

 

Create a rest-api with the Spring Boot Java framework

Here is an example on how to write a simple rest-api using the Spring Boot Java framework. This first post will get you up and running with a simple hello spring page. The next post will go into detail on how to add endpoints and code to access the database, parse the result and return it as json.

The source code is available on my github-page with a tiny description which assumes how to assemble the parts.

Lately we have seen some pretty awesome Java frameworks like Jooby and SparkJava that gets you up and running in a few minutes. This is great since Java thus becomes a viable alternative to web frameworks written in javascript, ruby, php etc.

Spring Boot is almost as easy to get started with as Jooby and SparkJava. And being such a capable framework it’s remarkable how easy Pivotal, the company behind the Spring projects, have made the process that gets you there.

I’ll outline the steps I took to put together this simple rest-api. It can search for cities/locations within a radius specified by latitude and longitude. I found many good examples in Spring Boots getting-started guides and the web and Stackoverflow is a great help when issues arises.

The guides show how to create the folders and the file pom.xml. This is the build-file maven use. You can also go to Springs starter page where you can select database, functionality etc. Download and unzip and start coding.

For this project I’ll show mostly the latter and also show how to edit pom.xml to add extra functions I forgot to select rest-functionality so this will show how to add it to pom.xml. And that is nowhere near fatal if some desired functionality is left out in the beginning.

Hab kein angst. Nur viel spaß.

 

First head over to Springs starter page.

springboot01

 

Click at the link at the bottom to expand to the full version.

springboot02

 

Select Cache and DevTools. The latter is nice during development since it reloads your code on changes. This way you don’t have to stop and start your web-server on changes.

springboot03

 

Then select JPA, JDBC and Postgresql.

springboot04

 

Then click on Generate Project and your file is being downloaded.

springboot05

 

I use Eclipse as my IDE. It has it’s quirks but I like the way it tries not to be too helpful while still give some good advice when I make mistakes. Other nice IDE’s are IntelliJ and Netbeans. You decide.

You can also edit the files using an editor and run the maven project from the command line.

Import the folder into Eclipse from File->Open Projects from File System.

springboot06

 

After import the main-function is ready to run.

springboot07

 

From now on you can either start the program from the command line using “mvn spring-boot:run” or add a run-configuration to Eclipse.

From the menu select Run->Run As->Maven build… and enter “spring-boot:run” in Goals. Just remember to select Maven build with the three dots (…).

springboot08

 

Then select the Source tab and click Add…

springboot09

 

Select the project worldcities and click OK.

springboot11

 

When you get back to the previous windows mark the Default folder and click remove so we are left with the worldcities folder. Then click Run and the program starts. It may need to download some files the first time it is being run.

springboot12

 

To show a message from Spring Boot create the Java class CityController in Eclipse. Make sure the package name is the same. In this case no.gnome.

Add @RestController shown on line 6. Usually Eclipse will automatically import the necessary functions when annotations like this is added to the code. This annotation add functionality to the Spring Boot environment so your program can handle rest-request.

On line 9 add @RequestMapping(“/”) and create the function on line 10-12.


public String index() {
    return "Hello from Spring Boot!";
}

springboot13

 

When you save the file Spring Boot will automatically reload to include the changes. Open a browser and go to localhost:8080 and you are greeted with the hello message.

springboot14

 

In the next episode I will show how to add the parts to query and filter locations. Until then take care.

My iphone-app has been approved by Apple

My iphone-app is now available on the app store in Norway, Denmark and Sweden. The app is for signing up on training sessions with the personal trainers Anne-Merete and Oddny Kleppenes, the first being my wife and the latter sister in law, hence the name of their company PT-Amok was coined. Buying the app gives one free training session.

Navigate to the app store and go exercise.

Amazon CloudFront with custom certificate

Hi there.

I recently wrote a javascript app with some dash of html for my wife and sister in law. They are personal trainers in their sparetime and announce their activities on Facebook and link to a page where one can sign up. The code resides in a S3 bucket and can be served from there. The app uses the web-based Facebook login.

Select the bucket, mark index.html and then click on the Properties button in the upper right side. The link can then be pasted into the announcement on FB. Which we also did to begin with but the URL is neither very pretty nor easy to remember. But good enough just to get started with the sign up process and get some feedback.

https://s3-eu-west-1.amazonaws.com/timebooking.gnome.no/index.html

Amazons CloudFront is a CDN (Content Delivery Network). CloudFront is build for speed and S3 buckets for storage. When you create a CloudFront distribution you can connect to your S3 bucket in the wizard. Log in to your Amazon account and select CloudFront from the leftmost column.

AmazonFBauthentication01

Then click on the top most ‘Get Started’ button in the section Web.

AmazonFBauthentication46

When you enter ‘Origin Domain Name’ a list with your S3 buckets appears. Select the bucket you want to add to the CloudFront distribution.

Then select ‘Redirect HTTP to HTTPS’ in ‘Default Cache Behaviour Settings’ so it always serves encrypted https.

In ‘Allowed HTTP methods’ you can change the value as needed. Use the bottom option if you need to write content.

Leaving the rest of the settings at their default will create a distribution and assign it a domain name. I got d3ejguxaohfe01.cloudfront.net, shorter than the S3 bucket URL but still odd looking.

https://d3ejguxaohfe01.cloudfront.net/index.html

AmazonFBauthentication54

To use your own domain name enter this in ‘Alternate Domain Names (CNAMESs)’ in the section ‘Distribution Settings’, in my case it’s pt-amok.gnome.no. Head over to your DNS and add the CNAME pt-amok.gnome.no and point it to d3ejguxaohfe01.cloudfront.net.

AmazonFBauthentication53

Then click on ‘Request an ACM certificate’ to have Amazon create a certificate for this domain.

AmazonFBauthentication50

Enter the domain name, use an asterix (*) so you can add any subdomains and click on ‘Review and request’.

AmazonFBauthentication51

Click on ‘Confirm and request’ and a mail is sent to the domain, and hostmaster is one of the recipients. Just make sure that one of the recipients have their mail forwarded to your account. When the mail arrives confirm you want to create this certificate. I selected the region N. Virginia when I requested the certificate.

AmazonFBauthentication52

Select ‘Custom SSL Certificate (example.com):’ and the appropriate certificate. When these changes are saved the distribution settings must be propagated throughout CloudFront and this step take some minutes. You can specify the default html file to be served by adding the filename to ‘Default Root Object’, in my case index.html. So now the link is prettier.

https://pt-amok.gnome.no/

 

Amazon Cognito/IAM and Facebook login, part two

This is the second part of the post which shows how to integrate Amazon Cognito and IAM (Identity & Access Management) and Facebook login. The first is here and is a series of screenshots.

This post will briefly explain how to set up a local environment and develop and test it before deploying it to Amazon S3. This and the first guide relies in part heavily on Serverless Single Page Apps by Ben Rady which you can buy from pragprog.com.

I use OS X and macports for package management on the command line so the examples provided are on this platform. Seasoned Linux- and BSD-users knows the difference and will apply appropriately.

I have very little experience with cygwin and mingw.

When you start developing the app you can do so on your local machine. It’s faster to test changes on local code instead of having to upload it to S3 first, easier to install extra programs etc.

AmazonFBauthentication42

At the bottom of the page you specify the ‘Site URL’ you are using. When I developed the app on my local machine my URL was ‘https://localhost/’. I had plain http to begin with but got some error messages that said I was mixing http and https so I changed it to encrypted https.

You may want to install a webserver. OS X ships with apache but sometimes Apple is slow updating apache, sometimes you want a custom-build apache server. I use nginx which can be installed issuing the command

$ sudo port install nginx

The default installation path is /opt/local and the configuration file is located at /opt/local/etc/nginx/nginx.conf.

After nginx is installted you will create a local snakeoil certificate. I followed this guide. When you have the certificates copy them to this location or choose your own path and edit nginx.conf and add or change these lines accordingly



# HTTPS server
server {
  listen 443 ssl;
  server_name localhost;

  ssl_certificate /opt/local/etc/openssl/certs/selfserve.crt;
  ssl_certificate_key /opt/local/etc/openssl/private/selfserve.key;

  location /cielo {
    root /Users/claus/devel/;
    index index.html;
  }
}

Don’t forget to reload the nginx configuration, this can be done with

$ sudo nginx -s reload

I have created a github repo with some example code which you are welcome to clone and modify. The poolId in utils.js

var poolId = 'eu-west-1:82de430e-6f53-4d84-90fa-509d6b6775d3';

is from the example code in ‘Federated Identities’ in the Cognito console.

AmazonFBauthentication06

The poolId is paired with the appId that was entered when the pool was created.

AmazonFBauthentication26

The appToken in the javascript code and the ‘Site URL’ shown in the first image is used by Facebook to grant your app access. So I conveniently changed the URL before publishing the code. Otherwise the code can easily be cloned and run from any local machine and possibly be abused.

var appToken = '860675960666169|00_5tkwxjsUj_u6P1-U1IXjj9mE';

The appToken consists of your appId and a token separated with a pipe symbol (|). You can generate the token using curl. Run the following command on the command line.

$ curl 'https://graph.facebook.com/oauth/access_token?client_id=APPID&client_secret=CLIENTSECRET&grant_type=client_credentials'

The output can look like

access_token=860675960666169|00_5tkwxjsUj_u6P1-U1IXjj9mE%

Copy the string between the equal- and percent-sign and paste it into your own code. I think I got the curl-command from a stackoverflow thread. You can read this blog for additional information.

Don’t reveal the app secret to others.

Create a bucket on S3. Bucket names are unique so if you have a domain add this. Descend down to the folder where the code is and issue this command

$ aws s3 sync . s3://your.bucket.name

Before you can use the aws command you have to install and configure it. Ben Rady explains the procedure in great detail in his book.

After the code is synchronized to S3 enable ‘Static Website Hosting’ on the right hand side and specify the ‘Index Document’. In this case it’s index.html.

AmazonFBauthentication43

Grant Everyone access to index.html and click Save. Repeat the process for other files where needed.

AmazonFBauthentication44

There is a publicly available link to index.html. The URL could be used but only the hostname is used by Facebook to restrict where the app can be run from. So anything after the forward slash after the hostname is ignored. Which means that you can’t rely on this to prevent others from impersonating you.

Instead you can use another service provided by Amazon called CloudFront. This also has the advantage they can provide encrypted https to your S3 bucket.

Ivan Kusalic have some advise if you use CloudFront with a third-party certificate. I did not have some of the problems Ivan mentions but maybe the service have matured since he tried it.

Creating a CloudFront service is easy. I feel that Amazon have put great efforts into the creation of services as effortless as they can become. Click on ‘Create Distribution’.

AmazonFBauthentication46

Click ‘Get Started’ in the Web section.

AmazonFBauthentication45

In ‘Origin Domain Name’ a list with your buckets will be available. Select the bucket you created above. If you only want encrypted https select ‘HTTPS Only’ in ‘Viewer Protocol Policy’. The other settings can be left as they are. I have selected ‘Use only US and Europe’ in ‘Price Class’ in the section ‘Distribution Settings’ since performance is not a concern. The section is in the same window but further down and thus not visible. Just scroll down and you’ll see it.

AmazonFBauthentication47

Click ‘Create Distribution’. It will take a while before it is ready. I went to bed when I created the distribution and it was finished when I woke up again but I doubt it takes all night.

Copy the domain name to the site URL in your Facebook app settings and you should be all set.

This app only show the content of a table. In a later update I’ll add the possibility to enter some information and update the table. Till them take care.

Amazon Cognito/IAM and Facebook login, part one

This guide will show you how to create services at Amazon and pair them with a Facebook login in order to access resources within the rich Amazon ecosystem.

A later post will show basic javascript code so you can login and retrieve information from a DynamoDB table.

I recommend reading ‘Serverless Single Page Apps’ by Ben Rady. You can buy the book in print and/or pdf from https://pragprog.com/book/brapps/serverless-single-page-apps. This gives a nice introduction to Amazon’s web-services.

Perform the following steps to create the required amazon services in order to authenticate using Facebook credentials.

Open a browser at https://developers.facebook.com and login/register and add a new app. In the dashboard the App Id will be used when creating a pool at Amazon.

Open a browser at https://aws.amazon.com/ and login/register.

Click on ‘Cognito, User Identity and App Data Synchronization’ in the third column in the section Mobile Services.

AmazonFBauthentication01

Click on ‘Managed Federated Identities’ in the next step.

AmazonFBauthentication02

Click on ‘Create new identity pool’.

AmazonFBauthentication03

Enter the name of the new pool in ‘Identity pool name’. Here I name it Generic Pool. Do not enable ‘Unauthenticated identities’ unless you provide anonymous access. Select the Facebook tab in ‘Authenticated providers’ and enter your App Id provided by Facebook and click ‘Create Pool’.

AmazonFBauthentication04

Click Allow to grant access to your ressource.

AmazonFBauthentication05

When access have been granted some example code shows how to access the ressource, in this case javascript.

AmazonFBauthentication06

Use the Dashboard to see information about the pool.

AmazonFBauthentication07

Open ‘Identity & Access Management’ in ‘Security & Identity’ in the second column.

AmazonFBauthentication01

Click on Roles in the left column and your newly created roles appear.

AmazonFBauthentication08

Clicking on Cognito_GenericPoolUnauth_Role shows that no policies are attached to this role. Since we don’t want to open up for anonymous access we just leave it as it is.

AmazonFBauthentication10

We want to allow Cognito_GenericPoolAuth_Role access to DynamoDB so click on ‘Attach Policy’ in ‘Managed Policies’ in the Permissions tab.

AmazonFBauthentication11

Select AmazonDynamoDBFullAccess and click ‘Attach Policy’ to allow this role to use DynamoDB.

AmazonFBauthentication12

The policy is then shown in ‘Managed Policies’.

AmazonFBauthentication13

Time to create tables in DynamoDB. Open https://eu-west-1.console.aws.amazon.com/dynamodb/home?region=eu-west-1 and click on ‘Create table’.

AmazonFBauthentication14

In this example I create a table with a partition- and sort-key.

AmazonFBauthentication15

When the table is created you can click on the Items tab on the right side and create an item.

AmazonFBauthentication17

Clicking on the ‘Create item’ button brings up a modal window. Enter the partition key and sort key and then append any desired fields.

AmazonFBauthentication16

I’ve inserted one record which we will retrieve later.

Click on the ‘Access control’ tab on the right hand side and select Facebook as the ‘Identity provider’. Select all Actions just beneath and ‘All attributes’ in ‘Allowed attributes’ and click ‘Create policy’. This will bring up the policy on the right which you can copy and paste into an editor and we’ll use it later when create a custom policy.

AmazonFBauthentication18

Lets create a custom policy that allow access our newly created table. Click on ‘Create policy’.

AmazonFBauthentication19

Select ‘Create Your Own Policy’.

AmazonFBauthentication20

Give it a descriptive name and description and paste the policy copied from above and click ‘Validate Policy’.

AmazonFBauthentication21

Click ‘Create Policy’ to save the policy.

AmazonFBauthentication22

Add the newly created policy to a role. Select Role from the left side and ‘Create New Role’.

AmazonFBauthentication23

Enter a name for the role and ‘Next Step’.

AmazonFBauthentication24

Select ‘Role for Identity Provider Access’ and then ‘Grant access to web identity providers’.

AmazonFBauthentication25

Select Facebook from ‘Identity Provider’ and enter the Application ID that is assigned by Facebook when the application was created and click on ‘Next Step’.

AmazonFBauthentication26

Click on ‘Next Step’.

AmazonFBauthentication27

Then you are asked to attach a policy. Select the one you just created and click ‘Next Step’. You may have to search for the policy in the filter input field.

AmazonFBauthentication28

Review and click ‘Create Role’.

AmazonFBauthentication29

Click on Groups in the left pane and ‘Create New Group’.

AmazonFBauthentication30

Enter the name of the group in ‘Group Name’ and click ‘Next Step’.

AmazonFBauthentication31

Enter the name of the policy you just created in the search field and select the policy and click ‘Next Step’.

AmazonFBauthentication32

Review and click ‘Create Group’.

AmazonFBauthentication33

Click on the group you just created.

AmazonFBauthentication34

A message notifies that this group has no users. Click on ‘Add Users to Group’.

AmazonFBauthentication35

Select the user and click ‘Add Users’.

AmazonFBauthentication36

The group is created, the policy is attached, the user is added to the group.

AmazonFBauthentication37

Now is the time to put the App ID assigned by Facebook and the pool ID by Amazon to some use. We will build a simple page in html and javascript to connect to the Amazon Cognito service using the javascript SDK from Facebook and Amazon. Don’t forget to change the invalid Facebook App ID in this example from 9012345678 to the real one given by Facebook.

AmazonFBauthentication38

When clicking on the Facebook button a new window will appear with a username and password dialog. Enter your credentials. The first time you open a new app from Facebook it asks for permission to access your public profile, which is basically your name, email-address if any and user-id. Click Okay to continue.

AmazonFBauthentication39

If permission is granted a new window will show what the app then can do. This can post on Facebook on your behalf and you can limit who will receive these messages. This app won’t post any messages. Click Okay.

AmazonFBauthentication40

When you are all set this is what the page looks like.

AmazonFBauthentication41

 

In a upcoming post I will link to the code I have and how you move it to Amazon’s S3 storage and serve it from there. As you can see the app is run from localhost. This will change when the code is copied to S3.

I hope you have enjoyed this post. It was originally intended as an reminder to myself but I figured others might find it useful as well.

Take care.

Websocket based server written in C++, part 1

I have written some small web apps that make use of a websocket based server in C++. I use the excellent framework websocketpp that makes it a breeze to use websockets in C++. It is a header only library so you only need to add the header file in your project to use it. In some cases it does need the boost libraries and I had to install and link to the boost system. It is not a big deal adding boost on mac from macports. Get it at https://github.com/zaphoyd/websocketpp.

The first app I wrote is based on an example that the author of websocketpp have provided on his website. I have modified it to fit my needs.

The app keeps track of a football league and while not rocket science I did learn a lot from this. It is very simple at the moment and can only keep track of goals and points and is not intended to replace the tools the big newspaper sites use for the various leagues around the world. My target audience is more the local leagues that do not have a dedicated journalist to update the table, cards given, corners and other useful information. My idea is to have friends and families update the goal score, crowdsourcing in other words.

I have also written a javascript client that talks to the server. They use json which is an integral part of javascript but not of C++. So I added nlohman/json that can be downloaded at https://github.com/nlohmann/json. This is also a header only framework and makes it easy to use json in C++.

I use postgresql as database. This is a database I am very comfortable with and have used it since  version 7 back in 2002.

Postgresql provides an official C++ driver I use.

The server is at https://github.com/kometen/websocket03 and the client at https://github.com/kometen/websocket-client.

The first version had all the logic in main.cpp but I have later moved the websocket-part into a websocketserver class and database calls to a database class.

The next step was to add a simple database connection pool. When searching I came across this stackoverflow thread that inspired me. http://stackoverflow.com/questions/12528199/libpqxx-connection-pool.

I added pooling by using std::stack pushing and popping them on and off. Easier than I initially thought it would be.

 

Detect long-press in javascript

Hi.

I recently had the need to detect a long-press on a button in javascript. I did a search on google on onmousedown, onclick, onmouseup, javascript and found some examples on stackowerflow.com. These examples showed how to set a timeout before executing some function.

So I came up with this solution where I can perform one action depending on how long I press a button.

html:

<!doctype html>
<html>
<head>
 <meta charset="utf-8">
 <title>Timeout</title>
</head>
<body>
 <button id="button">click</button>
 <script type="text/javascript" src="func.js"></script>
</body>

javascript:

(function(window, document, undefined){
 'use strict';
 var start;
 var end;
 var delta;
 var button = document.getElementById("button");

 button.addEventListener("mousedown", function(){
   start = new Date();
 });

 button.addEventListener("mouseup", function() {
   end = new Date();
   delta = end - start;
   if (delta > 0 && delta < 500) {
   alert("less than half second:");
 }
 if (delta > 500 && delta < 1000) {
   alert("more than half second and less than a second:");
 }
 if (delta > 1000) {
   alert("more than a second:");
 }
 });
})(window, document);

I forgot where I found the IIFE syntax example which I build this upon. There are many.

I assume there are many ways to detect a long-press.