Re: [SNMP4J] SNMP4J Correct Multi-thread Design for use it (under Linux) ?
Hi Franck, Think you for your help. Yes my factory method is not thread safe, but in my implementation, only the main create one instance of the singleton, and the threads call the static method getSnmp() that return the only one instance of snmp class. But, yes, I can add synchronized for the factory method getInstance(), it is better ☺ But, for the getSnmp() method, that is not synchronized, is the design of SNMP4J allow many threads to call the method snmp.send(pdu, target) in parallel ? In my design that works well expect when I make two call in parallel send(pdu,target), where targets are two different instances, but they are initialized with the same IP address. Is it a problem for SNMP4J or is it usual ? · Because I receive org.snmp4j.MessageException : Operation not permitted for the first request only (at each time). Do you know the cause/raison of this exception ? Thank you very much for your opinion. Best Regards, Thierry TESSALONIKOS From: Frank Fock [mailto:f...@agentpp.com] Sent: Saturday, September 24, 2016 11:42 AM To: TESSALONIKOS, THIERRY Cc: snmp4j@agentpp.org Subject: Re: SNMP4J Correct Multi-thread Design for use it (under Linux) ? Hi Thierry, Your singleton factory method is NOT thread safe. This could create issues and need to be fixed. Anything else does not seem to be a real issue with SNMP. The notInTimeWindow report is normal when two SNMPv3 entities exchange messages for the first time (the time needs to be synchronised). Best regards, Frank On 23 Sep 2016, at 15:57, TESSALONIKOS, THIERRY <thierry.tessaloni...@atos.net<mailto:thierry.tessaloni...@atos.net>> wrote: Hi, I need to use SNMP4J API in multi-threading design, because I must send 2 snmp set in parallel toward 2 Network Elements for sending them a parameters… So, I have a main thread that initialize the SNMP4J API, with a singleton like this : public class SNMP4JInitialize implements SNMPEngineInitInterface{ // properties SNMP4J private static SNMP4JInitialize snmp4JInitializeInstance; private static TransportMapping transport; private static Snmp snmp; private static USM usm; private static OctetString localEngineID; private SNMP4JInitialize() throws IOException { // Intialisation SNMP4J transport = new DefaultUdpTransportMapping(); //@TODO utiliser un autre constructeur pour positionner adresse IP d'écoute snmp = new Snmp(transport); localEngineID = new OctetString(MPv3.createLocalEngineID()); usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0); SecurityModels.getInstance().addSecurityModel(usm); SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES256With3DESKeyExtension()); transport.listen(); // Instanaciation de la classe qui gere les UsmUer automatiquement à partir des MAJ JMS envoyées par l'appli JEE OctetString securityName1 = new OctetString("toto"); UsmUser usmUser1 = new UsmUser(securityName1, // securityName AuthMD5.ID, // authenticationProtocol new OctetString("toto123456"), // authenticationPassphrase PrivAES128.ID, // privacyProtocol new OctetString("toto123456")); // privacyPassphrase snmp.getUSM().addUser(usmUser1); OctetString securityName2 = new OctetString("titi"); UsmUser usmUser2 = new UsmUser(securityName2, // securityName AuthSHA.ID, // authenticationProtocol new OctetString("toto123456"), // authenticationPassphrase PrivAES256With3DESKeyExtension.ID, // privacyProtocol //PrivAES256.ID, // privacyProtocol new OctetString("toto123456")); // privacyPassphrase snmp.getUSM().addUser(usmUser2); } public static Snmp getSnmp() { return snmp; } public static SNMP4JInitialize getInstance() throws IOException, Exception { if (snmp4JInitializeInstance == null) { snmp4JInitializeInstance = new SNMP4JInitialize(); } return (snmp4JInitializeInstance); } } And after I launch 2 thread in parallel (from a thread pool, managed by ExecutorService class…) Each thread create a new UserTarget and getSNMP instance from the Initialization Singleton, and send the PDU with snmp.send(pdu, target) like this : public class SNMP4JRequestSender implements SNMPModuleSenderInterface { public RequestTaskStatus sendsnmpv3Request(RequestTaskStatus requestTaskStatus, RequestTaskSNMP requestTaskSNMP) throws IOException { final Address targetAddress = GenericAddress.parse(requestTaskSNMP.getSnmpTargetURL()); // create the target UserTarget target = new UserTarget(); target.setAddress(targetAddress); target.setRetries(requestTaskSNMP.getRetry()); target.setTimeout(reques
Re: [SNMP4J] SNMP4J Correct Multi-thread Design for use it (under Linux) ?
Hi Thierry, Your singleton factory method is NOT thread safe. This could create issues and need to be fixed. Anything else does not seem to be a real issue with SNMP. The notInTimeWindow report is normal when two SNMPv3 entities exchange messages for the first time (the time needs to be synchronised). Best regards, Frank > On 23 Sep 2016, at 15:57, TESSALONIKOS, THIERRY >wrote: > > Hi, > > I need to use SNMP4J API in multi-threading design, because I must send 2 > snmp set in parallel toward 2 Network Elements for sending them a parameters… > > So, I have a main thread that initialize the SNMP4J API, with a singleton > like this : > > public class SNMP4JInitialize implements SNMPEngineInitInterface{ > > // properties SNMP4J > private static SNMP4JInitialize snmp4JInitializeInstance; > private static TransportMapping transport; > private static Snmp snmp; > private static USM usm; > private static OctetString localEngineID; > > > private SNMP4JInitialize() throws IOException { > > // Intialisation SNMP4J > transport = new DefaultUdpTransportMapping(); //@TODO utiliser un > autre constructeur pour positionner adresse IP d'écoute > snmp = new Snmp(transport); > localEngineID = new OctetString(MPv3.createLocalEngineID()); > usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0); > SecurityModels.getInstance().addSecurityModel(usm); > SecurityProtocols.getInstance().addPrivacyProtocol(new > PrivAES256With3DESKeyExtension()); > transport.listen(); > // Instanaciation de la classe qui gere les UsmUer automatiquement à > partir des MAJ JMS envoyées par l'appli JEE > > OctetString securityName1 = new OctetString("toto"); > UsmUser usmUser1 = new UsmUser(securityName1, // securityName > AuthMD5.ID, // authenticationProtocol > new OctetString("toto123456"), // authenticationPassphrase > PrivAES128.ID, // privacyProtocol > new OctetString("toto123456")); // privacyPassphrase > snmp.getUSM().addUser(usmUser1); > > > OctetString securityName2 = new OctetString("titi"); > UsmUser usmUser2 = new UsmUser(securityName2, // securityName > AuthSHA.ID, // authenticationProtocol > new OctetString("toto123456"), // authenticationPassphrase > PrivAES256With3DESKeyExtension.ID, // privacyProtocol > //PrivAES256.ID, // privacyProtocol > new OctetString("toto123456")); // privacyPassphrase > snmp.getUSM().addUser(usmUser2); > } > > public static Snmp getSnmp() { > return snmp; > } > > public static SNMP4JInitialize getInstance() throws IOException, > Exception { > > if (snmp4JInitializeInstance == null) { > snmp4JInitializeInstance = new SNMP4JInitialize(); > } > return (snmp4JInitializeInstance); > } > } > > And after I launch 2 thread in parallel (from a thread pool, managed by > ExecutorService class…) > > Each thread create a new UserTarget and getSNMP instance from the > Initialization Singleton, and send the PDU with snmp.send(pdu, target) like > this : > > public class SNMP4JRequestSender implements SNMPModuleSenderInterface { > > public RequestTaskStatus sendsnmpv3Request(RequestTaskStatus > requestTaskStatus, RequestTaskSNMP requestTaskSNMP) throws IOException { > > final Address targetAddress = > GenericAddress.parse(requestTaskSNMP.getSnmpTargetURL()); > > // create the target > UserTarget target = new UserTarget(); > target.setAddress(targetAddress); > target.setRetries(requestTaskSNMP.getRetry()); > target.setTimeout(requestTaskSNMP.getTimout()); > target.setVersion(SnmpConstants.version3); > target.setSecurityLevel(SecurityLevel.AUTH_PRIV); > target.setSecurityName(requestTaskSNMP.getSecurityName()); // The > same name used for usmUser > > //create the PDU > ScopedPDU pdu = new ScopedPDU(); > > List variableBindings = requestTaskSNMP.getOids(); > > if ((variableBindings == null) || (variableBindings.isEmpty())) { > requestTaskStatus.setResultStatus(GeneralResultStatusEnum.Failed); > > requestTaskStatus.setReasonStatus(ReasonStatusEnum.NoOIDinSNMPRequest); > return (requestTaskStatus); > } > for (VariableBinding variableBinding : variableBindings) { > pdu.add(variableBinding); > } > > pdu.setType(requestTaskSNMP.getPDUType()); > > // send the PDU > final ResponseEvent response = SNMP4JInitialize.getSnmp().send(pdu, > target); > > // extract the response PDU (could be null if timed out) > final PDU responsePDU =
[SNMP4J] SNMP4J Correct Multi-thread Design for use it (under Linux) ?
Hi, I need to use SNMP4J API in multi-threading design, because I must send 2 snmp set in parallel toward 2 Network Elements for sending them a parameters... So, I have a main thread that initialize the SNMP4J API, with a singleton like this : public class SNMP4JInitialize implements SNMPEngineInitInterface{ // properties SNMP4J private static SNMP4JInitialize snmp4JInitializeInstance; private static TransportMapping transport; private static Snmp snmp; private static USM usm; private static OctetString localEngineID; private SNMP4JInitialize() throws IOException { // Intialisation SNMP4J transport = new DefaultUdpTransportMapping(); //@TODO utiliser un autre constructeur pour positionner adresse IP d'écoute snmp = new Snmp(transport); localEngineID = new OctetString(MPv3.createLocalEngineID()); usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0); SecurityModels.getInstance().addSecurityModel(usm); SecurityProtocols.getInstance().addPrivacyProtocol(new PrivAES256With3DESKeyExtension()); transport.listen(); // Instanaciation de la classe qui gere les UsmUer automatiquement à partir des MAJ JMS envoyées par l'appli JEE OctetString securityName1 = new OctetString("toto"); UsmUser usmUser1 = new UsmUser(securityName1, // securityName AuthMD5.ID, // authenticationProtocol new OctetString("toto123456"), // authenticationPassphrase PrivAES128.ID, // privacyProtocol new OctetString("toto123456")); // privacyPassphrase snmp.getUSM().addUser(usmUser1); OctetString securityName2 = new OctetString("titi"); UsmUser usmUser2 = new UsmUser(securityName2, // securityName AuthSHA.ID, // authenticationProtocol new OctetString("toto123456"), // authenticationPassphrase PrivAES256With3DESKeyExtension.ID, // privacyProtocol //PrivAES256.ID, // privacyProtocol new OctetString("toto123456")); // privacyPassphrase snmp.getUSM().addUser(usmUser2); } public static Snmp getSnmp() { return snmp; } public static SNMP4JInitialize getInstance() throws IOException, Exception { if (snmp4JInitializeInstance == null) { snmp4JInitializeInstance = new SNMP4JInitialize(); } return (snmp4JInitializeInstance); } } And after I launch 2 thread in parallel (from a thread pool, managed by ExecutorService class...) Each thread create a new UserTarget and getSNMP instance from the Initialization Singleton, and send the PDU with snmp.send(pdu, target) like this : public class SNMP4JRequestSender implements SNMPModuleSenderInterface { public RequestTaskStatus sendsnmpv3Request(RequestTaskStatus requestTaskStatus, RequestTaskSNMP requestTaskSNMP) throws IOException { final Address targetAddress = GenericAddress.parse(requestTaskSNMP.getSnmpTargetURL()); // create the target UserTarget target = new UserTarget(); target.setAddress(targetAddress); target.setRetries(requestTaskSNMP.getRetry()); target.setTimeout(requestTaskSNMP.getTimout()); target.setVersion(SnmpConstants.version3); target.setSecurityLevel(SecurityLevel.AUTH_PRIV); target.setSecurityName(requestTaskSNMP.getSecurityName()); // The same name used for usmUser //create the PDU ScopedPDU pdu = new ScopedPDU(); List variableBindings = requestTaskSNMP.getOids(); if ((variableBindings == null) || (variableBindings.isEmpty())) { requestTaskStatus.setResultStatus(GeneralResultStatusEnum.Failed); requestTaskStatus.setReasonStatus(ReasonStatusEnum.NoOIDinSNMPRequest); return (requestTaskStatus); } for (VariableBinding variableBinding : variableBindings) { pdu.add(variableBinding); } pdu.setType(requestTaskSNMP.getPDUType()); // send the PDU final ResponseEvent response = SNMP4JInitialize.getSnmp().send(pdu, target); // extract the response PDU (could be null if timed out) final PDU responsePDU = response.getResponse(); if (responsePDU == null) { requestTaskStatus.setResultStatus(GeneralResultStatusEnum.Failed); requestTaskStatus.setReasonStatus(ReasonStatusEnum.NoResponseFromNetworkElement); } return (requestTaskStatus); } } Is this design is correct or supported with SNMP4J API ? (thread safe, ...). It seems work well when I launch in parallel the 2 thread for sending 2 snmp request toward to different IP address target. But when I launch the 2 thread toward the same IP address (but each thread use its own instance of UserTarget, but with the same IP) a have the following error only for the second request : -