From 66eeb6a273b1a60813375a4bf55bcc38e1a3d00a Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Wed, 25 May 2011 18:12:48 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- .../.settings/org.eclipse.wst.common.component | 1 + .../WebContent/WEB-INF/lib/antlr-2.7.6.jar | Bin 0 -> 443432 bytes .../WEB-INF/lib/commons-collections-3.1.jar | Bin 0 -> 559366 bytes .../WebContent/WEB-INF/lib/dom4j-1.6.1.jar | Bin 0 -> 313898 bytes .../lib/hibernate-jpa-2.0-api-1.0.0.Final.jar | Bin 0 -> 100884 bytes .../WebContent/WEB-INF/lib/hibernate3.jar | Bin 0 -> 4133342 bytes .../WebContent/WEB-INF/lib/javassist-3.12.0.GA.jar | Bin 0 -> 633312 bytes .../WebContent/WEB-INF/lib/jta-1.1.jar | Bin 0 -> 10899 bytes .../WebContent/WEB-INF/lib/log4j-1.2.16.jar | Bin 0 -> 481534 bytes .../WebContent/WEB-INF/lib/slf4j-api-1.6.1.jar | Bin 0 -> 25496 bytes .../WebContent/data/scripts/1.0.0/0-version.sql | 2 + .../data/scripts/1.0.0/1-security-schema.sql | 26 ++++ .../scripts/1.0.0/2-users-authorities-groups.sql | 21 +++ .../data/scripts/1.0.0/3-cluster-servers.sql | 16 +++ .../WebContent/scripts/Common.py | 34 ----- .../WebContent/scripts/Globals.py | 3 - .../WebContent/scripts/vmware-discover-servers.py | 83 ------------ .../src/META-INF/persistence.xml | 5 + .../management/server/data/ClusterInfo.java | 74 +++++++++++ .../management/server/data/PersistenceDao.java | 108 ++++++++++++++++ .../storage/management/server/data/ServerInfo.java | 65 ++++++++++ .../server/resources/AbstractServersResource.java | 13 +- .../server/resources/AlertsResource.java | 4 +- .../server/resources/ClustersResource.java | 112 ++++++++++++++++ .../server/resources/GlusterServersResource.java | 143 ++++++++++++++++++--- .../server/resources/RunningTaskResource.java | 4 +- .../server/resources/VolumesResource.java | 101 +++++++++------ .../management/server/tasks/InitServerTask.java | 97 +++++++++++--- .../management/server/utils/GlusterUtil.java | 19 +-- .../management/server/utils/ServerUtil.java | 29 ++++- .../storage/management/server/utils/SshUtil.java | 21 ++- .../src/data/scripts/security-schema.sql | 26 ---- .../src/data/scripts/users-authorities-groups.sql | 21 --- .../src/log4j.properties | 12 ++ .../src/spring/gluster-server-base.xml | 71 ++++++---- 35 files changed, 805 insertions(+), 306 deletions(-) create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/antlr-2.7.6.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/commons-collections-3.1.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/dom4j-1.6.1.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate3.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/javassist-3.12.0.GA.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jta-1.1.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/log4j-1.2.16.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/slf4j-api-1.6.1.jar create mode 100644 src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/0-version.sql create mode 100644 src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/1-security-schema.sql create mode 100644 src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/2-users-authorities-groups.sql create mode 100644 src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/3-cluster-servers.sql delete mode 100644 src/com.gluster.storage.management.server/WebContent/scripts/Common.py delete mode 100644 src/com.gluster.storage.management.server/WebContent/scripts/Globals.py delete mode 100755 src/com.gluster.storage.management.server/WebContent/scripts/vmware-discover-servers.py create mode 100644 src/com.gluster.storage.management.server/src/META-INF/persistence.xml create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ClusterInfo.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/PersistenceDao.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ServerInfo.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java delete mode 100644 src/com.gluster.storage.management.server/src/data/scripts/security-schema.sql delete mode 100644 src/com.gluster.storage.management.server/src/data/scripts/users-authorities-groups.sql create mode 100644 src/com.gluster.storage.management.server/src/log4j.properties (limited to 'src/com.gluster.storage.management.server') diff --git a/src/com.gluster.storage.management.server/.settings/org.eclipse.wst.common.component b/src/com.gluster.storage.management.server/.settings/org.eclipse.wst.common.component index bb2eaf45..e9b43da9 100644 --- a/src/com.gluster.storage.management.server/.settings/org.eclipse.wst.common.component +++ b/src/com.gluster.storage.management.server/.settings/org.eclipse.wst.common.component @@ -3,6 +3,7 @@ + diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/antlr-2.7.6.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/antlr-2.7.6.jar new file mode 100644 index 00000000..3702b645 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/antlr-2.7.6.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/commons-collections-3.1.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/commons-collections-3.1.jar new file mode 100644 index 00000000..41e230fe Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/commons-collections-3.1.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/dom4j-1.6.1.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/dom4j-1.6.1.jar new file mode 100644 index 00000000..c8c4dbb9 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/dom4j-1.6.1.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar new file mode 100644 index 00000000..4c9ac4e9 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate3.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate3.jar new file mode 100644 index 00000000..c1c81141 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/hibernate3.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/javassist-3.12.0.GA.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/javassist-3.12.0.GA.jar new file mode 100644 index 00000000..8f692f4f Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/javassist-3.12.0.GA.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jta-1.1.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jta-1.1.jar new file mode 100644 index 00000000..6d225b76 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jta-1.1.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/log4j-1.2.16.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/log4j-1.2.16.jar new file mode 100644 index 00000000..3f9d8476 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/log4j-1.2.16.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/slf4j-api-1.6.1.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/slf4j-api-1.6.1.jar new file mode 100644 index 00000000..f1f4fdd2 Binary files /dev/null and b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/slf4j-api-1.6.1.jar differ diff --git a/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/0-version.sql b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/0-version.sql new file mode 100644 index 00000000..4c3d81d1 --- /dev/null +++ b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/0-version.sql @@ -0,0 +1,2 @@ +create table version (version varchar(16) not null primary key); +insert into version(version) values('1.0.0'); \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/1-security-schema.sql b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/1-security-schema.sql new file mode 100644 index 00000000..fdde5823 --- /dev/null +++ b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/1-security-schema.sql @@ -0,0 +1,26 @@ +create table users( + username varchar(50) not null primary key, + password varchar(50) not null, + enabled smallint not null + ); + + create table authorities ( + username varchar(50) not null, + authority varchar(50) not null, + constraint fk_authorities_users foreign key(username) references users(username)); + create unique index ix_auth_username on authorities (username,authority); + +create table groups ( + id bigint generated by default as identity(start with 0) primary key, + group_name varchar(50) not null); + +create table group_authorities ( + group_id bigint not null, + authority varchar(50) not null, + constraint fk_group_authorities_group foreign key(group_id) references groups(id)); + +create table group_members ( + id bigint generated by default as identity(start with 0) primary key, + username varchar(50) not null, + group_id bigint not null, + constraint fk_group_members_group foreign key(group_id) references groups(id)); diff --git a/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/2-users-authorities-groups.sql b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/2-users-authorities-groups.sql new file mode 100644 index 00000000..35ccf965 --- /dev/null +++ b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/2-users-authorities-groups.sql @@ -0,0 +1,21 @@ +-- Create users +insert into users(username, password, enabled) values ('gluster','gluster',1); +insert into users(username, password, enabled) values ('guest','guest',1); + +-- Assign authorities to users (to be removed after implementing user group functionality) +insert into authorities(username,authority) values ('gluster','ROLE_USER'); +insert into authorities(username,authority) values ('gluster','ROLE_ADMIN'); +insert into authorities(username,authority) values ('guest','ROLE_USER'); + +-- Create user groups +insert into groups(group_name) values ('Users'); +insert into groups(group_name) values ('Administrators'); + +-- Add authorities to groups (functionality not yet implemented in code) +insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Users'; +insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Administrators'; +insert into group_authorities(group_id, authority) select id,'ROLE_ADMIN' from groups where group_name='Administrators'; + +-- Assign group members +insert into group_members(group_id, username) select id,'guest' from groups where group_name='Users'; +insert into group_members(group_id, username) select id,'gluster' from groups where group_name='Administrators'; \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/3-cluster-servers.sql b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/3-cluster-servers.sql new file mode 100644 index 00000000..17ca62d2 --- /dev/null +++ b/src/com.gluster.storage.management.server/WebContent/data/scripts/1.0.0/3-cluster-servers.sql @@ -0,0 +1,16 @@ +create table cluster_info ( + id bigint generated by default as identity, + name varchar(255), + primary key (id)); + +create unique index ix_cluster_name on cluster_info (name); + +create table server_info ( + id bigint generated by default as identity, + name varchar(255), + cluster_id bigint, + primary key (id)); + +create unique index ix_cluster_server on server_info (name, cluster_id); + +alter table server_info add constraint FK_CLUSTER_ID foreign key (cluster_id) references cluster_info(id); \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/Common.py b/src/com.gluster.storage.management.server/WebContent/scripts/Common.py deleted file mode 100644 index 60f200fe..00000000 --- a/src/com.gluster.storage.management.server/WebContent/scripts/Common.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2009 Gluster, Inc. -# This file is part of GlusterSP. -# -# GlusterSP is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published -# by the Free Software Foundation; either version 3 of the License, -# or (at your option) any later version. -# -# GlusterSP is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import syslog - -def log(priority, message=None): - if type(priority) == type(""): - logPriority = syslog.LOG_INFO - logMessage = priority - else: - logPriority = priority - logMessage = message - if not logMessage: - return - #if Globals.DEBUG: - # sys.stderr.write(logMessage) - else: - syslog.syslog(logPriority, logMessage) - return diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/Globals.py b/src/com.gluster.storage.management.server/WebContent/scripts/Globals.py deleted file mode 100644 index 6e68adbd..00000000 --- a/src/com.gluster.storage.management.server/WebContent/scripts/Globals.py +++ /dev/null @@ -1,3 +0,0 @@ -MULTICAST_GROUP = '224.224.1.1' -MULTICAST_PORT = 5353 -DISCOVERED_SERVER_LIST_FILENAME = "/tmp/discovered-server-list" diff --git a/src/com.gluster.storage.management.server/WebContent/scripts/vmware-discover-servers.py b/src/com.gluster.storage.management.server/WebContent/scripts/vmware-discover-servers.py deleted file mode 100755 index 6ac15fed..00000000 --- a/src/com.gluster.storage.management.server/WebContent/scripts/vmware-discover-servers.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2009 Gluster, Inc. -# This file is part of Gluster Storage Platform. -# -# Gluster Storage Platform is free software; you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# Gluster Storage Platform is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . - -import sys -import socket -import signal -import struct -import syslog -import Globals -import Common - -class TimeoutException(Exception): - pass - -def timeoutSignal(signum, frame): - raise TimeoutException, "Timed out" - -def serverDiscoveryRequest(multiCastGroup, port): - servers = [] - # Sending request to all the servers - socketSend = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketSend.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) - socketSend.sendto("ServerDiscovery", (multiCastGroup, port)) - - # Waiting for the response - socketReceive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - socketReceive.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - socketReceive.bind(('', port)) - mreq = struct.pack("4sl", socket.inet_aton(multiCastGroup), socket.INADDR_ANY) - - socketReceive.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - socketSend.sendto("ServerDiscovery", (multiCastGroup, port)) - - try: - while True: - response = socketReceive.recvfrom(200) - if response and response[0].upper() != "SERVERDISCOVERY": - servers.append(response[0]) - signal.signal(signal.SIGALRM, timeoutSignal) - signal.alarm(3) - except TimeoutException: - return servers - return None - -def main(): - syslog.openlog("discovery server request") - servers = serverDiscoveryRequest(Globals.MULTICAST_GROUP, Globals.MULTICAST_PORT) - if not servers: - Common.log(syslog.LOG_ERR, "Failed to discover new servers") - sys.exit(-1) - - servers = set(servers) - try: - #fp = open(Globals.DISCOVERED_SERVER_LIST_FILENAME, "w") - #fp.writelines(list(servers)) - #fp.close() - for server in servers: - print server - except IOError: - Common.log(syslog.LOG_ERR, "Unable to open file %s" % Globals.DISCOVERED_SERVER_LIST_FILENAME) - sys.exit(-1) - - #for serverName in servers: - # print serverName - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/com.gluster.storage.management.server/src/META-INF/persistence.xml b/src/com.gluster.storage.management.server/src/META-INF/persistence.xml new file mode 100644 index 00000000..36b252ea --- /dev/null +++ b/src/com.gluster.storage.management.server/src/META-INF/persistence.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ClusterInfo.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ClusterInfo.java new file mode 100644 index 00000000..093423f0 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ClusterInfo.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.data; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +import org.hibernate.cfg.AnnotationConfiguration; +import org.hibernate.tool.hbm2ddl.SchemaExport; + +@Entity(name="cluster_info") +public class ClusterInfo { + @Id + @GeneratedValue + private Integer id; + + private String name; + + @OneToMany(mappedBy="cluster") + private List servers; + + public void setId(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setServers(List servers) { + this.servers = servers; + } + + public List getServers() { + return servers; + } + + public static void main(String args[]) { + AnnotationConfiguration config = new AnnotationConfiguration(); + config.addAnnotatedClass(ClusterInfo.class); + config.addAnnotatedClass(ServerInfo.class); + config.configure(); + new SchemaExport(config).create(true, true); + } + +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/PersistenceDao.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/PersistenceDao.java new file mode 100644 index 00000000..6fd7ecdc --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/PersistenceDao.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.data; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.PersistenceUnit; +import javax.persistence.Query; + +/** + * + */ +public class PersistenceDao { + private Class type; + + private EntityManager entityManager; + + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; + + public PersistenceDao(Class type) { + this.type = type; + } + + public EntityTransaction startTransaction() { + EntityTransaction txn = getEntityManager().getTransaction(); + txn.begin(); + return txn; + } + + private synchronized EntityManager getEntityManager() { + if (entityManager == null) { + entityManager = entityManagerFactory.createEntityManager(); + } + return entityManager; + } + + public Object getSingleResult(String query) { + return getEntityManager().createQuery(query).getSingleResult(); + } + + public Object getSingleResult(String queryString, String... params) { + return createQuery(queryString, params).getSingleResult(); + } + + private Query createQuery(String queryString, String... params) { + Query query = getEntityManager().createQuery(queryString); + for (int i = 0; i < params.length; i++) { + query.setParameter(i + 1, params[i]); + } + return query; + } + + public Object getSingleResultFromSQL(String sqlQuery) { + return getEntityManager().createNativeQuery(sqlQuery).getSingleResult(); + } + + public T findById(int id) { + return getEntityManager().find(type, id); + } + + @SuppressWarnings("unchecked") + public List findAll() { + return getEntityManager().createQuery("select t from " + type.getName() + " t").getResultList(); + } + + @SuppressWarnings("unchecked") + public List findBy(String whereClause) { + return getEntityManager().createQuery("select t from " + type.getName() + " t where " + whereClause) + .getResultList(); + } + + @SuppressWarnings("unchecked") + public List findBy(String whereClause, String... params) { + return createQuery("select t from " + type.getName() + " t where " + whereClause, params).getResultList(); + } + + public void save(T obj) { + getEntityManager().persist(obj); + } + + public T update(T obj) { + return getEntityManager().merge(obj); + } + + public void delete(T obj) { + getEntityManager().remove(obj); + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ServerInfo.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ServerInfo.java new file mode 100644 index 00000000..88ce51ca --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/data/ServerInfo.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +/** + * + */ +@Entity(name="server_info") +public class ServerInfo { + @Id + @GeneratedValue + private Integer id; + + private String name; + + @ManyToOne + @JoinColumn(name="cluster_id") + private ClusterInfo cluster; + + public void setId(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setCluster(ClusterInfo cluster) { + this.cluster = cluster; + } + + public ClusterInfo getCluster() { + return cluster; + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java index 8c7f54ae..ce408502 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java @@ -32,10 +32,10 @@ import com.sun.jersey.api.core.InjectParam; */ public class AbstractServersResource { @InjectParam - private ServerUtil serverUtil; + protected ServerUtil serverUtil; @InjectParam - private GlusterUtil glusterUtil; + protected GlusterUtil glusterUtil; /** * Fetch details of the given server. The server name must be populated in the object before calling this method. @@ -47,16 +47,9 @@ public class AbstractServersResource { // fetch standard server details like cpu, disk, memory details Object response = serverUtil.executeOnServer(true, server.getName(), "get_server_details.py", Server.class); if (response instanceof Status) { + // TODO: check if this happened because the server is not reachable, and if yes, set it's status as offline throw new GlusterRuntimeException(((Status)response).getMessage()); } server.copyFrom((Server) response); // Update the details in object } - - protected void setGlusterUtil(GlusterUtil glusterUtil) { - this.glusterUtil = glusterUtil; - } - - protected GlusterUtil getGlusterUtil() { - return glusterUtil; - } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java index e33e06c9..4283b5d6 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java @@ -1,6 +1,6 @@ package com.gluster.storage.management.server.resources; -import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_ALERTS; +import static com.gluster.storage.management.core.constants.RESTConstants.*; import java.util.ArrayList; import java.util.List; @@ -16,7 +16,7 @@ import com.gluster.storage.management.core.model.AlertListResponse; import com.gluster.storage.management.core.model.Alert; @Component -@Path(RESOURCE_PATH_ALERTS) +@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_ALERTS) public class AlertsResource { @GET diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java new file mode 100644 index 00000000..f04941cf --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.resources; + +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityTransaction; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.response.StringListResponse; +import com.gluster.storage.management.server.data.ClusterInfo; +import com.gluster.storage.management.server.data.PersistenceDao; +import com.sun.jersey.api.core.InjectParam; + +/** + * + */ +@Path(RESOURCE_PATH_CLUSTERS) +public class ClustersResource { + + @InjectParam + private PersistenceDao clusterDao; + + public void setClusterDao(PersistenceDao clusterDao) { + this.clusterDao = clusterDao; + } + + public PersistenceDao getClusterDao() { + return clusterDao; + } + + @GET + @Produces(MediaType.TEXT_XML) + public StringListResponse getClusters() { + List clusters = getClusterDao().findAll(); + List clusterList = new ArrayList(); + for (ClusterInfo cluster : clusters) { + clusterList.add(cluster.getName()); + } + return new StringListResponse(clusterList); + } + + @POST + @Produces(MediaType.TEXT_XML) + public Status createCluster(@FormParam(FORM_PARAM_CLUSTER_NAME) String clusterName) { + EntityTransaction txn = clusterDao.startTransaction(); + ClusterInfo cluster = new ClusterInfo(); + cluster.setName(clusterName); + + try { + clusterDao.save(cluster); + txn.commit(); + return Status.STATUS_SUCCESS; + } catch (Exception e) { + txn.rollback(); + return new Status(Status.STATUS_CODE_FAILURE, "Exception while trying to save cluster [" + clusterName + + "]: [" + e.getMessage() + "]"); + } + } + + @SuppressWarnings("unchecked") + @Path("{" + PATH_PARAM_CLUSTER_NAME + "}") + @DELETE + @Produces(MediaType.TEXT_XML) + public Status deleteCluster(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { + List clusters = clusterDao.findBy("name = ?1", clusterName); + if (clusters == null || clusters.size() == 0) { + return new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"); + } + + ClusterInfo cluster = clusters.get(0); + EntityTransaction txn = clusterDao.startTransaction(); + try { + clusterDao.delete(cluster); + txn.commit(); + return Status.STATUS_SUCCESS; + } catch (Exception e) { + txn.rollback(); + return new Status(Status.STATUS_CODE_FAILURE, "Exception while trying to delete cluster [" + clusterName + + "]: [" + e.getMessage() + "]"); + } + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java index 71c0f7db..58f72ffd 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java @@ -18,6 +18,12 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; + +import java.util.ArrayList; import java.util.List; import javax.ws.rs.DELETE; @@ -27,38 +33,101 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; -import com.gluster.storage.management.core.constants.RESTConstants; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.GlusterServerListResponse; import com.gluster.storage.management.core.response.GlusterServerResponse; +import com.gluster.storage.management.core.utils.LRUCache; +import com.gluster.storage.management.server.data.ClusterInfo; +import com.gluster.storage.management.server.data.PersistenceDao; +import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.SshUtil; import com.sun.jersey.spi.resource.Singleton; @Component @Singleton -@Path("/cluster/servers") +@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_SERVERS) public class GlusterServersResource extends AbstractServersResource { public static final String HOSTNAMETAG = "hostname:"; - - private GlusterServerListResponse getServerDetails(String knownServer) { - List glusterServers = getGlusterUtil().getGlusterServers(knownServer); + private LRUCache clusterServerCache = new LRUCache(3); + + @Autowired + private PersistenceDao clusterDao; + + protected void fetchServerDetails(GlusterServer server) { + try { + super.fetchServerDetails(server); + } catch(ConnectionException e) { + server.setStatus(SERVER_STATUS.OFFLINE); + } + } + + // uses cache + public GlusterServer getOnlineServer(String clusterName) { + GlusterServer server = clusterServerCache.get(clusterName); + if(server != null) { + return server; + } + + return getNewOnlineServer(clusterName); + } + + // Doesn't use cache + public GlusterServer getNewOnlineServer(String clusterName) { + // no known online server for this cluster. find one. + ClusterInfo cluster = clusterDao.findBy("name = ?1", clusterName).get(0); + for(ServerInfo serverInfo : cluster.getServers()) { + GlusterServer server = new GlusterServer(serverInfo.getName()); + try { + fetchServerDetails(server); + // server is online. add it to cache and return + clusterServerCache.put(clusterName, server); + return server; + } catch(ConnectionException e) { + // server is offline. check the next server. + } + } + + // no online server found. + return null; + } + + private GlusterServerListResponse getServerDetails(String clusterName) { + GlusterServer onlineServer = getOnlineServer(clusterName); + if(onlineServer == null) { + return new GlusterServerListResponse(Status.STATUS_SUCCESS, new ArrayList()); + } + + List glusterServers; + try { + glusterServers = glusterUtil.getGlusterServers(onlineServer); + } catch(ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new GlusterServerListResponse(Status.STATUS_SUCCESS, new ArrayList()); + } + + glusterServers = glusterUtil.getGlusterServers(onlineServer); + } + int errCount = 0; StringBuilder errMsg = new StringBuilder("Couldn't fetch details for server(s): "); for (GlusterServer server : glusterServers) { - if (server.getStatus() == SERVER_STATUS.ONLINE) { + if (server.getStatus() == SERVER_STATUS.ONLINE && !server.getName().equals(onlineServer.getName())) { try { - fetchServerDetails(server); + fetchServerDetails(server); } catch (Exception e) { errMsg.append(CoreConstants.NEWLINE + server.getName() + " : [" + e.getMessage() + "]"); errCount++; @@ -79,17 +148,17 @@ public class GlusterServersResource extends AbstractServersResource { @GET @Produces(MediaType.TEXT_XML) public GlusterServerListResponse getGlusterServers( - @QueryParam(RESTConstants.QUERY_PARAM_KNOWN_SERVER) String knownServer) { - return getServerDetails(knownServer); + @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { + return getServerDetails(clusterName); } @GET @Path("{serverName}") @Produces(MediaType.TEXT_XML) public GlusterServerResponse getGlusterServer( - @QueryParam(RESTConstants.QUERY_PARAM_KNOWN_SERVER) String knownServer, + @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam("serverName") String serverName) { - GlusterServer server = getGlusterUtil().getGlusterServer(knownServer, serverName); + GlusterServer server = glusterUtil.getGlusterServer(getOnlineServer(clusterName), serverName); Status status = Status.STATUS_SUCCESS; if(server.isOnline()) { try { @@ -103,21 +172,59 @@ public class GlusterServersResource extends AbstractServersResource { @POST @Produces(MediaType.TEXT_XML) - public GlusterServerResponse addServer(@FormParam("serverName") String serverName, - @FormParam("existingServer") String existingServer) { - Status status = getGlusterUtil().addServer(serverName, existingServer); + public GlusterServerResponse addServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @FormParam("serverName") String serverName) { + GlusterServer onlineServer = getOnlineServer(clusterName); + if(onlineServer == null) { + return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"), null); + } + + Status status; + try { + status = glusterUtil.addServer(serverName, onlineServer.getName()); + } catch(ConnectionException e) { + onlineServer = getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"), null); + } + status = glusterUtil.addServer(serverName, onlineServer.getName()); + } if (!status.isSuccess()) { return new GlusterServerResponse(status, null); } - return new GlusterServerResponse(Status.STATUS_SUCCESS, getGlusterServer(existingServer, serverName) + + return new GlusterServerResponse(Status.STATUS_SUCCESS, getGlusterServer(clusterName, serverName) .getGlusterServer()); } @DELETE @Produces(MediaType.TEXT_XML) - public Status removeServer(@QueryParam("serverName") String serverName) { - return getGlusterUtil().removeServer(serverName); + public Status removeServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { + GlusterServer onlineServer = getOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"); + } + + Status status; + try { + return glusterUtil.removeServer(onlineServer.getName(), serverName); + } catch(ConnectionException e) { + onlineServer = getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"); + } + return glusterUtil.removeServer(onlineServer.getName(), serverName); + } + } + + private void setGlusterUtil(GlusterUtil glusterUtil) { + this.glusterUtil = glusterUtil; } public static void main(String[] args) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java index ea2cdf5d..10ce5da3 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java @@ -30,7 +30,7 @@ import javax.ws.rs.core.MediaType; import org.springframework.stereotype.Component; -import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_RUNNING_TASKS; +import static com.gluster.storage.management.core.constants.RESTConstants.*; import com.gluster.storage.management.core.model.Response; import com.gluster.storage.management.core.model.RunningTask; import com.gluster.storage.management.core.model.RunningTaskStatus; @@ -40,7 +40,7 @@ import com.gluster.storage.management.core.utils.StringUtil; import com.gluster.storage.management.server.runningtasks.managers.RunningTaskManager; @Component -@Path(RESOURCE_PATH_RUNNING_TASKS) +@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_RUNNING_TASKS) public class RunningTaskResource { private static final String PKG = "com.gluster.storage.management.server.runningtasks.managers"; diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 84980851..3857f104 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -26,6 +26,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_TARGET; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VALUE_START; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VALUE_STOP; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DELETE_OPTION; @@ -36,12 +37,13 @@ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_LOG_SEVERITY; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TO_TIMESTAMP; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_VOLUME_NAME; -import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_VOLUMES; -import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_DEFAULT_OPTIONS; -import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_DISKS; -import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_DOWNLOAD; -import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_LOGS; -import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_OPTIONS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DEFAULT_OPTIONS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DOWNLOAD; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_LOGS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_OPTIONS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES; import java.io.File; import java.io.IOException; @@ -89,7 +91,7 @@ import com.sun.jersey.api.core.InjectParam; import com.sun.jersey.spi.resource.Singleton; @Singleton -@Path(RESOURCE_PATH_VOLUMES) +@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_VOLUMES) public class VolumesResource { private static final String PREPARE_BRICK_SCRIPT = "create_volume_directory.py"; private static final String VOLUME_DIRECTORY_CLEANUP_SCRIPT = "clear_volume_directory.py"; @@ -110,8 +112,9 @@ public class VolumesResource { @GET @Produces(MediaType.TEXT_XML) - public VolumeListResponse getAllVolumes() { + public VolumeListResponse getAllVolumes(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { try { + // TODO: pass cluster name to getAllVolumes return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes()); } catch (Exception e) { // TODO: log the error @@ -123,7 +126,9 @@ public class VolumesResource { @POST @Consumes(MediaType.TEXT_XML) @Produces(MediaType.TEXT_XML) - public Status createVolume(Volume volume) { + public Status createVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, Volume volume) { + // TODO: Create volume on given cluster + // Create the directories for the volume List brickDirectories = glusterCoreUtil.getQualifiedBrickList(volume.getBricks()); Status status = glusterUtil.createVolume(volume, brickDirectories); if (status.isSuccess()) { @@ -139,16 +144,18 @@ public class VolumesResource { @GET @Path("{" + PATH_PARAM_VOLUME_NAME + "}") @Produces(MediaType.TEXT_XML) - public Volume getVolume(@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { + public Volume getVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { + // TODO: Pass cluster name to getVolume return glusterUtil.getVolume(volumeName); } @PUT @Path("{" + PATH_PARAM_VOLUME_NAME + "}") @Produces(MediaType.TEXT_XML) - public Status performOperation(@FormParam(FORM_PARAM_OPERATION) String operation, - @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { - + public Status performOperation(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_OPERATION) String operation) { + // TODO: Perform the operation on given cluster if (operation.equals(FORM_PARAM_VALUE_START)) { return glusterUtil.startVolume(volumeName); } @@ -161,8 +168,10 @@ public class VolumesResource { @DELETE @Path("{" + PATH_PARAM_VOLUME_NAME + "}") @Produces(MediaType.TEXT_XML) - public Status deleteVolume(@QueryParam(QUERY_PARAM_VOLUME_NAME) String volumeName, + public Status deleteVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @QueryParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { + // TODO: Delete volume on given cluster Volume volume = glusterUtil.getVolume(volumeName); Status status = glusterUtil.deleteVolume(volumeName); @@ -184,12 +193,14 @@ public class VolumesResource { } @DELETE - @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + SUBRESOURCE_DISKS) + @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_DISKS) @Produces(MediaType.TEXT_XML) - public Status removeBricks(@PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, - @QueryParam(QUERY_PARAM_BRICKS) String bricks, @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { + public Status removeBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICKS) String bricks, + @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { List brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query parameter) + // TODO: pass clusterName to removeBricks Status status = glusterUtil.removeBricks(volumeName, brickList); String deleteOption = ""; @@ -224,25 +235,29 @@ public class VolumesResource { } @POST - @Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + SUBRESOURCE_OPTIONS) + @Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + RESOURCE_OPTIONS) @Produces(MediaType.TEXT_XML) - public Status setOption(@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, + public Status setOption(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(RESTConstants.FORM_PARAM_OPTION_KEY) String key, @FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) { + // TODO: pass cluster name to setOption return glusterUtil.setOption(volumeName, key, value); } @PUT - @Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + SUBRESOURCE_OPTIONS) + @Path("{" + PATH_PARAM_VOLUME_NAME + " }/" + RESOURCE_OPTIONS) @Produces(MediaType.TEXT_XML) - public Status resetOptions(@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { + public Status resetOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { + // TODO: pass clusterName to resetOptions return glusterUtil.resetOptions(volumeName); } @GET - @Path(SUBRESOURCE_DEFAULT_OPTIONS) + @Path(RESOURCE_DEFAULT_OPTIONS) @Produces(MediaType.TEXT_XML) - public VolumeOptionInfoListResponse getDefaultOptions() { + public VolumeOptionInfoListResponse getDefaultOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { // TODO: Fetch all volume options with their default values from GlusterFS // whenever such a CLI command is made available in GlusterFS return new VolumeOptionInfoListResponse(Status.STATUS_SUCCESS, volumeOptionsDefaults.getDefaults()); @@ -362,14 +377,16 @@ public class VolumesResource { @GET @Produces(MediaType.APPLICATION_OCTET_STREAM) - @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + SUBRESOURCE_LOGS + "/" + SUBRESOURCE_DOWNLOAD) - public StreamingOutput getLogs(@PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { + @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS + "/" + RESOURCE_DOWNLOAD) + public StreamingOutput getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { - Volume volume = getVolume(volumeName); + Volume volume = getVolume(clusterName, volumeName); try { + // TODO: pass clusterName to downloadLogs File archiveFile = new File(downloadLogs(volume)); output.write(fileUtil.readFileAsByteArray(archiveFile)); archiveFile.delete(); @@ -405,21 +422,24 @@ public class VolumesResource { } @GET - @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + SUBRESOURCE_LOGS) - public LogMessageListResponse getLogs(@PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, - @QueryParam(QUERY_PARAM_DISK_NAME) String brickName, @QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity, + @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS) + public LogMessageListResponse getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, + @QueryParam(QUERY_PARAM_DISK_NAME) String brickName, + @QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity, @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, - @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { + @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, + @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { List logMessages = null; try { - Volume volume = getVolume(volumeName); + // TODO: Fetch logs from brick(s) of given cluster only + Volume volume = getVolume(clusterName, volumeName); if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) { logMessages = getLogsForAllBricks(volume, lineCount); } else { // fetch logs for given brick of the volume - // logMessages = getBrickLogs(volume, getBrickForDisk(volume, brickName), lineCount); logMessages = getBrickLogs(volume, brickName, lineCount); } } catch (Exception e) { @@ -491,17 +511,18 @@ public class VolumesResource { } @POST - @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + SUBRESOURCE_DISKS) - public Status addBricks(@PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, - @FormParam(FORM_PARAM_BRICKS) String bricks) { + @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_DISKS) + public Status addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_BRICKS) String bricks) { return glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(","))); } @PUT - @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + SUBRESOURCE_DISKS) - public Status replaceDisk(@PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, - @FormParam(FORM_PARAM_SOURCE) String diskFrom, @FormParam(FORM_PARAM_TARGET) String diskTo, - @FormParam(FORM_PARAM_OPERATION) String operation) { + @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_DISKS) + public Status replaceDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_SOURCE) String diskFrom, + @FormParam(FORM_PARAM_TARGET) String diskTo, @FormParam(FORM_PARAM_OPERATION) String operation) { + // TODO: Migrate disk on given cluster only return glusterUtil.migrateDisk(volumeName, diskFrom, diskTo, operation); } @@ -533,7 +554,7 @@ public class VolumesResource { // System.out.println("Code : " + status.getCode()); // System.out.println("Message " + status.getMessage()); - Status status1 = vr.removeBricks("test", "192.168.1.210:sdb", true); + Status status1 = vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true); System.out.println("Code : " + status1.getCode()); System.out.println("Message " + status1.getMessage()); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitServerTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitServerTask.java index d96db6ca..8e38bd40 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitServerTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitServerTask.java @@ -21,19 +21,26 @@ package com.gluster.storage.management.server.tasks; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.servlet.ServletContext; import org.apache.derby.tools.ij; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.security.authentication.encoding.PasswordEncoder; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; -import com.gluster.storage.management.core.utils.FileUtil; +import com.gluster.storage.management.server.data.ClusterInfo; +import com.gluster.storage.management.server.data.PersistenceDao; /** * Initializes the Gluster Management Server. @@ -42,6 +49,17 @@ public class InitServerTask extends JdbcDaoSupport { @Autowired private PasswordEncoder passwordEncoder; + @Autowired + private String appVersion; + + @Autowired + private PersistenceDao clusterDao; + + @Autowired + ServletContext servletContext; + + private static final String SCRIPT_DIR = "data/scripts/"; + public void securePasswords() { getJdbcTemplate().query("select username, password from users", new RowCallbackHandler() { @Override @@ -55,45 +73,90 @@ public class InitServerTask extends JdbcDaoSupport { }); } - private void executeScript(String script) { + private void executeScript(File script) { ByteArrayOutputStream sqlOut = new ByteArrayOutputStream(); int numOfExceptions; try { - numOfExceptions = ij.runScript(getJdbcTemplate().getDataSource().getConnection(), - new FileUtil().loadResource(script), CoreConstants.ENCODING_UTF8, sqlOut, - CoreConstants.ENCODING_UTF8); + numOfExceptions = ij.runScript(getJdbcTemplate().getDataSource().getConnection(), new FileInputStream( + script), CoreConstants.ENCODING_UTF8, sqlOut, CoreConstants.ENCODING_UTF8); String output = sqlOut.toString(); sqlOut.close(); - logger.debug("Data script [" + script + "] returned with exit status [" + numOfExceptions + logger.debug("Data script [" + script.getName() + "] returned with exit status [" + numOfExceptions + "] and output [" + output + "]"); if (numOfExceptions != 0) { - throw new GlusterRuntimeException("Server data initialization script [ " + script + "] failed with [" - + numOfExceptions + "] exceptions! [" + output + "]"); + throw new GlusterRuntimeException("Server data initialization script [ " + script.getName() + + "] failed with [" + numOfExceptions + "] exceptions! [" + output + "]"); } } catch (Exception ex) { - ex.printStackTrace(); - throw new GlusterRuntimeException("Server data initialization script [" + script + "] failed!", ex); + throw new GlusterRuntimeException("Server data initialization script [" + script.getName() + "] failed!", + ex); } } private void initDatabase() { logger.debug("Initializing server data..."); - executeScript("data/scripts/security-schema.sql"); - executeScript("data/scripts/users-authorities-groups.sql"); + executeScriptsFrom(getDirFromRelativePath(SCRIPT_DIR + appVersion)); + securePasswords(); // encrypt the passwords } + private File getDirFromRelativePath(String relativePath) { + String scriptDirPath = servletContext.getRealPath(relativePath); + File scriptDir = new File(scriptDirPath); + return scriptDir; + } + + private void executeScriptsFrom(File scriptDir) { + if (!scriptDir.exists()) { + throw new GlusterRuntimeException("Script directory [" + scriptDir.getAbsolutePath() + "] doesn't exist!"); + } + + List scripts = Arrays.asList(scriptDir.listFiles()); + if(scripts.size() == 0) { + throw new GlusterRuntimeException("Script directory [" + scriptDir.getAbsolutePath() + "] is empty!"); + } + + Collections.sort(scripts); + for (File script : scripts) { + executeScript(script); + } + } + /** * Initializes the server database, if running for the first time. */ public synchronized void initServer() { try { - // Query to check whether the user table exists - getJdbcTemplate().queryForInt("select count(*) from users"); - logger.debug("Server data is already initialized!"); - } catch (DataAccessException ex) { + String dbVersion = getDBVersion(); + if (!appVersion.equals(dbVersion)) { + logger.info("App version [" + appVersion + "] differs from data version [" + dbVersion + + "]. Trying to upgrade data..."); + upgradeData(dbVersion, appVersion); + } + } catch (Exception ex) { + ex.printStackTrace(); // Database not created yet. Create it! initDatabase(); } + + // For development time debugging. To be removed later. + List clusters = clusterDao.findAll(); + logger.info(clusters.size()); + + if (clusters.size() > 0) { + for (ClusterInfo cluster : clusters) { + logger.info("Cluster: [" + cluster.getId() + "][" + cluster.getName() + "]"); + } + } else { + logger.info("No cluster created yet."); + } + } + + private void upgradeData(String fromVersion, String toVersion) { + executeScriptsFrom(getDirFromRelativePath(SCRIPT_DIR + fromVersion + "-" + toVersion)); + } + + private String getDBVersion() { + return (String) clusterDao.getSingleResultFromSQL("select version from version"); } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java index b7cfd2ea..64595e5f 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java @@ -101,8 +101,8 @@ public class GlusterUtil { } - public GlusterServer getGlusterServer(String knownServer, String serverName) { - List servers = getGlusterServers(knownServer); + public GlusterServer getGlusterServer(GlusterServer onlineServer, String serverName) { + List servers = getGlusterServers(onlineServer); for(GlusterServer server : servers) { if(server.getName().equals(serverName)) { return server; @@ -112,14 +112,15 @@ public class GlusterUtil { } - public List getGlusterServers(String knownServer) { - String output = getPeerStatus(knownServer); + public List getGlusterServers(GlusterServer knownServer) { + String output = getPeerStatus(knownServer.getName()); if (output == null) { return null; } List glusterServers = new ArrayList(); - glusterServers.add(getKnownServer(knownServer)); // Append the known server + // TODO: Append the known server. But where? Order matters in replication/striping + glusterServers.add(knownServer); GlusterServer server = null; boolean foundHost = false; boolean foundUuid = false; @@ -193,8 +194,8 @@ public class GlusterUtil { return output; } - public Status addServer(String serverName, String existingServer) { - return new Status(sshUtil.executeRemote(existingServer, "gluster peer probe " + serverName)); + public Status addServer(String existingServer, String newServer) { + return new Status(sshUtil.executeRemote(existingServer, "gluster peer probe " + newServer)); } public Status startVolume(String volumeName) { @@ -522,8 +523,8 @@ public class GlusterUtil { return new Status(processUtil.executeCommand(command)); } - public Status removeServer(String serverName) { - return new Status(processUtil.executeCommand("gluster", "peer", "detach", serverName)); + public Status removeServer(String existingServer, String serverName) { + return new Status(sshUtil.executeRemote(existingServer, "gluster peer detach " + serverName)); } public static void main(String args[]) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java index 5b953c3d..4a72ebce 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java @@ -22,6 +22,7 @@ package com.gluster.storage.management.server.utils; import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; @@ -39,6 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.GenericResponse; @@ -57,6 +59,14 @@ public class ServerUtil { private static final String SCRIPT_COMMAND = "python"; private static final String REMOTE_SCRIPT_GET_DISK_FOR_DIR = "get_disk_for_dir.py"; + public void setSshUtil(SshUtil sshUtil) { + this.sshUtil = sshUtil; + } + + public SshUtil getSshUtil() { + return sshUtil; + } + public ProcessResult executeGlusterScript(boolean runInForeground, String scriptName, List arguments) { List command = new ArrayList(); @@ -97,14 +107,19 @@ public class ServerUtil { return ((GenericResponse) response).getStatus(); } return response; - } catch (Exception e) { - // any other exception means unexpected error. return status with error from exception. - return new Status(e); + } catch (RuntimeException e) { + // Except for connection exception, wrap any other exception in the a object and return it. + if (e instanceof ConnectionException) { + throw e; + } else { + // error during unmarshalling. return status with error from exception. + return new Status(e); + } } } private String executeOnServer(String serverName, String commandWithArgs) { - ProcessResult result = sshUtil.executeRemote(serverName, commandWithArgs); + ProcessResult result = getSshUtil().executeRemote(serverName, commandWithArgs); if (!result.isSuccess()) { throw new GlusterRuntimeException("Command [" + commandWithArgs + "] failed on [" + serverName + "] with error [" + result.getExitValue() + "][" + result.getOutput() + "]"); @@ -196,8 +211,10 @@ public class ServerUtil { } public static void main(String args[]) throws Exception { - // CreateVolumeExportDirectory.py md0 testvol - System.out.println(new ServerUtil().getFileFromServer("localhost", "/tmp/python/PeerAgent.py")); + ServerUtil su = new ServerUtil(); + su.setSshUtil(new SshUtil()); + // Object result = new ServerUtil().executeOnServer(true, "serverName", "ls -lrt", String.class); + // System.out.println(result); } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index 5816533b..cac71f9c 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -34,6 +34,7 @@ import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.core.utils.ProcessResult; @@ -71,18 +72,18 @@ public class SshUtil { private void authenticateWithPublicKey(Connection conn) { try { if (!supportsPublicKeyAuthentication(conn)) { - throw new GlusterRuntimeException("Public key authentication not supported on [" + conn.getHostname() + throw new ConnectionException("Public key authentication not supported on [" + conn.getHostname() + "]"); } // TODO: Introduce password for the PEM file (third argument) so that it is more secure if (!conn.authenticateWithPublicKey(USER_NAME, PEM_FILE, null)) { - throw new GlusterRuntimeException("SSH Authentication (public key) failed for server [" + throw new ConnectionException("SSH Authentication (public key) failed for server [" + conn.getHostname() + "]"); } } catch (IOException e) { e.printStackTrace(); - throw new GlusterRuntimeException("Exception during SSH authentication (public key) for server [" + throw new ConnectionException("Exception during SSH authentication (public key) for server [" + conn.getHostname() + "]", e); } } @@ -90,18 +91,18 @@ public class SshUtil { private void authenticateWithPassword(Connection conn) { try { if (!supportsPasswordAuthentication(conn)) { - throw new GlusterRuntimeException("Password authentication not supported on [" + conn.getHostname() + throw new ConnectionException("Password authentication not supported on [" + conn.getHostname() + "]"); } // TODO: Introduce password for the PEM file (third argument) so that it is more secure if (!conn.authenticateWithPassword(USER_NAME, DEFAULT_PASSWORD)) { - throw new GlusterRuntimeException("SSH Authentication (password) failed for server [" + throw new ConnectionException("SSH Authentication (password) failed for server [" + conn.getHostname() + "]"); } } catch (IOException e) { e.printStackTrace(); - throw new GlusterRuntimeException("Exception during SSH authentication (password) for server [" + throw new ConnectionException("Exception during SSH authentication (password) for server [" + conn.getHostname() + "]", e); } } @@ -121,8 +122,7 @@ public class SshUtil { conn.connect(); } catch (IOException e) { e.printStackTrace(); - throw new GlusterRuntimeException("Exception while creating SSH connection with server [" + serverName - + "]", e); + throw new ConnectionException("Exception while creating SSH connection with server [" + serverName + "]", e); } return conn; } @@ -159,10 +159,9 @@ public class SshUtil { session.close(); return result; } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new GlusterRuntimeException("Exception while executing command [" + command + "] on [" + + sshConnection.getHostname() + "]", e); } - return null; } private ProcessResult getResultOfExecution(Session session, BufferedReader stdoutReader, BufferedReader stderrReader) { diff --git a/src/com.gluster.storage.management.server/src/data/scripts/security-schema.sql b/src/com.gluster.storage.management.server/src/data/scripts/security-schema.sql deleted file mode 100644 index fdde5823..00000000 --- a/src/com.gluster.storage.management.server/src/data/scripts/security-schema.sql +++ /dev/null @@ -1,26 +0,0 @@ -create table users( - username varchar(50) not null primary key, - password varchar(50) not null, - enabled smallint not null - ); - - create table authorities ( - username varchar(50) not null, - authority varchar(50) not null, - constraint fk_authorities_users foreign key(username) references users(username)); - create unique index ix_auth_username on authorities (username,authority); - -create table groups ( - id bigint generated by default as identity(start with 0) primary key, - group_name varchar(50) not null); - -create table group_authorities ( - group_id bigint not null, - authority varchar(50) not null, - constraint fk_group_authorities_group foreign key(group_id) references groups(id)); - -create table group_members ( - id bigint generated by default as identity(start with 0) primary key, - username varchar(50) not null, - group_id bigint not null, - constraint fk_group_members_group foreign key(group_id) references groups(id)); diff --git a/src/com.gluster.storage.management.server/src/data/scripts/users-authorities-groups.sql b/src/com.gluster.storage.management.server/src/data/scripts/users-authorities-groups.sql deleted file mode 100644 index 35ccf965..00000000 --- a/src/com.gluster.storage.management.server/src/data/scripts/users-authorities-groups.sql +++ /dev/null @@ -1,21 +0,0 @@ --- Create users -insert into users(username, password, enabled) values ('gluster','gluster',1); -insert into users(username, password, enabled) values ('guest','guest',1); - --- Assign authorities to users (to be removed after implementing user group functionality) -insert into authorities(username,authority) values ('gluster','ROLE_USER'); -insert into authorities(username,authority) values ('gluster','ROLE_ADMIN'); -insert into authorities(username,authority) values ('guest','ROLE_USER'); - --- Create user groups -insert into groups(group_name) values ('Users'); -insert into groups(group_name) values ('Administrators'); - --- Add authorities to groups (functionality not yet implemented in code) -insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Users'; -insert into group_authorities(group_id, authority) select id,'ROLE_USER' from groups where group_name='Administrators'; -insert into group_authorities(group_id, authority) select id,'ROLE_ADMIN' from groups where group_name='Administrators'; - --- Assign group members -insert into group_members(group_id, username) select id,'guest' from groups where group_name='Users'; -insert into group_members(group_id, username) select id,'gluster' from groups where group_name='Administrators'; \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/src/log4j.properties b/src/com.gluster.storage.management.server/src/log4j.properties new file mode 100644 index 00000000..d7712c96 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/log4j.properties @@ -0,0 +1,12 @@ +log4j.rootLogger=INFO, CONSOLE + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.immediateFlush=true +log4j.appender.CONSOLE.target=System.out +log4j.appender.CONSOLE.threshold=DEBUG +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d{dd MMM, yyyy HH:mm:ss} %p: %c %t - %m%n + +log4j.logger.org.springframework=ERROR +log4j.logger.org.springframework.aop=DEBUG +log4j.logger.com.gluster=INFO \ No newline at end of file diff --git a/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml b/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml index 86a8708f..e65ef3a9 100644 --- a/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml +++ b/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml @@ -1,50 +1,73 @@ - + http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> - + - + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + com.gluster.storage.management.server.data.ClusterInfo + + + + - - + \ No newline at end of file -- cgit