上一篇文章介绍了利用《java访问华为网管软件iMaster NCE的北向接口》的一般性步骤,这里详细介绍其中一个读取性能数据的示例。原因是读取华为网管软件北向接口,完全找不到可供参考的例子。如果不需要传递什么参数,就能获取到结果,比如获取全部网元数据,这种相对还比较简单。但如果需要指定参数,比如读取指定网元的性能数据,如何传递参数就是个大问题。我上周尝试去读取NCE软件的性能接口时,反复向NCE软件请求,结果总是返回冷冰冰的报错信息:"Object type error",说是传递参数不对,后来才知道,要将网元信息完整的传过去才可以。关于NCE软件北向接口的数据类型,真是异常复杂。阅读官方文档,一种类型,实质包含的是另一种类型,结果指来指去,让人晕头转向。
以下是一些代表性的例子。
一、无须特别指定参数
以下是一个获取全部网元信息的例子。
1、官方文档
2、代码实例
以下代码可见,request的设置相对简单。
代码中的WebServiceUtil是一个自定义的访问工具,专用于连接NCE北向接口和发起请求,具体代码可见上一篇文章《java访问华为网管软件iMaster NCE的北向接口》。
java
/**
* 查询指定管理域的所有网元信息
*/
public List<ManagedElementType> getAllManagedElements() {
List<ManagedElementType> list = null;
ManagedElementRetrieval_RPC ws = WebServiceUtil.getWebService("ManagedElementRetrieval", ManagedElementRetrieval_RPC.class);
//设置request
GetAllManagedElementsRequest request = new GetAllManagedElementsRequest();
NamingAttributeType mdOrMlsnRef = new NamingAttributeType();
RelativeDistinguishNameType rd = new RelativeDistinguishNameType();
rd.setType("MD");
rd.setValue(WebServiceUtil.getStrMD());
mdOrMlsnRef.getRdn().add(rd);
request.setMdOrMlsnRef(mdOrMlsnRef);
try {
MultipleMeObjectsResponseType response = ws.getAllManagedElements(WebServiceUtil.getHeader(), request);
list = response.getMeList().getMe();
//可查看ManagedElementType结构,在《北向 XML 开发指南(存量)》里
meList = list;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
二、需要特别指定参数
以下是一个获取全部网元的性能数据例子。
1、官方文档
2、代码实例
思想:首先获取全体 网元,然后分别查找这些网元的性能数据。将网元作为参数传递。
java
/**
* 查询所有网元的当前性能数据
*
* String[] parameters:待查询的性能类型
*/
public List<Map<String, Object>> getAllCurrentPerformanceMonitoringData(String[] parameters) {
List<Map<String, Object>> data = new ArrayList<>();
List<ManagedElementType> lis = this.getAllManagedElements();//读取全部网元
if (lis != null) {
for (ManagedElementType el : lis) {
getAllCurrentPerformanceMonitoringData(el, data,parameters);
}
}
return data.stream()//按名称排序
.sorted(Comparator.comparing(m -> Optional.ofNullable(m.get("tpName"))
.map(Object::toString)
.orElse("")))
.collect(Collectors.toList());
}
/**
* 查询指定网元的性能数据
*
* ManagedElementType el,网元
* List<Map<String, Object>> data,接收返回数据的数组
* String[] parameters,待查询的性能类型
*/
private void getAllCurrentPerformanceMonitoringData(ManagedElementType el,
List<Map<String, Object>> data,
String[] parameters) {
PerformanceManagementRetrieval ws = WebServiceUtil.getWebService("PerformanceManagementRetrieval", PerformanceManagementRetrieval.class);
GetAllCurrentPerformanceMonitoringDataRequest request = getPerformanceRequest(el,parameters);
/**
* tpName NamingAttributeType 对象名称 -
* layerRate LayerRateType 对象的层速率 -
* granularity String 监视周期 15min|24h|NA|30s|30min -
* pmMeasurementList PerformanceMonitoringMeasurementListType 测量数据列表 -
* pmParameterName String 性能记录的参数名称 -
* pmLocation PerformanceMonitoringLocationType 性能记录的发生位置 -
* value Float 性能值 -
* measurementUnits String 性能记录的单位 -
* pmIntervalStatus PerformanceMonitoringIntervalStatusType 区段状态
* PMIS_Valid 历史性能|PMIS_Incomplete 当前性能
* retrievalTime XMLGregorianCalendar 网管系统从网元上获取性能数据的时间
*/
try {
MultiplePerformanceMonitoringDataObjectsResponseType response = ws.getAllCurrentPerformanceMonitoringData(WebServiceUtil.getHeader(), request);
List<PerformanceMonitoringDataType> list = response.getPmDataList().getPmData();
for (PerformanceMonitoringDataType item : list) {
Map<String, Object> row = new HashMap<>();
row.put("tpName", getNameAttributeTypeValue(item.getTpName().getValue().getRdn()));//对象名称
row.put("layerRate", item.getLayerRate().getValue().getValue());//层速率
row.put("granularity", item.getGranularity().getValue());//监视周期: 15min|24h|NA|30s|30min
row.put("retrievalTime", item.getRetrievalTime().toGregorianCalendar().getTime());//网管系统从网元上获取性能数据的时间
//测量数据列表
List<PerformanceMonitoringMeasurementType> lisPmm = item.getPmMeasurementList().getValue().getPmMeasurement();
List<Map<String, Object>> dataPmm = new ArrayList<>();
for (PerformanceMonitoringMeasurementType pmm : lisPmm) {
Map<String, Object> row2 = new HashMap<>();
row2.put("pmParameterName", pmm.getPmParameterName().getValue());//性能记录的参数名称
row2.put("pmLocation", pmm.getPmLocation().getValue().value());//性能记录的发生位置
row2.put("value", pmm.getValue().getValue());//float
row2.put("measurementUnits", pmm.getMeasurementUnits().getValue());//性能记录单位
row2.put("pmIntervalStatus", pmm.getPmIntervalStatus().getValue().value());//区段状态:PMIS_Valid 历史性能|PMIS_Incomplete 当前性能
dataPmm.add(row2);
}
row.put("pmms", dataPmm);
data.add(row);
}
} catch (GetAllCurrentPerformanceMonitoringDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//构造request
private GetAllCurrentPerformanceMonitoringDataRequest getPerformanceRequest(ManagedElementType el,String[] parameters) {
GetAllCurrentPerformanceMonitoringDataRequest request = null;
List<RelativeDistinguishNameType> rdn = el.getName().getRdn();
if (rdn != null && rdn.size() > 0) {
request = new GetAllCurrentPerformanceMonitoringDataRequest();
/**
* GetAllCurrentPerformanceMonitoringDataRequest:
*
* pmObjectSelectList
* 类型:PerformanceMonitoringObjectSelectListType
* 按该监视条件对查询结果进行过滤
*
* PerformanceMonitoringObjectSelectListType:
* pmObjectSelect List<PerformanceMonitoringObjectSelectType> 监视条件列表
*
* PerformanceMonitoringObjectSelectType:
* name 非空 NamingAttributeType
* layerRateList
* pmLocationList
* granularityList
*
* pmParameterList
* 类型:PerformanceMonitoringParameterNameListType
* 只查询列表中存在的参数类型的性能(为空代表查所有参数类型的性能)
* pmParameterName List<String>
*
*/
NamingAttributeType namingAttribute = new NamingAttributeType();
for (RelativeDistinguishNameType rd : rdn) {
namingAttribute.getRdn().add(rd);
}
ObjectFactory objFac = new ObjectFactory();
JAXBElement<NamingAttributeType> nameElement = objFac.createPerformanceMonitoringObjectSelectTypeName(namingAttribute);
PerformanceMonitoringObjectSelectType pmos = new PerformanceMonitoringObjectSelectType();
pmos.setName(nameElement);
// pmos.setLayerRateList(null);
// pmos.setGranularityList(null);
// pmos.setPmLocationList(null);
PerformanceMonitoringObjectSelectListType selectList = new PerformanceMonitoringObjectSelectListType();
selectList.getPmObjectSelect().add(pmos);
request.setPmObjectSelectList(selectList);
//查询哪些性能?
PerformanceMonitoringParameterNameListType pmParameterList = getPmParameterList(parameters);
request.setPmParameterList(pmParameterList);
}
return request;
}
//指定待查找的性能类型
private PerformanceMonitoringParameterNameListType getPmParameterList(String[] parameters) {
if(parameters == null) return null;
PerformanceMonitoringParameterNameListType pmParameterList =
new PerformanceMonitoringParameterNameListType();
// String[] myParameters = parameters != null ? parameters : new String[] {
// "丢包事件",
// "收到的错误超长包",
// "收到的坏包字节",
// "发送的坏包字节",
// "发送丢包事件",
// "发送的超长包",
// "FCS错误帧(MAC_FCS)",
// "接收方向端口带宽利用率平均值",
// "发送方向端口带宽利用率平均值",
// "单板温度最大值",
// "单板温度最小值",
// "单板温度当前值",
// "OSC通道不可用秒",
// "风扇转速最大值",
// "风扇转速最小值",
// "风扇转速当前值"
// };
// 将数组中的每个元素添加到 pmParameterList 中
for (String parameter : parameters) {
pmParameterList.getPmParameterName().add(parameter);
}
return pmParameterList;
}
3、调用实例
调用刚才写的方法 getAllCurrentPerformanceMonitoringData()
java
public String getPerformanceInfo() {
JSONArray jsonArray = new JSONArray();
List<Map<String, Object>> lis = getAllCurrentPerformanceMonitoringData(new String[]{
"丢包事件",
"发送丢包事件",
"接收方向端口带宽利用率平均值",
"发送方向端口带宽利用率平均值",
"收到的字节",
"发送的字节"
});
}
4、关于性能类型
由上可知,性能类型都是一些字符串,比如:
java
new String[]{
"丢包事件",
"发送丢包事件",
"接收方向端口带宽利用率平均值",
"发送方向端口带宽利用率平均值",
"收到的字节",
"发送的字节"
}
它们从哪里获取?很遗憾,官方文档没有给出,至少我是没有看到。我用了一个笨办法,写了一个方法,通过访问NCE获取,然后将它们一一列举。
思想:调用上面写的方法 getAllCurrentPerformanceMonitoringData(),但不指定待查询的性能类型,于是系统会查询所有的性能类型,获取后将性能类型去重、输出:
java
public String getPerformanceParams() {//性能参数
List<String> params = new ArrayList<>();
List<Map<String, Object>> lis = nceApiService.getAllCurrentPerformanceMonitoringData(null);
if (lis != null && lis.size() > 0) {
JSONObject jParam = new JSONObject();
for (Map<String, Object> map : lis) {
List<Map<String, Object>> pmms = (List<Map<String, Object>>) map.get("pmms");
for (Map<String, Object> pmm : pmms) {
String name = pmm.get("pmParameterName").toString();
if (!params.contains(name)) { // 检查是否已存在
params.add(name); // 仅当不存在时才添加
}
}
}
}
// 用 <br> 分隔每个参数,这样浏览器中会显示为每行一个
return String.join("<br>", params);
}
结果得到了清单如下:
java
收到的包(64字节)
收到的包(65~127字节)
收到的包(128~255字节)
收到的包(256~511字节)
收到的包(512~1023字节)
收到的包(1024~1518字节)
发送的包(64字节)
发送的包(65~127字节)
发送的包(128~255字节)
发送的包(256~511字节)
发送的包(512~1023字节)
发送的包(1024~1518字节)
收到的单播包
收到的组播包
收到的广播包
发送的单播包
发送的组播包
发送的广播包
收到的"PAUSE"帧
发送的"PAUSE"帧
丢包事件
收到的超短包
收到的超长包
收到的碎片
收到的错误超长包
收到的好包字节
发送的好包字节
收到的坏包字节
发送的坏包字节
收到的包(1519~MTU字节)
发送的包(1519~MTU字节)
发送丢包事件
发送的超长包
FCS错误帧(MAC_FCS)
收到的字节
收到的包
发送的字节
发送的包
接收方向端口带宽利用率
接收方向端口带宽利用率最小值
接收方向端口带宽利用率最大值
接收方向端口带宽利用率平均值
发送方向端口带宽利用率
发送方向端口带宽利用率最小值
发送方向端口带宽利用率最大值
发送方向端口带宽利用率平均值
激光器偏置电流最大值
激光器偏置电流最小值
激光器偏置电流当前值
激光器输入光功率最大值
激光器输入光功率最小值
激光器输入光功率当前值
激光器输出光功率最大值
激光器输出光功率最小值
激光器输出光功率当前值
激光器工作温度最大值
激光器工作温度最小值
激光器工作温度当前值
单板温度最大值
单板温度最小值
单板温度当前值
ODU0的PM段不可用秒
ODU0的PM段远端不可用秒
OTU2的SM段不可用秒
OTU2的SM段远端不可用秒
OTU2的SM段后向进入定位错误秒
OTU2的SM段进入定位错误秒
ODU2的PM段不可用秒
ODU2的PM段远端不可用秒
总输入光功率最大值
总输入光功率最小值
总输入光功率当前值
激光器工作电流最大值
激光器工作电流最小值
激光器工作电流当前值
激光器背光电流最大值
激光器背光电流最小值
激光器背光电流当前值
掺铒光纤放大器激光器制冷电流最大值
掺铒光纤放大器激光器制冷电流最小值
掺铒光纤放大器激光器制冷电流当前值
激光器温度最大值
激光器温度最小值
激光器温度当前值
总输出光功率最大值
总输出光功率最小值
总输出光功率当前值
信道光功率最大值
信道光功率最小值
信道光功率当前值
OSC通道不可用秒
风扇转速最大值
风扇转速最小值
风扇转速当前值
风扇转速波动值
单板物理内存最大值
单板物理内存最小值
单板物理内存当前值
单板当前温度
ODU0的PM段远端背景误码块
ODU0的PM段远端误码秒