由于华为很多资料都是保密的,所以在实现过程中有很大麻烦,并且在生成C++中也总出现无法解决的问题。如何利用网上现存的有限资源成为大家一直以来的问题。这里推荐两篇文章:
http://blog.csdn.net/fw0124/article/details/7197609
http://blog.csdn.net/linlianghui2004/article/details/6077213
JAVA在Windows下界面不近如人意,所以笔者在这里提供利用C#(.NET)来实现华为北向接口,其基本思路就行将JAVA代码转为C#而已。
关于CORBA原理请见上一篇文档。
如何应用C#开发成为主要问题,详见代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using common;
using CosEventChannelAdmin;
using CosNaming;
using CosNotification;
using CosNotifyChannelAdmin;
using CosNotifyComm;
using emsMgr;
using emsSession;
using emsSession.EmsSession_IPackage;
using emsSessionFactory;
using equipment;
using globaldefs;
using managedElement;
using managedElementManager;
using nmsSession;
using notifications;
using org.omg.CORBA;
using org.omg.PortableServer;
using org.omg.PortableServer.POAManagerPackage;
using org.omg.PortableServer.POAPackage;
namespace Corba_Client
{
/************************************************************************/
/* 类构造开始 */
/************************************************************************/
public partial class CorbaMain : Form
{
/************************************************************************/
/* 变量声明 */
/************************************************************************/
static ORB orb;
static EMSMgr_I emsMgr = null;
static EmsSession_I emsSession = null;
static POA rootpoa = null;
static POA poa = null;
static CosNotifyChannelAdmin.EventChannel notifChannel = null;
static CosNotifyChannelAdmin.EventChannelHolder chanHolder = new CosNotifyChannelAdmin.EventChannelHolder();
static ManagedElementMgr_I managedElementMgr = null;
static DateTime start_time = new DateTime();
static DateTime end_time = new DateTime();
static IntHolder id = null;
static CosNotifyChannelAdmin.ConsumerAdmin cadmin = null;
static StructuredProxyPushSupplier structuredProxyPushSupplier = null;
/************************************************************************/
/* 构造函数 */
/************************************************************************/
public CorbaMain()
{
InitializeComponent();
}
/************************************************************************/
/* 窗口初始化 */
/************************************************************************/
private void CorbaMain_Load(object sender, EventArgs e)
{
testCorba();
}
/************************************************************************/
/* CORBA */
/************************************************************************/
public static void testCorba() {
// 建立连接登录、建立消息通道
try {
String[] args = new String[2];
args[0] = "-ORBInitRef";
args[1] = "NameService=corbaloc::10.60.8.148:12001/NameService";
// 生成一个ORB,并初始化
orb = org.omg.CORBA.ORB.init(args, null);
} catch (Exception ex) {
Console.WriteLine("初始化ORB对象异常!");
}
NamingContextExt namingContext = null;
org.omg.CORBA.Object objRef = null;
try {
// 获取 POA对象
objRef = orb.resolve_initial_references("RootPOA");
rootpoa = org.omg.PortableServer.POAHelper.narrow(objRef);
rootpoa.the_POAManager().activate();
// 获得根命名上下文
objRef = orb.resolve_initial_references("NameService");
namingContext = NamingContextExtHelper.narrow(objRef);
Console.WriteLine("获取取名字服务成功:" + namingContext);
} catch (org.omg.CORBA.ORBPackage.InvalidName ex) {
Console.WriteLine("获取名字服务索引异常!");
ex.printStackTrace();
} catch (AdapterInactive e) {
Console.WriteLine("不能激活 POAManager" + e);
e.printStackTrace();
}
NameComponent[] path = new NameComponent[5];
path[0] = new NameComponent("TMF_MTNM", "Class");
path[1] = new NameComponent("HUAWEI", "Vendor");
path[2] = new NameComponent("DAL-T2000-7-P", "EmsInstance");
path[3] = new NameComponent("2.0", "Version");
path[4] = new NameComponent("DAL-T2000-7-P", "EmsSessionFactory_I");
EmsSessionFactory_I emsSessionFactory_I = null;
org.omg.CORBA.Object obj = null;
try {
obj = namingContext.resolve(path);
Console.WriteLine("obj=>" + obj);
emsSessionFactory_I = EmsSessionFactory_IHelper.narrow(obj);
Console.WriteLine("emsSessionFactory_I=>" + emsSessionFactory_I);
} catch (Exception e) {
}
EmsSession_IHolder sessionHolder = new EmsSession_IHolder();
// Log In and Retrieve EmsSession
try {
NmsSession_IPOA pNmsSessionServant = new NmsSessionImpl();
NmsSession_I nmsSession = pNmsSessionServant._this(orb);
// 用户名,密码
if (emsSessionFactory_I != null) {
emsSessionFactory_I.getEmsSession("***", "****",nmsSession, sessionHolder);
Console.WriteLine("NMSsession ---" + nmsSession + "\nVersion:" + emsSessionFactory_I.getVersion());
emsSession = sessionHolder.value;
CosNotifyChannelAdmin.EventChannelHolder eventChannelHolder = new CosNotifyChannelAdmin.EventChannelHolder();
emsSession.getEventChannel(eventChannelHolder);
notifChannel = eventChannelHolder.value;
connect();
} else {
return;
}
} catch (globaldefs.ProcessingFailureException ex) {
Console.WriteLine("获取EmsSession引用对象,异常!---ProcessingFailureException---");
Console.WriteLine("可能是用户名或者密码错误,或者权限不够[Corba OSS用户],或者已登陆的用户还未退出!");
Console.WriteLine(ex.toString());
}
// 通过命名服务 --- 查询
Common_IHolder common_IHolder = new Common_IHolder();
try {
// Retrieve List of Managers ---------- 该emsSession 所能管理的所有对象
managerNames_THolder supportedManagerList = new managerNames_THolder();
emsSession.getSupportedManagers(supportedManagerList);
String[] managers = supportedManagerList.value;
for (int i = 0; i < managers.Length; i++) {
Console.WriteLine("Manager " + i + " " + managers[i]);
}
// 返回所有网元
emsSession.getManager("ManagedElement", common_IHolder);
managedElementMgr = ManagedElementMgr_IHelper
.narrow(common_IHolder.value);
ManagedElementList_THolder meList = new ManagedElementList_THolder();
ManagedElementIterator_IHolder meIt = new ManagedElementIterator_IHolder();
int how_many = 20; // 网元个数个数为20
managedElementMgr.getAllManagedElements(how_many, meList, meIt);
ManagedElement_T[] me = meList.value;
for (int i = 0; i < me.Length; i++) {
String nativeEMSName = me[i].nativeEMSName;
String procuctName = me[i].productName;
NameAndStringValue_T[] name = me[i].name;
Console.WriteLine(nativeEMSName + "," + procuctName + ","
+ name[0].name + " | " + name[0].value + ","
+ name[1].name + " | " + name[1].value);
}
// 查询网管系统中所有未结束的告警和未结束的TCA事件
try {
emsSession.getManager("EMS", common_IHolder);
emsMgr = EMSMgr_IHelper.narrow(common_IHolder.value);
} catch (globaldefs.ProcessingFailureException e) {
e.printStackTrace();
}
String[] excludeProbCauseList = new String[0];
PerceivedSeverity_T[] excludeSeverityList = new PerceivedSeverity_T[0];
EventList_THolder eventList = new EventList_THolder();
EventIterator_IHolder eventIt = new EventIterator_IHolder();
how_many = 10;
start_time = new DateTime();
emsMgr.getAllEMSAndMEActiveAlarms(excludeProbCauseList, excludeSeverityList, how_many, eventList, eventIt);
end_time = new DateTime();
long sec = (end_time.Second - start_time.Second) / 1000; // 花费的时间(单位:s)
Console.WriteLine(how_many + "个告警 ------ getAllEMSAndMEActiveAlarms ------ 消耗:"+ sec + " 秒");
StructuredEvent[] events = eventList.value;
for (int i = 0; i < events.Length; i++) {
Property[] propertyList = events[i].filterable_data;
Console.WriteLine("event:" + i);
// 1、通知事件的唯一ID编号
String notification = propertyList[0].value.extract_string();
Console.WriteLine("1、通知事件的唯一ID编号 " + propertyList[0].name
+ " --- " + notification);
// 2、上报事件的对象名称
NameAndStringValue_T[] nsv = globaldefs.NamingAttributes_THelper
.extract(propertyList[1].value);
Console.WriteLine("2、上报事件的对象名称 " + propertyList[1].name + " --- ");
for (int j = 0; j < nsv.Length; j++) {
Console.WriteLine(" " + nsv[j].name
+ ": " + nsv[j].value);
}
// 3、产生告警的对象的相关信息
String nativeEMSName = propertyList[2].value.extract_string();
Console.WriteLine("3、产生告警的对象的相关信息 " + propertyList[2].name
+ " --- " + nativeEMSName);
// 4、EMS 用户界面上描述的告警原因
String nativeProbableCause = propertyList[3].value
.extract_string();
Console.WriteLine("4、EMS 用户界面上描述的告警原因 " + propertyList[3].name
+ " --- " + nativeProbableCause);
// 5、上报该告警的对象的类型
ObjectType_T objectTypeT = notifications.ObjectType_THelper
.extract(propertyList[4].value);
String obtString = objectTypeT.toString();
int obt = objectTypeT.value();
Console.WriteLine("5、上报该告警的对象的类型 " + propertyList[4].name
+ " --- " + obtString + " " + obt);
// 6、EMS 上报事件的时间值(为UTC 时间),比neTime晚2 秒
String emsTimeString = Time_THelper
.extract(propertyList[5].value);
Console.WriteLine("6、EMS 上报事件的时间值(为UTC 时间),比neTime晚2 秒 "
+ propertyList[5].name + " --- " + emsTimeString);
// 7、网元上报事件的时间值(为UTC 时间),如果网元没有上报该时间值,则为空
String neTimeString = Time_THelper
.extract(propertyList[6].value);
Console.WriteLine("7、网元上报事件的时间值(为UTC 时间),如果网元没有上报该时间值,则为空 "
+ propertyList[6].name + " --- " + neTimeString);
// 8、标识是否可以被清除
bool bClearable = propertyList[7].value.extract_boolean();
Console.WriteLine("8、标识是否可以被清除 " + propertyList[7].name + " --- "
+ bClearable);
// 9、标识告警产生对象的层速率
short sRate = transmissionParameters.LayerRate_THelper
.extract(propertyList[8].value);
Console.WriteLine("9、标识告警产生对象的层速率 " + propertyList[8].name
+ " --- " + sRate);
// 10、TMF 定义的告警可能原因
String probableCause = propertyList[9].value.extract_string();
Console.WriteLine("10、TMF 定义的告警可能原因 " + propertyList[9].name
+ " --- " + probableCause);
// 11、与EqType 和AeID(设备类型和告警事件ID)字段一起来唯一标识一条告警事件类型
String probableCauseQualifier = propertyList[10].value
.extract_string();
Console.WriteLine("11、与EqType 和AeID(设备类型和告警事件ID)字段一起来唯一标识一条告警事件类型 "
+ propertyList[10].name
+ " --- "
+ probableCauseQualifier);
// 12、告警级别(包括PS_CRITICAL、PS_MAJOR、PS_MINOR、PS_WARNING
// 四个),对于清除告警, 其告警级别为PS_CLEARED
PerceivedSeverity_T cNT = notifications.PerceivedSeverity_THelper
.extract(propertyList[11].value);
String perceivedSeverity = cNT.toString();
Console.WriteLine("12、告警级别(包括PS_CRITICAL、PS_MAJOR、PS_MINOR、PS_WARNING 四个) "
+ propertyList[11].name + " --- " + perceivedSeverity);
// 13、标识该告警是否对业务造成影响(SA_UNKNOWN / SA_SERVICE_AFFECTING /
// SA_NON_SERVICE_AFFECTING)
ServiceAffecting_T eNT = notifications.ServiceAffecting_THelper
.extract(propertyList[12].value);
String serviceAffecting = eNT.toString();
Console.WriteLine("13、标识该告警是否对业务造成影响 " + propertyList[12].name
+ " --- " + serviceAffecting);
// 14、受影响的终结点列表
NameAndStringValue_T[] NASV = globaldefs.NamingAttributes_THelper
.extract(propertyList[13].value);
Console.WriteLine("14、受影响的终结点列表 " + propertyList[13].name
+ " --- ");
for (int j = 0; j < NASV.Length; j++)
{
Console.WriteLine(" " + NASV[j].name + ": " + NASV[j].value);
}
// 15、 产生该告警的对象的详细信息
String additionalText = propertyList[14].value.extract_string();
Console.WriteLine("15、 产生该告警的对象的详细信息 " + propertyList[14].name
+ " --- " + additionalText);
// 16、包含告警序列号(AlarmSerialNo:此字段可唯一标识一条告警)、告警简要原因(AlarmReason)、设备类型(ProductName)、单板名称(EquipmentName)、告警
// 确认状态(AffirmState)、告警参数信息(DetailInfo)六个附加字段、从子架名称(SlaveShelf)
NameAndStringValue_T[] ADI = globaldefs.NamingAttributes_THelper
.extract(propertyList[15].value);
Console.WriteLine("16、包含告警序列号、告警简要原因、设备类型、单板名称、告警确认状态、告警参数信息 "
+ propertyList[15].name + " --- ");
for (int j = 0; j < ADI.Length; j++)
{
Console.WriteLine(" " + ADI[j].name + ": " + ADI[j].value);
}
// 17、根据ITU-T X.733 将告警分为6
// 个基本类型:“communicationsAlarm"、"qualityofServiceAlarm"、"equipmentAlarm"、"processingErrorAlarm"、"securityAlarm"、"environmentalAlarm"
String X733EventType = propertyList[16].value.extract_string();
Console.WriteLine("17、根据ITU-T X.733 将告警分为6 个基本类型 "
+ propertyList[16].name + " --- " + X733EventType);
// 18、上报告警事件的对象的类型,该字段只指针对TMF3.0版本中新增的对象类型
String objectTypeQualifier = propertyList[17].value
.extract_string();
Console.WriteLine("18、上报告警事件的对象的类型 " + propertyList[17].name
+ " --- " + objectTypeQualifier);
for (int j = 0; j < propertyList.Length; j++)
{
Console.WriteLine(" " + propertyList[j].name + ", "
+ propertyList[j].value);
}
}
} catch (ProcessingFailureException e) {
Console.WriteLine("Processing Exception" + e.getMessage());
e.printStackTrace();
Console.WriteLine(e.errorReason);
} finally {
emsSession.endSession();
}
}
/************************************************************************/
/* 连接 */
/************************************************************************/
public static void connect()
{
/* Defines the type of proxy required */
ClientType ctype = ClientType.STRUCTURED_EVENT;
/* Holder to hold the proxy id */
id = new org.omg.CORBA.IntHolder();
/* Proxy supplier variable */
ProxySupplier proxySupplier = null;
/* Obtain the consumer admin object reference */
cadmin = notifChannel.default_consumer_admin();
// subscibe event
try
{
_EventType[] added = new _EventType[1];
_EventType[] removed = new _EventType[0];
added[0] = new _EventType("tmf_mtnm", "NT_ALARM"); // 参考TMF814
cadmin.subscription_change(added, removed);
}
catch (InvalidEventType e1)
{
e1.printStackTrace();
}
catch (System.NullReferenceException e)
{
}
try
{
/* obtain a structured push supplier object reference. */
proxySupplier = ((CosNotifyChannelAdmin.ConsumerAdminOperations)cadmin).obtain_notification_push_supplier(ctype, id);
}
catch (AdminLimitExceeded ex)
{
/*
* Thrown if the admin object is unable to have any more proxy suppliers associated with it.
*/
}
/* Narrow the proxy supplier to a Structured Proxy Push Supplier */
structuredProxyPushSupplier = StructuredProxyPushSupplierHelper.narrow(proxySupplier);
try
{
/* connect the consumer to the proxy */
structuredProxyPushSupplier.connect_structured_push_consumer(getObject());
orb.run();
}
catch (AlreadyConnected e)
{
/*
* This exception is thrown if a consumer is already connected to this proxy. This should not be thrown because the proxy has just been created.
*/
MessageBox.Show("Already connected!");
}
catch (TypeError e)
{
/*
* This exception is thrown if you attempt to connect a sequenced consumer to a structured proxy or vice versa.
*/
MessageBox.Show("Type error!");
}
}
/************************************************************************/
/* 获取对象 */
/************************************************************************/
private static StructuredPushConsumer getObject() {
StructuredPushConsumer serverObj = null;
org.omg.PortableServer.Servant servant = new StructuredPushConsumerPOAImpl();
org.omg.CORBA.Object refo=null;
try {
refo = rootpoa.servant_to_reference(servant);
serverObj = StructuredPushConsumerHelper.narrow(refo);
} catch (ServantNotActive e) {
MessageBox.Show("Unexpected Exception: " + e);
} catch (WrongPolicy e) {
MessageBox.Show("Unexpected Exception: " + e);
}
return serverObj;
}
}
}
上面的代码包含常见的两种采集方式:推送和查询。代码中都有详细的说明。