Obtendo a lista de alarmes do OSS via interface AlarmIRP

Olá. Este tópico é muito pouco divulgado na Web porque é de interesse apenas em círculos estreitos. Para preencher um pouco essa lacuna, este lugar me parece o mais adequado.

A interface CORBA AlarmIRP está presente em todos os sistemas de controle dos fabricantes de equipamentos com os quais eu tive que lidar, porque é prescrita pelo padrão 3GPP 3G TS 32.106-2. Considere o OSS-RC Ericsson como um exemplo, em cuja documentação o processo é pelo menos de alguma forma descrito. Para o NetAct Nokia e Huawei M-2000, o código será aproximadamente o mesmo, com diferenças nas nuances da implementação de um padrão. Tentarei descrever o mais claramente possível o processo de criação de um aplicativo para a leitura da lista de mensagens de alarme, mas como nunca escrevi nada em Java antes e não trabalhei com o CORBA, permitirei que eu deixe alguns detalhes fora do escopo deste artigo.

O aplicativo inteiro pode ser dividido em 3 partes:

  1. obtendo interface IOR
  2. criando um objeto referenciando uma interface
  3. chamando métodos de interface

Portanto, de acordo com a documentação, o IOR é armazenado em dois locais: no arquivo
/var/opt/ericsson/blkcm/data/bulkcm.nameservice
e no servidor web
http: // "masterhost ip": 80 / ior / ExternalNameService.ior
Vamos usar o primeiro método:

private String readIOR() { String mastersvc = "/var/opt/ericsson/blkcm/data/bulkcm.nameservice"; File f = new File(mastersvc); BufferedReader br; String iorContents = null; try { br = new BufferedReader(new FileReader(f)); iorContents = br.readLine(); br.close(); } catch (IOException e) { e.printStackTrace(); } return iorContents; } 

Para ser mais preciso, o método acima nos retornará não um IOR, mas um link para um NameService (terminologia CORBA), que poderíamos obter de um arquivo IOR em um servidor web. Se for mais simples: usaremos o resultado para inicializar a conexão.

O segundo estágio é a inicialização do objeto de conexão ORB:

 public void createAlarmObj(){ org.omg.CORBA.Object rootObj = null; NamingContextExt rootNameCon = null; Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitRef", "NameService=" + readIOR()); org.omg.CORBA.ORB orb = ORB.init(new String[0], props); // Resolve the CORBA Naming Service try { rootObj = orb.resolve_initial_references("NameService"); rootNameCon = NamingContextExtHelper.narrow(rootObj); String s = "com/ericsson/nms/fm_cirpagent/AlarmIRP"; //Locate Alarm IRP rootObj = rootNameCon.resolve(rootNameCon.to_name(s)); _alarmIrp = com.ericsson.irp.AlarmIRPSystem._AlarmIRPOperationsHelper.narrow(rootObj); } catch (InvalidName | NotFound | CannotProceed | org.omg.CosNaming.NamingContextPackage.InvalidName e) { e.printStackTrace(); } } 

Agora temos um link para um objeto que podemos acessar chamando seus métodos. Em particular, o método get_alarm_list retorna a lista que precisamos. Aqui está sua escritura do 3GPP:
Este método retorna informações de alarme. Se a bandeira é
TRUE, todas as informações de alarme retornadas devem estar em AlarmInformationSeq
que contém 0,1 ou mais informações de alarme. Iter do parâmetro de saída
será inútil. Se o sinalizador for FALSE, nenhuma informação de alarme será
em AlarmInformationSeq. O IRPAgent precisa usar o iter para recuperá-los.

 public void getActiveAlarms(){ BooleanHolder flag = new BooleanHolder(false); // false for iteration com.ericsson.irp.AlarmIRPSystem.AlarmInformationIteratorHolder iter = new com.ericsson.irp.AlarmIRPSystem.AlarmInformationIteratorHolder(); try { _alarmIrp.get_alarm_list(alarmFilter, flag, iter); EventBatchHolder alarmInformation = new EventBatchHolder(); short alarmSize = 100; List<StructuredEvent> alarms = new ArrayList<StructuredEvent>(); boolean haveMoreAlarms = false; do{ if (iter.value != null) { haveMoreAlarms = iter.value.next_alarmInformations(alarmSize, alarmInformation); alarms.addAll(Arrays.asList(alarmInformation.value)); } }while (haveMoreAlarms); for (StructuredEvent alarm: alarms) { alarmPrint(alarm); } } } catch (GetAlarmList | ParameterNotSupported | InvalidParameter | NextAlarmInformations e) { e.printStackTrace(); } } 

Esse método recebe um iterador contendo uma lista de alarmes na forma de objetos do tipo StructuredEvent que, em seguida, exibe alarmPrint (alarm) no console. A entrada StructuredEvent contém o cabeçalho e, de fato, os dados filterable_data . Os dados também são um registro com o nome nome e valor . A descrição dos campos também está no padrão:
const string NV_NOTIFICATION_ID = "a";
const string NV_CORRELATED_NOTIFICATIONS = "b";
const string NV_EVENT_TIME = "c";
const string NV_SYSTEM_DN = "d";
const string NV_MANAGED_OBJECT_CLASS = "e";
const string NV_MANAGED_OBJECT_INSTANCE = "f";
const string NV_SPECIFIC_PROBLEM = "i";
...

Agora vamos coletar tudo isso juntos e derivar, por exemplo, instance e specific_problem :

 private void alarmPrint(StructuredEvent alarm){ String result = "" if (alarm.filterable_data != null) { for (Property filterableData: alarm.filterable_data) { String fieldName = filterableData.name; switch (fieldName){ case "f": result = result + filterableData.value.extract_string() + ";"; break; case "i": result = result + filterableData.value.extract_string(); break; } } } System.out.println(result); } 

Por fim, o código completo para o rascunho resultante:

Código completo
 import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import org.omg.CORBA.*; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.CosNaming.NamingContextExt; import org.omg.CosNaming.NamingContextExtHelper; import org.omg.CosNaming.NamingContextPackage.CannotProceed; import org.omg.CosNaming.NamingContextPackage.NotFound; import org.omg.CosNotification.EventBatchHolder; import org.omg.CosNotification.Property; import org.omg.CosNotification.StructuredEvent; import com.ericsson.irp.AlarmIRPSystem.GetAlarmList; import com.ericsson.irp.AlarmIRPSystem.InvalidParameter; import com.ericsson.irp.AlarmIRPSystem.NextAlarmInformations; import com.ericsson.irp.AlarmIRPSystem.ParameterNotSupported; public class AlarmClient { private com.ericsson.irp.AlarmIRPSystem._AlarmIRPOperations _alarmIrp = null; public static void main(String[] args) { AlarmClient ac = new AlarmClient(); ac.createAlarmObj(); ac.getActiveAlarms(); } private String readIOR() { File f = new File("/var/opt/ericsson/blkcm/data/bulkcm.nameservice"); BufferedReader br; String iorContents = null; try { br = new BufferedReader(new FileReader(f)); iorContents = br.readLine(); br.close(); } catch (IOException e) { e.printStackTrace(); } return iorContents; } public void createAlarmObj(){ org.omg.CORBA.Object rootObj = null; NamingContextExt rootNameCon = null; Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitRef", "NameService=" + readIOR()); org.omg.CORBA.ORB orb = ORB.init(new String[0], props); // Resolve the CORBA Naming Service try { rootObj = orb.resolve_initial_references("NameService"); rootNameCon = NamingContextExtHelper.narrow(rootObj); String s = "com/ericsson/nms/fm_cirpagent/AlarmIRP"; //Locate Alarm IRP rootObj = rootNameCon.resolve(rootNameCon.to_name(s)); _alarmIrp = com.ericsson.irp.AlarmIRPSystem._AlarmIRPOperationsHelper.narrow(rootObj); //System.out.println(_alarmIrp); } catch (InvalidName | NotFound | CannotProceed | org.omg.CosNaming.NamingContextPackage.InvalidName e) { e.printStackTrace(); } } public void getActiveAlarms(){ BooleanHolder flag = new BooleanHolder(false); // false for iteration com.ericsson.irp.AlarmIRPSystem.AlarmInformationIteratorHolder iter = new com.ericsson.irp.AlarmIRPSystem.AlarmInformationIteratorHolder(); try { _alarmIrp.get_alarm_list("", flag, iter); EventBatchHolder alarmInformation = new EventBatchHolder(); short alarmSize = 100; List<StructuredEvent> alarms = new ArrayList<StructuredEvent>(); boolean haveMoreAlarms = false; do{ if (iter.value != null) { haveMoreAlarms = iter.value.next_alarmInformations(alarmSize, alarmInformation); alarms.addAll(Arrays.asList(alarmInformation.value)); } }while (haveMoreAlarms); if (iter.value != null) { for (StructuredEvent alarm: alarms) { alarmPrint(alarm); } } } catch (GetAlarmList | ParameterNotSupported | InvalidParameter | NextAlarmInformations e) { e.printStackTrace(); } } private void alarmPrint(StructuredEvent alarm){ String result = ""; if (alarm.filterable_data != null) { for (Property filterableData: alarm.filterable_data) { String fieldName = filterableData.name; switch (fieldName){ case "f": result = result + filterableData.value.extract_string() + ";"; break; case "i": result = result + filterableData.value.extract_string(); break; } } } System.out.println(result); } } 


O lançamento é realizado pelo comando:
java -cp .: / opt / ericsson / fm_core / classes / alarmirp.jar AlarmClient

Qual é o resultado: além do "fã", ainda não estou usando outros aplicativos. No futuro, haverá o NotificationIRP - recebendo eventos imediatamente após sua aparência, BulkCmIRP - configuração de um sistema externo, etc. A tecnologia é semelhante, mas se necessário, você pode escrever um artigo separado. Talvez seja tudo sobre esse assunto. Eu posso responder perguntas nos comentários. Obrigada

Source: https://habr.com/ru/post/pt422293/


All Articles