From 95da103879bcdae40a976aefcb5d2b628c106208 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Wed, 10 Sep 2008 07:20:25 +0000 Subject: [PATCH] LMS-445 Logging of GenericServer invocations logged. SVN: 8255 --- .../web/client/application/Application.java | 11 +- .../web/client/application/ui/GroupsView.java | 7 +- .../client/application/ui/PersonsView.java | 37 +++++ .../generic/genericApplicationContext.xml | 23 ++- .../openbis/generic/server/GenericServer.java | 22 ++- .../server/GenericServerLogInterceptor.java | 48 ++++++ .../generic/server/GenericServerLogger.java | 145 ++++++++++++++++++ .../server/LogMessagePrefixGenerator.java | 5 +- .../generic/server/SessionFactory.java | 2 +- .../generic/shared/IGenericServer.java | 2 +- .../openbis/generic/shared/dto/Session.java | 14 +- 11 files changed, 291 insertions(+), 25 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/PersonsView.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogInterceptor.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Application.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Application.java index d07609fd6c5..f1f0a078fcc 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Application.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Application.java @@ -17,12 +17,14 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application; import com.extjs.gxt.ui.client.widget.LayoutContainer; +import com.extjs.gxt.ui.client.widget.layout.AccordionLayout; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.GroupsView; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.PersonsView; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.Header; /** - * + * Panel of the application. * * @author Franz-Josef Elmer */ @@ -36,6 +38,11 @@ public class Application extends LayoutContainer private void createGUI(final GenericViewContext viewContext) { add(new Header(viewContext)); - add(new GroupsView(viewContext)); + LayoutContainer content = new LayoutContainer(); + content.setHeight(500); + content.setLayout(new AccordionLayout()); + add(content); + content.add(new GroupsView(viewContext)); + content.add(new PersonsView(viewContext)); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupsView.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupsView.java index 404160d3638..73849998495 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupsView.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupsView.java @@ -25,7 +25,6 @@ import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.Text; -import com.extjs.gxt.ui.client.widget.VerticalPanel; import com.extjs.gxt.ui.client.widget.table.DateTimeCellRenderer; import com.extjs.gxt.ui.client.widget.table.Table; import com.extjs.gxt.ui.client.widget.table.TableColumn; @@ -43,7 +42,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Person; /** * @author Franz-Josef Elmer */ -public class GroupsView extends VerticalPanel +public class GroupsView extends ContentPanel { private LayoutContainer groupsPanel; @@ -52,7 +51,7 @@ public class GroupsView extends VerticalPanel public GroupsView(GenericViewContext viewContext) { this.viewContext = viewContext; - add(new Text("Groups:")); + setHeading("Groups:"); groupsPanel = new LayoutContainer(); groupsPanel.add(new Text("data loading...")); add(groupsPanel); @@ -60,12 +59,10 @@ public class GroupsView extends VerticalPanel viewContext.getService().listGroups(null, new AbstractAsyncCallback<List<Group>>(viewContext) { - public void onSuccess(List<Group> groups) { fillGroupsPanel(groups); } - }); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/PersonsView.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/PersonsView.java new file mode 100644 index 00000000000..e250fb5b970 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/PersonsView.java @@ -0,0 +1,37 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui; + +import com.extjs.gxt.ui.client.widget.ContentPanel; + +import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericViewContext; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class PersonsView extends ContentPanel +{ + private static final String PREFIX = "personsView_"; + + public PersonsView(GenericViewContext viewContext) + { + setHeading(viewContext.getMessage(PREFIX + "heading")); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/genericApplicationContext.xml b/openbis/source/java/ch/systemsx/cisd/openbis/generic/genericApplicationContext.xml index f3f4a5c4927..d97917cfac4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/genericApplicationContext.xml +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/genericApplicationContext.xml @@ -16,12 +16,25 @@ <constructor-arg ref="request-context-provider" /> </bean> - <bean id="generic-server" class="ch.systemsx.cisd.openbis.generic.server.GenericServer"> - <constructor-arg ref="${authentication-service}" /> - <constructor-arg ref="request-context-provider" /> - <!-- The time after which an inactive session is expired by the service (in minutes). --> - <constructor-arg value="${session-timeout}" /> + <bean id="generic-server" class="org.springframework.aop.framework.ProxyFactoryBean"> + <property name="proxyInterfaces"><value>ch.systemsx.cisd.openbis.generic.shared.IGenericServer</value></property> + <property name="target"> + <bean class="ch.systemsx.cisd.openbis.generic.server.GenericServer"> + <constructor-arg ref="${authentication-service}" /> + <constructor-arg ref="request-context-provider" /> + <!-- The time after which an inactive session is expired by the service (in minutes). --> + <constructor-arg value="${session-timeout}" /> + </bean> + </property> + <property name="interceptorNames"> + <list> + <value>logInterceptor</value> + </list> + </property> </bean> + <bean id="logInterceptor" class="ch.systemsx.cisd.openbis.generic.server.GenericServerLogInterceptor"/> + + </beans> \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java index 4c067226d3a..c449a550e5a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java @@ -24,17 +24,17 @@ import java.util.Random; import ch.systemsx.cisd.authentication.DefaultSessionManager; import ch.systemsx.cisd.authentication.IAuthenticationService; import ch.systemsx.cisd.authentication.ISessionManager; +import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.servlet.IRequestContextProvider; import ch.systemsx.cisd.common.servlet.RequestContextProviderAdapter; import ch.systemsx.cisd.lims.base.dto.GroupPE; import ch.systemsx.cisd.lims.base.dto.PersonPE; import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier; -import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException; import ch.systemsx.cisd.openbis.generic.shared.IGenericServer; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** - * + * Implementation of client-server interface. * * @author Franz-Josef Elmer */ @@ -53,6 +53,19 @@ public class GenericServer implements IGenericServer createFakeGroups(); } + GenericServer(ISessionManager<Session> sessionManager) + { + this.sessionManager = sessionManager; + } + + /** + * Creates a logger used to log invocations of objects of this class. + */ + GenericServerLogger createLogger(boolean invocationSuccessful) + { + return new GenericServerLogger(sessionManager, invocationSuccessful); + } + private void createFakeGroups() { groups = new ArrayList<GroupPE>(); @@ -76,11 +89,6 @@ public class GenericServer implements IGenericServer return group; } - GenericServer(ISessionManager<Session> sessionManager) - { - this.sessionManager = sessionManager; - } - public int getVersion() { return 1; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogInterceptor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogInterceptor.java new file mode 100644 index 00000000000..43abc4b45c8 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogInterceptor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +/** + * Interceptor for {@link GenericServer} which logs method invocations. Logging is delegated + * to the logger created by {@link GenericServer#createLogger(boolean)}. + * + * @author Franz-Josef Elmer + */ +public class GenericServerLogInterceptor implements MethodInterceptor +{ + + public Object invoke(MethodInvocation invocation) throws Throwable + { + boolean invocationSuccessful = false; + GenericServer server = (GenericServer) invocation.getThis(); + try + { + Object result = invocation.proceed(); + invocationSuccessful = true; + return result; + } finally + { + GenericServerLogger logger = server.createLogger(invocationSuccessful); + invocation.getMethod().invoke(logger, invocation.getArguments()); + } + } + + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java new file mode 100644 index 00000000000..8b56cf94ca3 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java @@ -0,0 +1,145 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server; + +import java.util.List; + +import org.apache.log4j.Logger; + +import ch.systemsx.cisd.authentication.ISessionManager; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.lims.base.dto.GroupPE; +import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.IGenericServer; +import ch.systemsx.cisd.openbis.generic.shared.dto.Session; + +/** + * Logger class for {@link GenericServer} which creates readable logs of method invocations. + * + * @author Franz-Josef Elmer + */ +class GenericServerLogger implements IGenericServer +{ + private final static String RESULT_SUCCESS = ""; + private final static String RESULT_FAILURE = " ...FAILED"; + + private static final Logger accessLog = + LogFactory.getLogger(LogCategory.ACCESS, GenericServer.class); + private static final Logger trackingLog = + LogFactory.getLogger(LogCategory.TRACKING, GenericServer.class); + + private final ISessionManager<Session> sessionManager; + private final boolean invocationSuccessful; + private final LogMessagePrefixGenerator logMessagePrefixGenerator; + + /** + * Creates an instance for the specified session manager and invocation status. + * The session manager is used to retrieve user information which will be a part of the + * log message. + */ + GenericServerLogger(ISessionManager<Session> sessionManager, boolean invocationSuccessful) + { + this.sessionManager = sessionManager; + this.invocationSuccessful = invocationSuccessful; + logMessagePrefixGenerator = new LogMessagePrefixGenerator(); + } + + private void logAccess(final String sessionToken, + final String commandName, final String parameterDisplayFormat, + final Object... parameters) + { + logMessage(accessLog, sessionToken, commandName, parameterDisplayFormat, parameters); + } + + private void logTracking(final String sessionToken, + final String commandName, final String parameterDisplayFormat, + final Object... parameters) + { + logMessage(trackingLog, sessionToken, commandName, parameterDisplayFormat, parameters); + } + + private void logMessage(final Logger logger, final String sessionToken, + final String commandName, final String parameterDisplayFormat, + final Object[] parameters) + { + final Session session = sessionManager.getSession(sessionToken); + final String prefix = logMessagePrefixGenerator.createPrefix(session); + for (int i = 0; i < parameters.length; i++) + { + Object parameter = parameters[i]; + if (parameter == null) + { + parameters[i] = LogMessagePrefixGenerator.UNDEFINED; + } else + { + parameters[i] = "'" + parameter + "'"; + } + } + final String message = String.format(parameterDisplayFormat, parameters); + final String invocationStatusMessage = getInvocationStatusMessage(); + // We put on purpose 2 spaces between the command and the message derived from the + // parameters. + logger.info(prefix + + String.format(": %s %s%s", commandName, message, invocationStatusMessage)); + } + + private String getInvocationStatusMessage() + { + return invocationSuccessful ? RESULT_SUCCESS : RESULT_FAILURE; + } + + // + // IGenericServer + // + + public int getVersion() + { + return 0; + } + + public Session tryToAuthenticate(String user, String password) + { + // No logging because already done by the session manager + return null; + } + + public void logout(String sessionToken) + { + // No logging because already done by the session manager + } + + public List<GroupPE> listGroups(String sessionToken, DatabaseInstanceIdentifier identifier) + { + String command = "list_groups"; + if (identifier == null || identifier.getDatabaseInstanceCode() == null) + { + logAccess(sessionToken, command, ""); + } else + { + logAccess(sessionToken, command, "DATABASE-INSTANCE(%s)", identifier); + } + return null; + } + + public void registerGroup(String sessionToken, String groupCode, String descriptionOrNull, + String groupLeaderOrNull) + { + logTracking(sessionToken, "register_group", "CODE(%s)", groupCode); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java index 9e247f09247..32fca099703 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java @@ -22,12 +22,13 @@ import ch.systemsx.cisd.lims.base.dto.PersonPE; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** - * + * Log message prefix generator based on user information found in a {@link Session} object. * * @author Franz-Josef Elmer */ class LogMessagePrefixGenerator implements ILogMessagePrefixGenerator<Session> { + static final String UNDEFINED = "<UNDEFINED>"; public String createPrefix(Session session) { @@ -59,6 +60,6 @@ class LogMessagePrefixGenerator implements ILogMessagePrefixGenerator<Session> private String cite(final String text) { - return text == null ? "<UNDEFINED>" : "'" + text + "'"; + return text == null ? UNDEFINED : "'" + text + "'"; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java index 3d40db13169..b36db47db18 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java @@ -21,7 +21,7 @@ import ch.systemsx.cisd.authentication.Principal; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** - * + * Factory of {@link Session} objects. * * @author Franz-Josef Elmer */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java index a944a160715..da42cb9d8bf 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java @@ -23,7 +23,7 @@ import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** - * + * Definition of the client-server interface. * * @author Franz-Josef Elmer */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java index 93e2ce09e08..42dc5012498 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java @@ -20,10 +20,11 @@ import org.apache.commons.lang.time.DateFormatUtils; import ch.systemsx.cisd.authentication.BasicSession; import ch.systemsx.cisd.authentication.Principal; +import ch.systemsx.cisd.lims.base.dto.GroupPE; import ch.systemsx.cisd.lims.base.dto.PersonPE; /** - * + * Extendion of {@link BasicSession} which may holds a {@link PersonPE} instance. * * @author Franz-Josef Elmer */ @@ -55,7 +56,16 @@ public class Session extends BasicSession @Override public final String toString() { - return "Session{user=" + getUserName() + ",group=" + person.getHomeGroup() + ",remoteHost=" + String homeGroupCode = "<UNKNOWN>"; + if (person != null) + { + GroupPE homeGroup = person.getHomeGroup(); + if (homeGroup != null) + { + homeGroupCode = homeGroup.getCode(); + } + } + return "Session{user=" + getUserName() + ",group=" + homeGroupCode + ",remoteHost=" + getRemoteHost() + ",sessionstart=" + DateFormatUtils.format(getSessionStart(), DATE_FORMAT_PATTERN) + "}"; } -- GitLab