/* * Copyright to the original author or authors. * * 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 org.rioproject.cybernode.proxy; import com.sun.jini.proxy.ConstrainableProxyUtil; import net.jini.core.constraint.MethodConstraints; import net.jini.core.constraint.RemoteMethodControl; import net.jini.id.Uuid; import net.jini.security.TrustVerifier; import net.jini.security.proxytrust.ProxyTrustIterator; import net.jini.security.proxytrust.SingletonProxyTrustIterator; import net.jini.security.proxytrust.TrustEquivalence; import org.rioproject.cybernode.CybernodeAdmin; import org.rioproject.proxy.admin.ServiceAdminProxy; import org.rioproject.system.ComputeResourceUtilization; import org.rioproject.system.ResourceCapability; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; import java.rmi.RemoteException; /** * A <code>CybernodeAdminProxy</code> is a proxy for the CybernodeAdmin * server. This is the object passed to clients of the CybernodeAdmin. * * @author Dennis Reedy */ public class CybernodeAdminProxy extends ServiceAdminProxy implements CybernodeAdmin, Serializable { private static final long serialVersionUID = 3L; final CybernodeAdmin cybernodeAdminProxy; /** * Creates a CybernodeAdmin proxy, returning an instance that implements * RemoteMethodControl if the server does too. * * @param serviceAdmin The CybernodeAdmin server * @param id The Uuid of the CybernodeAdmin * * @return A CybernodeAdminProxy */ public static CybernodeAdminProxy getInstance(final CybernodeAdmin serviceAdmin, final Uuid id) { if(serviceAdmin instanceof RemoteMethodControl) { return new ConstrainableCybernodeAdminProxy(serviceAdmin, id, null); } else { return (new CybernodeAdminProxy(serviceAdmin, id)); } } /* * Private constructor */ private CybernodeAdminProxy(final CybernodeAdmin serviceAdmin, final Uuid uuid) { super(serviceAdmin, uuid); cybernodeAdminProxy = serviceAdmin; } /** * A subclass of CybernodeAdminProxy that implements RemoteMethodControl. */ final static class ConstrainableCybernodeAdminProxy extends CybernodeAdminProxy implements RemoteMethodControl { private static final long serialVersionUID = 2L; /* Creates an instance of this class. */ private ConstrainableCybernodeAdminProxy(final CybernodeAdmin serviceAdmin, final Uuid id, final MethodConstraints constraints) { super(constrainServer(serviceAdmin, constraints), id); } /* * Returns a copy of the server proxy with the specified client * constraints and methods mapping. */ private static CybernodeAdmin constrainServer(final CybernodeAdmin serviceAdmin, final MethodConstraints constraints) { java.lang.reflect.Method[] methods = CybernodeAdmin.class.getMethods(); java.lang.reflect.Method[] methodMapping = new java.lang.reflect.Method[methods.length * 2]; for(int i = 0; i < methodMapping.length; i++) methodMapping[i] = methods[i / 2]; MethodConstraints methodConstraints = ConstrainableProxyUtil.translateConstraints(constraints, methodMapping); return (CybernodeAdmin)((RemoteMethodControl)serviceAdmin).setConstraints(methodConstraints); } /* @see net.jini.core.constraint.RemoteMethodControl#setConstraints */ public RemoteMethodControl setConstraints(final MethodConstraints constraints) { return (new ConstrainableCybernodeAdminProxy((CybernodeAdmin)serviceAdmin, uuid, constraints)); } /** @see RemoteMethodControl#getConstraints */ public MethodConstraints getConstraints() { return ((RemoteMethodControl)serviceAdmin).getConstraints(); } /* Note that the superclass's hashCode method is OK as is. */ /* Note that the superclass's equals method is OK as is. */ /* * Returns a proxy trust iterator that is used in * <code>ProxyTrustVerifier</code> to retrieve this object's trust * verifier. */ @SuppressWarnings("unused") private ProxyTrustIterator getProxyTrustIterator() { return (new SingletonProxyTrustIterator(serviceAdmin)); } /* * Performs various functions related to the trust verification process * for the current instance of this proxy class, as detailed in the * description for this class. * * @throws InvalidObjectException if any of the * requirements for trust verification (as detailed in the class * description) are not satisfied. */ private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { /* * Note that basic validation of the fields of this class was * already performed in the readObject() method of this class' super * class. */ s.defaultReadObject(); // Verify that the server implements RemoteMethodControl if(!(serviceAdmin instanceof RemoteMethodControl)) { throw new InvalidObjectException("ConstrainableCybernodeAdminProxy.readObject "+ "failure : serviceAdmin does not implement " + "constrainable functionality"); } } } /* -------- Implement CybernodeAdmin methods -------- */ /* * (non-Javadoc) * * @see org.rioproject.cybernode.CybernodeAdmin#getServiceLimit() */ public Integer getServiceLimit() throws RemoteException { return (((CybernodeAdmin)serviceAdmin).getServiceLimit()); } public int getRegistryPort() throws RemoteException { return ((CybernodeAdmin)serviceAdmin).getRegistryPort(); } /* * (non-Javadoc) * * @see org.rioproject.cybernode.CybernodeAdmin#setServiceLimit(java.lang.Integer) */ public void setServiceLimit(final Integer count) throws RemoteException { ((CybernodeAdmin)serviceAdmin).setServiceLimit(count); } /* * (non-Javadoc) * * @see org.rioproject.cybernode.CybernodeAdmin#getServiceCount() */ public Integer getServiceCount() throws RemoteException { return (((CybernodeAdmin)serviceAdmin).getServiceCount()); } /* * (non-Javadoc) * * @see org.rioproject.cybernode.CybernodeAdmin#getPersistentProvisioning() */ public boolean getPersistentProvisioning() throws RemoteException { return (((CybernodeAdmin)serviceAdmin).getPersistentProvisioning()); } /* * (non-Javadoc) * * @see org.rioproject.cybernode.CybernodeAdmin#setPersistentProvisioning(boolean) */ public void setPersistentProvisioning(final boolean support) throws IOException { ((CybernodeAdmin)serviceAdmin).setPersistentProvisioning(support); } public ResourceCapability getResourceCapability() throws RemoteException { return ((CybernodeAdmin)serviceAdmin).getResourceCapability(); } /* * (non-Javadoc) * * @see org.rioproject.system.ComputeResourceAdmin#getComputeResourceUtilization() */ public ComputeResourceUtilization getComputeResourceUtilization() throws RemoteException { return (((CybernodeAdmin)serviceAdmin).getComputeResourceUtilization()); } public ComputeResourceUtilization getComputeResourceUtilization(final Uuid serviceUuid) throws RemoteException { return (((CybernodeAdmin)serviceAdmin).getComputeResourceUtilization(serviceUuid)); } /** * A trust verifier for secure smart proxies. */ public final static class Verifier implements TrustVerifier, Serializable { private static final long serialVersionUID = 1L; private final RemoteMethodControl serverProxy; /* * Create the verifier, throwing UnsupportedOperationException if the * server proxy does not implement both RemoteMethodControl and * TrustEquivalence. */ public Verifier(final Object serverProxy) { if (serverProxy instanceof RemoteMethodControl && serverProxy instanceof TrustEquivalence) { this.serverProxy = (RemoteMethodControl) serverProxy; } else { throw new UnsupportedOperationException(); } } /** * Implement TrustVerifier */ public boolean isTrustedObject(final Object obj, final TrustVerifier.Context ctx) throws RemoteException { if (obj == null || ctx == null) { throw new IllegalArgumentException(); } else if (!(obj instanceof ConstrainableCybernodeAdminProxy)) { return false; } RemoteMethodControl otherServerProxy = (RemoteMethodControl)((ConstrainableCybernodeAdminProxy)obj).cybernodeAdminProxy; MethodConstraints mc = otherServerProxy.getConstraints(); TrustEquivalence trusted = (TrustEquivalence) serverProxy.setConstraints(mc); return(trusted.checkTrustEquivalence(otherServerProxy)); } } }