Skip to content

Commit

Permalink
#78: ability to edit model now configurable
Browse files Browse the repository at this point in the history
 - by configuration (defaults.disableModelUpdate) the text area and 'save changes' button can now be changed to prevent modification from the UI
  • Loading branch information
ypujante committed Sep 8, 2011
1 parent 5669134 commit af2d554
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ console.defaults =
]
],

// set this value to true if you don't want to allow for model update (the text area)
// meaning you can only load a new model
disableModelUpdate: false,


header:
[
metadata: ['drMode']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ console.dev.defaults =
'metadata.cluster': [name: 'cluster']
],

disableModelUpdate: false,

model:
[
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class UrlMappings

// system
"/admin/system/save"(controller: 'system', action: 'save') { __nvbe = 'System' }
"/admin/system/setAsCurrent"(controller: 'system', action: 'setAsCurrent') { __nvbe = 'System' }
"/admin/system/addEntry"(controller: 'system', action: 'addEntry') { __nvbe = 'System' }

// audit log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class SystemController extends ControllerBase
systemService.findSystems(request.fabric.name, false, params)

[
currentSystem: request.system,
systems: map.systems,
total: map.count
]
Expand All @@ -57,7 +56,7 @@ class SystemController extends ControllerBase
*/
def view = {
def system = systemService.findDetailsBySystemId(params.id)
[system: system]
[systemDetails: system]
}

/**
Expand Down Expand Up @@ -89,6 +88,28 @@ class SystemController extends ControllerBase
}
}

/**
* Set the system provided as the current one
*/
def setAsCurrent = {
try
{
boolean res = systemService.setAsCurrentSystem(request.fabric.name, params.id)

if(res)
flash.message = "Current system has been set to [${params.id}]"
else
flash.message = "Current system is already [${params.id}]"

redirect(action: 'list')
}
catch(Throwable th)
{
flashException("Could not set the model as the current one: ${th.message}", th)
render(action: 'list')
}
}

/**
* Add a single entry to the model
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public class SystemStorageException extends Exception
{
}

SystemStorageException(String msg)
{
super(msg)
}

SystemStorageException(Errors errors)
{
super(errors?.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,38 @@ public class SystemStorageImpl implements SystemStorage
}
}

@Override
boolean setAsCurrentSystem(String fabric, String systemId)
{
boolean res = false

DbSystemModel.withTransaction { TransactionStatus txStatus ->
DbSystemModel dbSystem = DbSystemModel.findBySystemId(systemId)

DbCurrentSystem dbc = DbCurrentSystem.findByFabric(fabric, [cache: false])

if(dbc)
{
res = dbc.systemModel.systemId != systemId
dbc.systemModel = dbSystem
}
else
{
dbc = new DbCurrentSystem(systemModel: dbSystem,
fabric: fabric)
res = true
}

if(!dbc.save())
{
txStatus.setRollbackOnly()
throw new SystemStorageException(dbc.errors)
}
}

return res
}

@Override
int getSystemsCount(String fabric)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<%@ page import="org.linkedin.util.lang.MemorySize; org.linkedin.glu.grails.utils.ConsoleConfig; org.linkedin.glu.console.controllers.SystemController" %>
<g:set var="columns" value="${columns == null ? ConsoleConfig.getInstance().defaults.system : columns}"/>
<g:form action="setAsCurrent" method="post">
<table>
<thead>
<tr>
Expand All @@ -27,11 +28,12 @@
<th>${column.name}</th>
</g:each>
<th>Size</th>
<th>Current</th>
</tr>
</thead>
<tbody>
<g:each in="${systems}" status="i" var="system">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'} ${system.systemId == currentSystem?.id ? 'current' : ''}">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'} ${(system.systemId == request.system?.id) ? 'current' : ''}">
<td class="systemId"><g:link controller="system" action="view" id="${system.systemId}">${system.systemId}</g:link></td>
<td>${system.fabric}</td>
<td><cl:formatDate date="${system.dateCreated}"/></td>
Expand All @@ -40,7 +42,9 @@
<td>${stats[columnName] ?: 0}</td>
</g:each>
<td><g:if test="${system.size}">${new MemorySize(system.size)}</g:if><g:else>N/A</g:else></td>
<td><input type="radio" name="id" value="${system.systemId}" ${system.systemId == request.system?.id ? 'checked="checked"' : ''} onclick="if(confirm('Are you sure you want to set system [${system.systemId}] as the curren one?')) {this.form.submit()} else return false;"/></td>
</tr>
</g:each>
</tbody>
</table>
</g:form>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%{--
- Copyright (c) 2010-2010 LinkedIn, Inc
- Portions Copyright (c) 2011 Yan Pujante
-
- 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
Expand All @@ -14,7 +15,7 @@
- the License.
--}%

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="org.linkedin.glu.grails.utils.ConsoleConfig" contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>GLU Console - View System ${params.id}</title>
Expand All @@ -28,6 +29,9 @@
padding: 0.2em;
text-align: center;
}
.current {
background: #eeeeff;
}
</style>
</head>
<body>
Expand All @@ -37,14 +41,17 @@
<li><g:link action="delta">Current</g:link></li>
<li class="selected">View [${params.id}]</li>
</ul>
<g:if test="${system}">
<g:render template="system" model="[systems: [system]]"/>
<g:if test="${systemDetails}">
<g:set var="editable" value="${!ConsoleConfig.getInstance().defaults.disableModelUpdate}"/>
<g:render template="system" model="[systems: [systemDetails]]"/>
<g:form action="save" method="post">
<textarea rows="40" cols="150" id="content" name="content">${params.content ?: system.systemModel}</textarea>
<textarea rows="40" cols="150" id="content" name="content" ${editable ? '' : 'readonly="true"'}>${params.content ?: systemDetails.systemModel}</textarea>
<g:hiddenField name="id" value="${params.id}"/>
<div class="buttons">
<span class="button"><input class="save" type="submit" value="Save changes"/></span>
</div>
<g:if test="${editable}">
<div class="buttons">
<span class="button"><input class="save" type="submit" value="Save changes"/></span>
</div>
</g:if>
</g:form>
</g:if>
<g:else>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,50 @@ class SystemServiceIntegrationTests extends GroovyTestCase
assertEquals('json', currentModel.contentSerializer)
assertEquals(model2, currentModel.systemModel)
}

public void testSetAsCurrentSystem()
{
SystemModel model1 = new SystemModel(fabric: 'f1')
model1.addEntry(new SystemEntry(agent: 'h1', script: 's1', mountPoint: '/m1'))

SystemModel model2 = new SystemModel(fabric: 'f1')
model2.addEntry(new SystemEntry(agent: 'h2', script: 's2', mountPoint: '/m2'))

SystemModel model3 = new SystemModel(fabric: 'f2')
model2.addEntry(new SystemEntry(agent: 'h3', script: 's3', mountPoint: '/m3'))

assertTrue(systemService.saveCurrentSystem(model1))
model1 = systemService.findCurrentSystem('f1')

// setting the current system to be model1: already model1 => return false
assertFalse(systemService.setAsCurrentSystem('f1', model1.id))

// changing current system to model2
assertTrue(systemService.saveCurrentSystem(model2))
model2 = systemService.findCurrentSystem('f1')

// should be the new one
assertNotSame(model1.id, model2.id)

// now resetting current system to model1 => return true
assertTrue(systemService.setAsCurrentSystem('f1', model1.id))
assertEquals(model1.id, systemService.findCurrentSystem('f1').id)

// saving model3 as current system (in fabric f2!)
assertTrue(systemService.saveCurrentSystem(model3))
model3 = systemService.findCurrentSystem('f2')

// should not affect f1!
assertEquals(model1.id, systemService.findCurrentSystem('f1').id)

// trying to set as current a system from a different fabric should fail
shouldFail(IllegalArgumentException) {
systemService.setAsCurrentSystem('f1', model3.id)
}

// trying to set an unknown system should fail
shouldFail(IllegalArgumentException) {
systemService.setAsCurrentSystem('f1', 'unknown system')
}
}
}
13 changes: 13 additions & 0 deletions docs/manual/src/main/sphinx/source/console.rst
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,19 @@ This configuration results in the following output:
* the key represent the :term:`dotted notation` of an entry (see: :ref:`goe-filter-syntax` for more details and examples on the dotted notation)
* the value is a map with (currently) one entry only: ``name`` which represents the (display) name of the column

.. note:: Since 3.3.0, it takes effect only when showing a single system: for performance reasons the page which shows the list of systems no longer fetches the system and as such cannot display this information

Non Editable Model
""""""""""""""""""

You can enable or disable the fact that a system model is editable or not by changing the following property::

disableModelUpdate: false,

By default, the model is editable which means that there is a ``Save Changes`` button and the text area containing the body is editable. Changing this value to ``true`` removes the button and makes the text area non editable anymore.

.. note:: Even if the model is not editable, it is always possible to *load* a new one by going to the ``Model`` tab. The idea behind this feature is to enforce the fact that the model should be properly versioned outside of glu and changing it should go through a proper flow that is beyond the scope of glu.

Model
"""""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public interface SystemService
*/
boolean saveCurrentSystem(SystemModel newSystemModel)

/**
* Sets the system provided its id as the current system
*
* @return <code>false</code> if the provided system is already the current system,
* <code>true</code> otherwise
*/
boolean setAsCurrentSystem(String fabric, String systemId)

/**
* @return the number of systems in the fabric
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ public class SystemServiceImpl implements SystemService
return true;
}

@Override
synchronized boolean setAsCurrentSystem(String fabric, String systemId)
{
SystemModel previousSystemModel = systemStorage.findBySystemId(systemId)

if(previousSystemModel == null)
throw new IllegalArgumentException("no such system: ${systemId}")

if(previousSystemModel.fabric != fabric)
throw new IllegalArgumentException("system [${systemId}] does not belong to fabric ${fabric}")

systemStorage.setAsCurrentSystem(fabric, systemId)
}

@Override
SystemModel findCurrentSystem(String fabric)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public interface SystemStorage

void saveCurrentSystem(SystemModel systemModel)

boolean setAsCurrentSystem(String fabric, String systemId)

/**
* params can be what grails accept for paginating queries: <code>max</code>,
* <code>offset</code>, <code>sort</code>, <code>order</code>
Expand Down

0 comments on commit af2d554

Please sign in to comment.