Skip to content

Commit

Permalink
added tag to autologin to dbconsole
Browse files Browse the repository at this point in the history
  • Loading branch information
burtbeckwith committed Sep 27, 2011
1 parent aac11c7 commit 10fda78
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .classpath
Expand Up @@ -4,7 +4,9 @@
<classpathentry kind="src" path="src/groovy"/> <classpathentry kind="src" path="src/groovy"/>
<classpathentry kind="src" path="src/docs"/> <classpathentry kind="src" path="src/docs"/>
<classpathentry kind="src" path="grails-app/conf"/> <classpathentry kind="src" path="grails-app/conf"/>
<classpathentry kind="src" path="grails-app/taglib"/>
<classpathentry kind="src" path="scripts"/> <classpathentry kind="src" path="scripts"/>
<classpathentry kind="src" path="test/integration"/>
<classpathentry kind="src" path="test/unit"/> <classpathentry kind="src" path="test/unit"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="com.springsource.sts.grails.core.CLASSPATH_CONTAINER"/> <classpathentry kind="con" path="com.springsource.sts.grails.core.CLASSPATH_CONTAINER"/>
Expand Down
1 change: 0 additions & 1 deletion build.xml
Expand Up @@ -60,7 +60,6 @@
<delete dir='grails-app/domain'/> <delete dir='grails-app/domain'/>
<delete dir='grails-app/i18n'/> <delete dir='grails-app/i18n'/>
<delete dir='grails-app/services'/> <delete dir='grails-app/services'/>
<delete dir='grails-app/taglib'/>
<delete dir='grails-app/utils'/> <delete dir='grails-app/utils'/>
<delete dir='grails-app/views'/> <delete dir='grails-app/views'/>
<delete dir='web-app'/> <delete dir='web-app'/>
Expand Down
128 changes: 128 additions & 0 deletions grails-app/taglib/grails/plugin/cloudfoundry/CloudFoundryTagLib.groovy
@@ -0,0 +1,128 @@
/* Copyright 2011 SpringSource.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package grails.plugin.cloudfoundry

import grails.converters.JSON

import java.util.Map

/**
* @author Burt Beckwith
*/
class CloudFoundryTagLib {

static namespace = 'cf'

def grailsApplication
def pluginManager

/**
* Creates a link that opens the H2 database console using connect information from VCAP_SERVICES.
*
* @attr name if specified the link will be for that service, otherwise the first JDBC service will be used
* @attr consolePath optional - the root of the uri to the console; usually not necessary but useful if you have a url mapping
*/
def dbconsoleLink = { attrs, body ->

String name = attrs.name ?: null
def connectInfo = findDbConnectInfo(name)
if (!connectInfo) {
if (name) {
log.warn "No service found with name '$name'"
}
else {
log.warn "No MySQL or PostgreSQL service found"
}
return
}

String dbDriver = URLEncoder.encode(connectInfo.driver, 'UTF-8')
String dbUrl = URLEncoder.encode(connectInfo.url, 'UTF-8')
String dbUser = URLEncoder.encode(connectInfo.user, 'UTF-8')
String dbPassword = URLEncoder.encode(connectInfo.password, 'UTF-8')

String consolePath
if (attrs.consolePath) {
consolePath = attrs.consolePath
}
else {
if (pluginManager.hasGrailsPlugin('dbconsole')) {
// not configurable in the plugin
consolePath = '/dbconsole'
}
else {
consolePath = grailsApplication.config.grails.dbconsole.urlRoot ?: '/dbconsole'
}
}

out << """<a href='javascript:void(0)' onclick='openDbConsole()'>${body()}</a>
<script>
function openDbConsole() {
\$.get('${request.contextPath}$consolePath/login.do', function(html) {
var start = html.indexOf('login.jsp?jsessionid=');
var end = html.indexOf("'", start + 1);
var jsessionid = html.substring(start + 21, end);
location.href = '${request.contextPath}$consolePath/login.do?driver=${dbDriver}&url=${dbUrl}&user=${dbUser}&password=${dbPassword}&jsessionid=' + jsessionid;
});
}
</script>
"""
}

private Map findDbConnectInfo(String name, boolean multiple = false) {
// put in TreeMap to make order predictable for testing
def servicesMap = new TreeMap(JSON.parse(System.getenv('VCAP_SERVICES')))

for (entry in servicesMap) {
String key = entry.key
def services = entry.value
String type
String driver
if (key.startsWith('mysql')) {
type = 'mysql'
driver = 'com.mysql.jdbc.Driver'
}
else if (key.startsWith('postgresql')) {
type = 'postgresql'
driver = 'org.postgresql.Driver'
}
else {
continue
}

def maps = []
for (service in services) {
if (name == null || name.equals(service.name)) {
def data = [
url: "jdbc:$type://$service.credentials.hostname:$service.credentials.port/$service.credentials.name",
user: service.credentials.user,
password: service.credentials.password,
driver: driver]

if (multiple) {
maps << data
}
else {
return data
}
}
}

if (multiple) {
return maps
}
}
}
}
@@ -0,0 +1,114 @@
package grails.plugin.cloudfoundry

import grails.test.GroovyPagesTestCase

class CloudFoundryTagLibTests extends GroovyPagesTestCase {

static transactional = false

private realSystemMetaclass

private static final String JSON = '''
{"redis-2.2":
[{"name":"redis-1d8e28a",
"label":"redis-2.2",
"plan":"free",
"credentials":{
"node_id":"redis_node_3",
"hostname":"172.30.48.42",
"port":5004,
"password":"1463d9d0-4e35-4f2e-be2f-01dc5536f183",
"name":"redis-1a69a915-6522-496c-93d5-1271d2b3118e"}
}],
"mongodb-1.8":
[{"name":"mongodb-3854dbe",
"label":"mongodb-1.8",
"plan":"free",
"credentials":{
"hostname":"172.30.48.63",
"port":25003,
"username":"b6877670-da98-4124-85ca-84357f042797",
"password":"f53e6a4b-f4b8-497d-ac81-43cb22cf1e88",
"name":"mongodb-9dda2cfb-9672-4d58-8786-98c3abcb21ec",
"db":"db"}
}],
"mysql-5.1":
[{"name":"mysql-service",
"label":"mysql-5.1",
"plan":"free",
"credentials":{
"node_id":"mysql_node_8",
"hostname":"mysql_server",
"port":4321,
"password":"mysql_password",
"name":"mysql_database",
"user":"mysql_user"}
}],
"postgresql-9":
[{"name":"postgres-service",
"label":"postgres-9",
"plan":"free",
"credentials":{
"node_id":"postgres_node_8",
"hostname":"postgresql_server",
"port":1234,
"password":"postgresql_password",
"name":"postgresql_database",
"user":"postgresql_user"}
}]
}
'''

@Override
protected void setUp() {
super.setUp()

//registerMetaClass isn't available
realSystemMetaclass = System.metaClass
def emc = new ExpandoMetaClass(System, true, true)
emc.initialize()
GroovySystem.metaClassRegistry.setMetaClass(System, emc)

System.getenv('VCAP_SERVICES')
System.metaClass.static.getenv = { String name -> JSON }
}

@Override
protected void tearDown() {
super.tearDown()
GroovySystem.metaClassRegistry.removeMetaClass(System)
GroovySystem.metaClassRegistry.setMetaClass(System, realSystemMetaclass)
}

void testNoName() {
String output = applyTemplate('<cf:dbconsoleLink>MySQL DbConsole</cf:dbconsoleLink>')

assertTrue output.contains("<a href='javascript:void(0)' onclick='openDbConsole()'>MySQL DbConsole</a>")

assertTrue output.contains(
"location.href = '/dbconsole/login.do" +
"?driver=com.mysql.jdbc.Driver" +
"&url=jdbc%3Amysql%3A%2F%2Fmysql_server%3A4321%2Fmysql_database" +
"&user=mysql_user" +
"&password=mysql_password" +
"&jsessionid=' + jsessionid;")
}

void testBadName() {
assertOutputEquals('', '<cf:dbconsoleLink name="flongle">Foo</cf:dbconsoleLink>')
}

void testGoodName() {
String output = applyTemplate('<cf:dbconsoleLink name="postgres-service">PostgreSQL DbConsole</cf:dbconsoleLink>')

assertTrue output.contains("<a href='javascript:void(0)' onclick='openDbConsole()'>PostgreSQL DbConsole</a>")

assertTrue output.contains(
"location.href = '/dbconsole/login.do" +
"?driver=org.postgresql.Driver" +
"&url=jdbc%3Apostgresql%3A%2F%2Fpostgresql_server%3A1234%2Fpostgresql_database" +
"&user=postgresql_user" +
"&password=postgresql_password" +
"&jsessionid=' + jsessionid;")
}
}

0 comments on commit 10fda78

Please sign in to comment.