Java 8 Date Time: Convert from ISO 8601 String with TZ info, in this eg. UTC (javascript json friendly) to zone aware java date time object and render as local system date time

Whole groovy sample (paste into the groovyconsole)

import java.time.ZonedDateTime
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter

final String UTC_DATE_TIME="2017-08-30T13:12:46.824Z"

ZonedDateTime zdt = ZonedDateTime.parse(UTC_DATE_TIME,DateTimeFormatter.ISO_DATE_TIME)
println zdt.getZone() // 'Z' => UTC

println ZoneId.systemDefault() // "Europe/London"

assert ZoneId.systemDefault().equals(ZonedDateTime.now().getZone()) // Defaults to JVM TZ 
//on windows, use tzutil.exe to get/set the system time zone
//override for JVM with -Duser.timezone

ZonedDateTime londonZdt = zdt.withZoneSameInstant(ZoneId.of("Europe/London"))
ZonedDateTime rioZdt = zdt.withZoneSameInstant(ZoneId.of("America/Argentina/Buenos_Aires"))

assert(!londonZdt.equals(rioZdt))
assert(!londonZdt.isBefore(rioZdt))
assert(!londonZdt.isAfter(rioZdt))
assert(londonZdt.isEqual(rioZdt))

println zdt //2017-08-30T13:12:46.824Z
println londonZdt //2017-08-30T14:12:46.824+01:00[Europe/London]
println rioZdt //2017-08-30T10:12:46.824-03:00[America/Argentina/Buenos_Aires]
println "-----"

println zdt.toLocalDateTime() //2017-08-30T13:12:46.824
println londonZdt.toLocalDateTime() //2017-08-30T14:12:46.824
println rioZdt.toLocalDateTime() //2017-08-30T10:12:46.824

 

output on my machine :

Z
Europe/London
2017-08-30T13:12:46.824Z
2017-08-30T14:12:46.824+01:00[Europe/London]
2017-08-30T10:12:46.824-03:00[America/Argentina/Buenos_Aires]
-----
2017-08-30T13:12:46.824
2017-08-30T14:12:46.824
2017-08-30T10:12:46.824

Why is AngularJS 1.x tutorial not working for me in a Grails 2.x app?

This wasted 40 mins of my time before a ‘duh’ moment

I had set up a minimal app using ‘grails create-app’ which gave me a single GSP and a main.gsp sitemesh layout

My single gsp looked like this:

<html>
 <head>
  <meta name="layout" content="main">
  <r:require modules="application, angularjs"/>
 </head>
 <body ng-app>
  <p>{{1 + 3}}</p>
 </body>
</html>

…but even though the resource modules were configured correctly in my ApplicationResources.groovy, angurlarjs was not getting initialized. I looked at the rendered html and the body tag was bare, no attribute

As per the sitemesh layout template’s directives:

<g:layoutHead/>
<g:layoutBody/>

the contents of my GSPs head and body elements were being rendered into the response but not the actual head, body (or html) elements themselves from my GSP, they were coming from the layouts file.

So, I just moved my ng-app attribute into a newly created div, but it could go into the layouts file either.

The take away is to not decorate head, body (or html) elements in GSP page templates if a layout file is in use.

Large Font issue in MySQL Workbench on Retina Mac book pro

logged in this bug report. http://bugs.mysql.com/bug.php?id=67042

Workaround: edit /Users/$USER/Library/Application Support/MySQL/Workbench/wb_options.xml

replace occurrences of ‘Andale Mono 13’ with ‘Andale Mono 7’ (suggested)

GORM Grails example: cascading deletes many-to-one and manual deletes many-to-many

My self-learning excercise for Grails GORM  (cascading) deletes using a set of 3 models and a test script executed using the excellent grails console (instantiating the groovy ui console).

The models:

package rmdb

class Movie {
String title
static hasMany = [actors: Actor, chapters: Chapter]
static mapping = {chapters cascade: "all-delete-orphan"}
}

class Actor {
String name
static hasMany = [movies: Movie]
static belongsTo = Movie
}

class Chapter {
String title
Movie movie
static belongsTo = Movie
}

With those models the following script illustrates adding and deleting from the three models

import rmdb.*

def movie = new Movie(title: 'The Guard')
movie.addToChapters(new Chapter(title: 'Chapter 1'))
movie.save(flush: true)

movie = new Movie(title: 'In Bruges')
movie.addToChapters(new Chapter(title: 'Chapter 1'))
movie.save(flush: true)

assert(Chapter.count() == 2)
assert(Movie.count() == 2)
assert(Actor.count() == 0)

movie = new Movie(title: 'Intermission')
movie.addToActors(new Actor(name: 'Colin Farrell'))
movie.addToActors(new Actor(name: 'Cillian Murphy'))
movie.save(flush: true)

assert(Chapter.count() == 2)
assert(Movie.count() == 3)
assert(Actor.count() == 2)

// many to many => has a join table => clears out the join table
// does not cascade deletes to Actors but has disassociated the models.
// thereby facilitating deletes without FK constraint exceptions
Movie.all.each {
it.actors?.clear()
it.save(flush: true)
}

// Assert that the above hasn't changed anything (except the join table)
assert(Chapter.count() == 2)
assert(Movie.count() == 3)
assert(Actor.count() ==2)

// now we can delete
Actor.executeUpdate("delete from Actor")

assert(Chapter.count() == 2)
assert(Movie.count() == 3)
assert(Actor.count() ==0)

// We can cascade delete many-to-one Chapters (bi-dir with belongsTo and no join table)
// N.B. cascade delete is courtesy of: Movie static mapping = {chapters cascade: "all-delete-orphan"}
// Also the explicit belongsTo back ref to Movie in Chapters is not needed for cascading saves from the
// owning Movie domain class, just for facilitating bi-directional nav from a chapter to a movie instance
// and for delete cascade.

Movie.all.each {
it.chapters?.clear()
it.save(flush: true)
}

// Hmmm... re above: if there was no back ref.i.e. no explicit 'movie' member of Chapter,
// then grails would have used a join table.
// In this case the delete would NOT have cascaded (need to check this)

assert(Chapter.count() == 0)
assert(Movie.count() == 3)
assert(Actor.count() ==0)

// and finally
Movie.executeUpdate("delete from Movie")

assert(Chapter.count() == 0)
assert(Movie.count() == 0)
assert(Actor.count() ==0)

Grails, GORM, isDirty, flush, and multiple instances

Given domain class:

package rmdb

class Actor {
String name;
}


import rmdb.*;
Actor.executeUpdate("delete from Actor")

new Actor(name: 'William Shatner').save(flush: true)

a1 = Actor.findWhere(name: 'William Shatner')
assert(!a1.isDirty())

a2 = Actor.findWhere(name: 'William Shatner')
assert(!a2.isDirty())

// a1 and a2, refer to the same in memory db row proxy GORM object
a1.name = 'Bill Shatner'
assert(a1.isDirty())
assert(a2.isDirty())
assert(a1.name == a2.name)

// despite no explicit save, by default the in mem object 'Bill Shatner'
// is persisted unless it ia explicitly discarded
// a1.discard() // => 'William Shatner'

Grails, GORM, isDirty and flush

Given domain class:

package rmdb

class Actor {
String name;
}

Some observations on saving, flushing and isDirty.

Scenario 1: Creating a new Domain class instance in mem

import rmdb.*;
Actor.executeUpdate("delete from Actor")

def actorA = new Actor(name: 'William Shatner')

// Even though a new actor has been created, it is not dirty
// 'dirty' => read 'inconsistent with DB' as opposed to
// 'is not persisted in the DB in current state'
// A record needs to have an ID/primary key before an
// ORM can make a determination on whether
// the in mem version is consistent or not with its DB saved version
assert(!actorA.isDirty())

actorA.name = 'Will Shatner'
assert(!actorA.isDirty()) // still 'not inconsistent with itself in the DB'
assert(actorA.save()) //no auto-flush, no actual save
println actorA.id // => '1'
assert(!actorA.isDirty())
actorA.name = "Bill Shatner"
assert(actorA.isDirty()) // Now, record actorA is 'not inconsistent with DB'

// If I don't want "Bill Shatner" persisted, I have to
// explicitly discard actorA, otherwise, in mem version will be flushed
// to the DB automatically at the end of request (when the session is flushed/closed)
actorA.discard()

// btw, this implicit save on flush only applies to non-transient domain classes
// ie those domain class instances attached to a hibernate session (with a db ID)
// transient domain class instances are not auto saved.

//aside: oddly actorA.isDirty() now causes an NPE

Scenario 2 – loading an instance from the DB

// Note we didn't save Bill
def actorB = Actor.findWhere(name: 'Will Shatner')
assert(!actorB.isDirty())
actorB.name = "Willie Shatner"
assert(actorB.isDirty())
actorB.save()
assert(actorB.isDirty()) //still dirty after a save (no flush)
actorB.save(flush: true) //save with flush
assert(!actorB.isDirty()) // now, we're good.

Conventions for evaluating a set of applicable access control (acl) policy statements

‘Access Denied’ or ‘Access Granted’ – Assuming an authenticated request, should it be authorized?

Questions:

What happens when an authenticated request attempts to access a system which controls access to resources based on a set of (potentially conflicting) policy statements?

What are the rules of precedence normally used to decide the result of the aggregated authorization request?

Is it the order of the policies?
Is it specificity of the polciy statement?
Is there a priority/weighting associated with each statement?

Answer:
Typically, it works like this:

All statements in the policy are evaluated against the attributes of the  request: (Principal – who wants to do it, Action – what do they want to do, Resource – on what object). Each statement will evaluate to EXPLICIT_ALLOW, EXPLICIT_DENY or DEFAULT_DENY. These policy statements evaluations are then aggregated into an overall ALLOW or DENY

  • Policy statements which do not explicitly pertain to the request attributes ( in terms of the Principal, Action and Resource) evaluate to DEFAULT_DENY
  • All the policies are applicable and evaluates to either EXPLITI_DENY or EXPLICIT_ALLOW

Aggregating the result:

if EXPLICIT_DENY.count > 0
return DENY

if EXPLICIT_ALLOW.count > 0
return ALLOW

return DENY;

Adding access control security features to legacy systems

It is not best practice to default any security system to ‘allow all’ in the absence of more explicit policies and then to hone  it with explicit ‘denies’. As an admin, if you make a mistake, it is likely you omitted an explicit ‘deny’ and you’ve left  the system open in a scenario where  you really want it closed. The most secure systems start out with a ‘deny all’ default and open it up incrementally with explicit ‘allows’ over time.

Though the above may seems like stating the obvious, when you’re faced with adding access control based security to a legacy (read: ‘working’) system, backwards compatibility constraints and availability concerns may dictate an ‘allow all’  default.

If this is the case, you should still start with an implementation based on a ‘deny all’ default but you should prime every resource’s/user’s access control with an ‘Allow all’ override. so when resource owners / admins get around to locking down their resources, they are reverting to customizing a secure by default system. Everyone should be happy.

SQL Joins tutorial / refresher

Considering the following simple schema:

CREATE TABLE one (
id int,
c_name varchar(255),
c_info1 varchar(255),
c_info2 varchar(255));
CREATE TABLE two (
id int,
c_name varchar(255),
c_info1 varchar(255),
c_info2 varchar(255));

insert into one values(1,'aaa','','');
insert into one values(2,'bbb','','');
insert into one values(3,'ccc','c','');
insert into one values(4,'ccc','','');
insert into one values(5,'ccc','','');
insert into one values(6,'ddd','d','');
insert into one values(7,'ddd','','');
insert into one values(8,'eee','','');

insert into two values(1,'aaa','','');
insert into two values(2,'ccc','','');
insert into two values(3,'ccc','','');
insert into two values(4,'ddd','','');
insert into two values(5,'eee','e','');
insert into two values(6,'fff','','');


select count(distinct c_name) from one; -- 5
select count(*) from one; -- 8

Inner joins

The default join is an inner join, therefore the ‘inner’ modifier does not need to be specified. Inner joins are about getting the commonality between the tables as defined in the join clause. There is no extra left/right consideration and swapping the tables around makes no difference to the content of the resulting table.
The following 4 selects are equivalent:

select * from one join two on one.c_name=two.c_name;
select * from one inner join two on one.c_name=two.c_name;
select * from two join one on two.c_name=one.c_name;
select * from two inner join one on two.c_name=one.c_name;

Every row in the left table is evaluated in turn, against every row in the right table based on the criteria expressed in the join clause. If the conditional expression part of the join clause evaluates to true, (in this case, that the value in the c_name column/field in the left row is the same as the c_name value in the row under consideration in the right table) then the rows are joined and included in the resultant table.

-- 10 records
1 aaa 1 aaa
3 ccc c 2 ccc
4 ccc 2 ccc
5 ccc 2 ccc
3 ccc c 3 ccc
4 ccc 3 ccc
5 ccc 3 ccc
6 ddd d 4 ddd
7 ddd 4 ddd
8 eee 5 eee e

In the above example the join key ‘ccc’ occurs 3 times in the left table and 2 times in the right table. Each of the 3 records in the left table matches each of the 2 records in the right table, giving rise to (3×2) six records in the output. Therefore, you can have more records in the result set than in either table.

Note: the row from table one with id 2 and the row from table two with id 6 have been are omitted from the result set by the join based on the join clause.

Cross Joins – just give me everything.

If you take the join conditional clause out of an inner join, and formalize this by putting the ‘cross’ modifier in – you get a cross join. A cross join the same as an inner join in that every combination of pairs of records (one from each table) is considered, but as there’s no limiting join clause, all possible candidate joined rows are accepted for inclusion in the resulting table. The number of entries in the result set is always the number of rows in the left table multiplied by the number of rows in the right table.

select * from one cross join two;
-- yields 8 x 6 = 48 records

Outer joins

We’re not always interested in what is common between two tables, we also want to know what is unique to either or both tables. Outer joins help us with this. There are 3 types of outer join

Left Outer

Changing the join type to left outer causes the query to return additional rows above and beyond an inner join. A “left outer” join specifies that whether or not a row in the left table has a matching record in the right table, it should be included in the result set. The columns in the result table which would normally be populated with the values from the matching row in the right table contain NULLs.

select *
from one left outer join two
on one.c_name = two.c_name

yields a table with one additional row above that yielded by the inner join, ie the left table row not included in the inner join as it has no matching right table row according to the join clause criteria.

1 aaa 1 aaa
2 bbb NULL NULL NULL NULL
3 ccc c 2 ccc
3 ccc c 3 ccc
4 ccc 2 ccc
4 ccc 3 ccc
5 ccc 2 ccc
5 ccc 3 ccc
6 ddd d 4 ddd
7 ddd 4 ddd
8 eee 5 eee e

This union of the commonality and the left table specific data is generally not what we’re after. Mostly we’re after the left table only data.  The nulled out data in the last result set gives us a hook for excluding the inner join rows by adding a where clause:

select *
from one left outer join two
on one.c_name = two.c_name
where two.id is null;

yields the rows specific to the left table

2 bbb NULL NULL NULL NULL

Right Outer

The complement to left outer. The resulting table is going to include all right table rows irrespective of the join clause.

select *
from one right outer join two
on one.c_name = two.c_name

yields and 11 row table containing the 10 inner join rows along with the single row specific to the right table, according to the join clause.

1 aaa 1 aaa
3 ccc c 2 ccc
4 ccc 2 ccc
5 ccc 2 ccc
3 ccc c 3 ccc
4 ccc 3 ccc
5 ccc 3 ccc
6 ddd d 4 ddd
7 ddd 4 ddd
8 eee 5 eee e
NULL NULL NULL NULL 6 fff

If adding a where clause to filter out the inner join rows, it must be based on null values in the left table columns.

select *
from one right outer join two
on one.c_name = two.c_name
where one.id is null

yields the row specific to the right table

NULL NULL NULL NULL 6 fff

Full Outer

A Full Outer join is the union of left and right outer joins

select *
from one full outer join two
on one.c_name = two.c_name

1 aaa 1 aaa
2 bbb NULL NULL NULL NULL
3 ccc c 2 ccc
3 ccc c 3 ccc
4 ccc 2 ccc
4 ccc 3 ccc
5 ccc 2 ccc
5 ccc 3 ccc
6 ddd d 4 ddd
7 ddd 4 ddd
8 eee 5 eee e
NULL NULL NULL NULL 6 fff

To exclude the inner join rows in order to limit the results to the rows specific to the left and right tables extend the where clause to detect NULLs from left and right.

select *
from one full outer join two
on one.c_name = two.c_name
where one.id is null or two.id is null;

2 bbb NULL NULL NULL NULL
NULL NULL NULL NULL 6 fff

Relationship between types of joins

If an inner join returns M rows, a left outer join on the same tables returns M + N rows, a right outer returns M + O, then a full join returns M + N + O, and a cross returns M x N.

Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT)

http://bugs.mysql.com/bug.php?id=18227
[14 Mar 2006 16:55] Mats-Ove Fant
Redefining the VIEW as this solves the problem:

CREATE VIEW test_view AS SELECT sysid,name FROM test_table WHERE name COLLATE
latin1_swedish_ci =
substring_index(substring_index(CURRENT_USER(),’@’,1),’.’,-1);