Merge pull request #232 from mwoodiupui/DS-1456

[DS-1456] "dspace version" command-line script
This commit is contained in:
Mark H. Wood
2013-10-15 08:55:59 -07:00
16 changed files with 444 additions and 30 deletions

View File

@@ -208,7 +208,7 @@
</configuration>
</plugin>
<plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
@@ -263,10 +263,10 @@
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
@@ -483,11 +483,11 @@
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>0.90.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>0.90.3</version>
</dependency>
<dependency>
<groupId>com.coverity.security</groupId>
@@ -508,6 +508,10 @@
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,191 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.util;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.TableRowIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represent a DSpace application while it is running. This helps us report
* which applications *are* running, by exposing a record that can be viewed
* externally.
*
* @author mwood
*/
abstract public class AbstractDSpaceWebapp
implements DSpaceWebappMXBean
{
private static final Logger log = LoggerFactory.getLogger(AbstractDSpaceWebapp.class);
protected String kind;
protected Date started;
protected String url;
private TableRow row;
/** Prevent null instantiation. */
protected AbstractDSpaceWebapp()
{
}
/**
* Construct a particular kind of DSpace application.
*
* @param kind what kind of application is this? (XMLUI, JSPUI, etc.)
*/
public AbstractDSpaceWebapp(String kind)
{
this.kind = kind;
started = new Date();
url = ConfigurationManager.getProperty("dspace.url");
if (null == url)
{
throw new IllegalStateException("dspace.url is undefined");
}
}
/** Record that this application is running. */
public void register()
{
// Create the database entry
Timestamp now = new Timestamp(started.getTime());
try {
Context context = new Context();
row = DatabaseManager.create(context, "Webapp");
row.setColumn("AppName", kind);
row.setColumn("URL", url);
row.setColumn("Started", now);
row.setColumn("isUI", isUI() ? 1 : 0); // update won't widen boolean to integer
DatabaseManager.update(context, row);
context.complete();
} catch (SQLException e) {
log.error("Failed to record startup in Webapp table.", e);
}
}
/** Record that this application is not running. */
public void deregister()
{
// Remove the database entry
try {
Context context = new Context();
DatabaseManager.delete(context, row);
context.complete();
} catch (SQLException e) {
log.error("Failed to record shutdown in Webapp table.", e);
}
}
/** Return the list of running applications. */
static public List<AbstractDSpaceWebapp> getApps()
{
ArrayList<AbstractDSpaceWebapp> apps = new ArrayList<AbstractDSpaceWebapp>();
TableRowIterator tri;
Context context = null;
HttpMethod request = null;
try {
context = new Context();
tri = DatabaseManager.queryTable(context, "Webapp",
"SELECT * FROM Webapp");
for (TableRow row : tri.toList())
{
DSpaceWebapp app = new DSpaceWebapp();
app.kind = row.getStringColumn("AppName");
app.url = row.getStringColumn("URL");
app.started = row.getDateColumn("Started");
app.uiQ = row.getBooleanColumn("isUI");
HttpClient client = new HttpClient();
request = new HeadMethod(app.url);
int status = client.executeMethod(request);
request.getResponseBody();
if (status != HttpStatus.SC_OK)
{
DatabaseManager.delete(context, row);
context.commit();
continue;
}
apps.add(app);
}
} catch (SQLException e) {
log.error("Unable to list running applications", e);
} catch (HttpException e) {
log.error("Failure checking for a running webapp", e);
} catch (IOException e) {
log.error("Failure checking for a running webapp", e);
} finally {
if (null != request)
{
request.releaseConnection();
}
if (null != context)
{
context.abort();
}
}
return apps;
}
/** Container for retrieved database rows. */
static private class DSpaceWebapp
extends AbstractDSpaceWebapp
{
private boolean uiQ;
@Override
public boolean isUI()
{
return uiQ;
}
}
/* DSpaceWebappMXBean methods */
@Override
public String getKind()
{
return kind;
}
@Override
public String getURL()
{
return url;
}
@Override
public String getStarted()
{
return started.toString();
}
}

View File

@@ -23,22 +23,24 @@ import java.util.Enumeration;
/**
* Class to initialize / cleanup resources used by DSpace when the web application
* is started or stopped
* is started or stopped.
*/
public class DSpaceContextListener implements ServletContextListener
{
private static Logger log = Logger.getLogger(DSpaceContextListener.class);
/**
* The DSpace config parameter, this is where the path to the DSpace
* configuration file can be obtained
* Name of the context parameter giving the path to the DSpace configuration file.
*/
public static final String DSPACE_CONFIG_PARAMETER = "dspace-config";
private AbstractDSpaceWebapp webApp;
/**
* Initialize any resources required by the application
* Initialize any resources required by the application.
* @param event
*/
@Override
public void contextInitialized(ServletContextEvent event)
{
@@ -114,6 +116,23 @@ public class DSpaceContextListener implements ServletContextListener
"either the local servlet or global context.\n\n",e);
}
/**
* Stage 3
*
* Register that this application is running.
*/
try {
Class webappClass = Class.forName("org.dspace.utils.DSpaceWebapp");
webApp = (AbstractDSpaceWebapp) webappClass.newInstance();
webApp.register();
} catch (ClassNotFoundException ex) {
event.getServletContext().log("Can't create webapp MBean: " + ex.getMessage());
} catch (InstantiationException ex) {
event.getServletContext().log("Can't create webapp MBean: " + ex.getMessage());
} catch (IllegalAccessException ex) {
event.getServletContext().log("Can't create webapp MBean: " + ex.getMessage());
}
}
/**
@@ -121,8 +140,11 @@ public class DSpaceContextListener implements ServletContextListener
*
* @param event
*/
@Override
public void contextDestroyed(ServletContextEvent event)
{
webApp.deregister();
try
{
// Remove the database pool

View File

@@ -0,0 +1,29 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.util;
/**
* MBean type for discovering DSpace web applications.
*
* @author mwood
*/
public interface DSpaceWebappMXBean
{
/** Is this webapp a user interface? False if machine interface such as SWORD. */
public boolean isUI();
/** What kind of webapp? XMLUI, OAI, etc. */
public String getKind();
/** What is the base URL of this application? */
public String getURL();
/** When did this application start? */
public String getStarted();
}

View File

@@ -49,7 +49,14 @@ public class Version
sys.get("os.arch"),
sys.get("os.version"));
// TODO UIs used
// UIs used
List<AbstractDSpaceWebapp> apps = AbstractDSpaceWebapp.getApps();
System.out.println(" Applications:");
for (AbstractDSpaceWebapp app : apps)
{
System.out.printf(" %s at %s\n",
app.getKind(), app.getURL());
}
// Is Discovery available?
ConfigurationService config = new DSpace().getConfigurationService();
@@ -57,11 +64,13 @@ public class Version
List<String> consumerList = Arrays.asList(consumers.split("\\s*,\\s*"));
if (consumerList.contains("discovery"))
{
System.out.println("Discovery enabled.");
System.out.println(" Discovery: enabled.");
}
// Is Lucene search enabled?
if (consumerList.contains("search"))
{
System.out.println("Lucene search enabled.");
System.out.println(" Lucene search: enabled.");
}
// Java version

View File

@@ -0,0 +1,31 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.utils;
import org.dspace.app.util.AbstractDSpaceWebapp;
/**
* An MBean to identify this web application.
*
* @author mwood
*/
public class DSpaceWebapp
extends AbstractDSpaceWebapp
{
public DSpaceWebapp()
{
super("JSPUI");
}
@Override
public boolean isUI()
{
return true;
}
}

View File

@@ -97,6 +97,10 @@
<groupId>org.dspace</groupId>
<artifactId>dspace-api</artifactId>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-services</artifactId>
</dependency>
<!-- Custom build DSpace cocoon -->
<dependency>

View File

@@ -0,0 +1,31 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.utils;
import org.dspace.app.util.AbstractDSpaceWebapp;
/**
* An MBean to identify this web application.
*
* @author mwood
*/
public class DSpaceWebapp
extends AbstractDSpaceWebapp
{
public DSpaceWebapp()
{
super("XMLUI");
}
@Override
public boolean isUI()
{
return true;
}
}

View File

@@ -116,6 +116,7 @@ CREATE SEQUENCE group2group_seq;
CREATE SEQUENCE group2groupcache_seq;
CREATE SEQUENCE harvested_collection_seq;
CREATE SEQUENCE harvested_item_seq;
CREATE SEQUENCE webapp_seq;
-------------------------------------------------------
-- BitstreamFormatRegistry table
@@ -807,8 +808,11 @@ CREATE TABLE versionitem
CREATE SEQUENCE versionitem_seq;
CREATE SEQUENCE versionhistory_seq;
CREATE TABLE Webapp
(
webapp_id INTEGER NOT NULL PRIMARY KEY,
AppName VARCHAR(32),
URL VARCHAR,
Started TIMESTAMP,
isUI INTEGER
);

View File

@@ -72,6 +72,7 @@ CREATE SEQUENCE harvested_collection_seq;
CREATE SEQUENCE harvested_item_seq;
CREATE SEQUENCE versionitem_seq;
CREATE SEQUENCE versionhistory_seq;
CREATE SEQUENCE webapp_seq;
-------------------------------------------------------
-- BitstreamFormatRegistry table
@@ -751,3 +752,12 @@ CREATE TABLE versionitem
version_summary VARCHAR2(255),
versionhistory_id INTEGER REFERENCES VersionHistory(versionhistory_id)
);
CREATE TABLE Webapp
(
webapp_id INTEGER NOT NULL PRIMARY KEY,
AppName VARCHAR(32),
URL VARCHAR,
Started TIMESTAMP,
isUI INTEGER
);

View File

@@ -0,0 +1,37 @@
--
-- database_schema_18-3.sql
--
-- Version: $Revision$
--
-- Date: $Date: 2012-05-29
--
-- The contents of this file are subject to the license and copyright
-- detailed in the LICENSE and NOTICE files at the root of the source
-- tree and available online at
--
-- http://www.dspace.org/license/
--
--
-- SQL commands to upgrade the database schema of a live DSpace 1.8 or 1.8.x
-- to the DSpace 3 database schema
--
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
--
-------------------------------------------
-- Table of running web applications for 'dspace version' --
-------------------------------------------
CREATE SEQUENCE webapp_seq;
CREATE TABLE Webapp
(
webapp_id INTEGER NOT NULL PRIMARY KEY,
AppName VARCHAR(32),
URL VARCHAR,
Started TIMESTAMP,
isUI INTEGER
);

View File

@@ -86,6 +86,7 @@
@updateseq.sql metadataschemaregistry_seq metadataschemaregistry metadata_schema_id ""
@updateseq.sql harvested_collection_seq harvested_collection id ""
@updateseq.sql harvested_item_seq harvested_item id ""
@updateseq.sql webapp_seq webapp id ""
-- Handle Sequence is a special case. Since Handles minted by DSpace use the 'handle_seq',
-- we need to ensure the next assigned handle will *always* be unique. So, 'handle_seq'

View File

@@ -109,6 +109,7 @@ CREATE SEQUENCE harvested_collection_seq;
CREATE SEQUENCE harvested_item_seq;
CREATE SEQUENCE versionitem_seq;
CREATE SEQUENCE versionhistory_seq;
CREATE SEQUENCE webapp_seq;
-------------------------------------------------------
-- BitstreamFormatRegistry table
@@ -798,9 +799,11 @@ CREATE TABLE versionitem
versionhistory_id INTEGER REFERENCES VersionHistory(versionhistory_id)
);
CREATE TABLE Webapp
(
webapp_id INTEGER NOT NULL PRIMARY KEY,
AppName VARCHAR(32),
URL VARCHAR,
Started TIMESTAMP,
isUI INTEGER
);

View File

@@ -0,0 +1,37 @@
--
-- database_schema_18-3.sql
--
-- Version: $Revision$
--
-- Date: $Date: 2012-05-29
--
-- The contents of this file are subject to the license and copyright
-- detailed in the LICENSE and NOTICE files at the root of the source
-- tree and available online at
--
-- http://www.dspace.org/license/
--
--
-- SQL commands to upgrade the database schema of a live DSpace 1.8 or 1.8.x
-- to the DSpace 3 database schema
--
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST.
--
-------------------------------------------
-- New columns and longer hash for salted password hashing DS-861 --
-------------------------------------------
CREATE SEQUENCE webapp_seq;
CREATE TABLE Webapp
(
webapp_id INTEGER NOT NULL PRIMARY KEY,
AppName VARCHAR(32),
URL VARCHAR,
Started TIMESTAMP,
isUI INTEGER
);

View File

@@ -84,6 +84,7 @@ SELECT setval('metadatavalue_seq', max(metadata_value_id)) FROM metadatavalue;
SELECT setval('metadataschemaregistry_seq', max(metadata_schema_id)) FROM metadataschemaregistry;
SELECT setval('harvested_collection_seq', max(id)) FROM harvested_collection;
SELECT setval('harvested_item_seq', max(id)) FROM harvested_item;
SELECT setval('webapp_seq', max(id)) FROM webapp;
-- Handle Sequence is a special case. Since Handles minted by DSpace use the 'handle_seq',
-- we need to ensure the next assigned handle will *always* be unique. So, 'handle_seq'

View File

@@ -798,7 +798,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<version>2.5</version>
</dependency>
<dependency>