Commit 74c8aabb authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan
Browse files

rpc: added sopport for multiple version of a program

A program may have different versions. Each version of a program
can be handled by a different dispatcher.

Acked-By: Paul
Patch: http://rb.dcache.org/r/1467/
parent 1f0bea46
......@@ -29,7 +29,10 @@ import org.dcache.chimera.FileSystemProvider;
import org.dcache.chimera.JdbcFs;
import org.dcache.chimera.XMLconfig;
import org.dcache.chimera.nfs.ExportFile;
import org.dcache.chimera.nfs.v3.xdr.mount_prot;
import org.dcache.chimera.nfs.v3.xdr.nfs3_prot;
import org.dcache.xdr.OncRpcSvc;
import org.dcache.xdr.OncRpcProgram;
import org.dcache.xdr.portmap.OncRpcEmbeddedPortmap;
public class Main {
......@@ -55,27 +58,27 @@ public class Main {
OncRpcPortmapClient portmap = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1"));
portmap.getOncRpcClient().setTimeout(2000);
if (!portmap.setPort(100005, 3, OncRpcProtocols.ONCRPC_TCP, 2049)) {
if (!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3, OncRpcProtocols.ONCRPC_TCP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv1 service within portmap.");
}
if (!portmap.setPort(100005, 3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
if (!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv1 service within portmap.");
}
if (!portmap.setPort(100005, 1, OncRpcProtocols.ONCRPC_TCP, 2049)) {
if (!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V1, OncRpcProtocols.ONCRPC_TCP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv3 service within portmap.");
}
if (!portmap.setPort(100005, 1, OncRpcProtocols.ONCRPC_UDP, 2049)) {
if (!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V1, OncRpcProtocols.ONCRPC_UDP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv3 service within portmap.");
}
if (!portmap.setPort(100003, 3, OncRpcProtocols.ONCRPC_TCP, 2049)) {
if (!portmap.setPort(nfs3_prot.NFS_PROGRAM, nfs3_prot.NFS_V3, OncRpcProtocols.ONCRPC_TCP, 2049)) {
_log.log(Level.SEVERE, "Failed to register NFSv3 service within portmap.");
}
if (!portmap.setPort(100003, 3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
if (!portmap.setPort(nfs3_prot.NFS_PROGRAM, nfs3_prot.NFS_V3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
_log.log(Level.SEVERE, "Failed to register NFSv3 service within portmap.");
}
......@@ -85,8 +88,8 @@ public class Main {
NfsServerV3 nfs3 = new NfsServerV3(exports, fs);
OncRpcSvc service = new OncRpcSvc(DEFAULT_PORT);
service.register(100003, nfs3);
service.register(100005, ms);
service.register(new OncRpcProgram(nfs3_prot.NFS_PROGRAM, nfs3_prot.NFS_V3), nfs3);
service.register(new OncRpcProgram(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3), ms);
service.start();
}
......
......@@ -31,7 +31,9 @@ import org.dcache.chimera.JdbcFs;
import org.dcache.chimera.XMLconfig;
import org.dcache.chimera.nfs.ExportFile;
import org.dcache.chimera.nfs.v3.MountServer;
import org.dcache.chimera.nfs.v3.xdr.mount_prot;
import org.dcache.chimera.nfs.v4.mover.DSOperationFactory;
import org.dcache.chimera.nfs.v4.xdr.nfs4_prot;
import org.dcache.xdr.portmap.OncRpcEmbeddedPortmap;
......@@ -66,20 +68,20 @@ public class Main {
OncRpcPortmapClient portmap = new OncRpcPortmapClient(InetAddress
.getByName("127.0.0.1"));
portmap.getOncRpcClient().setTimeout(2000);
if ( !portmap.setPort(100005, 3, OncRpcProtocols.ONCRPC_TCP, 2049) ) {
if ( !portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3, OncRpcProtocols.ONCRPC_TCP, 2049) ) {
_log.log(Level.SEVERE, "Failed to register mountv1 service within portmap.");
}
if (!portmap.setPort(100005, 3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
if (!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3, OncRpcProtocols.ONCRPC_UDP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv1 service within portmap.");
}
if(!portmap.setPort(100005, 1, OncRpcProtocols.ONCRPC_TCP, 2049)) {
if(!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V1, OncRpcProtocols.ONCRPC_TCP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv3 service within portmap.");
}
if(!portmap.setPort(100005, 1, OncRpcProtocols.ONCRPC_UDP, 2049)) {
if(!portmap.setPort(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V1, OncRpcProtocols.ONCRPC_UDP, 2049)) {
_log.log(Level.SEVERE, "Failed to register mountv3 service within portmap.");
}
if( !portmap.setPort(100003, 4, OncRpcProtocols.ONCRPC_TCP, 2049) ) {
if( !portmap.setPort(nfs4_prot.NFS4_PROGRAM, nfs4_prot.NFS_V4, OncRpcProtocols.ONCRPC_TCP, 2049) ) {
_log.log(Level.SEVERE, "Failed to register NFSv4 service within portmap.");
}
......@@ -89,8 +91,8 @@ public class Main {
NFSServerV41 nfs4 = new NFSServerV41(new MDSOperationFactory(), new DeviceManager(),
fs, exports);
service.register(100003, nfs4);
service.register(100005, ms);
service.register( new OncRpcProgram(nfs4_prot.NFS4_PROGRAM, nfs4_prot.NFS_V4), nfs4);
service.register( new OncRpcProgram(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3), ms);
}else{
port = DEFAULT_PORT_DS;
......@@ -98,7 +100,7 @@ public class Main {
_log.log(Level.INFO, "starting DS on: {0}", port );
NFSServerV41 ds = new NFSServerV41(new DSOperationFactory(), new DeviceManager(),
fs, null);
service.register(100003, ds);
service.register( new OncRpcProgram(nfs4_prot.NFS4_PROGRAM, nfs4_prot.NFS_V4), ds);
}
service.start();
......
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.xdr;
/**
* Each RPC service has a program number. Because most new protocols evolve,
* a version field of the call message identifies which version of the protocol
* the caller is using. Version numbers enable support of both old and new
* protocols through the same server process.
*
*/
public class OncRpcProgram {
/**
* RPC program number.
*/
private final int _number;
/**
* RPC program version number;
*/
private final int _version;
/**
* Get program number.
* @return program number
*/
public int getNumber() {
return _number;
}
/**
* Get program version.
* @return version number.
*/
public int getVersion() {
return _version;
}
public OncRpcProgram(int number, int version) {
this._number = number;
this._version = version;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if ( ! (obj instanceof OncRpcProgram) ) return false;
final OncRpcProgram other = (OncRpcProgram) obj;
return (this._number == other._number) &&
(this._version == other._version);
}
@Override
public int hashCode() {
return _number;
}
}
......@@ -46,8 +46,8 @@ public class OncRpcSvc {
/**
* mapping of registered programs.
*/
private final Map<Integer, RpcDispatchable> _programs =
new ConcurrentHashMap<Integer, RpcDispatchable>();
private final Map<OncRpcProgram, RpcDispatchable> _programs =
new ConcurrentHashMap<OncRpcProgram, RpcDispatchable>();
/**
* Create a new server. Bind to all supported protocols.
......@@ -186,7 +186,7 @@ public class OncRpcSvc {
* @param prog program number
* @param handler RPC requests handler.
*/
public void register(Integer prog, RpcDispatchable handler) {
public void register(OncRpcProgram prog, RpcDispatchable handler) {
_log.log(Level.INFO, "Registering new program {0} : {1}",
new Object[] {prog, handler});
_programs.put(prog, handler);
......@@ -197,7 +197,7 @@ public class OncRpcSvc {
*
* @param prog
*/
public void unregister(Integer prog) {
public void unregister(OncRpcProgram prog) {
_log.log(Level.INFO, "Inregistering program {0}", prog);
_programs.remove(prog);
}
......
......@@ -33,7 +33,7 @@ public class RpcDispatcher implements ProtocolFilter {
* List of registered RPC services
*
*/
private final Map<Integer, RpcDispatchable> _programs;
private final Map<OncRpcProgram, RpcDispatchable> _programs;
/**
* Create new RPC dispatcher for given program.
......@@ -44,7 +44,7 @@ public class RpcDispatcher implements ProtocolFilter {
*
* @throws NullPointerException if programs is null
*/
public RpcDispatcher( Map<Integer, RpcDispatchable> programs )
public RpcDispatcher( Map<OncRpcProgram, RpcDispatchable> programs )
throws NullPointerException{
if( programs == null)
......@@ -65,7 +65,7 @@ public class RpcDispatcher implements ProtocolFilter {
_log.log(Level.FINE, "processing request prog={0}, vers={1}, proc={2}",
new Object[] {prog, vers, proc});
RpcDispatchable program = _programs.get(Integer.valueOf(prog));
RpcDispatchable program = _programs.get( new OncRpcProgram(prog, vers));
if( program == null ) {
call.failProgramUnavailable();
}else{
......
......@@ -27,6 +27,7 @@ public class SimpleRpcServer {
static final int DEFAULT_PORT = 1717;
private static final int PROG_NUMBER = 100017;
private static final int PROG_VERS = 1;
public static void main(String[] args) throws Exception {
......@@ -45,7 +46,7 @@ public class SimpleRpcServer {
OncRpcPortmapClient portmap = new OncRpcPortmapClient(InetAddress
.getByName("127.0.0.1"));
portmap.getOncRpcClient().setTimeout(2000);
portmap.setPort(PROG_NUMBER, 1, 6, port);
portmap.setPort(PROG_NUMBER, PROG_VERS, IpProtocolType.TCP, port);
RpcDispatchable dummy = new RpcDispatchable() {
......@@ -56,7 +57,7 @@ public class SimpleRpcServer {
};
OncRpcSvc service = new OncRpcSvc(port);
service.register(PROG_NUMBER, dummy);
service.register(new OncRpcProgram(PROG_NUMBER, PROG_VERS), dummy);
service.start();
}
......
......@@ -24,6 +24,7 @@ import org.dcache.xdr.IpProtocolType;
import org.dcache.xdr.OncRpcClient;
import org.dcache.xdr.OncRpcException;
import org.dcache.xdr.OncRpcSvc;
import org.dcache.xdr.OncRpcProgram;
import org.dcache.xdr.RpcAuth;
import org.dcache.xdr.RpcAuthTypeNone;
import org.dcache.xdr.RpcCall;
......@@ -64,7 +65,7 @@ public class OncRpcEmbeddedPortmap {
if(!localPortmapperRunning) {
OncRpcSvc rpcbindServer = new OncRpcSvc(OncRpcPortmap.PORTMAP_PORT, IpProtocolType.UDP | IpProtocolType.TCP);
rpcbindServer.register(OncRpcPortmap.PORTMAP_PROGRAMM, new OncRpcbindServer());
rpcbindServer.register(new OncRpcProgram( OncRpcPortmap.PORTMAP_PROGRAMM, OncRpcPortmap.PORTMAP_V2), new OncRpcbindServer());
rpcbindServer.start();
}
}
......
......@@ -32,6 +32,7 @@ public class OncRpcPortmap {
/*
* V2
*/
public static final int PORTMAP_V2 = 2;
public static final int PMAPPROC_NULL = 0;
public static final int PMAPPROC_SET = 1;
public static final int PMAPPROC_UNSET = 2;
......@@ -42,6 +43,7 @@ public class OncRpcPortmap {
/*
* V4
*/
public static final int PORTMAP_V4 = 4;
public static final int RPCBPROC_SET = 1;
public static final int RPCBPROC_UNSET = 2;
public static final int RPCBPROC_GETADDR = 3;
......
......@@ -26,6 +26,7 @@ import org.dcache.xdr.OncRpcException;
import org.dcache.xdr.RpcCall;
import org.dcache.xdr.RpcDispatchable;
import org.dcache.xdr.OncRpcSvc;
import org.dcache.xdr.OncRpcProgram;
import org.dcache.xdr.XdrBoolean;
import org.dcache.xdr.XdrVoid;
......@@ -40,8 +41,8 @@ public class OncRpcbindServer implements RpcDispatchable {
private final Set<rpcb> _services = new HashSet<rpcb>();
public OncRpcbindServer() {
_services.add(new rpcb(100000, 2, "tcp", "0.0.0.0.0.111", "superuser"));
_services.add(new rpcb(100000, 2, "udp", "0.0.0.0.0.111", "superuser"));
_services.add(new rpcb(OncRpcPortmap.PORTMAP_PROGRAMM, OncRpcPortmap.PORTMAP_V2, "tcp", "0.0.0.0.0.111", "superuser"));
_services.add(new rpcb(OncRpcPortmap.PORTMAP_PROGRAMM, OncRpcPortmap.PORTMAP_V2, "udp", "0.0.0.0.0.111", "superuser"));
//_services.add(new rpcb(100000, 4, "tcp", "0.0.0.0.0.111", "superuser"));
}
public void dispatchOncRpcCall(RpcCall call) throws OncRpcException, IOException {
......@@ -130,7 +131,8 @@ public class OncRpcbindServer implements RpcDispatchable {
RpcDispatchable rpcbind = new OncRpcbindServer();
OncRpcSvc server = new OncRpcSvc(port);
server.register(OncRpcPortmap.PORTMAP_PROGRAMM, rpcbind);
server.register(new OncRpcProgram( OncRpcPortmap.PORTMAP_PROGRAMM,
OncRpcPortmap.PORTMAP_V2), rpcbind);
server.start();
......
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.xdr;
import org.junit.Test;
import static org.junit.Assert.*;
public class OncRpcProgramTest {
@Test
public void testGetNumber() {
int progNum = 15;
int progVers = 17;
OncRpcProgram program = new OncRpcProgram(progNum, progVers);
assertEquals("Program number miss match", progNum, program.getNumber());
}
@Test
public void testGetVersion() {
int progNum = 15;
int progVers = 17;
OncRpcProgram program = new OncRpcProgram(progNum, progVers);
assertEquals("Program version miss match", progVers, program.getVersion());
}
@Test
public void testEqualsTrue() {
int progNum = 15;
int progVers = 17;
OncRpcProgram program1 = new OncRpcProgram(progNum, progVers);
OncRpcProgram program2 = new OncRpcProgram(progNum, progVers);
assertTrue("Equals programs not detected", program1.equals(program2));
}
@Test
public void testNotEqualByProgNumber() {
int progNum = 15;
int progVers = 17;
OncRpcProgram program1 = new OncRpcProgram(progNum, progVers);
OncRpcProgram program2 = new OncRpcProgram(progNum, progVers + 10);
assertFalse("Different programs not detected", program1.equals(program2));
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment