From 770c3208931e3dff82eb7ae705c88837dd3ead01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Rodr=C3=ADguez=20Robotham?= Date: Sat, 1 Feb 2020 13:10:37 -0300 Subject: [PATCH 1/4] #89 version 2.3.1 --- pom.xml | 2 +- .../bigdata/common/huemul_BigDataGovernance.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5478ced..b9ce54a 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.huemulsolutions.bigdata huemul-bigdatagovernance - 2.3 + 2.3.1 HuemulSolutions - BigDataGovernance Enable full data quality and data lineage for BigData Projects. Huemul BigDataGovernance, es una librería que trabaja sobre Spark, Hive y HDFS. Permite la implementación de una **estrategia corporativa de dato único**, basada en buenas prácticas de Gobierno de Datos. diff --git a/src/main/scala/com/huemulsolutions/bigdata/common/huemul_BigDataGovernance.scala b/src/main/scala/com/huemulsolutions/bigdata/common/huemul_BigDataGovernance.scala index e2be372..89af892 100644 --- a/src/main/scala/com/huemulsolutions/bigdata/common/huemul_BigDataGovernance.scala +++ b/src/main/scala/com/huemulsolutions/bigdata/common/huemul_BigDataGovernance.scala @@ -52,7 +52,7 @@ import org.apache.log4j.Level * @param LocalSparkSession(opcional) permite enviar una sesión de Spark ya iniciada. */ class huemul_BigDataGovernance (appName: String, args: Array[String], globalSettings: huemul_GlobalPath, LocalSparkSession: SparkSession = null) extends Serializable { - val currentVersion: String = "2.3" + val currentVersion: String = "2.3.1" val GlobalSettings = globalSettings val warehouseLocation = new File("spark-warehouse").getAbsolutePath //@transient lazy val log_info = org.apache.log4j.LogManager.getLogger(s"$appName [with huemul]") From d3d5f891e8d0c50729d4fe4d78abee2788a372d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Rodr=C3=ADguez=20Robotham?= Date: Sat, 1 Feb 2020 13:11:05 -0300 Subject: [PATCH 2/4] =?UTF-8?q?#89=20agrega=20print=20para=20revisi=C3=B3n?= =?UTF-8?q?=20de=20permisos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../huemulsolutions/bigdata/common/huemul_Authorization.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/com/huemulsolutions/bigdata/common/huemul_Authorization.scala b/src/main/scala/com/huemulsolutions/bigdata/common/huemul_Authorization.scala index c8df093..b2e0c8f 100644 --- a/src/main/scala/com/huemulsolutions/bigdata/common/huemul_Authorization.scala +++ b/src/main/scala/com/huemulsolutions/bigdata/common/huemul_Authorization.scala @@ -15,6 +15,7 @@ class huemul_Authorization extends Serializable { } def HasAccess(ClassName: String, PackageName: String): Boolean = { + //Access.foreach { x => println(s"""${x.getLocalClassName().toUpperCase()} == ${ClassName.replace("$", "").toUpperCase()} && ${x.getLocalPackageName().toUpperCase()} == ${PackageName.replace("$", "").toUpperCase()}""" ) } val values = Access.filter { x => x.getLocalClassName().toUpperCase() == ClassName.replace("$", "").toUpperCase() && x.getLocalPackageName().toUpperCase() == PackageName.replace("$", "").toUpperCase() } return (values.length >= 1 || Access.length == 0 ) From 31389b31f42b5a41dd56515da1b4109e9ca863d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Rodr=C3=ADguez=20Robotham?= Date: Sat, 1 Feb 2020 13:26:29 -0300 Subject: [PATCH 3/4] #89 corrige getClassAndPackage. Iterar hasta llegar a clase que invoca --- .../bigdata/tables/huemul_Table.scala | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/scala/com/huemulsolutions/bigdata/tables/huemul_Table.scala b/src/main/scala/com/huemulsolutions/bigdata/tables/huemul_Table.scala index 85090ab..82d48ca 100644 --- a/src/main/scala/com/huemulsolutions/bigdata/tables/huemul_Table.scala +++ b/src/main/scala/com/huemulsolutions/bigdata/tables/huemul_Table.scala @@ -2750,13 +2750,29 @@ class huemul_Table(huemulBigDataGov: huemul_BigDataGovernance, Control: huemul_C } private def getClassAndPackage(): huemul_AuthorizationPair = { - val Invoker = new Exception().getStackTrace()(2) - val InvokerName: String = Invoker.getClassName().replace("$", "") + var Invoker: StackTraceElement = null + var InvokerName: String = null + var ClassNameInvoker: String = null + var PackageNameInvoker: String = null - val ArrayResult = InvokerName.split('.') - - val ClassNameInvoker = ArrayResult(ArrayResult.length-1) - val PackageNameInvoker: String = InvokerName.replace(".".concat(ClassNameInvoker), "") + var numClassBack: Int = 1 + do { + //repeat until find className different to myself + numClassBack += 1 + Invoker = new Exception().getStackTrace()(numClassBack) + InvokerName = Invoker.getClassName().replace("$", "") + + val ArrayResult = InvokerName.split('.') + + ClassNameInvoker = ArrayResult(ArrayResult.length-1) + PackageNameInvoker = InvokerName.replace(".".concat(ClassNameInvoker), "") + + //println(s"${numClassBack}, ${ClassNameInvoker.toLowerCase()} == ${this.getClass.getSimpleName.toLowerCase()}") + if (ClassNameInvoker.toLowerCase() == this.getClass.getSimpleName.toLowerCase() || ClassNameInvoker.toLowerCase() == "huemul_table") { + Invoker = null + } + + } while (Invoker == null) return new huemul_AuthorizationPair(ClassNameInvoker,PackageNameInvoker) } From 61e03ffd19c7de0dc00c28072d5125a55ff4c366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Rodr=C3=ADguez=20Robotham?= Date: Sat, 1 Feb 2020 17:07:16 -0300 Subject: [PATCH 4/4] =?UTF-8?q?Update=20generador=20de=20c=C3=B3digo=20a?= =?UTF-8?q?=20version=202.3.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bigdata/datalake/huemul_DataLake.scala | 87 ++++++++++--------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/src/main/scala/com/huemulsolutions/bigdata/datalake/huemul_DataLake.scala b/src/main/scala/com/huemulsolutions/bigdata/datalake/huemul_DataLake.scala index 88ede01..d80b6a2 100644 --- a/src/main/scala/com/huemulsolutions/bigdata/datalake/huemul_DataLake.scala +++ b/src/main/scala/com/huemulsolutions/bigdata/datalake/huemul_DataLake.scala @@ -374,25 +374,23 @@ def GenerateInitialCode(PackageBase: String, PackageProject: String, NewObjectNa LocalFields += s" ,${x.getcolumnName_Business}\n" LocalMapping += s" huemulTable.${x.getcolumnName_Business}.SetMapping(${Coma}${x.getcolumnName_Business}${Coma})\n" - LocalColumns += s" val ${x.getcolumnName_Business} = new huemul_Columns (${x.getDataType}, true, ${Coma}${x.getDescription}${Coma}) \n" - LocalColumns += s" ${x.getcolumnName_Business}.setARCO_Data(false) \n" - LocalColumns += s" ${x.getcolumnName_Business}.setSecurityLevel(huemulType_SecurityLevel.Public) \n" + LocalColumns += s" val ${x.getcolumnName_Business} = new huemul_Columns (${x.getDataType}, true, ${Coma}${x.getDescription}${Coma})" if (TableType == huemulType_Tables.Master || TableType == huemulType_Tables.Reference) { - LocalColumns += s" ${x.getcolumnName_Business}.setMDM_EnableOldValue(true) \n" - LocalColumns += s" ${x.getcolumnName_Business}.setMDM_EnableDTLog(true) \n" - LocalColumns += s" ${x.getcolumnName_Business}.setMDM_EnableProcessLog(true) \n" + LocalColumns += s".setMDM_EnableOldValue().setMDM_EnableDTLog().setMDM_EnableProcessLog()" } + LocalColumns += s" \n" + if (huemulBigDataGov.IsNumericType(x.getDataType)) { - LocalColumns += s" //${x.getcolumnName_Business}.setDQ_MinDecimalValue(Decimal.apply(0)) \n" - LocalColumns += s" //${x.getcolumnName_Business}.setDQ_MaxDecimalValue(Decimal.apply(200.34)) \n" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MinDecimalValue(Decimal.apply(0),"DQ_USER_ERROR_") \n""" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MaxDecimalValue(Decimal.apply(200.34),"DQ_USER_ERROR_") \n""" } else if (huemulBigDataGov.IsDateType(x.getDataType)) { - LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MinDateTimeValue("2018-01-01") \n""" - LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MaxDateTimeValue("2018-12-31") \n""" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MinDateTimeValue("2018-01-01","DQ_USER_ERROR_") \n""" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MaxDateTimeValue("2018-12-31","DQ_USER_ERROR_") \n""" } else if (x.getDataType == StringType) { - LocalColumns += s" //${x.getcolumnName_Business}.setDQ_MinLen(5) \n" - LocalColumns += s" //${x.getcolumnName_Business}.setDQ_MaxLen(100) \n" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MinLen(5,"DQ_USER_ERROR_") \n""" + LocalColumns += s""" //${x.getcolumnName_Business}.setDQ_MaxLen(100,"DQ_USER_ERROR_") \n""" } LocalColumns += s"\n" @@ -441,12 +439,11 @@ class ${NewTableName}(huemulBigDataGov: huemul_BigDataGovernance, Control: huemu this.setLocalPath("${LocalPath}") //Frecuencia de actualización this.setFrequency(huemulType_Frequency.${Frecuency}) - //Permite guardar los errores y warnings en la aplicación de reglas de DQ, valor por default es true - //this.setSaveDQResult(true) - //Permite guardar backup de tablas maestras - //this.setSaveBackup(true) //default value = false + //permite asignar un código de error personalizado al fallar la PK + this.setPK_externalCode("COD_ERROR") /********** O P T I M I Z A C I O N ****************************************/ + //nuevo desde version 2.0 //Indica la cantidad de particiones al guardar un archivo, para archivos pequeños (menor al bloque de HDFS) se //recomienda el valor 1, mientras mayor la tabla la cantidad de particiones debe ser mayor para aprovechar el paralelismo //this.setNumPartitions(1) @@ -456,6 +453,7 @@ class ${NewTableName}(huemulBigDataGov: huemul_BigDataGovernance, Control: huemu //this.setSaveDQResult(true) //Permite guardar backup de tablas maestras //this.setSaveBackup(true) //default value = false + ${ if (TableType == huemulType_Tables.Transaction) { @@ -489,37 +487,44 @@ class ${NewTableName}(huemulBigDataGov: huemul_BigDataGovernance, Control: huemu ${ if (TableType == huemulType_Tables.Transaction) { s""" //Columna de period - val period_${PeriodName} = new huemul_Columns (StringType, true,"periodo de los datos") - period_${PeriodName}.setIsPK(true) + val period_${PeriodName} = new huemul_Columns (StringType, true,"periodo de los datos").setIsPK() """ } else ""} ${LocalColumns} - //**********Atributos adicionales de DataQuality - //yourColumn.setIsPK(true) //valor por default en cada campo es false - //yourColumn.setIsUnique(true) //valor por default en cada campo es false - //yourColumn.setNullable(true) //valor por default en cada campo es false - //yourColumn.setIsUnique(true) //valor por default en cada campo es false - //yourColumn.setDQ_MinDecimalValue(Decimal.apply(0)) - //yourColumn.setDQ_MaxDecimalValue(Decimal.apply(200.0)) - //yourColumn.setDQ_MinDateTimeValue("2018-01-01") - //yourColumn.setDQ_MaxDateTimeValue("2018-12-31") - //yourColumn.setDQ_MinLen(5) - //yourColumn.setDQ_MaxLen(100) - //yourColumn.setDQ_RegExp("") //desde versión 2.0 - //yourColumn.setDefaultValue("'string'") // "10" // "'2018-01-01'" + //**********Atributos adicionales de DataQuality + /* + .setIsPK() //por default los campos no son PK + .setIsUnique("COD_ERROR") //por default los campos pueden repetir sus valores + .setNullable() //por default los campos no permiten nulos + .setDQ_MinDecimalValue(Decimal.apply(0),"COD_ERROR") + .setDQ_MaxDecimalValue(Decimal.apply(200.0),"COD_ERROR") + .setDQ_MinDateTimeValue("2018-01-01","COD_ERROR") + .setDQ_MaxDateTimeValue("2018-12-31","COD_ERROR") + .setDQ_MinLen(5,"COD_ERROR") + .setDQ_MaxLen(100,"COD_ERROR") + .setDQ_RegExpresion("","COD_ERROR") //desde versión 2.0 + */ //**********Atributos adicionales para control de cambios en los datos maestros - //yourColumn.setMDM_EnableDTLog(true) - //yourColumn.setMDM_EnableOldValue(true) - //yourColumn.setMDM_EnableProcessLog(true) - //yourColumn.setMDM_EnableOldValue_FullTrace(true) //desde 2.0: guarda cada cambio de la tabla maestra en tabla de trace + /* + .setMDM_EnableDTLog() + .setMDM_EnableOldValue() + .setMDM_EnableProcessLog() + .setMDM_EnableOldValue_FullTrace() //desde 2.0: guarda cada cambio de la tabla maestra en tabla de trace + */ //**********Otros atributos de clasificación - //yourColumn.setEncryptedType("tipo") - //yourColumn.setARCO_Data(true) - //yourColumn.setSecurityLevel(huemulType_SecurityLevel.Public) - //yourColumn.setBusinessGlossary_Id("BG_ID") //desde 2.0: enlaza id de glosario de términos con campos de la tabla - + /* + .encryptedType("tipo") + .setARCO_Data() + .securityLevel(huemulType_SecurityLevel.Public) + .setBusinessGlossary("CODIGO") //desde 2.0: enlaza id de glosario de términos con campos de la tabla + */ + //**********Otros atributos + /* + .setDefaultValues("'string'") // "10" // "'2018-01-01'" + .encryptedType("tipo") + */ //**********Ejemplo para aplicar DataQuality de Integridad Referencial //val i[[tbl_PK]] = new [[tbl_PK]](huemulBigDataGov,Control) @@ -537,7 +542,7 @@ ${LocalColumns} //******************** SaveErrorDetails es opcional, por default es "true", permite almacenar el detalle del error o warning en una tabla específica, debe estar habilitada la opción DQ_SaveErrorDetails en GlobalSettings //******************** DQ_ExternalCode es opcional, por default es "null", permite asociar un Id externo de DQ //val DQ_NombreRegla: huemul_DataQuality = new huemul_DataQuality(ColumnXX,"Descripcion de la validacion", "Campo_1 > Campo_2",1) - //**************Adicionalmeente, puedes agregar "tolerancia" a la validacion, es decir, puedes especiicar + //**************Adicionalmente, puedes agregar "tolerancia" a la validacion, es decir, puedes especiicar //************** numFilas = 10 para permitir 10 errores (al 11 se cae) //************** porcentaje = 0.2 para permitir una tolerancia del 20% de errores //************** ambos parametros son independientes (condicion o), cualquiera de las dos tolerancias que no se cumpla se gatilla el error o warning