/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.snmp.mock; import java.util.ArrayList; import java.util.List; import org.opennms.netmgt.snmp.SnmpObjId; abstract public class RequestPdu extends TestPdu { protected int getNonRepeaters() { return size(); } protected int getMaxRepititions() { return 0; } /* * This simulates send a packet and waiting for a response. * * This is a template method based on te getBulk algorithm. We use the getBulk * algorithm for get and nexts as well. nonRepeaters for gets and nexts is always * equals to pdu size so there are no repeaters. maxRepitions is also always zero * for gets and nexts. * * The method getRespObjIdFromReqObjId which by default goes 'next' is overridden * and does 'get' in the GetPdu. */ public ResponsePdu send(TestAgent agent) { ResponsePdu resp = TestPdu.getResponse(); try { // first do non repeaters int nonRepeaters = Math.min(size(), getNonRepeaters()); for(int i = 0; i < nonRepeaters; i++) { int errIndex = i+1; TestVarBind varBind = (TestVarBind) getVarBindAt(i); SnmpObjId lastOid = varBind.getObjId(); TestVarBind newVarBind = getResponseVarBind(agent, lastOid, errIndex); resp.addVarBind(newVarBind); // make sure we haven't exceeded response size validateResponseSize(resp, agent); } // make a list to track the repititions int repeaters = size() - nonRepeaters; List<SnmpObjId> repeaterList = new ArrayList<SnmpObjId>(repeaters); for(int i = nonRepeaters; i < size(); i++) { repeaterList.add(getVarBindAt(i).getObjId()); } // now generate varbinds for the repeaters for(int count = 0; count < getMaxRepititions(); count++) { for(int i = 0; i < repeaterList.size(); i++) { int errIndex = nonRepeaters+i+1; SnmpObjId lastOid = (SnmpObjId)repeaterList.get(i); TestVarBind newVarBind = getResponseVarBind(agent, lastOid, errIndex); resp.addVarBind(newVarBind); repeaterList.set(i, newVarBind.getObjId()); // make sure we haven't exceeded response size validateResponseSize(resp, agent); } } return resp; } catch (AgentIndexException e) { // this happens for GenErr and NoSuchName errs resp.setVarBinds(getVarBinds()); resp.setErrorStatus(e.getErrorStatus()); resp.setErrorIndex(e.getErrorIndex()); // errorIndex uses indices starting at 1 return resp; } catch (AgentTooBigException e) { // when we exceed response size we'll get here return handleTooBig(agent, resp); } } protected ResponsePdu handleTooBig(TestAgent agent, ResponsePdu resp) { resp.setVarBinds(new TestVarBindList()); resp.setErrorStatus(ResponsePdu.TOO_BIG_ERR); resp.setErrorIndex(0); // errorIndex uses indices starting at 1 return resp; } private void validateResponseSize(ResponsePdu resp, TestAgent agent) { if (resp.size() > agent.getMaxResponseSize()) throw new AgentTooBigException(); } protected TestVarBind getResponseVarBind(TestAgent agent, SnmpObjId lastOid, int errIndex) { return agent.getNextResponseVarBind(lastOid, errIndex); } }