集成 i2 COPLINK 与 Intelligence Operations Center

本文描述了一种将 IBM® i2® COPLINK® 数据与 IBM Intelligent Operations Center 集成的方法。为了实现此方法,我们将利用现有的 XML 规范(比如 NIEM 和 LEXS)和来自产品的工具,包括来自 COPLINK 的 COPLINK File Exporter 和来自 Intelligent Operations Center 的 Websphere Message Broker Toolkit。

Brian Daly, 软件开发人员, IBM

Brian Daly 的照片Brian Daly 是一名软件开发人员,是位于爱尔兰 Mulhuddart 的 Technology Campus 的 IBM Industry Solutions Development 小组的成员。他开发了扩展行业解决方案产品的新内容。



2013 年 4 月 23 日

概述

IBM i2 COPLINK 是一个数据库应用程序,它整合了警务数据,协助完成协作,并帮助生成战术性线索。IBM Intelligent Operations Center 可以监视和管理城市服务。通过集中的情报提供每日城市运作情况的操作性洞察。集成这两个系统有助于充实可供城市管理者使用的信息,帮助他们快速而又有效地确定和解决潜在问题。这一集成可帮助城市以某种具有凝聚力的方式使用其资源,有助于将城市打造为智慧城市,更好地管理次要事故和重大灾难。


NIEM、IEPD 和 LEXS 简介

NIEM

National Information Exchange Model (NIEM) 是一个信息共享框架,允许国家机构将其系统映射到它提供的构建块。它降低了及时地在机构之间共享重要信息的复杂性,无需对它们维护的系统进行重大调整。

IEPD

Information Exchange Package Documentation (IEPD) 是在信息的生成者与使用者之间成功交换信息所需的规则的一种正式、结构化、基于 XML 的表示。信息生成者使用 NIEM 构建了一个用来方便信息交换的 IEPD(例如 IBM i2 COPLINK IEPD)。

LEXS

Logical Entity Exchange Specification (LEXS) 构建于 NIEM 之上,以便提供进一步的框架,此构建既遵守 NIEM,又支持执行发布、搜索和检索操作的一致方式的 IEPD。NIEM IEPD 用于两个特定系统的生成者和使用者之间的特定的信息交换,LEXS IEPD 提供了一个更加流畅的解决方案,转移了不同的信息生成者和使用者的需求。这种流动性是通过拥有一种基本的数据级别来实现的,这种数据级别称为摘要 (digest),所有 LEX 实现(生成者和使用者)都能理解它。


转换消息流

以下是消息流的简短概述,如 图 1 所示:

  • 消息流从 File Input 节点开始,该节点使用 sftp 协议从一个远程文件系统读入 IBM i2 COPLINK 分发。
  • 然后,映射节点 doPub-CopAug 从 LEXS 消息消除结构化工作负载,检索已改善的 IBM i2 COPLINK 信息。从 LEXS 消息的基准信息中检索额外的字段,然后将它们存储在本地环境中,以便在整个消息流中访问它们。
  • CopAug-CAP 映射节点用于将 CoplinkAugmentation 消息的 IBM i2 COPLINK 元素映射到 CAP 消息的 CAP 元素。
  • 过滤器节点 checkAddress 用于验证 IBM i2 COPLINK 分发是否包含有效的地址信息,因为需要将地址进行地理编码为 GPS 坐标,所以可在 IBM Intelligent Operations Center 中的地图 portler 上显示它们。
  • Java™ 计算节点 geocodeCoords 查询一个 ESRI 提供的 Web 服务,该 Web 服务将在收到有效的地址信息后返回 GPS 坐标。
  • 过滤器节点 checkEvent 检查是否为 CAP 分配了有效的事件(来自 IBM i2 COPLINK 消息的 DispatchTypeText 的事件数据地图)。
  • 最后的过滤器节点 checkCoords 检查 Web 服务返回的 GPS 坐标是否有效。如果为 Web 服务提供了坏的或不完整的地址信息,它将返回 0.0 表示 GPS 坐标的经度和纬度。

完成最后一步检查后,经过验证的 CAP 消息将转移到 Intelligent Operations Center 的 Input CAP 消息队列,即 IOC.CAP.IN

图 1. 完整的转换消息流
完整的转换消息流

消息流步骤

现在,让我们更仔细地查看消息流的各个步骤。

File Input 节点(消息流的第一个节点)使用 sftp 协议连接到 IBM i2 COPLINK File Exporter 服务器上的一个远程目录,以便允许传输 COPLINK 信息更新,COPLINK File Exporter 会将这些更新导出到远程目录。图 2 显示了配置此节点的一个示例。

图 2. 针对 SFTP 传输而配置 File Input 节点
针对 SFTP 传输而配置 File Input 节点

File Input 节点将会监听由 IBM i2 COPLINK File Exporter 导出的新文件,将这些文件安全地传输到在 Intelligent Operations Center Application and Integration 服务器上运行的消息流,以便开始将 IBM i2 COPLINK 分发数据转换为 CAP 格式的过程。

可使用 CAP 1.2 模式和 IBM i2 COPLINK IEPD 创建两个映射节点 doPub-CopAugCopAug-CAP(参见 图 3),可将它们导入两个不同的消息集项目。可手动生成 CAP 消息定义文件,方法是单击 File -> New -> Message Definition File From... -> XML 模式文件并选择 CAP-v1.2.xsd 文件。由于 CAP 是一个相对简单的模式,所以惟一可选择的全局元素是一个警告元素。结果得到的是一个 CAP-v1.2.mxsd 或消息定义文件,以及一条可由映射节点在一个消息映射中使用的警告消息对象。

图 3. 消息流的一部分,包含两个将 COPLINK IEPD 输出转换为 CAP 格式的映射节点
消息流部分

IBM i2 COPLINK 模式或 IEPD(从 LEX 3.1.4 和 NIEM 2.0 构建)涉及到许多 .xsd 文件。您可以手动导入这些文件,就像 CAP 规范一样,但由于涉及到许多 .xsd 文件,这可能是一个费力的过程。我们可运行 WebSphere Message Broker Toolkit 中的一个批处理工具,一起处理所有 .xsd 文件。该工具将分析它们之间的依赖关系,生成需要在一个消息映射中使用的消息对象。要运行批处理工具,可将 LEX 3.1.4 模式解压到系统上的某个文件夹,将 coplink.xsd 放在此文件夹中,如 4 所示。一个运行此命令的示例是:

mqsicreatemsgdefs -p coplinkxsdauto -data
/home/briand/projects/con_coplink_ioc/workspaces/transformation26061012 -d
/home/briand/projects/con_coplink_ioc -rmp -rmd -ns

注意:要成功运行此命令,您必须先关闭 WebSphere Message Broker Toolkit。

在 WebSphere Message Broker 信息中心中名为 从命令行导入 的一节中,可以找到此命令和它使用的参数的说明。

图 4. 设置消息定义文件的批量创建
设置消息定义文件的批量创建

图 3 中描绘的消息流演示了汇编所需的 CAP 消息的两步流程。doPub-CopAug 映射节点是此流程中的第一步,由一个名为 doPubCopAug.msgmap 的消息映射和一个名为 doPubCopAug_submap0.msgmap 的子映射组成。

可像任何其他节点一样,将映射节点拖放到您的消息流上。然后消息映射可以通过两种方式之一创建:双击映射节点,或者选择 File -> New -> Message Map。然后系统会要求您选择消息映射的来源和目标消息。请选择 doPublish 消息作为来源,因为这将提供获取前面描述的结构化工作负载的途径。选择 CoplinkAugmentation 消息作为消息映射的目标。CoplinkAugmentation 消息将包含在 LEX 消息的结构化工作负载中一个通配符元素中。要到达此元素,可按如下路线导航来源:lexspd:doPublish -> lexs:PublishMessageContainer -> lexs:PublishMessage -> substitutions for lex:PublishMessageItemAbstract -> lexs:DataItemPackage -> specializations for lexs:StructuredPayload -> lexs:StructuredPayload -> Wildcard Element,然后将 Wildcard Element 拖动到目标中的 CoplinkAugmentation Type,如 图 5 所示。

图 5. 消息映射 Wildcard Element -> CoplinkAugmentation
Wildcard Element 的消息映射

图 6 演示了将从此操作中获得的子映射。可从来源的 CoplinkAugmentations Type 拖动到目标的 CoplinkAugmentations Type 来完成该子映射。这将成功地映射来自 LEX 消息的 IBM i2 COPLINK 数据,但您仍然需要访问 CAP 消息的其他一些 LEX 消息元素。这些元素可存储在消息流的本地环境中,以方便访问。保存子映射并返回到原始消息映射,在我们的示例中为 doPubCopAug.msgmap。右键单击消息映射的目标面板 -> Add or Remove Headers and Folders -> Selected headers and other folders,然后选择 LocalEnvironment

图 6. Wildcard Element 到 CoplinkAugmentation 的子映射
Wildcard Element 的子映射

此实例中需要的额外的 LEX 元素包括 lexs:MessageDateTime、nc:AddressFullText 和 lex:DataItemID。图 7 演示了将一个变量拖动到本地环境中的变量的 Wildcard Element,显示了所有三个变量的映射脚本。

图 7. 将变量添加到本地环境
将变量添加到本地环境

IBM i2 COPLINK 消息和本地环境中存储的额外的 LEX 数据必须转换为可由 Intelligent Operations Center 解释的 CAP 格式。图 7 是消息映射 CopAug_CAP.msgmap 的一个屏幕截图,它是为 图 3 中的消息流的第二个映射节点创建的。一些 CAP 消息元素从 COPLINK、LEXS 和 NIEM 数据映射而来,一些元素定义为约束。清单 1 显示了详细映射。注意:尽管在本示例中,我们将 GPS 坐标设置为常量,但实际的 IBM i2 COPLINK 数据并非如此。

清单 1. CAP 消息元素的详细映射
cap:identifier -> $source/LocalEnvironment/Variables/lexs:DataItemID

cap:sender ->
$source/coplink:CoplinkAugmentation/coplink:DispatchAugmentation
/coplink:ReportingOrganizationText

cap:sent -> $source/LocalEnvironment/Variables/lexs:MessageDateTime 

cap:status -> 'Actual' 

cap:msgType -> 'Alert' 

cap:scope -> 'Public' 

cap:code -> 'Event' 

cap:info 

    cap:category ->       'Security' 
    
    cap:event -> $source/coplink:CoplinkAugmentation/coplink:DispatchAugmentation
    /coplink:DispatchTypeText
    
    cap:urgency ->        'Immediate' 
    
    cap:severity ->       'Severe' 
    
    cap:certainty ->      'Observed' 
    
    cap:headline -> '$source/coplink:CoplinkAugmentation/coplink:DispatchAugmentation
    /coplink:DispatchTypeText'
                
    cap:description -> $source/coplink:CoplinkAugmentation/coplink:DispatchAugmentation
    /coplink:DispatchTypeText
    
    cap:area 
                cap:areaDesc ->
    $source/LocalEnvironment/Variables/nc:AddressFullText
    
                cap:circle ->     '30.199192440061,-97.763281799772 0'
图 8. 消息映射 CoplinkAugmentation -> CAP
消息映射 CoplinkAugmentation -> CAP

过滤器节点用于检查是否提供了一个完整地址。过滤器节点中编写了以下 ESQL 来提供此功能,此验证可查看 CAP 消息的 areaDesc 字段是否为空。如果地址是空的,那么消息会放在 ADDRESS_NOT_EXIST 队列中。如果过滤器节点抛出一个错误,那么结果消息会放入 ADDRESS_FAIL 队列中。

清单 2. 检查地址是否有效的 ESQL 代码
CREATE FILTER MODULE CoplinkTransform_CheckAddress 
    CREATE FUNCTION Main() RETURNS BOOLEAN 
    BEGIN
        IF Root.XMLNSC.ns:alert.ns:info.ns:area.ns:areaDesc IS NULL THEN 
        RETURN FALSE; 
        ELSE
                RETURN TRUE; 
        END IF; 
    END;
END MODULE;

messageFlow 的下一步涉及到使用一个 Java 计算节点 geocodeCoords,以便使用 COPLINK 所提供的地址对一个有效的经度和维度进行地理编码。清单 3 中的 Java 代码有助于演示这一点。它从 CAP 消息读取完整的地址,将它拆分为街道、城市、州和邮政编码。然后建立到 ESRI Web 服务的一个连接,该 Web 服务将接受一个地址作为输入,尝试以 JSON 对象的形式返回有效的 GPS 坐标。使用一个 IBM JSON 解析器来解析 GPS 坐标,以下这段代码将编辑 CAP 消息,将 GPS 坐标插入消息的正确部分。

清单 3. 检查地址是否有效的 ESQL 代码
import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.ibm.json.java.JSON;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;


public class RESTExample_JavaCompute extends 
MbJavaComputeNode {

    private Double x_ =0.0;
    private Double y_ =0.0;

    public void evaluate(MbMessageAssembly inAssembly) throws 
    MbException {
        MbOutputTerminal out = getOutputTerminal("out");
        MbOutputTerminal alt = getOutputTerminal("alternate");
        
        MbMessage inMessage = inAssembly.getMessage();
        
        MbElement areaDesc = inMessage.getRootElement().getLastChild().getFirstChild()
            .getLastChild().getLastChild().getFirstChild();
        String fullAddress = areaDesc.getValueAsString();
        String [] commaSplit = fullAddress.split(",");
        String [] spaceSplit = commaSplit[2].split(" "); 
        
        // ----------------------------------------------------------
        // Add user code below
    try{
        String messageStreet = commaSplit[0].trim();
        String messageCity = commaSplit[1].trim();
        String messageState = spaceSplit[1].trim();
        String messageZip = spaceSplit[2].trim();
        String street = "Street=" + messageStreet.replaceAll(" ", "+");
        String city = "City=" + messageCity.replaceAll(" ", "+");
        String state = "State=" + messageState.replaceAll(" ", "+");
        String zip = "ZIP=" + messageZip.replaceAll(" ", "+");
        String amp = "&";
        String urlStr = "http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators
            /TA_Streets_US/GeocodeServer/findAddressCandidates?";
        String urlLastBit = "outFields=&outSR=&f=json";
        String urlFinal = urlStr + street + amp + city + amp + state + amp + zip + 
        amp + urlLastBit; 

    URL url = new URL(urlFinal);
        HttpURLConnection conn =
        (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json;charset=utf-8");

        if (conn.getResponseCode() != 200) {
            throw new IOException(conn.getResponseMessage());
        }

    // Buffer the result into a string
    BufferedReader rd = new BufferedReader(new InputStreamReader
    (conn.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = rd.readLine()) != null) {
            sb.append(line);
            JSONObject obj = (JSONObject)JSON.parse(line);
            JSONArray candidates = (JSONArray)obj.get("candidates");
            JSONObject firstCandidate = (JSONObject)candidates.get(0);
            JSONObject location = (JSONObject) firstCandidate.get("location"); 
            this.x_ = (Double) location.get("x");
            this.y_ = (Double) location.get("y");
        }
        rd.close();

        conn.disconnect();
    }
    catch(Exception e){
        e.printStackTrace();
    }


    // create new message
    MbMessage outMessage = new MbMessage(inMessage);
    String circle = this.y_ + "," + 
    this.x_ + " " + 0;               

outMessage.getRootElement().getLastChild().getFirstChild().getLastChild().getLastChild()
.getLastChild().setValue(circle);
    System.out.println("ok");

    MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly,
            outMessage);

    try {

            // The following should only be changed
            // if not propagating message to the 'out' terminal
            out.propagate(outAssembly);

    } finally {
            // clear the outMessage
            outMessage.clearMessage();
        }
    }

}

还有其他两个过滤器节点的执行验证检查的方式类似于地址过滤器。过滤器节点 checkEvent 确保 CAP 消息未错过一个事件。

清单 4. 检查一个事件是否有效的 ESQL 代码
CREATE FILTER MODULE CoplinkTransform_CheckEvent 
        CREATE FUNCTION Main() RETURNS BOOLEAN 
        BEGIN 
            IF Root.XMLNSC.ns:alert.ns:info.ns:event IS NULL THEN 
                RETURN FALSE; 
            ELSE 
                RETURN TRUE;
            END IF; 
        END;       
END MODULE;

过滤器代码 checkCoords 检查从 ESRI Web 服务返回的任何为 0.0 的 GPS 坐标并未发送给 Intelligent Operations Center 进行进一步的处理。

清单 5. 检查 GPS 坐标是否有效的 ESQL 代码
CREATE FILTER MODULE CoplinkTransform_checkCoords 
        CREATE FUNCTION Main() RETURNS BOOLEAN 
        BEGIN 
            IF Root.XMLNSC.ns:alert.ns:info.ns:area.ns:circle = '0.0,0.0 0' THEN 
            RETURN FALSE; 
            ELSE
                RETURN TRUE; 
            END IF; 
        END; 
END MODULE;

消息流的结果是一个已从传入的 COPLINK 分发消息转换的有效的 CAP 消息。最后一个阶段是将它们传入 Intelligent Operations Center 进行处理,这通过将它们放在 Intelligent Operations Center 用于处理 CAP 消息的一个消息队列上来完成。对于 图 3 中的消息流中的 MQOutput 节点,应该在将由 Intelligent Operations Center 处理的队列管理器 IOC.MB.QM 上、在队列 IOC.CAP.IN 中进行配置。图 9 显示了通过消息流放入并已由 Intelligent Operations Center 成功处理和显示的一些 IBM i2 COPLINK 分发样例。

图 9. Intelligent Operations Center 显示的样例 COPLINK 分发
显示的样例 COPLINK 分发

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Industries
ArticleID=877282
ArticleTitle=集成 i2 COPLINK 与 Intelligence Operations Center
publish-date=04232013