• Inicio
  • Novedades
  • Academia SAP
  • FAQ
  • Blog
  • Contacto
S4PCADEMY_Logo
Twitter Linkedin Instagram
S4PCADEMY_Logo
Twitter Linkedin Instagram
FORMACIÓN SAP

SAP CPI: CI/CD de cero a héroe: inspección de código y control de calidad

By s4pcademy 


Este blog es parte de una serie de blogs, por lo que puede encontrar la primera página aquí (https://blogs.sap.com/2023/02/02/sap-cpi-ci-cd-from-from-zero-to-hero/). Esta es la agenda que estamos siguiendo:

  • Copia de seguridad de binarios y código fuente
  • Inspección de código y control de calidad (explicado en esta página)
  • Controles de gestión de transporte
  • Caducidad de certificados
  • Examen de la unidad
  • Documentación
  • Revisión de código
  • Transparencia de configuración

Uno de los aspectos clave de nuestras interfaces es la calidad y consistencia del código. Dado que tenemos muchas interfaces, debemos asegurarnos de que todas sigan nuestro marco de pautas de desarrollo. Después de investigar un poco, encontré CPI Lint, un github de código abierto para traer pelusa a CPI desde @mortenw

CPILint%20comprobando%20código%20cumplimiento%20con%20desarrollo%20directrices

CPILint verificando el cumplimiento del código con las pautas de desarrollo

Creo que el código es excelente, así que un agradecimiento especial a Morten por proporcionar esta herramienta. Más detalles sobre CPI Lint en su github https://github.com/mwittrock/cpilint y también en este blog de savia https://blogs.sap.com/2019/02/01/meet-cpilint/

A pesar de que Morten lanzó la versión 1.0.4, actualmente estamos usando la versión 1.0.3 y estoy en proceso de migrarla a la 1.0.4. En resumen, la herramienta actual es capaz de leer el código de un flujo de integración y compararlo con las reglas definidas en un archivo xml.

Desafortunadamente, nuestra empresa tiene pautas/reglas específicas que la herramienta «estándar» no cubre, por lo que bifurqué el repositorio de Morten para permitirle registrar reglas de extensión al proporcionar estas reglas adicionales en un proyecto separado. El código bifurcado (https://github.com/nunomcpereira/cpilint) ahora puede buscar archivos jar de extensión en el classpath que contiene reglas adicionales. También tuve que hacer públicos algunos de los métodos aquí y allá para que estuvieran disponibles para usar en estas reglas adicionales.
  • regla-de-nombres-no-permitidos-predeterminada: Dado que CPI no tiene un concepto de comentarios para cada componente, queremos asegurarnos de tener nombres significativos en los componentes que describan la lógica del flujo de flujo continuo, por lo que verificamos que para todos los posibles componentes de CPI no tengamos nombres predeterminados como «Modificador de contenido 1“, “Solicitud de respuesta 1” nombrar o “maravilloso1” para nombres de archivo. Escuché de Morten que esto ahora es compatible con su versión 1.0.4, así que lo seguiré (ejemplo a continuación).Predeterminado%20names%20dentro%20iflows
  • regla de parámetros no utilizados: ¿Cuántas veces has definido unos parámetros externos que al final no se utilizaron? CPI proporciona el “Eliminar parámetros no utilizados” que funcionaría de manera similar a esta regla. Esta regla solo afirma que se están utilizando todos sus parámetros definidos (ejemplo de la pantalla de parámetros externalizados a continuación).
  • encabezados-permitidos-vacíos: Tenemos iflows principales (alcanzados desde el exterior) e iflows internos que se comunican a través de procesos directos. En ambos escenarios, el “Encabezados permitidos«La configuración vacía podría ser un problema porque, de ser así, los encabezados se perderían entre las llamadas directas al proceso. En el caso de flujos principales, hay algunos encabezados que permitimos recibir, como SapAuthenticatedUserName, por ejemplo. En este momento, de acuerdo con nuestra configuración de reglas, solo estamos validando a propósito las comunicaciones a través del proceso directo, no haciendo que sea obligatorio recibir encabezados en el iflow principal, pero esto es configurable en la regla (ejemplo de encabezados vacíos permitidos a continuación).
  • encabezados de respuesta permitidos: Durante los desarrollos, nos enfrentamos a un problema en el que se llamó a un sistema de destino y se recuperó un encabezado no válido para CPI. No recuerdo los detalles pero si creo que fue porque el encabezado excedió el tamaño máximo que puede manejar el CPI. Con este error, aprendemos a no aceptar * por defecto en los encabezados de respuesta de nuestras llamadas http. Esta regla hace cumplir eso (ejemplo de uso del encabezado de respuesta en el adaptador http a continuación).
  • tipo de datos no declarado: Durante los desarrollos, nos dimos cuenta de que teníamos una propiedad definida en un modificador de contenido sin un tipo especificado y, para ese escenario en particular, esto resultó en un error de tiempo de ejecución ya que CPI asumió que la propiedad era de alguna manera un objeto complejo cuando queríamos que fuera una cadena normal. Por lo tanto, esta regla verifica todas sus propiedades y se asegura de que las que soliciten un tipo (que no es obligatorio en cpi), obliguen a completarlo cuando lo verifique a través de esta regla (ejemplo de una propiedad sin tipo de datos a continuación).

Todas estas reglas se pueden combinar con las regulares proporcionadas por el código base de cpilint.

Ejemplo de un archivo rules.xml válido que contiene tanto reglas estándar cpi lint como reglas personalizadas.

<?xml version="1.0"?>
<cpilint>
    <rules>
        <default-names-not-allowed-rule>
			<exclude>Exception Subprocess</exclude>
		</default-names-not-allowed-rule>
		<iflow-matches-name>
		  <naming-pattern>FER_(S2P|F2I|M2C|Common|InterfaceName|MessageMappingsUnitTest|)(.*)(Publish|Subscribe|MAIN)$</naming-pattern>
		</iflow-matches-name>
		<disallowed-scripting-languages>
            <disallow>javascript</disallow>
        </disallowed-scripting-languages>
		<cleartext-basic-auth-not-allowed/>
		<!-- <matching-process-direct-channels-required/> We can't use this since we have cross package references and cpilint runs on a package basis -->
		<disallowed-receiver-adapters>
			<disallow>facebook</disallow>
			<disallow>ftp</disallow>
			<disallow>twitter</disallow>
		</disallowed-receiver-adapters>
		<disallowed-sender-adapters>
			<disallow>ftp</disallow>
		</disallowed-sender-adapters>
		<unencrypted-data-store-write-not-allowed/>
		<unencrypted-endpoints-not-allowed/>
		<csrf-protection-required-with-exclude>
			<exclude>FER_DUMMYVALUE_MAIN</exclude>
			<exclude>FER_DUMMYVALUE_MAIN2</exclude>
		</csrf-protection-required-with-exclude>
		<iflow-description-required/>
		<unused-parameters-rule/>
		<allowed-headers-empty><include>(.*)(Publish|Subscribe)$</include></allowed-headers-empty>
		<response-headers-allowed><exclude>\*</exclude></response-headers-allowed>
		<undeclared-data-type/>
    </rules>
</cpilint>

Para ejecutarlo, puede ir al directorio jenkins donde se extrajeron y ejecutaron los archivos zip para los flujos de flujo:

def call(String packageId, String reponame, boolean changesDone){
	script {
		dir("./IntegrationContent"){
			def localPackage = packageId.startsWith('Test')
			if(!localPackage)
			{
				def files = findFiles glob: "**/*.zip"
				boolean exists = files.length > 0
				
				if(exists)
				{
					catchError(buildResult: 'UNSTABLE', stageResult: 'UNSTABLE') {                 
						bat 'cpilint -rules %CPILINT_HOME%rules.xml -directory ./' 
					}
				}
			}
		}
	}
}

En nuestro caso, este archivo se almacena dentro de la carpeta vars del repositorio git de Jenkins y se interpreta como una biblioteca compartida en Jenkins.

Biblioteca CPILint%20as%20a%20custom%20jenkins%20shared%20

CPILint como una biblioteca compartida personalizada de jenkins

Para registrar bibliotecas compartidas personalizadas en jenkins, debe ir a la página de inicio de jenkins->Administrar Jenkins->Configurar sistema

Shared%20library%20registration%20on%20Jenkins

Registro de biblioteca compartida en Jenkins

Si alguna de las reglas falla, finalizamos la canalización del paquete con una advertencia y notificamos al desarrollador responsable.

CPILint%20Jenkins%20fining%20as%20advertencia

CPILint Jenkins terminando como advertencia

Actualmente estoy en conversaciones con Morten (que actualmente está trabajando en CPILint 1.0.5), así que una vez que esté disponible, también planeo migrar estas reglas personalizadas a la nueva versión.

Además de estas comprobaciones, también estamos comprobando (fuera de esta herramienta):

  • Que se cree un enlace de documentación a nivel de paquete (con un nombre predeterminado) apuntando a nuestro sistema de gestión documental. Para ello nos basamos en el archivo resources.cnt que está disponible dentro del archivo zip del paquete una vez exportado. Allí puede encontrar referencias para la URL mantenida en el paquete.
    def packageInfo = readFile(file: 'resources.cnt')
    def slurper = new JsonSlurper().parseText(new String(packageInfo.decodeBase64()))
    def documentationUrl=""
    def hasCustomTags = false
    slurper.resources.each
    {
    	if(it.resourceType=="Url" && (it.name=="YOURPREDETERMINEDNAME" || it.displayName=="YOURPREDETERMINEDNAME"))
    	{
    		try{
    			documentationUrl = it.additionalAttributes.url.attributeValues[0]
    		}
    		catch(Exception e)
    		{
    			error("Error while reading documentation: ${e}")
    		}
    	}
    }​
  • Valide que las etiquetas estándar definidas en el nivel del paquete estén definidas (ejemplo a continuación para la etiqueta LineOfBusiness)
    if(it.resourceType=="ContentPackage")
    {
    	List<String> raiseErrorTags = [];
    	def customAttribute = it.additionalAttributes.LineOfBusiness;
    	if(customAttribute!=null)
    	{
    		def list = customAttribute.attributeValues;
    		def hasValues = false;
    		for(int i=0;i<list.size();i++)
    		{
    			if(list[i]!="")
    			{
    				hasValues=true
    			}
    		}
    		if(!hasValues)
    		{
    			raiseErrorTags.push("LineOfBusiness");
    		}
    	}
    	else
    	{
    		raiseErrorTags.push("LineOfBusiness");
    	}
    }​

  • Tenemos una etiqueta personalizada que es una referencia de JIRA que es obligatorio completar para que podamos asociar las historias de usuario de JIRA a los paquetes de CPI, por lo que verificamos que la etiqueta personalizada se complete con ella.

Próximos pasos

  • Usa sonarqube o codenarc para borrar la sintaxis maravillosa utilizada.
  • Migrar a CPILint 1.0.4 y luego a 1.0.5 una vez publicado

En este tema, presentamos la herramienta principal que usamos para verificar problemas de código (CPILint), así como verificaciones adicionales realizadas para asegurarnos de que la documentación y las etiquetas se mantuvieran correctamente.

Te invito a compartir algunos comentarios o pensamientos en las secciones de comentarios. Estoy seguro de que todavía hay mejoras o ideas para nuevas reglas que beneficiarían a toda la comunidad. Siempre puede obtener más información sobre la integración de la nube en el página de tema para el producto




Evaluación de descubrimiento digital de SAP | Blogs de SAP
Previo
SAP, una empresa impulsada por el ecosistema: historia de Int4 AG
Siguiente

Madrid

Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010

México

Paseo de la Reforma 26
Colonia Juárez,  Cuauhtémoc
Ciudad de México 06600

Costa Rica

Real Cariari
Autopista General Cañas, 
San José, SJ 40104

Perú

Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073

Twitter Linkedin Instagram
Copyright 2022 | All Right Reserved.