In this example, we want to run something after an async task. Using the Promise syntax, the code seems to flow the async operation into a more synchronous style. At least that is how I see and value it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Sometimes it is useful to run multiple async task in sequence. Let’s say we need to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Another common pattern is to have multiple tasks start as soon as they can. As soon as all the tasks complete, we execute some code. The difference between this and chaining above is all the promises run at the same time instead of running one by one in sequence.
A scenario for this could look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Hopefully these examples make it easier to get started with JavaScript promises. It is still useful to refer to Promise documentation on other features like error handling and Promise.race().
Note that all the examples can executed on your browser’s developer console – provided the browser supports Promise (Chrome >= 32; Firefox >= 29; IE >= 11; Opera >= 19; Safari >= 7.1).
]]>The steps described on the Cloud DNS Getting Started page are quite detailed to get started.
Since Google Cloud DNS is not a domain name registrar, you will need to register a domain name and point the name server of the domain to the “NS” record of the managed zone created in Google Cloud DNS.
If you have multiple zones, take note that Google’s name servers look similar but may not be the same for each zone.
○ → gcloud dns managed-zone list
[
{
"creationTime": "2014-06-21T08:51:36.824Z",
"description": "xxx.net.",
"dnsName": "xxx.net.",
"id": "9014807081031811107",
"kind": "dns#managedZone",
"name": "xxxnet",
"nameServers": [
"ns-cloud-e1.googledomains.com.",
"ns-cloud-e2.googledomains.com.",
"ns-cloud-e3.googledomains.com.",
"ns-cloud-e4.googledomains.com."
]
},
{
"creationTime": "2014-06-21T08:51:38.759Z",
"description": "xxx.com.",
"dnsName": "xxx.com.",
"id": "6449170171006388811",
"kind": "dns#managedZone",
"name": "xxxcom",
"nameServers": [
"ns-cloud-b1.googledomains.com.",
"ns-cloud-b2.googledomains.com.",
"ns-cloud-b3.googledomains.com.",
"ns-cloud-b4.googledomains.com."
]
}
]
On a related note, Google just announced a domain registration service! At the moment, it is in private beta and requires an invite. I am sure details about this service will be announced during Google I/O 2014.
These are the common commands used when managing DNS zones and records through this service.
# managing zone where each TLD should be in a separate zone
gcloud dns managed-zone list
gcloud dns managed-zone create --dns_name xxx.com. -- description xxx.com. xxxcom -q
gcloud dns managed-zone delete xxxcom
# managing records within a zone
gcloud dns records --zone=xxxcom list
gcloud dns records --zone=xxxcom edit
While there are many types of DNS records, understanding Type A, CNAME and MX records will be sufficient for common web and mail hosting needs.
Type | Host Record | Points to | TTL | Description |
---|---|---|---|---|
A | xxx.com. | 123.123.123.123 | 21600 | Maps xxx.com to 123.123.123.123. |
CNAME | www.xxx.com. | xxx.com. | 21600 | Maps www.xxx.com to xxx.com. |
MX | xxx.com | aspmx.l.google.com. | 21600 | This record is used to map domain to message transfer agent (MTA) to send/receive emails. |
For example, to configure:
Insert the following JSON data to the “additions” section when editing DNS records:
{
"kind": "dns#resourceRecordSet",
"name": "xxx.com.",
"rrdatas": [
"123.123.123.123"
],
"ttl": 21600,
"type": "A"
},
{
"kind": "dns#resourceRecordSet",
"name": "www.xxx.com.",
"rrdatas": [
"xxx.com."
],
"ttl": 21600,
"type": "CNAME"
},
{
"kind": "dns#resourceRecordSet",
"name": "mail.xxx.com.",
"rrdatas": [
"ghs.googlehosted.com."
],
"ttl": 21600,
"type": "CNAME"
},
{
"kind": "dns#resourceRecordSet",
"name": "docs.xxx.com.",
"rrdatas": [
"ghs.googlehosted.com."
],
"ttl": 21600,
"type": "CNAME"
},
{
"kind": "dns#resourceRecordSet",
"name": "xxx.com.",
"rrdatas": [
"10 aspmx.l.google.com.",
"20 alt1.aspmx.l.google.com.",
"20 alt2.aspmx.l.google.com.",
"30 alt3.aspmx.l.google.com.",
"30 alt4.aspmx.l.google.com."
],
"ttl": 21600,
"type": "MX"
}
]]>However, default implementations for “persistent token” only support in-memory (for testing) and JDBC. I wanted to implement this with App Engine using Objectify for persistence.
All it takes is to implement a custom PersistentTokenRepository
and configure Spring Security to use it. This post assumes that Spring Security has been configured to work correctly with App Engine.
RememberMeToken
EntityDefine an Objectify entity class that will be used to store token data.
1 2 3 4 5 6 7 8 9 10 11 |
|
PersistentRememberMeToken
And RememberMeToken
Since different objects are used during runtime and persistence, I use Spring’s generic conversion service to help with type conversion.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
ObjectifyPersistentTokenRepository
as a PersistentTokenRepository
This PersistentTokenRepository
implementation uses a conversion service that has a RememberMeConverter
registered and Objectify for persistence.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
The final bit is to hook things up when configuring Spring Security. This can be done in the configure(HttpSecurity http)
method if you are using Java configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Just in case you are wondering how the HTML form fields look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
1 2 3 4 5 6 |
|
Basically Collection<RelatedService>
is telling Spring to look for all beans matching the type of RelatedService
and put them in a Collection
for me to use in myService()
.
Then I wanted to make relatedServices
an optional dependency. Ideally, I would like to be able to do something like this:
1 2 3 4 5 6 7 |
|
However, @Autowired
cannot annotate a parameter. This is what I end up doing.
1 2 3 4 5 6 7 8 9 |
|
I would prefer to limit the visibility/scope of relatedServices
within the method but it does not look possible.
bower link
feature makes it easy to change & test packages while using it as a dependency in other packages. If you are using Bower, you should be using this.
It helps resolve this common scenario:
project-a
and project-b
.project-b
uses project-a
via bower install project-a
.project-b
, you need to make a change in project-a
.Solution: Just tell Bower that the project-a
dependency used in project-b
is located in a symlink location – where you actually checked out project-a
.
To do this:
project-a
, run bower link
to create a global link for the projectproject-b
, run bower link project-a
to let Bower know that we should refer to project-a
through the symlink.That’s it. Simple & effective.
]]>UserService
in JUnit test cases with the help of LocalUserServiceTestConfig
. However, switching user within a test case is not so simple.
Switching user within a test case allows simulation of multi-user scenarios such as:
Create a loginAs(String, Closure)
method in Groovy to switch the injected UserService
within Spring MVC controller object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
This attribute makes it an excellent choice for Java developers trying to pick up this dynamic language – start by writing Java and ease into Groovy’s style as you practice.
To make the transition even smoother, you can mix Java classes with Groovy classes in Maven projects. All you need is to configure your project’s pom.xml
to “recognize” Groovy classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
That’s it.
Some tips when doing this:
If you are new to Groovy, it is good to know the differences from Java.
Start with writing unit tests in Groovy where its syntactic sugar will make writing unit tests much more concise and enjoyable. This feature alone can justify enabling Groovy support in a Maven project.
Turn any existing Java class into a Groovy class by just renaming the file to .groovy. Note: This can be done via IntelliJ’s refactor “Rename File…” action.
If you are not familiar with the dynamic nature of Groovy, just code in plain Java. No need to stress yourself out trying to be a pro-Groovy coder quickly.
IntelliJ’s refactoring feature “Convert to Java” can be useful to convert Groovy class into Java class. While this does not always produce 100% usable/runnable Java code, it is still useful for learning purposes.
If you are using Spring Framework, know that all your beans/classes can be created as a Groovy class including things like @Configuration
, @Controllers
, @Service
and other components – Groovy is a first class citizen in Spring based application.
Using this in conjunction with IntelliJ’s excellent Groovy support, it is hard to understand why this not the default configuration for all Maven based Java projects.
]]>First thing, get a Jekyll blog set up. create a new blog structure in the current directory with:
jekyll new .
See quick start guide for details on viewing it from Jekyll’s built-in server.
Next, enable live reload as you are editing content. Basically, it works as a Grunt project that uses grunt-contrib-watch plugin’s support for livereload. It also bypasses Jekyll’s built-in web server and use Grunt’s web server for hosting – not a big deal but just so you know.
Create Gruntfile.js
:
module.exports = function (grunt) {
grunt.initConfig({
shell: {
jekyllBuild: {
command: 'jekyll build'
}
},
connect: {
server: {
options: {
port: 8080,
base: '_site'
}
}
},
watch: {
livereload: {
files: [
'_config.yml',
'index.html',
'_layouts/**',
'_posts/**',
'_includes/**',
],
tasks: ['shell:jekyllBuild'],
options: {
livereload: true
},
},
}
});
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-shell');
grunt.registerTask('default', ['shell', 'connect', 'watch'])
}
Create package.json
:
{
"name": "My Jeykll Blog",
"version": "0.0.1",
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-connect": "~0.6.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-shell": "~0.6.4"
}
}
Update _config.yml
to exclude these non-Jekyll files from being processed by Jekyll:
exclude: [node_modules, Gruntfile.js, package.json]
Update .gitignore
to exclude node_modules from being committed.
To make this work, there are some pre-requisites.
Type npm install
to download the required Grunt dependencies for the first time.
After that, just type grunt
to start a web server at port 8080 to host your blog with live reload enabled.
→ grunt
Running "shell:jekyllBuild" (shell) task
Running "connect:server" (connect) task
Started connect web server on http://localhost:8080
Running "watch" task
Waiting...
Hope you find this helpful.
]]>