¿Cómo eliminar un item de una producción por código?

Hola a todos,

Estoy intentado eliminar un item de una producción a través de una rutina que instala y deshabilita items.

Para añadir no tengo problemas, incluso para habilitar y deshabilitar algunos items en particular.

El problema me surge cuando intento eliminar el item de la producción, porque cuando lo hace, la producción se queda inestable y solo vuelve a funcionar cuando se añade nuevamente este item en la colección (o se elimina de forma manual el item en el fichero produccion.cls

 

Este es mi intento de código:

set produccionName="MyApp.production"

set itemDelete = "MyApp.BP.item"

if ##class(Ens.Config.Item).NameExists(produccionName,itemDelete, .idItem)
{
    write !,"Removing BP: "_itemDelete
    set objItem=##class(Ens.Config.Item).%OpenId(idItem)
    do objItem.%Delete()
    kill objItem

   do ##class(Ens.Director).RestartProduction(0,1)
}

En el mejor de los casos, no hace nada y el item se mantiene. He probado también usando directamente el método %DeleteId() y algunas funciones de la clase Ens.Config.Production como RemoveItem

¿Alguna idea?

 

Un gran saludo,

Francisco López

 

 

  • 0
  • 0
  • 26
  • 4
  • 1

Respuestas

Hay que retocar multiples clases para manipular una producción:

Hay que cargar la definición del XML, manipular esta definición y volver a grabar los cambios al XML.

Aquí un ejemplo:

ClassMethod Remove(pProdName, pItemName) As %Status
{
  #DIM tSC as %Status=$$$OK
  #DIM errObj as %Exception.AbstractException
  try {
  //Copy Production XData Content to the Ens.Config.Production and Save
  $$$THROWONERROR(tSC,##class(Ens.Config.Production).LoadFromClass(pProdName))

  set tProdConfig=##class(Ens.Config.Production).%OpenId(pProdName)
  if (tProdConfig="") {
    $$$ThrowStatus($$$ERROR($$$GeneralError,"No se ha encontrado la Configuración de producción "_pProdName))
  }
  for tIx=tProdConfig.Items.Count():-1:1 {  //Reverse Scan to Avoid skipping Item after remove
    set tItem=tProdConfig.Items.GetAt(tIx)
    if (tItem.Name=pItemName) {
      //---Remove Item from Production Configuration
      Do tProdConfig.Items.RemoveAt(tIx) 
      Do ##class(Ens.Config.Item).%DeleteId(tItem.%Id())
    }
  }
  // update production class
  $$$THROWONERROR(tSC,tProdConfig.SaveToClass())
  //Recompile Class
  do $SYSTEM.OBJ.Compile(pProdName,"f")
  //Update or Restart Production
  do ##class(Ens.Director).UpdateProduction()
  }catch(errObj) {
    set tSC=errObj.AsStatus()
  }
  quit tSC
}

 

Lo utilizo en una herramienta adhoc de gestión de despliegues de Integración; permite borrar / añadir nuevos componentes a una producción en funcionamiento, y configurarlos con sus parametros que pueden ser distintos en los entornos test / prod.

Aqui otra solución mucho más sencilla

/// Elimina un item de la producción
ClassMethod ProductionItemRemove(pProdName, pItemName) As %Status
{
    write !,"Removing Item: "_pItemName

   if ##class(Ens.Config.Item).NameExists(pProdName, pItemName,.itemId)

    {
        set objItem=##class(Ens.Config.Item).%OpenId(itemId)
        set prod=##class(Ens.Config.Production).%OpenId(pProdName)
        do prod.RemoveItem(objItem)
        do prod.%Save()
        
        kill objItem
    
        do ##class(Ens.Director).RestartProduction(0,1)
    }
    
    quit $$$OK
}

Un saludo,

Francisco López