001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.jmx.ha;
023:
024: import java.lang.reflect.Method;
025: import java.lang.reflect.InvocationTargetException;
026: import java.lang.reflect.UndeclaredThrowableException;
027: import java.security.Principal;
028: import java.util.Collections;
029: import java.util.HashMap;
030: import java.util.Map;
031:
032: import org.jboss.ha.jmx.HAServiceMBeanSupport;
033: import org.jboss.invocation.Invocation;
034: import org.jboss.invocation.MarshalledInvocation;
035: import org.jboss.security.SecurityAssociation;
036: import org.jboss.system.Registry;
037:
038: public class HAService extends HAServiceMBeanSupport implements
039: HAServiceRemote, HAServiceMBean {
040: private int count = 0;
041:
042: private Map marshalledInvocationMapping;
043:
044: public void startService() throws Exception {
045: super .startService();
046:
047: // Calulate method hashes for remote invocation
048: Method[] methods = HAServiceRemote.class.getMethods();
049: HashMap tmpMap = new HashMap(methods.length);
050: for (int m = 0; m < methods.length; m++) {
051: Method method = methods[m];
052: Long hash = new Long(MarshalledInvocation
053: .calculateHash(method));
054: tmpMap.put(hash, method);
055: }
056: marshalledInvocationMapping = Collections
057: .unmodifiableMap(tmpMap);
058:
059: // Place our ObjectName hash into the Registry so invokers can resolve it
060: Registry.bind(new Integer(serviceName.hashCode()), serviceName);
061: }
062:
063: public void stopService() throws Exception {
064: super .stopService();
065:
066: // No longer available to the invokers
067: Registry.unbind(new Integer(serviceName.hashCode()));
068: }
069:
070: /**
071: * Expose the client mapping
072: */
073: public Map getMethodMap() {
074: return marshalledInvocationMapping;
075: }
076:
077: /**
078: * This is the "remote" entry point
079: */
080: public Object invoke(Invocation invocation) throws Exception {
081: // Invoked remotely, inject method resolution
082: if (invocation instanceof MarshalledInvocation) {
083: MarshalledInvocation mi = (MarshalledInvocation) invocation;
084: mi.setMethodMap(marshalledInvocationMapping);
085: }
086: Method method = invocation.getMethod();
087: Object[] args = invocation.getArguments();
088:
089: // Setup any security context (only useful if something checks it, this impl doesn't)
090: Principal principal = invocation.getPrincipal();
091: Object credential = invocation.getCredential();
092: SecurityAssociation.setPrincipal(principal);
093: SecurityAssociation.setCredential(credential);
094:
095: // Dispatch the invocation
096: try {
097: return method.invoke(this , args);
098: } catch (InvocationTargetException e) {
099: Throwable t = e.getTargetException();
100: if (t instanceof Exception)
101: throw (Exception) t;
102: else
103: throw new UndeclaredThrowableException(t, method
104: .toString());
105: } finally {
106: // Clear the security context
107: SecurityAssociation.clear();
108: }
109: }
110:
111: // Implementation of remote methods
112:
113: public String hello() {
114: return "Hello";
115: }
116:
117: public String getClusterNode() {
118: return getPartition().getNodeName();
119: }
120:
121: }
|