从snmp代理查询我的sql db

时间:2013-10-22 22:33:01

标签: java snmp snmp4j

我是snmp并使用snmp4j创建snmp代理的新手。我的java应用程序需要监听snmp请求并根据传入的oid查询db并发回响应。我有snmp代理的src代码。但是代理如何根据传入的oid查询数据库?我是否需要在我的数据库中将所有oid注册为代理中的托管对象,以便代理可以在请求到达时进行查找?或换句话说,我如何从代理指向我的数据存储区/数据库?

这是我正在使用的代码。

http://shivasoft.in/blog/java/snmp/creating-snmp-agent-server-in-java-using-snmp4j/

`List oidList = impl.getOidList(); //从db

获取数据

for(Oid oid:oidList){

   agent.registerManagedObject(MOScalarFactory.createReadOnly(new OID(
                oid.getOid()), oid.getValue()));

    }'

我正在尝试使用db中的数据注册托管对象。它是否正确? 我在第二行收到重复的注册例外,虽然oid是唯一的。

`.1.3.6.1.4.1.1166.1.6.1.2.2.1.3.1.1

.1.3.6.1.4.1.1166.1.6.1.2.2.1.3.1.2`

我不认为这是正确的方法,因为如果db是巨大的呢? 非常感谢任何帮助/提示。

2 个答案:

答案 0 :(得分:3)

问题

您获得 org.snmp4j.agent.DuplicateRegistrationException ,因为ContextScope中只能有一个ManagedObject。每次注册都会为ManagedObject分配MOContextScope值。第二次注册尝试将第二个对象设置为contextScope。范围已经填充,因此抛出异常。 但是每个标量值应该最终得到.0。您可以检查任何MIB浏览器,如iReasoning并选择任何值。如果此值是标量 - 尽管在MIB文件中未提及,但是会自动附加尾随零。所以最多"正确"方法是使用4.1解决方案。

解决方案1 ​​ - 拥有MOScalar

编写自己的MOScalar。有更小的界限。 你应该覆盖getLowerBound,getUpperBound,isLowerIncluded,isUpperIncluded来为你的对象获取单独的contextScopes。

我建议每次返回Scalar OID并包含两个边界。 上边界和下边界最好返回相同的OID。

解决方案2 - 拥有MOServer

编写自己的MOServer。有了blackJack和其他人...... 尽管如此,你可以简单地复制代码

private SortedMap<MOScope, ManagedObject> registry;

看起来应该是这样的

private SortedMap<MOScope, Set<ManagedObject>> registry;

它会影响注册,注销和其他逻辑。 DefaultMOServer - 678行包含。评论。实际上你应该修复几个类:

  

query.matchesQuery(对象)

private boolean matchesQuery(MOQuery query, ManagedObject object) {
    if ((query.matchesQuery(object)) && object.getScope().isOverlapping(query.getScope()))
        if (object instanceof MOScalar) {
            MOScalar moScalar = (MOScalar) object;
            return query.getLowerBound().compareTo(moScalar.getID()) <= 0 &&
                    query.getUpperBound().compareTo(moScalar.getID()) >= 0;
        } else {
            return true;
        }

    return false;
}
  

protected void fire ...事件(ManagedObject对象,MOQuery查询){

protected void fire...Event(Set<ManagedObject> objects, MOQuery query) {
        if (lookupListener != null) {
            for (ManagedObject mo : objects) {
  

ManagedObject other = lookup(new DefaultMOQuery(contextScope));

Set<ManagedObject> other = lookup(new DefaultMOQuery(contextScope), false);

等等......

解决方案3 - 表

使用表格行。 您可以添加表并追加行。

您将能够以

的形式访问单元格
<tableEntryOID>.<columnSubID>.<rowIndexOID>

您可以使用this question作为教程。

解决方案4 - OIDs fixup

让你使用不同的contextScopes。

解决方案4.1 添加尾随零

    agent.registerManagedObject(
            MOScalarFactory.createReadOnly(
                    new OID(oid.getOid()).successor(),
                    oid.getValue()
            )
    );

这会将 .0 附加到相同级别的属性。

  

snmpget -v2c -c public localhost:2001 oid.getOid()。0

此外,任何MIB浏览器都会将.0附加到MIB文件中定义的每个标量oid。您可以将iReasoning作为最受欢迎的浏览器进行检查。甚至hrSystemUptime(.1.3.6.1.2.1.25.1.1 - 见左下角)也被请求作为最顶层的hrSystemUptime.0(.1.3.6.1.2.1.25.1.1.0)。

解决方案4.2 在基地分开OID。

static final OID sysDescr1 = new OID("1.3.6.1.4.1.5.6.1.8.9"),
        sysDescr2 = new OID("1.3.6.1.4.1.5.6.2.2.5");

修复数据库OID以获取单独的contextScope。

另外

您可以尝试阅读SNMP4J-Agent-Instrumentation-Guide.pdf。这对我没有帮助 您可以将源附加到IDE以阅读零预告片和其他细微差别。这有助于我获得有关DefaultMOServer的更多信息。

更正 pom.xml 导入以获取最新版本

    <repositories>
        <repository>
            <id>SNMP4J</id>
            <url>https://oosnmp.net/dist/release/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.snmp4j</groupId>
            <artifactId>snmp4j-agent</artifactId>
            <version>2.3.2</version>
        </dependency>
    </dependencies>

答案 1 :(得分:1)

首先,OID确实以一个数字开头 - 而不是一个点。您使用的语法来自NET-SNMP,并且是非标准的。

其次,请阅读SNMP4J-Agent-Instrumentation-Guide.pdf文档,该文档详细描述了如何为MIB设置代理。您获得了重复的注册异常,因为您将标量注册为子树。标量OID必须以“.0”实例后缀结束。

使用CommandResponder接口有点重新发明轮子。当您从头开始时,您很可能永远无法实现安全且标准的符合SNMP代理。使用SNMP4J-Agent及其检测钩子将为您节省大量工作和麻烦。